MATLAB Answers

How to store matrices in a cell from a loop?

4 views (last 30 days)
Pedro Leal
Pedro Leal on 15 Jul 2021
Commented: Pedro Leal on 19 Jul 2021
I am running an external software (GAMS) to do some optimization where I call GAMS in a loop and get back 16 variables (matrices) that I want to store in a cell in every iteration from the loop. I have trouble doing so without delcaring the variables in the workspace first. See bellow what I did. Thanks.
for k = 1:55
% Some calculations in every iteration (k)
% Call GAMS model in every iteration (k) and get 16 variables
[Var1 Var2 Var3 ...] = gams('My_model.gms')
% This is what I do now but want to modify
Var1(:,k) = Var1.val(:,2);
Var2(:,k) = Var2.val(:,2);
Var3(:,k) = Var3.val(:,2);
end
Instead of declaring every variable in the workspace, which are matrices (24x55), I want to store the variables in a cell array: My_cell = {1,16}, where each cell is the matrix (24x55) that results from the iterations and I need to add a header to each cell to identify the variables.
The difficulty I have is that every matrix is written in sequence (k) e.g, k=1 (24x1), k=2 (24x2) ... k=55 (24x55) and at the same time I need to fill the cells of My_cell = {1,16} in the loop. I have tried with a nested loop without success.
  2 Comments
Pedro Leal
Pedro Leal on 15 Jul 2021
This is the code I am using:
for k=1:55
Parameters = [t_day,PV,Load,Pbuy,Psell,EV,Heat,Pdrive,Pup];
writematrix(Parameters,'Parameters.csv');
% Call GAMS
[Cost, GridCosts, IntCosts, BatCosts, EVCosts, RegCosts, Ppv, Pev, Pbat, ...
Pinv, Pgrid, Ebat, Eev, Pev_up, Pev_dwn, Pbat_up, Pbat_dwn, Ppv_dwn, P_reg_up, ...
P_reg_dwn, SoC_bat, SoC_ev] = gams('Model.gms');
% Scheduled outputs from GAMS
Ppv_sched_W(:,k) = Ppv.val(:,2);
Pev_sched_W(:,k) = Pev.val(:,2);
Pbat_sched_W(:,k) = Pbat.val(:,2);
Pinv_sched_W(:,k) = Pinv.val(:,2);
Pgrid_sched_W(:,k) = Pgrid.val(:,2);
Ebat_sched_W(:,k) = Ebat.val(:,2);
Eev_sched_W(:,k) = Eev.val(:,2);
Pev_up_sched_W(:,k) = Pev_up.val(:,2);
Pev_dwn_sched_W(:,k) = Pev_dwn.val(:,2);
Pbat_up_sched_W(:,k) = Pbat_up.val(:,2);
Pbat_dwn_sched_W(:,k) = Pbat_dwn.val(:,2);
Ppv_dwn_sched_W(:,k) = Ppv_dwn.val(:,2);
P_reg_up_sched_W(:,k) = P_reg_dwn.val(:,2);
P_reg_dwn_sched_W(:,k) = P_reg_dwn.val(:,2);
SoC_bat_sched_W(:,k) = SoC_bat.val(:,2);
SoC_ev_sched_W(:,k) = SoC_ev.val(:,2);
end
What the output needs to be is a cell array: M = (1x16) where every M{1} = (24x55). Each column of the cell stores one matrix (24x55), corresponding to each of the 16 variables above. Those variables are obtained as a vector (24x1) for every iteration k and they fill every column of each matrix until k = 25. Hope this is clearer.

Sign in to comment.

Accepted Answer

