Calculating area under curve with cutoff

1 次查看(过去 30 天)
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 个评论
darova
darova 2020-2-14
Im aksing about this curve
Don't understand how do you want to lift the red one up
Robin Schäfer
Robin Schäfer 2020-2-15
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 =)

请先登录,再进行评论。

回答(1 个)

darova
darova 2020-2-15
编辑:darova 2020-2-15
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

类别

Help CenterFile Exchange 中查找有关 Mathematics 的更多信息

Community Treasure Hunt

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

Start Hunting!

Translated by