sandbox/easystab/diffmat.m

    Presentation of the differentiation matrix

    The differentiation matrix is at the heart of all the codes that we will be using here. This script is a way to show how it works and give a means to test it. It is discussed from a general point of view in pedagogy#differentiation-matrices.

    In this code, I give an example and a test based on finite differences. For most of the codes, we embed the creation of the differentiation matrices in a special function dif1D.m in 1D (and dif2D.m in 2D). Please see diffmat_dif1D.m for the same code as here but using dif1D.m to produce the differentiation matrices.

    We suppose that we have a function f that is discretized on a grid x, let’s say first a simple equidistant grid with N gridpoints. Then in the computer, f is described as a column vector of the N values of the function f at each point of the grid. To compute the derivative f' of this function, knowing its values at the gridpoints, the simplest way is to use finite differences: \displaystyle f'_i=\frac{f_{i+1}-f_{i-1}}{2h}, where the index i refers to the number of the cell and h is the distance betwen grid points. This formula is an approximation of the exact derivative: \displaystyle f'(x)=\lim_{h \to 0} \frac{f(x+h)-f(x)}{h}

    The differentiation is a linear operation, so it can be described by a matrix-vector product. \displaystyle f'=Df So how can we build the matrix? We will do this simply by stacking in a matrix the operations of the finite difference.

    \displaystyle \left( \begin{array}{l} f'_{1}\\ f'_{2}\\ \vdots \\ \\ f'_{N} \end{array}\right) = \frac{1}{2\Delta x} \left(\begin{array}{ccccc} -3 & 4 & -1 &\dots & 0\\ -1 & 0 & 1 & & \\ &\ddots&\ddots&\ddots& \\ &&-1&0&1\\ 0&\dots&1&-4&3 \end{array}\right) \left(\begin{array}{l} f_1\\ f_2\\ \vdots \\ \\ f_N \end{array}\right)

    You see that we where in the need to change the formula for the derivative at the first and last grid points because we have used centered stencils that require the knowledge of the values of f before and after the grid point i. Thus at the first and last gridpoints we have used uncentered stencils.

    clear all; clf
    
    % parameters
    L=2*pi; % domain length
    N=15; % number of points
    
    % the grid
    x=linspace(0,L,N)';
    h=x(2)-x(1); % the grid size
    
    % first derivative
    D=zeros(N,N);
    D(1,1:3)=[-3/2, 2, -1/2]/h;
    for ind=2:N-1
        D(ind,ind-1:ind+1)=[-1/2, 0, 1/2]/h;
    end
    D(end,end-2:end)=[1/2, -2, 3/2]/h;
    
    % second derivative
    DD=zeros(N,N);
    DD(1,1:3)=[1, -2, 1]/h^2;
    for ind=2:N-1
        DD(ind,ind-1:ind+1)=[1, -2, 1]/h^2;
    end
    DD(end,end-2:end)=[1, -2, 1]/h^2;
    

    Now that the differentiation matrices are built and stored in D and DD, we can test how they work by comparing to the derivative of a function for which we know the exact derivative, for instance the cosinus(x). In the graph below we plot a cosinus on the grid, the its derivative: -sin in red and compare it to D*f in red with a dashed line. The same comparison is also done for the second derivative, in magenta.

    % test of the derivatives
    f=cos(x);
    fp=-sin(x)';
    
    plot(x,cos(x),'b.-',x,-sin(x),'r.-',x,D*cos(x),'r.--',x,-cos(x),'m.-',x,DD*cos(x),'m.--');
    legend('cos','-sin','D*cos(x)','-cos','DD*cos')
    print('-dsvg','diffmat.svg'); % save the figure
    

    test of the computation

    And here is the figure that is produced by the code:

    Comparison of the numerical and exact derivative for the first and second derivative of a cosinus

    Comparison of the numerical and exact derivative for the first and second derivative of a cosinus

    First look at the two red curves. This is the comparison of the exact and numerical derivatives. They are close but they are not the same. The discrepancy is the numerical approximation. To improve the approximation, you can increase the number of gridpoints or use a higher order formula for the differentiation matrix. in Easystab we use often pseudospectral differentiation matrices, based for instance on Chebychev polynomials, see for instance ???.

    Links

    Here we have shown the differentiation matrix for a 1D function. We can as well build differentiation matrices for 2D and 3D functions (the function f depends for instance of three spatial direction f(x,y,z)). See a pedagogical introduction to higher dimensionality in pedagogy#1D,-2D-and-3D and the implementation in the codes diffmat_2D.m and diffmat_3D.m.

    We use differentiation matrices to solve differential equations, for instance see pedagogy#boundary-conditions for a general introduction to the way to enforce boundary conditions, and differential_equations.m for the implementation. In poisson1D.m, poisson2D.m and poisson3D.m we solve Poisson equations in 1D, 2D and 3D.

    Exercices/contributions

    • Please do a convergence study in the number of gridpoints, showing how the error tends to zero when the number of points increase
    • Please build the differentiation matrices using 5-point stencils for the finite differences (for this you can use the function ufdwt.m which gives you the finite difference weights)
    • Please test the accuracy of the differentiation on a different function than a cosinus
    • Please code the differentiation matrices for a periodic domain (for which there is no need to use uncentered stencils at the boundaries, but instead use the value of the function “on the other side” of the domain -> periodicals boudaries.m
    • Please test the differentiation matrix based on Chebychev spectral discretisation (chebdif.m)like done in most of the other codes, for instance blasius.m.
    • Please test the differentiation matrix based on Fourier spectral discretisation for periodic domain fourdif.m.
    • Please build the differentiation matrix for higher order derivatives. diffmat_thirdorder.m.
    • Please do the comparison between the second derivative computed by multiplication twice by the first derivative matrix or once by the second derivative matrix. comparison