Code covered by the BSD License  

Highlights from
slatec

from slatec by Ben Barrowes
The slatec library converted into matlab functions.

[fun,a,b,err,ansmlv,ierr,k]=dqnc79(fun,a,b,err,ansmlv,ierr,k);
function [fun,a,b,err,ansmlv,ierr,k]=dqnc79(fun,a,b,err,ansmlv,ierr,k);
%***BEGIN PROLOGUE  DQNC79
%***PURPOSE  Integrate a function using a 7-point adaptive Newton-Cotes
%            quadrature rule.
%***LIBRARY   SLATEC
%***CATEGORY  H2A1A1
%***TYPE      doubleprecision (QNC79-S, DQNC79-D)
%***KEYWORDS  ADAPTIVE QUADRATURE, INTEGRATION, NEWTON-COTES
%***AUTHOR  Kahaner, D. K., (NBS)
%           Jones, R. E., (SNLA)
%***DESCRIPTION
%
%     Abstract  *** a doubleprecision routine ***
%       DQNC79 is a general purpose program for evaluation of
%       one dimensional integrals of user defined functions.
%       DQNC79 will pick its own points for evaluation of the
%       integrand and these will vary from problem to problem.
%       Thus, DQNC79 is not designed to integrate over data sets.
%       Moderately smooth integrands will be integrated efficiently
%       and reliably.  For problems with strong singularities,
%       oscillations etc., the user may wish to use more sophis-
%       ticated routines such as those in QUADPACK.  One measure
%       of the reliability of DQNC79 is the output parameter K,
%       giving the number of integrand evaluations that were needed.
%
%     Description of Arguments
%
%     --Input--* FUN, A, B, ERR are doubleprecision *
%       FUN  - name of external function to be integrated.  This name
%              must be in an EXTERNAL statement in your calling
%              program.  You must write a Fortran function to evaluate
%              FUN.  This should be of the form
%                    doubleprecision function FUN (X)
%              C
%              C     X can vary from A to B
%              C     FUN(X) should be finite for all X on interval.
%              C
%                    FUN = ...
%                    RETURN
%                    end
%       A    - lower limit of integration
%       B    - upper limit of integration (may be less than A)
%       ERR  - is a requested error tolerance.  Normally, pick a value
%              0 .LT. ERR .LT. 1.0D-8.
%
%     --Output--
%       ANS  - computed value of the integral.  Hopefully, ANS is
%              accurate to within ERR * integral of ABS(FUN(X)).
%       IERR - a status code
%            - Normal codes
%               1  ANS most likely meets requested error tolerance.
%              -1  A equals B, or A and B are too nearly equal to
%                  allow normal integration.  ANS is set to zero.
%            - Abnormal code
%               2  ANS probably does not meet requested error tolerance.
%       K    - the number of function evaluations actually used to do
%              the integration.  A value of K .GT. 1000 indicates a
%              difficult problem; other programs may be more efficient.
%              DQNC79 will gracefully give up if K exceeds 2000.
%
%***REFERENCES  (NONE)
%***ROUTINES CALLED  D1MACH, I1MACH, XERMSG
%***REVISION HISTORY  (YYMMDD)
%   790601  DATE WRITTEN
%   890531  Changed all specific intrinsics to generic.  (WRB)
%   890911  Removed unnecessary intrinsics.  (WRB)
%   890911  REVISION DATE from Version 3.2
%   891214  Prologue converted to Version 4.0 format.  (BAB)
%   900315  CALLs to XERROR changed to CALLs to XERMSG.  (THJ)
%   920218  Code redone to parallel QNC79.  (WRB)
%   930120  Increase array size 80->99, and KMX 2000->5000 for SUN -r8
%           wordlength.  (RWC)
%***end PROLOGUE  DQNC79
%     .. Scalar Arguments ..
persistent aa ae area bank blocal c ce ee ef eps f f1 f2 f3 f4 f5 f6 f7 first firstCall gt hh i kml kmx l lmn lmx lr nbits nib nlmn nlmx q13 q7 q7l q7r sq2 test tol vl vr w1 w2 w3 w4 ; if isempty(firstCall),firstCall=1;end; 

