Calculating area under curve with cutoff

3 次查看(过去 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 中查找有关 Matrix Indexing 的更多信息

Community Treasure Hunt

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

Start Hunting!

Translated by