MATLAB Answers

Calculating area under curve with cutoff

18 views (last 30 days)
Robin Schäfer
Robin Schäfer on 13 Feb 2020 at 19:26
Edited: darova on 15 Feb 2020 at 18:26
Hey Community,
I got a n-by-1 row vector obtained by measured data with n likely beeing about 100.000. The values can be either positive or negative and are derived as the difference from 2 other functions:
I calculated the area with cumtrapz / cumsum (red line):
The value of the cumulated area under the curve should display a state which can not be negative. Therefore, I want to lift up the curve in the upper graph in the consecutive negativ intervals, so it looks like the blue line. To get there i used this code:
dv=diff(v);
for a=1:length(v)-2
if v(a)<0
if dv(a)>0 && dv(a+1)<=0
v(a:end)=v(a:end)-v(a);
end
v(a)=0;
end
end
This code works for me, but it is not very economic. I would like to avoid the for loop and use a faster vectorized solution because of speed. The function is going to be called about thousand times or even more often with vectors about 100k. Could you help me to find a more convenient way for calculation?
A possible solution could seek for consecutive local minima (tn). Detect the first point following after the local minimum which is equal (pn) and then create a stepwise mixed function which looks similar to this one:

  4 Comments

Show 1 older comment
Robin Schäfer
Robin Schäfer on 14 Feb 2020 at 18:55
If you mean the last plot (single blue line): It is the difference between the red and blue line from the upper graph. Therefore, it is somehow the result from my for-loop. If I can create the curve by a vectorized solution it is just a simple addition...
darova
darova on 14 Feb 2020 at 19:02
Im aksing about this curve
Don't understand how do you want to lift the red one up
Robin Schäfer
Robin Schäfer on 15 Feb 2020 at 13:41
Okay - The for-loop above is doing what I want:
dv=diff(v); % difference to determine local minima
for a=1:length(v)-2
if v(a)<0 % for all negative values: set zero
if dv(a)>0 && dv(a+1)<=0 % detect change of sign for local minimum
v(a:end)=v(a:end)-v(a); % lift up the rest of v to the actual value(v(a))
end
v(a)=0;
end
end
% After the lift up nothing is going to happen until negative values occur again
% note that actual value v(a) has to be negative, otherwise + abs(v(a)) could be used as well
Again: The formula works like intended, but I would like to prefer a vectorized solution for faster computing =)

Sign in to comment.

Answers (1)

darova
darova on 15 Feb 2020 at 18:25
Edited: darova on 15 Feb 2020 at 18:26
Don't know about vectorizing. Maybe this part will be simpler and faster
load v.mat
v = cumsum(v);
v1 = v;
dv1 = v*0;
for i = 1:length(v1)-1
if v1(i+1) < dv1(i)
dv1(i+1) = v1(i+1);
else
dv1(i+1) = dv1(i);
end
end

  0 Comments

Sign in to comment.

Sign in to answer this question.