home *** CD-ROM | disk | FTP | other *** search
-
- (* :Name: NumericalMath`ListIntegrate` *)
-
- (* :Title: Approximate Integration of Functions That Are Known Only at a Few
- Distinct Points *)
-
- (* :Author: Jerry B. Keiper *)
-
- (* :Summary:
- Given a function in the form of a sorted list of ordered pairs
- (or simply as a list of ordinates, assuming equally spaced
- abscissae), ListIntegrate gives an approximation to the definite
- integral of that function from the first to the last abscissa.
- *)
-
- (*:Context: NumericalMath`ListIntegrate` *)
-
- (*:Package Version: Mathematica 2.0 *)
-
- (* :Copyright: Copyright 1990 Wolfram Research, Inc.
- Permission is hereby granted to modify and/or make copies of
- this file for any purpose other than direct profit, or as part
- of a commercial product, provided this copyright notice is left
- intact. Sale, other than for the cost of media, is prohibited.
-
- Permission is hereby granted to reproduce part or all of
- this file, provided that the source is acknowledged.
- *)
-
- (* :History:
- Revised by Jerry B. Keiper, November, 1990.
- Original version by Jerry B. Keiper, March, 1989.
- *)
-
- (* :Keywords: integration, numerical integration, interpolation *)
-
- (* :Source: any elementary numerical analysis textbook. *)
-
- (* :Warnings:
- ListIntegrate[ ] should not be used if the data contain
- significant error. In such cases the error should be smoothed
- using Fit[ ], and the fitted function should be integrated
- using Integrate[ ] or NIntegrate[ ].
- *)
-
- (* :Limitations:
- The list {{x0,y0},{x1,y1},...,{xn,yn}} is assumed to be in sorted
- order (i.e., the xi's are assumed to be monotonically increasing);
- no checking is done. It does not allow integration over an
- arbitrary interval; you must integrate from the initial point to
- the final point.
- *)
-
- BeginPackage["NumericalMath`ListIntegrate`"]
-
- ListIntegrate::usage =
- "ListIntegrate[{y0,y1,...,yn}, h, k] gives an approximation to the integral of
- a function from x = x0 to x = xn with constant step size h between the
- consecutive x values. The function integrated is piecewise of degree k-1 and
- is the interpolating polynomial through the k/2 points to the left and k/2
- points to the right of x. If k is odd it is increased by 1. k must be less
- than or equal to the total number of data points. The default value of k is 4.
- ListIntegrate[{{x0,y0},{x1,y1},...,{xn,yn}},k] can be used for variable
- stepsize data. If the data are known to contain errors, you may be better off
- performing Integrate[] on the result of Fit[] applied to the data."
-
-
- Begin["NumericalMath`ListIntegrate`Private`"]
-
- ListIntegrate[cl_?VectorQ, h_, k_Integer:4] :=
- Module[{ans},
- ans /; (ans = ListIntegrate0[h, cl, k]) =!= $Failed
- ] /; k > 0;
-
- ListIntegrate[cl_?MatrixQ, k_Integer:4] :=
- Module[{ans, dim = Length[Dimensions[cl]]},
- ans /; ((dim == 2) &&
- (Length[cl[[1]]] == 2) &&
- ((ans = ListIntegrate1[cl, k]) =!= $Failed))
- ] /; k > 0;
-
-
- ListIntegrate::degerr = "Number of data points (`1`) is insufficient for the
- degree of interpolant requested (`2`)."
-
- ListIntegrate0[h_, cl_, k_] :=
- Module[{ke = k + If[IntegerQ[k/2], 0, 1], data},
- If[Length[cl] < ke,
- Message[ListIntegrate::degerr,Length[cl],ke-1];
- Return[$Failed]
- ];
- If[ke == 2,
- h (Apply[Plus,cl] - (cl[[1]] + cl[[-1]])/2),
- (* else *)
- data = Array[h #&,{Length[cl]}];
- data = Transpose[{data,cl}];
- ListInt[data,ke]
- ]
- ];
-
- ListIntegrate1[cl_, k_] :=
- Module[{ke = k + If[IntegerQ[k/2], 0, 1], x, y},
- If[Length[cl] < ke,
- Message[ListIntegrate::degerr,Length[cl],ke-1];
- Return[$Failed]
- ];
- If[ke == 2,
- y = Transpose[cl];
- x = Drop[y[[1]],1]-Drop[y[[1]],-1];
- y = Drop[y[[2]],1]+Drop[y[[2]],-1];
- (x . y)/2,
- (* else *)
- ListInt[cl,ke]
- ]
- ];
-
- ListInt[cl_,k_] :=
- Module[{i,tmp,sum,x,m=k/2,m1=k/2+1},
- If[Length[cl] == k,
- IntInt[cl,1,-1],
- (* else *)
- sum = IntInt[Take[cl,k],1,m1];
- Do[sum += IntInt[Take[cl,{i,i+k-1}],m,m1],
- {i,2,Length[cl]-k}];
- tmp = Take[cl,-k];
- sum + IntInt[Take[cl,-k],m,k]
- ]
- ];
-
- IntInt[data_,i_,j_] :=
- Module[{cl, x, k, sum, tmp},
- cl = CoefficientList[InterpolatingPolynomial[data,x],x];
- x = data[[j,1]];
- tmp = 0;
- Do[tmp = (tmp + cl[[k]]/k) x,{k,Length[cl],1,-1}];
- sum = tmp;
- x = data[[i,1]];
- tmp = 0;
- Do[tmp = (tmp + cl[[k]]/k) x,{k,Length[cl],1,-1}];
- sum - tmp
- ];
-
- End[] (* NumericalMath`ListIntegrate`Private` *)
-
- Protect[ListIntegrate];
-
- EndPackage[] (* NumericalMath`ListIntegrate` *)
-
-
-