Viewing contents of file '../idllib/contrib/esrg_ucsb/integral.pro'
function integral,x,y,xrange=xrange,accumulate=accumulate
;+
; ROUTINE: integral
;
; USEAGE: result=integral(x,y,xrange=xrange,accumulate=accumulate)
;
; PURPOSE: integration by trapezoid rule
;
; INPUT:
; x vector of x axis points. If XRANGE is not set,
; limits of integration will be from x(0) to x(n_elements(x)-1)
; If XRANGE is not set, X need not be monitonic.
;
; y vector of corresponding y axis points
;
; KEYWORD_INPUT:
;
; xrange 2 element vector, lower and upper limit of integration
; The use of XRANGE with a non-monitonic variation in x may
; produce incorrect results.
;
; accumulate if set, return value is a vector giving the accumulated
; integral at each value of x. XRANGE can't be used when
; this option is set.
;
; OUTPUT: result of integration
;
; EXAMPLE:
;; /4
;; find | x dx
;; /0
; x=findgen(5) & y=x
; print,integral(x,y)
; 8.00000 ; answer for linear integrand is exact
;
;
;; /5.5
;; find | x^2 dx
;; /0
;
; x=findgen(7) & y=x^2 &$
; print," numerical analytic" &$
; print,integral(x,y,xrange=[0,5.5]), 5.5^3/3
; 56.3750 55.4583
;
;; use more resolution in x to improve answer
;
; x=findgen(551)/100. & y=x^2 &$
; print," numerical analytic" &$
; print,integral(x,y), 5.5^3/3
; 55.4584 55.4583 ; much better
;
; author: Paul Ricchiazzi 3NOV92
; Institute for Computational Earth System Science
; University of California, Santa Barbara
;
; REVISIONS:
; sep93: fixed error in treatment of xrange, added examples
; apr96: allow use of xrange with monitonically decreasing x
;-
if n_params() eq 0 then begin
xhelp,'integral'
return,0
endif
nn=n_elements(x)
if nn ne n_elements(y) then message,'x and y vectors must be same size'
dx=shift(x,-1)-x
yy=.5*(shift(y,-1)+y)
if keyword_set(accumulate) then begin
sum=fltarr(nn)
for i=1,nn-1 do sum(i)=sum(i-1)+dx(i-1)*yy(i-1)
return,sum
endif
if n_elements(xrange) eq 0 then return,total(dx(0:nn-2)*yy(0:nn-2))
; rest of code is to treat end points when xrange is set...
;
xmin=min(xrange)
xmax=max(xrange)
ii=where(x ge xmin and x le xmax,nc)
if nc eq nn then return,total(dx(0:nn-2)*yy(0:nn-2))
n1=ii(0)
if n1 eq -1 then return,0.
n2=ii(nc-1)
sum=0.
; sum up points fully inside range
if n2 gt n1 then sum=total(dx(n1:n2-1)*yy(n1:n2-1))
; now add in rest of area inside integration limits
if n1 gt 0 then begin
if x(n1) lt x(n2) then x1=xmin else x1=xmax
y1=y(n1)+(x1-x(n1))*(y(n1+1)-y(n1))/(x(n1+1)-x(n1))
sum1=.5*(y1+y(n1))*(x(n1)-x1)
sum=sum+sum1
endif
if n2 lt nn-1 then begin
if x(n1) lt x(n2) then x2=xmax else x2=xmin
y2=y(n2)+(x2-x(n2))*(y(n2+1)-y(n2))/(x(n2+1)-x(n2))
sum2=.5*(y2+y(n2))*(x2-x(n2))
sum=sum+sum2
endif
return,sum
end