## Copyright (C) 2000 Kai Habel ## ## This program is free software; you can redistribute it and/or modify ## it under the terms of the GNU General Public License as published by ## the Free Software Foundation; either version 2 of the License, or ## (at your option) any later version. ## ## This program is distributed in the hope that it will be useful, ## but WITHOUT ANY WARRANTY; without even the implied warranty of ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ## GNU General Public License for more details. ## ## You should have received a copy of the GNU General Public License ## along with this program; if not, write to the Free Software ## Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA ## -*- texinfo -*- ## @deftypefn {Function File} {@var{X} =} del2 (@var{M}) ## @deftypefnx {Function File} {[@var{X},@var{Y}] =}del2 (@var{M}) ## @deftypefnx {Function File} {[...] =}del2 (...,@var{dx},@var{dy}) ## ## @var{X} = del2 (@var{M}) calculates the one dimensional ## del2 if M is a vector. Is M a Matrix the del2 is calculated ## for each row. ## [@var{X},@var{Y}] = del2 (@var{M}) calculates the one dimensinal ## del2 for each direction if @var{M} is a matrix. ## Spacing values between two points can be provided by the ## @var{dx}, @var{dy} parameters, otherwise the spacing is set to 1. ## A scalar value specifies an equidistant spacing. ## A vector value can be used to specify a variable spacing. The length ## must match the respective dimension of @var{M}. ## ## The second derivative is calculated using the first approximation. ## You need at least 3 data points for each dimension. ## Boundary points are calculated with y0'' and y2'' respectively. ## For interior point y1'' is taken. ## ## @example ## y0''(i) = 1/(dx^2) *(y(i)-2*y(i+1)+y(i+2)). ## y1''(i) = 1/(dx^2) *(y(i-1)-2*y(i)+y(i+1)). ## y2''(i) = 1/(dx^2) *(y(i-2)-2*y(i-1)+y(i)). ## @end example ## ## @end deftypefn ## Author: Kai Habel function D = del2 (M, dx, dy) if ((nargin < 1) || (nargin > 3)) usage ("del2(M,dx,dy)"); elseif (nargin == 1) dx = dy = 1; elseif (nargin == 2) dy = 1; endif if (is_vector (M)) M = M(:)'; endif if (!is_matrix (M)) error ("first argument must be a vector or matrix"); else if is_scalar (dx) dx = dx * ones (1, columns(M) - 1); else if !(length(dx) == columns(M)) error ("columns of M must match length of dx") else dx = diff (dx); endif endif if (is_scalar (dy)) dy = dy * ones (rows (M) - 1, 1); else if !(length(dy) == rows(M)) error ("rows of M must match length of dy") else dy = diff (dy); endif endif endif [mr,mc] = size (M); D = zeros (size (M)); if (mr >= 3) ## x direction ## left and right boundary D(:, 1) = (M(:, 1) .- 2 * M(:, 2) + M(:, 3)) / (dx(1) * dx(2)); D(:, mc) = (M(:, mc - 2) .- 2 * M(:, mc - 1) + M(:, mc))\ / (dx(mc - 2) * dx(mc - 1)); ## interior points D(:, 2:mc - 1) = D(:, 2:mc - 1)\ + (M(:, 3:mc) .- 2 * M(:, 2:mc - 1) + M(:, 1:mc - 2))\ ./ kron (dx(1:mc -2 ) .* dx(2:mc - 1), ones (mr, 1)); endif if (mc >= 3) ## y direction ## top and bottom boundary D(1, :) = D(1,:)\ + (M(1, :) .- 2 * M(2, :) + M(3, :)) / (dy(1) * dy(2)); D(mr, :) = D(mr, :)\ + (M(mr - 2,:) .- 2 * M(mr - 1, :) + M(mr, :))\ / (dy(mr - 2) * dx(mr - 1)); ## interior points D(2:mr - 1, :) = D(2:mr - 1, :)\ + (M(3:mr, :) .- 2 * M(2:mr - 1, :) + M(1:mr - 2, :))\ ./ kron (dy(1:mr - 2) .* dy(2:mr - 1), ones (1, mc)); endif D = D ./ 4; endfunction