function [A,g,xmesh,ucomp] = finitediff2(M,a,c,f) %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % function [A,g,xmesh,ucomp] = finitediff2(M,a,c,f) % This function uses a 2nd order finite difference method % to form an approximate solution to the differential equation % -(a(x) u'(x))' + c(x) u(x) = f(x) for x in (0,1) % with u(0)=u(1)=0. % % The function a should satisfy a(x) \ge a_0 > 0 on (0,1), % and the function c should satisfy c(x) \ge 0 on (0,1). % % Inputs: % M defines the number of mesh points, including the % endpoints of the interval. % a, c, and f are user-defined Matlab functions. % Their input is a row or column vector of x coordinates % in the interval [0,1], and their output is a vector of % values of a(x), c(x), or f(x). % The function a also has a second output argument, a vector of % values of a'(x). % % Outputs: % A is the matrix from which the coefficients of the solution are % computed. % The matrix entries are computed using central difference % approximations for u'' and u': % u'(x) -> (u(x+h)-u(x-h)) / (2h) % - u''(x) -> (-u(x+h)+ 2 u(x) -u(x-h)) / (h^2) % g is the right-hand side of the matrix problem. % xmesh contains the equally-spaced points at which the solution % is computed. % ucomp is the vector of values of the % computed solution at the interior mesh points. % % finitediff2.m Dianne P. O'Leary January 2005 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % Initialize some parameters. % h is the spacing between meshpoints. % x is the vector of meshpoints. % xmesh is the vector of interior meshpoints. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% x = linspace(0,1,M); h = x(2); h2inv = 1/h^2; n = M - 2; xmesh = x(2:n+1)'; %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % Form the diagonals of A % and form the right-hand side rhs so that % A ucomp = rhs. % A is a tridiagonal matrix with values 2a/h^2 + c on its main diagonal, % -a/h^2 + a'/(2h) on its subdiagonal, % and -a/h^2 - a'/(2h) on its superdiagonal. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% [a0,ap] = feval(a,xmesh); adiff = a0*h2inv; bdiff = ap/(2*h); cdiff = feval(c,xmesh); rhs = feval(f,xmesh); %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % Pad the vectors to make Matlab's spdiags pick up the proper % values for each row. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% adiffu = [0;adiff(1:n-1)]; bdiffu = [0;bdiff(1:n-1)]; bdiffl = [bdiff(2:n);0]; adiffl = [adiff(2:n);0]; A = spdiags([-adiffl+bdiffl,2*adiff + cdiff,-bdiffu-adiffu],-1:1,n,n); g = rhs; %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % Solve the linear system. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% ucomp = A \ g;