Code covered by the BSD License  

Highlights from
gaussquad

image thumbnail
from gaussquad by Matt Fig
Adaptive form of gaussleg.m.

gaussquad(f,a,b,tol)
function anss = gaussquad(f,a,b,tol)
% GAUSSQUAD(f,a,b,tol) Definite integration using Gauss-Legendre 
% quadrature.  Finds the definite integral of function f from a to b. 
% User can define the relative convergence tolerence, tol; the default is 
% 10^-14.  If f is an inline function, it needs to accept vector args.
% Function f can also be ananymous or a function handle.
%
% Example:       
%
%            f = @(x) sin(x)./x+exp(-x); % Vectorized function handle.
%            gaussquad(f,-1,1)
%
% See also quad, quadl, quadv and rombquad (on the FEX)
%
% Author:  Matt Fig
% Date:  revised 1/31/2006
% Contact:  popkenai@yahoo.com


% Check for infinite boundaries. 
if nargin<3
   error ('Not enough arguments. See help.')
elseif nargin < 4
    tol = 1e-14;  % Default.
end

if isinf(f(a)) || isinf(f(b)) 
    error('Infinite limits not allowed.')
end


% Initially use a 40 point Gauss-Legendre quadrature in 15 subintervals.
gp = 40;  
cnt = 1;  
ints = 15;  
maxcount = 35;   
anss1 = 1;  
anss2 = 0;                          % Initialization for while.

% Main loop.  Each pass through, the number of intervals and Gauss points 
% is increased until either the tol is met or the maxcount is exceeded.                                                                                                                                                     
while abs(anss2-anss1) >= tol && cnt < maxcount
      anss1 = core(f,a,b,gp,ints);
      anss2 = core(f,a,b,gp+8,ints+3);
      gp =  gp+16;
      ints = ints+6;
      cnt = cnt+1;
end 

% Give a warning if max iterations is reached and give an error estimate.
if cnt>=maxcount                 
    str = sprintf(['Maximum iterations reached, results may be\n'...
                   '         inaccurate.  Estimated error: %.2d'],...
                   abs(anss2-anss1));
    warning(str); %#ok
end

anss = anss2;


function anss = core(f,a,b,gp,ints)
% Core subfunction that performs the integrations.
[abs1, wgt1] = Gauss(gp);                               % Get Gauss points.
bb(1) = a;                                              % Get subintervals.
bb(2:ints) = (2:ints)*(b-a)/ints+a;
dif = diff(bb)/2;
% Evaluate f at scaled intervals, need to map each interval to [-1 1].
an = f((abs1+1)*dif+repmat(bb(1:end-1),gp,1));      % Function evaluations.
new = dif*an'*wgt1;                % Multiply by the weights and intervals.
anss = sum(new(:));


function [x, w] = Gauss(n)
% Generates the abscissa and weights for a Gauss-Legendre quadrature.
% Reference:  Numerical Recipes in Fortran 77, Cornell press.
x = zeros(n,1);                                           % Preallocations.
w = x;
m = (n+1)/2;
for ii=1:m
    z = cos(pi*(ii-.25)/(n+.5));                        % Initial estimate.
    z1 = z+1;
while abs(z-z1)>eps
    p1 = 1;
    p2 = 0;
    for jj = 1:n
        p3 = p2;
        p2 = p1;
        p1 = ((2*jj-1)*z*p2-(jj-1)*p3)/jj;       % The Legendre polynomial.
    end
    pp = n*(z*p1-p2)/(z^2-1);                        % The L.P. derivative.
    z1 = z;
    z = z1-p1/pp;
end
    x(ii) = -z;                                   % Build up the abscissas.
    x(n+1-ii) = z;
    w(ii) = 2/((1-z^2)*(pp^2));                     % Build up the weights.
    w(n+1-ii) = w(ii);
end

Contact us