Search code examples
arraysmatlabgradientdifferentiation

Differences in Differentiation Implementations in MATLAB


I'm trying to find the (numerical) curvature at specific points. I have data stored in an array, and I essentially want to find the local curvature at every separate point. I've searched around, and found three different implementations for this in MATLAB: diff, gradient, and del2.

If my array's name is arr I have tried the following implementations:

curvature = diff(diff(arr));
curvature = diff(arr,2); 
curvature = gradient(gradient(arr)); 
curvature = del2(arr); 

The first two seem to output the same values. This makes sense, because they're essentially the same implementation. However, the gradient and del2 implementations give different values from each other and from diff.

I can't figure out from the documentation precisely how the implementations work. My guess is that some of them are some type of two-sided derivative, and some of them are not two-sided derivatives. Another thing that confuses me is that my current implementations use only the data from arr. arr is my y-axis data, the x-axis essentially being time. Do these functions default to a stepsize of 1 or something like that?

If it helps, I want an implementation that takes the curvature at the current point using only previous array elements. For context, my data is such that a curvature calculation based on data in the future of the current point wouldn't be useful for my purposes.

tl;dr I need a rigorous curvature at a point implementation that uses only data to the left of the point.

Edit: I kind of better understand what's going on based on this, thanks to the answers below. This is what I'm referring to:

gradient calculates the central difference for interior data points. For example, consider a matrix with unit-spaced data, A, that has horizontal gradient G = gradient(A). The interior gradient values, G(:,j), are

G(:,j) = 0.5*(A(:,j+1) - A(:,j-1)); The subscript j varies between 2 and N-1, with N = size(A,2).

Even so, I still want to know how to do a "lefthand" computation.


Solution

  • diff is simply the difference between two adjacent elements in arr, which is exactly why you lose 1 element for using diff once. For example, 10 elements in an array only have 9 differences.

    gradient and del2 are for derivatives. Of course, you can use diff to approximate derivative by dividing the difference by the steps. Usually the step is equally-spaced, but it does not have to be. This answers your question why x is not used in the calculation. I mean, it's okay that your x is not uniform-spaced.

    So, why gradient gives us an array with the same length of the original array? It is clearly explained in the manual how the boundary is handled,

    The gradient values along the edges of the matrix are calculated with single->sided differences, so that

    G(:,1) = A(:,2) - A(:,1);

    G(:,N) = A(:,N) - A(:,N-1);

    Double-gradient and del2 are not necessarily the same, although they are highly correlated. It's all because how you calculate/approximate the 2nd-oder derivatives. The difference is, the former approximates the 2nd derivative by doing 1st derivative twice and the latter directly approximates the 2nd derivative. Please refer to the help manual, the formula are documented.

    Okay, do you really want curvature or the 2nd derivative for each point on arr? They are very different. https://en.wikipedia.org/wiki/Curvature#Precise_definition

    You can use diff to get the 2nd derivative from the left. Since diff takes the difference from right to left, e.g. x(2)-x(1), you can first flip x from left to right, then use diff. Some codes like,

    x=fliplr(x)
    first=x./h
    second=diff(first)./h
    

    where h is the space between x. Notice I use ./, which idicates that h can be an array (i.e. non-uniform spaced).