Stephen
Stephen on 16 Jul 2021
Edited: Stephen on 16 Jul 2021
Rather than lots of separate variables, use a comma-separated list to store the function outputs:
then transfer the required data to preallocated output matrices. Something like this should get you started:
itr = 55;
tmp = cell(1,22);
out = tmp;
out(:) = {nan(24,itr)};
for ii = 1:itr
[tmp{:}] = gams('Model.gms');
for jj = 1:numel(tmp)
out{jj}(:,ii) = tmp{jj}.val(:,2);
end
end
Checking the output (note that it is simpler to collect all 22(?) outputs, not just the 16 that you need. If you really can only collect those 16 outputs, add indexing as appropriate):
out
out = 1×22 cell array
{24×55 double} {24×55 double} {24×55 double} {24×55 double} {24×55 double} {24×55 double} {24×55 double} {24×55 double} {24×55 double} {24×55 double} {24×55 double} {24×55 double} {24×55 double} {24×55 double} {24×55 double} {24×55 double} {24×55 double} {24×55 double} {24×55 double} {24×55 double} {24×55 double} {24×55 double}
out{1} % first cell
ans = 24×55
1101 2101 3101 4101 5101 6101 7101 8101 9101 10101 11101 12101 13101 14101 15101 16101 17101 18101 19101 20101 21101 22101 23101 24101 25101 26101 27101 28101 29101 30101 1102 2102 3102 4102 5102 6102 7102 8102 9102 10102 11102 12102 13102 14102 15102 16102 17102 18102 19102 20102 21102 22102 23102 24102 25102 26102 27102 28102 29102 30102 1103 2103 3103 4103 5103 6103 7103 8103 9103 10103 11103 12103 13103 14103 15103 16103 17103 18103 19103 20103 21103 22103 23103 24103 25103 26103 27103 28103 29103 30103 1104 2104 3104 4104 5104 6104 7104 8104 9104 10104 11104 12104 13104 14104 15104 16104 17104 18104 19104 20104 21104 22104 23104 24104 25104 26104 27104 28104 29104 30104 1105 2105 3105 4105 5105 6105 7105 8105 9105 10105 11105 12105 13105 14105 15105 16105 17105 18105 19105 20105 21105 22105 23105 24105 25105 26105 27105 28105 29105 30105 1106 2106 3106 4106 5106 6106 7106 8106 9106 10106 11106 12106 13106 14106 15106 16106 17106 18106 19106 20106 21106 22106 23106 24106 25106 26106 27106 28106 29106 30106 1107 2107 3107 4107 5107 6107 7107 8107 9107 10107 11107 12107 13107 14107 15107 16107 17107 18107 19107 20107 21107 22107 23107 24107 25107 26107 27107 28107 29107 30107 1108 2108 3108 4108 5108 6108 7108 8108 9108 10108 11108 12108 13108 14108 15108 16108 17108 18108 19108 20108 21108 22108 23108 24108 25108 26108 27108 28108 29108 30108 1109 2109 3109 4109 5109 6109 7109 8109 9109 10109 11109 12109 13109 14109 15109 16109 17109 18109 19109 20109 21109 22109 23109 24109 25109 26109 27109 28109 29109 30109 1110 2110 3110 4110 5110 6110 7110 8110 9110 10110 11110 12110 13110 14110 15110 16110 17110 18110 19110 20110 21110 22110 23110 24110 25110 26110 27110 28110 29110 30110
"I need to add a header to each cell to identify the variables."
Cell arrays do not have headers. If you want a header then you should use a structure or a table, for example:
fld = {'Cost', 'GridCosts', 'IntCosts', 'BatCosts', 'EVCosts', 'RegCosts', 'Ppv', 'Pev', 'Pbat', 'Pinv', 'Pgrid', 'Ebat', 'Eev', 'Pev_up', 'Pev_dwn', 'Pbat_up', 'Pbat_dwn', 'Ppv_dwn', 'P_reg_up', 'P_reg_dwn', 'SoC_bat', 'SoC_ev'};
str = cell2struct(out,fld,2)
str = struct with fields:
Cost: [24×55 double] GridCosts: [24×55 double] IntCosts: [24×55 double] BatCosts: [24×55 double] EVCosts: [24×55 double] RegCosts: [24×55 double] Ppv: [24×55 double] Pev: [24×55 double] Pbat: [24×55 double] Pinv: [24×55 double] Pgrid: [24×55 double] Ebat: [24×55 double] Eev: [24×55 double] Pev_up: [24×55 double] Pev_dwn: [24×55 double] Pbat_up: [24×55 double] Pbat_dwn: [24×55 double] Ppv_dwn: [24×55 double] P_reg_up: [24×55 double] P_reg_dwn: [24×55 double] SoC_bat: [24×55 double] SoC_ev: [24×55 double]
str.Cost % checking
ans = 24×55
1101 2101 3101 4101 5101 6101 7101 8101 9101 10101 11101 12101 13101 14101 15101 16101 17101 18101 19101 20101 21101 22101 23101 24101 25101 26101 27101 28101 29101 30101 1102 2102 3102 4102 5102 6102 7102 8102 9102 10102 11102 12102 13102 14102 15102 16102 17102 18102 19102 20102 21102 22102 23102 24102 25102 26102 27102 28102 29102 30102 1103 2103 3103 4103 5103 6103 7103 8103 9103 10103 11103 12103 13103 14103 15103 16103 17103 18103 19103 20103 21103 22103 23103 24103 25103 26103 27103 28103 29103 30103 1104 2104 3104 4104 5104 6104 7104 8104 9104 10104 11104 12104 13104 14104 15104 16104 17104 18104 19104 20104 21104 22104 23104 24104 25104 26104 27104 28104 29104 30104 1105 2105 3105 4105 5105 6105 7105 8105 9105 10105 11105 12105 13105 14105 15105 16105 17105 18105 19105 20105 21105 22105 23105 24105 25105 26105 27105 28105 29105 30105 1106 2106 3106 4106 5106 6106 7106 8106 9106 10106 11106 12106 13106 14106 15106 16106 17106 18106 19106 20106 21106 22106 23106 24106 25106 26106 27106 28106 29106 30106 1107 2107 3107 4107 5107 6107 7107 8107 9107 10107 11107 12107 13107 14107 15107 16107 17107 18107 19107 20107 21107 22107 23107 24107 25107 26107 27107 28107 29107 30107 1108 2108 3108 4108 5108 6108 7108 8108 9108 10108 11108 12108 13108 14108 15108 16108 17108 18108 19108 20108 21108 22108 23108 24108 25108 26108 27108 28108 29108 30108 1109 2109 3109 4109 5109 6109 7109 8109 9109 10109 11109 12109 13109 14109 15109 16109 17109 18109 19109 20109 21109 22109 23109 24109 25109 26109 27109 28109 29109 30109 1110 2110 3110 4110 5110 6110 7110 8110 9110 10110 11110 12110 13110 14110 15110 16110 17110 18110 19110 20110 21110 22110 23110 24110 25110 26110 27110 28110 29110 30110
Fake GAMS function:
function varargout = gams(s)
persistent m
if isempty(m); m=1e3; else m=m+1e3; end
fun = @(n) struct('val',(1:24).'+m+n*[0,100]);
varargout = arrayfun(fun,1:22,'Uni',0);
end
  1 Comment
Pedro Leal
Pedro Leal on 19 Jul 2021
Thanks for te detailed response Stephen! I think this should work, I have not tried it since I have been focusing in some other parts, but will do shortly.

Sign in to comment.

More Answers (1)

ANKUR KUMAR
ANKUR KUMAR on 16 Jul 2021
I am taking random data to show how you can store the output in a cell array using loop.
for index=1:16
output{index}=randi(100,25,55);
end
output
output = 1×16 cell array
{25×55 double} {25×55 double} {25×55 double} {25×55 double} {25×55 double} {25×55 double} {25×55 double} {25×55 double} {25×55 double} {25×55 double} {25×55 double} {25×55 double} {25×55 double} {25×55 double} {25×55 double} {25×55 double}
You can do even without using loop too.
arrayfun(@(x) randi(100,25,55), 1:16, 'uni', 0)
ans = 1×16 cell array
{25×55 double} {25×55 double} {25×55 double} {25×55 double} {25×55 double} {25×55 double} {25×55 double} {25×55 double} {25×55 double} {25×55 double} {25×55 double} {25×55 double} {25×55 double} {25×55 double} {25×55 double} {25×55 double}
  1 Comment
Pedro Leal
Pedro Leal on 19 Jul 2021
Thanks for the response Ankur. I understand that it is possible to do it without the loop, however for this particular case I am not quite sure is possible since I have to initialize the external optimization every time and then gather the output data to be stored in the cell array.

Sign in to comment.

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!