Indexing a variable using the slice of another matrix
6 次查看(过去 30 天)
显示 更早的评论
Hello, I'm struggling to wrap my head around what I think it quite a simple problem My digi-bog model is taking an awfully long time to complete (5hours), I checked the profiler and over 3 hours of that runtime was spent on this line
%% convert Q to water stage
for i = 1:numel(river_discharge_per_channel) % 4.4e6 values (very long daily time series)
[~,index] = min(abs(Q_list-river_discharge_per_channel(i))); %Q_list changing length 2000-7000
water_depth(i) = d(index);
end
This step was being perfomed for every 20 interation of the main loop (12000 iterations, with 365 sub steps). I realised that this was not necassary and that I only needed to calculate the water stage for the next 20 years so I rewrote the above code to:
%% convert Q to water stage
for i = 1:20 % not nessary to go through the entire daily discharge list, we will only do it for 20years
river_discharge_per_channel_year = river_discharge_per_channel(lookup_year==t-1+i); %lookup_year is the year corresponding to the daily values (I made a lookup table for this) t = the main yearly loop
for j = 1:numel(river_discharge_per_channel_year)
[~,index] = min(abs(Q_list-river_discharge_per_channel_year(j)));
water_depth(river_discharge_per_channel(lookup_year==t-1+i(j))) = d(index); % this is where I'm going wrong, I want to reference the day within the yearly slice I made earlier.
end
end
It's when I try to assign the water_depth values (d) back into the daily list of water_depths, I'm not managing the index it correctly. I attempt this with this line:
water_depth(river_discharge_per_channel(lookup_year==t-1+i(j))) = d(index);
I'm not sure this is possible the way I'm trying to accomplish it, suggestions most welcome. I'm not sure the issue will be understood easily by readers, not least of becuase of my dyslexic brain, so questions most welcome.
Thanks in advance
Alex
5 个评论
Matt J
2021-5-29
编辑:Matt J
2021-6-4
Well, I think I've already given it to you in my Answer below. Once you know how to rewrite the first version of your loop, it is straightforward to rewrite your double for-loop in a similar way (however, I don't see any benefit to this):
%% convert Q to water stage
[Q_list, isort]=sort(Q_list);
d=d(isort);
for i = 1:20 % not nessary to go through the entire daily discharge list, we will only do it for 20years
index=(lookup_year==t-1+i);
water_depth(index) = interp1(Q_list,d, river_discharge_per_channel(index), 'nearest');
end
采纳的回答
Matt J
2021-5-29
编辑:Matt J
2021-6-4
Your original loop,
for i = 1:numel(river_discharge_per_channel) % 4.4e6 values (very long daily time series)
[~,index] = min(abs(Q_list-river_discharge_per_channel(i))); %Q_list changing length 2000-7000
water_depth(i) = d(index);
end
can be replaced with the following,
[Q_list, isort]=sort(Q_list);
d=d(isort);
water_depth = interp1(Q_list,d, river_discharge_per_channel, 'nearest');
You then showed us a modified version with a double for-loop. Adapting the above to this is straightforward,
for i = 1:20 % not nessary to go through the entire daily discharge list, we will only do it for 20years
index=(lookup_year==t-1+i);
water_depth(index) = interp1(Q_list,d, river_discharge_per_channel(index), 'nearest');
end
but might be unnecessary and sub-optimal. I don't see why you wouldn't use the original version, which requires no loops.
7 个评论
Matt J
2021-6-4
You can discard that. It's a remnant of an earlier version of my answer which turned out to be unnecessary.
更多回答(0 个)
另请参阅
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!