Put values from an array in a while loop into a table
14 Ansichten (letzte 30 Tage)
Ältere Kommentare anzeigen
Vladislavs Grigorjevs
am 6 Apr. 2022
Kommentiert: Vladislavs Grigorjevs
am 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 Kommentare
Akzeptierte Antwort
Stephen23
am 6 Apr. 2022
Bearbeitet: Stephen23
am 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 Kommentare
Stephen23
am 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.
Weitere Antworten (1)
Simon Allosserie
am 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 Kommentare
Simon Allosserie
am 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
am 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.
Siehe auch
Kategorien
Mehr zu Logical finden Sie in Help Center und File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!