Put values from an array in a while loop into a table
21 views (last 30 days)
Show older comments
Vladislavs Grigorjevs
on 6 Apr 2022
Commented: Vladislavs Grigorjevs
on 6 Apr 2022
I have a while loop that produces an array of values in each iteration. What I need is for this array to be output in tabular form, ideally into an Excel table, into a new row for each iteration. Here's what the while loop looks like:
while any(maxnrep~=0)
f = [zeros(1,n) 1];
intcon = 1:n;
% A*w + x == s
Aeq = [A 1];
beq = s;
lb = [zeros(1,n) 0];
hb = [maxnrep, Inf];
wx = intlinprog(f, intcon, [], [], Aeq, beq, lb, hb, options);
% number of coins to approximate s
w=round(wx(1:n))';
% the residual x
x = s - sum(w.*A); % == wx(n+1)
if any(w~=y)
iterCount_sub=iterCount-iterCount_sub;
if c~=1
fprintf ('Repeat %.0f times \n', iterCount_sub)
end
fprintf ('\nWay number %.0f\n', c);
fprintf(['%.1f = ' repmat('%.1d*%.0f + ', 1, n) '%.0f\n'], s, [w; A], x)
c=c+1;
iterCount_sub=iterCount;
end
maxnrep = maxnrep - w;
y=w;
iterCount=iterCount+1;
end
The array I need to get into a table is w. I also need separate columns for x and iterCount_sub. As of now, the output looks like this:
Way number 1
12000.0 = 0*6690 + 0*4740 + 0*5990 + 0*6540 + 0*4840 + 0*3240 + 3*4000 + 0
Repeat 609 times
Way number 2
12000.0 = 0*6690 + 1*4740 + 0*5990 + 0*6540 + 0*4840 + 1*3240 + 1*4000 + 20
Repeat 2 times
Way number 3
12000.0 = 0*6690 + 0*4740 + 2*5990 + 0*6540 + 0*4840 + 0*3240 + 0*4000 + 20
Repeat 120 times
etc..
Here, each value that goes before the * sign is part of the w array, and each value that goes after it is part of the A array, the values for which are input by the user.
What I need in the end should look something like this, along with an Excel table:
6690 4740 5990 6540 4840 3240 4000 x rep. count
---- ---- ---- ---- ---- ---- ---- --- ----------
0 0 0 0 0 0 3 0 609
0 1 0 0 0 1 1 20 2
0 0 2 0 0 0 0 20 120
% Is this possible?
0 Comments
Accepted Answer
Stephen23
on 6 Apr 2022
Edited: Stephen23
on 6 Apr 2022
There is no need to create lots of separate vectors, doing so would be very inefficient.
Much simpler to convert the matrix using ARRAY2TABLE and then save the table. Note that the table variable/columns names do not need to have 'c' as lead character.
M = [0,0,0,0,0,0,3,0,609;0,1,0,0,0,1,1,20,2;0,0,2,0,0,0,0,20,120]
S = ["6690","4740","5990","6540","4840","3240","4000","x","rep.count"];
T = array2table(M,'VariableNames',S)
writetable(T,"coefficienttable.xlsx")
5 Comments
Stephen23
on 6 Apr 2022
"Is there any way I could suppress that first 0 value and move all of the values up 1 row?"
You could either modify your code to include that offset, or modify the data after the loop, e.g. something like this:
M(:,end) = [M(2:end,end);NaN];
The last row doesn't need a rep.count value."
But numeric arrays cannot have "holes" in them, so there has to be some value there. What value depends on you. As an alternative you could replace the entire table column/variable with a cell array of scalar numerics and place an empty array in the last cell.
More Answers (1)
Simon Allosserie
on 6 Apr 2022
To put info in tables, you best put them in columns. So you could define coefficient vectors for each coefficient, and through your loops add values to these column vectors. In your example, they would look like this
c6690 = [0 0 0]' %a variable name can't start with a number, so I start the name with c(oefficient)
c4740 = [0 1 0]'
c5590 = [0 0 2]'
..
repcount = [609 2 120]'
Then you define a table like (see https://nl.mathworks.com/help/matlab/ref/table.html)
T = table(c9960, c4740, .., repcount)
Next write it to Excel using writetable (see https://nl.mathworks.com/help/matlab/ref/writetable.html)
writetable(T,"coefficienttable.xlsx")
That should do the trick.
3 Comments
Simon Allosserie
on 6 Apr 2022
In that case, you could make one matrix instead of column matrices, where the size is dependent on the user input. The user should then also give the column names such that you can define the table as
T = table(M, 'VariableNames', {'c6690','c4740', .., 'repcount'})
Of course, you can also create the variableNames yourself by converting the coefficients to text with num2str() and adding 'c' before it with strcat()
For the length of the vectors/size of the matrix, there are multiple options.
1) You can predefine the length very largely, e.g.
c = zeros(1000,1)
after calculations, you can shorten the matrices to delete the zero elements.
2) You can just add elements in each iteration
c(i) = value
and in the case c is 10 long, and you add c(11), matlab will automatically make c longer to be able to add this element on that location. The drawback here is that this takes a lot of time, so option (1) is recommended.
Stephen23
on 6 Apr 2022
"...you can define the table as T = table(M, 'VariableNames', {'c6690','c4740', .., 'repcount'})"
No, that will not work. Lets try it with a simple example:
M = rand(5,3);
T = table(M, 'VariableNames', {'c6690','c4740','repcount'})
Why does it not work? Because it creates a table with one variable/column, but then attempts to name three variables. Thus the number of variable names does not match the number of variables/columns, as the error clearly states.
See Also
Categories
Find more on Loops and Conditional Statements in Help Center and File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!