how to fix a nested for loop

2 次查看(过去 30 天)
Vert
Vert 2014-10-20
回答: Orion 2014-10-21
I am trying to run through several values for two of the variables in a function. The function worked fine when I gave it individual values for K and Smax but I can't get the loop to work.
I keep getting one of two errors, no matter what I've tried: Subscripted assignment dimension mismatch. -OR- Attempted to access Storage(2,2); index out of bounds because size(Storage)=[1,2].
Below is the code I'm working on and the data file is attached.
Define parameter space
K_min = 0.01; K_max = 1;
Smax_min = 10; Smax_max = 500;
stride = 10; % or 50 or 100
K = linspace(K_min,K_max,stride); % vector of k
K = repmat(K,[stride,1]); %space of k
Smax = linspace(Smax_min,Smax_max,stride);
Smax = repmat(Smax,[stride,1]);
Run Model
Storage = [Precipmmday(1) 0];
for Smax = 1:stride;
for K = 1:stride;
for k1 = 2:length(Precipmmday)
Storage = [Precipmmday(1) 0];
Baseflow = [Precipmmday(1) 0 ];
Baseflow (k1,:) = [(Storage(k1-1,2)+Precipmmday(k1-1))*K];
Storage(k1,:) = [(Storage(k1-1,2)+Precipmmday(k1-1))*(1-K)];
end
end
end
ModelStorage = Storage;
SynthStorage (:,1) =[];
ModelSpill=ModelStorage - Smax;
ModelSpill(ModelSpill<0)=0;
ModelStorage(ModelStorage>Smax)=Smax;
ModelBaseflow = Baseflow;
ModelBaseflow (:,1) = [];
ModelOutflow = ModelBaseflow + ModelSpill;
I know it's clunky, I'm new to MatLab. It doesn't have to be pretty, I just want it to work!
Any help appreciated.

回答(3 个)

Orion
Orion 2014-10-20
Hi Rosa,
- the variable Precipmmday is not defined in your code.
- you should reedit your question with the code part formatted, so we can check it more easily.
- about the error you get Attempted to access Storage(2,2); index out of bounds because size(Storage)=[1,2].
in your loop, at every iteration, you redefine
Storage = [Precipmmday(1) 0];
so Storage is a row vector with 2 elements, and then you do
Baseflow (k1,:) = [(Storage(k1-1,2)+Precipmmday(k1-1))*K];
if k1 == 2, it works, but at the second iteration, k1 = 3, and so you are trying to access the second row of a one row vector, which gives you that error.
also, there are the two consecutive lines :
Baseflow = [Precipmmday(1) 0 ];
Baseflow (k1,:) = [(Storage(k1-1,2)+Precipmmday(k1-1))*K];
the first line will reset the variable Baseflow at each iteration, which is probably not what you want
  1 个评论
Vert
Vert 2014-10-20
Thank you for replying. I re-formatted it.
Yes, I think I see what you mean, but I don't know how to fix the dimensions problem. I had used that code earlier to calculate the variables for one set of parameters and it worked, but now trying to run through multiple parameter sets, I can't figure it out.
Below is the rest of what I was doing, if that helps.
Basic Variables
TimeDay = 1:1088;
TimeDay = TimeDay';
%Precipitation Time Series
%
plot(TimeDay, Precipmmday)
xlabel('Time (day)');
ylabel('Rainfall (mm/day)');
title('Precipitation');
No Spill Scenario Storage where k=0.3; Smax=100
SynthK=0.3;
SynthSmax=100;
Storage = [Precipmmday(1) 0];
Baseflow = [Precipmmday(1) 0 ];
for k1 = 2:length(Precipmmday)
Baseflow (k1,:) = [(Storage(k1-1,2)+Precipmmday(k1-1))*SynthK];
Storage(k1,:) = [(Storage(k1-1,2)+Precipmmday(k1-1))*(1-SynthK)];
end
SynthStorage = Storage;
SynthStorage (:,1) =[];
SynthSpill=SynthStorage - SynthSmax;
SynthSpill(SynthSpill<0)=0;
SynthStorage(SynthStorage>SynthSmax)=SynthSmax;
SynthBaseflow = Baseflow;
SynthBaseflow (:,1) = [];
SynthOutflow = SynthBaseflow + SynthSpill;
Define parameter space
K_min = 0.01; K_max = 1;
Smax_min = 10; Smax_max = 500;
stride = 10; % or 50 or 100
K = linspace(K_min,K_max,stride); % vector of k
K = repmat(K,[stride,1]); %space of k
Smax = linspace(Smax_min,Smax_max,stride);
Smax = repmat(Smax,[stride,1]);
Run Model
for Smax = 1:stride;
for K = 1:stride;
Baseflow (k1,:) = [(Storage(k1-1,2)+Precipmmday(k1-1))*K];
Storage(k1,:) = [(Storage(k1-1,2)+Precipmmday(k1-1))*(1-K)];
end
end
ModelStorage = Storage;
SynthStorage (:,1) =[];
ModelSpill=ModelStorage - Smax;
ModelSpill(ModelSpill<0)=0;
ModelStorage(ModelStorage>Smax)=Smax;
ModelBaseflow = Baseflow;
ModelBaseflow (:,1) = [];
ModelOutflow = ModelBaseflow + ModelSpill;
Thanks again for your help.

请先登录,再进行评论。


Orion
Orion 2014-10-20
your double loop is not using the index Smax. also, k1 is fixed in this double loop.
this doesn't mean so much ?
(and Precipmmday still not defined.)
  1 个评论
Vert
Vert 2014-10-20
I cleaned it up a bit and tried to address what you're saying, but I can't get it to run. Can you give any suggestions about what I should do to fix the issues? (I see what you are saying but this is my first time in MatLab and I can't figure out how to actually address the problems)
My goal is for it to repeat through every combination of K and Smax.
Run Model
Storage = [Precipmmday(1) 0];
Baseflow = [Precipmmday(1) 0];
for Smax = linspace(10,500,10);
Smax = repmat(Smax,10,1);
for K = linspace(0.01,1,10);
K = repmat(K,10,1);
for k1 = 2:length(Precipmmday)
Baseflow(k1,:) = [(Storage(k1-1,2)+Precipmmday(k1-1))*K];
Storage(k1,:) = [(Storage(k1-1,2)+Precipmmday(k1-1))*(1-K)];
end
ModelStorage = Storage;
ModelSpill=ModelStorage - Smax;
ModelSpill(ModelSpill<0)=0;
ModelStorage(ModelStorage>Smax)=Smax;
ModelBaseflow = Baseflow;
ModelOutflow = ModelBaseflow + ModelSpill;
end
end

请先登录,再进行评论。


Orion
Orion 2014-10-21
this code just can't work because you're redefining the index variable Smax ans K inside the loops
for Smax = linspace(10,500,10);
Smax = repmat(Smax,10,1);
You must never do that (you will lost control of your code).
I don't know the problem you're studying. But here's what you should do to achieve your goal.
Write properly your algorithm on a paper (not the code, just the idea) and identify which variable must be a scalar, a vector, a matrix.
because, when you do Smax = linspace(10,500,10); , you're creating a vector, but then Smax = repmat(Smax,10,1), you're creating a matrix, in which all lines are the same (is there a real meaning to this), and so on for K.
So, what do you you need to create in the end : vector or matrix (ModelBaseflow, ModelOutflow ,...) ?
According your need, you will create 1 or loops, and manipulate differents index.

Community Treasure Hunt

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

Start Hunting!

Translated by