Loop with several conditions

2 views (last 30 days)
Julie Møller
Julie Møller on 27 Apr 2021
Commented: Julie Møller on 28 Apr 2021
I struggle with making a loop containing several conditions at once.
I have a matrix consisting of days (1st column), hours (2nd column) and a temperature value (3rd column). The total length of the matrix is (183 days x 24 hours =) 4392. Some days have no temp. value and other days have two temp. values.
All NaN-values should be found using linear interpolation, however some conditions apply:
If a day has two values e.g. day 61 (hour 6 and 16) (see screenshot (1)), the values for the hours in between (hour 7 to 15) is found by linear interpolation.
The values for day 61 before hour 6 and after hour 16 are also found by linear interpolation. The values before hour 6 is depending on day 60 having two values or not, and the same applies for the values after hour 16 that is then depending on day 62 having two values or not.
Day 60 does not have two values assigned (see screenshot (2)) and the way I need the interpolation to be done for the values before hour 6 is that a zero should be assigned for the hour located 12 hours before hour 6 (being day 60 hour 18) and then linear interpolation should be done for the 11 hours in between (hour 19 to 5).
On the other hand, day 62 has a value assigned at hour 3 (and 13) (see screenshot (3)), whereby the values between day 61 hour 16 and day 62 hour 3 need to be linearly interpolated between the corresponding values.
However, if day 62 had no values assigned, a zero should be assigned to the hour located 12 hours ahead of day 61 hour 16 and the values for the 11 hours in between should then be linearly interpolated as for the 12 hours before days 61 hour 6.
If several adjacent days have no values assigned, they should be zero. So, the values before day 60 hour 18 should be zeros until another value appears which happens to be at day 58 hours 24. In this case, zeros should then only be assigned until day 59 hour 12 as the same principle with the 12 hours ahead of day 58 hour 24 applies.
And so on and so forth for all hours of the 183 days.
I really struggle with making a loop containing all these conditions.. I hope someone can help me figuring it out!
If you have difficulties understanding the conditions, don’t hesitate to ask and I will try to elaborate further.
/Julie
  1 Comment
DGM
DGM on 27 Apr 2021
Edited: DGM on 27 Apr 2021
I don't really see this as a multiple conditions problem. You'd find days without Tdata, place zeros (or other dummy data) accordingly. Once all days have datapoints, extract only the rows with non-NaN Tdata, and do interp1() on the whole thing.

Sign in to comment.

Accepted Answer

DGM
DGM on 27 Apr 2021
Edited: DGM on 27 Apr 2021
Maybe this is a start.
% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% build example data
A = zeros([240 3]);
for d=1:10
A(24*(d-1)+(1:24),1) = 60+(d-1);
A(24*(d-1)+(1:24),2) = 1:24;
A(24*(d-1)+(1:24),3) = NaN;
if any((d-1)==[1 2 4 5 9])
A(24*(d-1)+[5 17],3) = rand(2,1);
end
end
% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% show initial datapoints
plot(A(:,1)+(A(:,2)-1)/24,A(:,3),'bo'); hold on; grid on
daylist = unique(A(:,1));
hassamples = ismember(daylist,unique(A(~isnan(A(:,3)),1)))'
firstzero = [0 -diff(hassamples)]==1;
lastzero = [diff(hassamples) 0]==1;
needsfirst = daylist(firstzero) % days which need first sample
for d=1:numel(needsfirst)
idxp = find(A(:,1)==(needsfirst(d)-1)); % rows corresponding to prior day
lastdatapointhour = find(~isnan(A(idxp,3)),1,'last');
A(idxp(lastdatapointhour)+12,3) = 0; % insert sample
end
needssecond = daylist(lastzero) % days which need second sample
for d=1:numel(needssecond)
idxn = find(A(:,1)==(needssecond(d)+1)); % rows corresponding to next day
nextdatapointhour = find(~isnan(A(idxn,3)),1,'first');
A(idxn(nextdatapointhour)-12,3) = 0; % insert sample
end
T = A(:,3); % extract T data
xf = 1:numel(T);
x = xf(~isnan(T)); % strip NaN samples
T = T(~isnan(T));
% interpolate, using 0 for extrapolated values at ends
% adjust as needed
A(:,3) = interp1(x,T,xf,'linear',0);
% show interpolated data
plot(A(:,1)+(A(:,2)-1)/24,A(:,3));
It might be faster to strip NaNs first, allowing work on smaller arrays, but I chose to do it this way instead.
  1 Comment
Julie Møller
Julie Møller on 28 Apr 2021
Thank you very much, your code does exactly what I requested! I had difficulties thinking my way through the problem and what commands would be smart to use. I can follow your code, and of course it seems simpler now, thank you for your time :-)

Sign in to comment.

More Answers (0)

Categories

Find more on Loops and Conditional Statements in Help Center and File Exchange

Tags

Community Treasure Hunt

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

Start Hunting!