Fourier differentiation matrix
function [x, DM] = fourdif(N,m)
%
% The function [x, DM] = fourdif(N,m) computes the m'th derivative Fourier
% spectral differentiation matrix on grid with N equispaced points in [0,2pi)
%
% Input:
% N: Size of differentiation matrix.
% M: Derivative required (non-negative integer)
%
% Output:
% x: Equispaced points 0, 2pi/N, 4pi/N, ... , (N-1)2pi/N
% DM: m'th order differentiation matrix
%
%
% Explicit formulas are used to compute the matrices for m=1 and 2.
% A discrete Fouier approach is employed for m>2. The program
% computes the first column and first row and then uses the
% toeplitz command to create the matrix.
% For m=1 and 2 the code implements a "flipping trick" to
% improve accuracy suggested by W. Don and A. Solomonoff in
% SIAM J. Sci. Comp. Vol. 6, pp. 1253--1268 (1994).
% The flipping trick is necesary since sin t can be computed to high
% relative precision when t is small whereas sin (pi-t) cannot.
%
% S.C. Reddy, J.A.C. Weideman 1998. Corrected for MATLAB R13
% by JACW, April 2003.
x=2*pi*(0:N-1)'/N; % gridpoints
h=2*pi/N; % grid spacing
zi=sqrt(-1);
kk=(1:N-1)';
n1=floor((N-1)/2); n2=ceil((N-1)/2);
if m==0, % compute first column
col1=[1; zeros(N-1,1)]; % of zeroth derivative
row1=col1; % matrix, which is identity
elseif m==1, % compute first column
if rem(N,2)==0 % of 1st derivative matrix
topc=cot((1:n2)'*h/2);
col1=[0; 0.5*((-1).^kk).*[topc; -flipud(topc(1:n1))]];
else
topc=csc((1:n2)'*h/2);
col1=[0; 0.5*((-1).^kk).*[topc; flipud(topc(1:n1))]];
end;
row1=-col1; % first row
elseif m==2, % compute first column
if rem(N,2)==0 % of 2nd derivative matrix
topc=csc((1:n2)'*h/2).^2;
col1=[-pi^2/3/h^2-1/6; -0.5*((-1).^kk).*[topc; flipud(topc(1:n1))]];
else
topc=csc((1:n2)'*h/2).*cot((1:n2)'*h/2);
col1=[-pi^2/3/h^2+1/12; -0.5*((-1).^kk).*[topc; -flipud(topc(1:n1))]];
end;
row1=col1; % first row
else % employ FFT to compute
N1=floor((N-1)/2); % 1st column of matrix for m>2
N2 = (-N/2)*rem(m+1,2)*ones(rem(N+1,2));
mwave=zi*[(0:N1) N2 (-N1:-1)];
col1=real(ifft((mwave.^m).*fft([1 zeros(1,N-1)])));
if rem(m,2)==0,
row1=col1; % first row even derivative
else
col1=[0 col1(2:N)]';
row1=-col1; % first row odd derivative
end;
end;
DM=toeplitz(col1,row1);