if isempty(gt), gt=zeros(1,2); end;
%     .. function Arguments ..
%     .. Local Scalars ..
if isempty(ae), ae=0; end;
if isempty(area), area=0; end;
if isempty(bank), bank=0; end;
if isempty(blocal), blocal=0; end;
if isempty(c), c=0; end;
if isempty(ce), ce=0; end;
if isempty(ee), ee=0; end;
if isempty(ef), ef=0; end;
if isempty(eps), eps=0; end;
if isempty(q13), q13=0; end;
if isempty(q7), q7=0; end;
if isempty(q7l), q7l=0; end;
if isempty(sq2), sq2=0; end;
if isempty(test), test=0; end;
if isempty(tol), tol=0; end;
if isempty(vr), vr=0; end;
if isempty(w1), w1=0; end;
if isempty(w2), w2=0; end;
if isempty(w3), w3=0; end;
if isempty(w4), w4=0; end;
if isempty(i), i=0; end;
if isempty(kml), kml=0; end;
if isempty(kmx), kmx=0; end;
if isempty(l), l=0; end;
if isempty(lmn), lmn=0; end;
if isempty(lmx), lmx=0; end;
if isempty(nbits), nbits=0; end;
if isempty(nib), nib=0; end;
if isempty(nlmn), nlmn=0; end;
if isempty(nlmx), nlmx=0; end;
if isempty(first), first=false; end;
%     .. Local Arrays ..
if isempty(aa), aa=zeros(1,99); end;
if isempty(f), f=zeros(1,13); end;
if isempty(f1), f1=zeros(1,99); end;
if isempty(f2), f2=zeros(1,99); end;
if isempty(f3), f3=zeros(1,99); end;
if isempty(f4), f4=zeros(1,99); end;
if isempty(f5), f5=zeros(1,99); end;
if isempty(f6), f6=zeros(1,99); end;
if isempty(f7), f7=zeros(1,99); end;
if isempty(hh), hh=zeros(1,99); end;
if isempty(q7r), q7r=zeros(1,99); end;
if isempty(vl), vl=zeros(1,99); end;
if isempty(lr), lr=zeros(1,99); end;
%     .. External Functions ..
%     .. External Subroutines ..
%     .. Intrinsic Functions ..
%     .. Save statement ..
%     .. Data statements ..
if firstCall,   kml=[7];  end;
if firstCall,  kmx=[5000];  end;
if firstCall,  nlmn=[2];  end;
if firstCall,   first=[true];  end;
firstCall=0;
%***FIRST EXECUTABLE STATEMENT  DQNC79
gt(:)=0;
if( first )
w1 = 41.0d0./140.0d0;
w2 = 216.0d0./140.0d0;
w3 = 27.0d0./140.0d0;
w4 = 272.0d0./140.0d0;
nbits = fix(d1mach(5).*i1mach(14)./0.30102000d0);
nlmx = fix(min(99,fix((nbits.*4)./5)));
sq2 = sqrt(2.0d0);
end;
first = false;
ansmlv = 0.0d0;
ierr = 1;
ce = 0.0d0;
while (1);
if( a~=b )
lmx = fix(nlmx);
lmn = fix(nlmn);
if( b~=0.0d0 )
if( (abs(1.0d0).*sign(b)).*a>0.0d0 )
c = abs(1.0d0-a./b);
if( c<=0.1d0 )
if( c<=0.0d0 )
break;
end;
nib = fix(0.5d0 - log(c)./log(2.0d0));
lmx = fix(min(nlmx,nbits-nib-4));
if( lmx<2 )
break;
end;
lmn = fix(min(lmn,lmx));
end;
end;
end;
tol = max(abs(err),2.0d0.^(5-nbits));
if( err==0.0d0 )
tol = sqrt(d1mach(4));
end;
eps = tol;
hh(1) =(b-a)./12.0d0;
aa(1) = a;
lr(1) = 1;
for i = 1 : 2: 11 ;
f(i) = fun(a+(i-1).*hh(1));
end; i = fix(11 +1);
blocal = b;
f(13) = fun(blocal);
k = 7;
l = 1;
area = 0.0d0;
q7 = 0.0d0;
ef = 256.0d0./255.0d0;
bank = 0.0d0;
%
%     Compute refined estimates, estimate the error, etc.
%
while( true );
gt(:)=0;
for i = 2 : 2: 12 ;
f(i) = fun(aa(l)+(i-1).*hh(l));
end; i = fix(12 +1);
k = fix(k + 6);
%
%     Compute left and right half estimates
%
q7l = hh(l).*((w1.*(f(1)+f(7))+w2.*(f(2)+f(6)))+(w3.*(f(3)+f(5))+w4.*f(4)));
q7r(l) = hh(l).*((w1.*(f(7)+f(13))+w2.*(f(8)+f(12)))+(w3.*(f(9)+f(11))+w4.*f(10)));
%
%     Update estimate of integral of absolute value
%
area = area +(abs(q7l)+abs(q7r(l))-abs(q7));
%
%     Do not bother to test convergence before minimum refinement level
%
if( l>=lmn )
%
%     Estimate the error in new value for whole interval, Q13
%
q13 = q7l + q7r(l);
ee = abs(q7-q13).*ef;
%
%     Compute nominal allowed error
%
ae = eps.*area;
%
%     Borrow from bank account, but not too much
%
test = min(ae+0.8d0.*bank,10.0d0.*ae);
%
%     Don't ask for excessive accuracy
%
test = max([test,tol.*abs(q13),0.00003d0.*tol.*area]);
%
%     Now, did this interval pass or not?
%
if( ee<=test )
%
%     On good intervals accumulate the theoretical estimate
%
ce = ce +(q7-q13)./255.0d0;
else;
%
%     Consider the left half of next deeper level
%
if( k>kmx )
lmx = fix(min(kml,lmx));
end;
if( l<lmx )
gt(2)=1;
end;
%
%     Have hit maximum refinement level -- penalize the cumulative error
%
if(gt(2)==0)
ce = ce +(q7-q13);
end;
end;
%
%     Update the bank account.  Don't go into debt.
%
if(gt(2)==0)
bank = bank +(ae-ee);
if( bank<0.0d0 )
bank = 0.0d0;
end;
%
%     Did we just finish a left half or a right half?
%
if( lr(l)<=0 )
%
%     Proceed to right half at this level
%
vl(l) = q13;
else;
%
%     Left and right halves are done, so go back up a level
%
vr = q13;
while( l>1 );
if( l<=17 )
ef = ef.*sq2;
end;
eps = eps.*2.0d0;
l = fix(l - 1);
if( lr(l)<=0 )
vl(l) = vl(l+1) + vr;
gt(1)=1;
break;
else;
vr = vl(l+1) + vr;
end;
end;
if(gt(1)==0)
break;
end;
end;
gt(1)=0;
q7 = q7r(l-1);
lr(l) = 1;
aa(l) = aa(l) + 12.0d0.*hh(l);
f(1) = f1(l);
f(3) = f2(l);
f(5) = f3(l);
f(7) = f4(l);
f(9) = f5(l);
f(11) = f6(l);
f(13) = f7(l);
continue;
end;
gt(2)=0;
end;
l = fix(l + 1);
eps = eps.*0.5d0;
if( l<=17 )
ef = ef./sq2;
end;
hh(l) = hh(l-1).*0.5d0;
lr(l) = -1;
aa(l) = aa(l-1);
q7 = q7l;
f1(l) = f(7);
f2(l) = f(8);
f3(l) = f(9);
f4(l) = f(10);
f5(l) = f(11);
f6(l) = f(12);
f7(l) = f(13);
f(13) = f(7);
f(11) = f(6);
f(9) = f(5);
f(7) = f(4);
f(5) = f(3);
f(3) = f(2);
end;
%
%     Exit
%
ansmlv = vr;
if( abs(ce)>2.0d0.*tol.*area )
ierr = 2;
xermsg('SLATEC','DQNC79','ANS is probably insufficiently accurate.',2,1);
end;
return;
end;
break;
end;
ierr = -1;
xermsg('SLATEC','DQNC79',['A and B are too nearly equal to allow normal integration. $$','ANS is set to zero and IERR to -1.'],-1,-1);
end %subroutine dqnc79
%DECK DQNG

Contact us at files@mathworks.com