Function "diff" and the loss of an element in the array

42 Ansichten (letzte 30 Tage)
Bryan Ambrósio
Bryan Ambrósio am 13 Sep. 2023
Kommentiert: dpb am 14 Sep. 2023
I have an issue with MATLAB, specifically related to a "diff" operation that is causing the loss of an element. The "diff" function in MATLAB is used to calculate the differences between consecutive elements in an array or matrix. I am using this function to calculate the derivate of an array.
It is clear to me that the resulting vector must have one less element. However, I need to perform the "diff" operation twice on the same array (resulting in an array with two less elements), and the issue I'm facing is that I don't know whether the vector is losing an element at the beginning or at the end. Initially, I thought it might be at the beginning. But when I compare the result of this operation with a reference value, it seems to be shifted on the axis. How can I be sure of this?
PS: It really makes a difference in my implementation.
  1 Kommentar
Stephen23
Stephen23 am 13 Sep. 2023
"... the issue I'm facing is that I don't know whether the vector is losing an element at the beginning or at the end."
Neither: differences are between the elements of your vector, not at the same locations as them.

Melden Sie sich an, um zu kommentieren.

Akzeptierte Antwort

Torsten
Torsten am 13 Sep. 2023
Use "gradient" if you don't want to loose elements:
  2 Kommentare
William Rose
William Rose am 13 Sep. 2023
Bearbeitet: William Rose am 13 Sep. 2023
I didn't know about gradient. Thanks @Torsten !
t=0:7; x=t.^3;
dxdtD=diff(x); d2xdt2D=diff(diff(x));
dxdtG=gradient(x); d2xdt2G=gradient(gradient(x));
disp(x); disp(dxdtG); disp(d2xdt2G)
0 1 8 27 64 125 216 343 1 4 13 28 49 76 109 127 3.0000 6.0000 12.0000 18.0000 24.0000 30.0000 25.5000 18.0000
@Bryan Ambrósio, compare the results from gradient() to the theoretical results for this signal, and to the results using diff(). An advantage of gradient() is that it gives estimates at the same locaitons as the sample locations, including at the edges. But you may not like its estimates at the edges. Your call.
legstr={'theo','Diff','Gradient'};
subplot(211);
plot(t,3*t.^2,'-g',t(1:end-1)+.5,dxdtD,'gx',t,dxdtG,'go');
ylabel('dx/dt'); grid on;
legend(legstr,'Location','best')
subplot(212);
plot(t,6*t,'-b',t(2:end-1),d2xdt2D,'bx',t,d2xdt2G,'bo');
ylabel('d^2X/dt^2'); xlabel('Time'); grid on;
legend(legstr,'Location','best')
Walter Roberson
Walter Roberson am 13 Sep. 2023
And gradient allows you to specify the spacing between elements, which is important for getting the right scale on the derivatives.

Melden Sie sich an, um zu kommentieren.

Weitere Antworten (2)

dpb
dpb am 13 Sep. 2023
diff is defined as x(i+1)-x(i) for i=2:numel(x). But, MATLAB arrays are always 1-based so the result of x(2)-x(1) is in the first location of the result vector. You don't really "lose" anything, but the location of the nth position corresponding to the initial vector does move down each successive operation...
Easy enough to illustrate numerically...
>> V=randi(20,1,10)
V =
7 6 13 9 10 10 19 2 6 9
>> dV1=diff(V)
dV1 =
-1 7 -4 1 0 9 -17 4 3
>> dV2=diff(dV1)
dV2 =
8 -11 5 -1 9 -26 21 -1
>>
Oftentimes it is convenient for coding purposes to prepend to the result to maintain the same length;
dV1=[nan diff(V)];
for example.
  4 Kommentare
dpb
dpb am 14 Sep. 2023
I disagree @Stephen23; it simply notes that owing to the size differential, the indices to the locations of the original data are numerically lower than those to the original data from which the difference was computed to address the specifics of the original question as to which difference is stored where.
Of course, there are no other differences available to be stored, but that's somewhat different... :)
dpb
dpb am 14 Sep. 2023
Yeah, @Steven Lord, I thought about adding in the alternate syntax but opted for brevity to keep to the original Q? only...sometimes one might need both differences in which case the three argument version doesn't help so much; you've got two calls either way.
I've thought of (but have never actually submitted it as formal enhancment request) it might be a worthwhile option to have a flag to return an array of successive differences as an alternative to the one n-th difference -- the problem and argument against being it makes it hard to deal with the higher dimension cases other than vector inputs.

Melden Sie sich an, um zu kommentieren.


William Rose
William Rose am 13 Sep. 2023
Bearbeitet: William Rose am 13 Sep. 2023
[edit: changed the code for plotting d2xdt2. The plotted result is unchanged, but the new verison of the code is more robust, because it will put d2xdt2 at the correct horizontal location, even if delta T is not unity.]
You can answer your own question by experiment.
t=0:1:7; x=t.^3;
dxdt=diff(x); d2xdt2=diff(diff(x));
disp(x); disp(dxdt); disp(d2xdt2)
0 1 8 27 64 125 216 343 1 7 19 37 61 91 127 6 12 18 24 30 36
You can see that the times associated with the second derivative are offset by 1 sample at the beginning and by 1 at the end. Plot the results as shown:
subplot(311); plot(t,x,'-r.'); ylabel('X'); grid on
subplot(312); plot(t(1:end-1)+.5,dxdt,'-g.'); ylabel('dX/dt'); grid on
subplot(313); plot(t(2:end-1),d2xdt2,'-b.');
ylabel('d^2X/dt^2'); xlabel('Time'); xlim([0 7]); grid on
The plots agree with the analytical solution for the first and second derivatives of x=t^3.

Kategorien

Mehr zu MATLAB finden Sie in Help Center und File Exchange

Produkte


Version

R2021a

Community Treasure Hunt

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

Start Hunting!

Translated by