Using cumulative areas as an error threshold
2 vues (au cours des 30 derniers jours)
Afficher commentaires plus anciens
Hello!
I have a function r(t), which in this case is a logistic function, but for all intents and purposes could be any function r(t).
My goal is to begin at the first value of r and compare it to the second value of r. If the area formed by the triangle under the curve is above a certain threshold then I keep the second value of r. If it is below, then I move to the third value of r and compare the area of the triangle now formed between the first and third r values to the threshold. I repeat until I find the value of r that is above the threshold. For the parameters below, this r value is the 75th index.
I then begin the process again between the 75th and 76th index and so on and so on. My final result is therefore a logical array that is true when r is above the threshold.
I have written a looping procedure that carries this out successfully, but my instinct is telling me there should be a more efficient solution, perhaps involving some loop-less cumulative function. Or a clever use of a step function...
Would appreciate any suggestions / ideas!
r0 = 3; % start r
r1 = 6; % end r
t0 = 5; % halfway point
k = 2; % exponential growth
r_ = @(t) 1./(1+exp(-k*(t-t0))) * (r1-r0) + r0;
t = linspace(0,15,301);
r = r_(t);
dt = mean(diff(t));
dr = abs(diff(r));
threshold = 5e-3;
A_ = 0;
lgc = false;
for idr = 1:numel(dr)
A = dt*(dr(idr))/2;
A_ = A_ + A;
if A_ >= threshold
lgc(idr) = true;
A_ = 0;
else
lgc(idr) = false;
end
end
lgc = [true lgc];
hold on
plot(t,r)
plot(t(lgc),r(lgc),'x')
0 commentaires
Réponse acceptée
Voss
le 28 Sep 2023
You can use cumsum to perform the cumulative sum over all dr at once. Then loop over sections of that cumulative sum, finding the first index where it exceeds threshold each time and subtracting off that element. You still have a loop, but it has fewer iterations.
r0 = 3; % start r
r1 = 6; % end r
t0 = 5; % halfway point
k = 2; % exponential growth
r_ = @(t) 1./(1+exp(-k*(t-t0))) * (r1-r0) + r0;
t = linspace(0,15,301);
r = r_(t);
dt = mean(diff(t));
dr = abs(diff(r));
threshold = 5e-3;
lgc = [true false(1,numel(dr))];
A = dt*cumsum(dr)/2;
while true
idx = find(A >= threshold, 1);
if isempty(idx)
break
end
lgc(idx+1) = true;
A = A-A(idx);
end
hold on
plot(t,r)
plot(t(lgc),r(lgc),'x')
6 commentaires
Voss
le 5 Oct 2023
Maybe something like this. See if it seems right.
r0 = 3; % start r
r1 = 6; % end r
t0 = 5; % halfway point
k = 2; % exponential growth
r_ = @(t) 1./(1+exp(-k*(t-t0))) * (r1-r0) + r0;
t = linspace(0,15,301);
r = r_(t);
dt = mean(diff(t));
cA = cumtrapz(t,r-r(1));
dA = cA-cA.';
threshold = 5e-3;
lgc = [true false(1,numel(r)-1)];
row = 1;
while true
idx = find(dA(row,:) >= threshold, 1);
if isempty(idx)
break
end
dA = dA-dA(row,idx);
lgc(idx+1) = true;
row = idx;
end
hold on
plot(t,r)
plot(t(lgc),r(lgc),'x')
Plus de réponses (0)
Voir également
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!