Re: Derivative of InterpolatingFunction
- To: mathgroup at smc.vnet.net
- Subject: [mg4374] Re: Derivative of InterpolatingFunction
- From: Paul Abbott <paul at physics.uwa.edu.au>
- Date: Mon, 15 Jul 1996 07:11:10 -0400
- Organization: University of Western Australia
- Sender: owner-wri-mathgroup at wolfram.com
Andrei Constantinescu wrote: > I have the following problem: > > fct = InterpolatingFunction[{{0., 3.14159}, {0., 3.14159}}, <>] > > ... so its an InterpolatingFunction of 2 variables . > > What I want now to do is the derivative of this function. > But I fail ! > > I get for example: > > In[69]:= Derivative[1,0][fct] > > (1,0) > Out[69]= (InterpolatingFunction[{{25., 210.}, {0., 17.}}, <>]) > In[71]:= %69[100., 4.] In The Mathematica Journal 4(2):31 the following appears: Partial Derivatives Presently, Mathematica cannot handle partial derivatives of InterpolatingFunctions. The package DInterpolatingFunction.m, provided by Hon Wah Tam (tam at wri.com) and included in the electronic supplement, computes partial derivatives of two-dimensional InterpolatingFunctions. Enhancements for higher dimensions will eventually be incorporated into Mathematica. After placing DInterpolatingFunction.m in your home directory, it can be loaded using the command: << DInterpolatingFunction` Define an array of data points: g[x_, y_] := Sin[3 x] Cos[4 y] tb = Table[{x, y, g[x, y]}, {x, 0, 1, .1}, {y, 0, 1, .05}]; and then interpolate it: ifunc = Interpolation[Flatten[tb, 1]]; You can evaluate the interpolated function directly: ifunc[0.23, 0.41] -0.0440066 and plot its graph: Plot3D[ifunc[x, y], {x, 0, 1}, {y, 0, 1}]; With the DInterpolatingFunction.m package, you can also compute partial derivatives. Here is the derivative with respect to the first variable: dx = Derivative[1, 0][ifunc]; dx[0.23, 0.41] -0.160227 which can be compared with the expected value: Derivative[1, 0][g][0.23, 0.41] -0.159991 Similarly: dy = Derivative[0, 1][ifunc]; dy[0.23, 0.41] -2.53594 Derivative[0, 1][g][0.23, 0.41] -2.54005 Here is the package: (* DInterpolatingFunction.m *) Unprotect[ InterpolatingFunction ]; BeginPackage[ "DInterpolatingFunction`", "Global`" ] Begin[ "`Private`" ] DiffElem[ element_, zerolist_ ] := Module[ { coeffs, dvdfs, order, var, polynomial, j, newelement }, dvdfs = element[[1]]; coeffs = element[[2]]; order = Length[ coeffs ]; polynomial = dvdfs[[ order + 1 ]]; For[ j = order, j >= 1, j--, polynomial = ( var + coeffs[[j]] ) * polynomial + dvdfs[[j]] ]; polynomial = D[ Expand[ polynomial ], var ]; dvdfs = CoefficientList[ polynomial, var ]; If[ Length[ dvdfs ] < order, dvdfs = Join[ dvdfs, zerolist[[ order - Length[ dvdfs ] ]] ] ]; newelement = { dvdfs, zerolist[[order-1]] }; Return[ newelement ]; ]; Interpolate[ x_, dvdfs_, coeffs_, tn_, order_ ] := Module[ { answer, xmtn, j }, answer = dvdfs[[order+1]]; xmtn = x - tn; For[ j = order, j >= 1, j--, answer = ( xmtn + coeffs[[j]] ) * answer + dvdfs[[j]] ]; Return[ answer ]; ] DiffLine[ line_, zerolist_, lastdimpts_ ] := Module[ { i, newline, dvdfs, coeffs, order, tn, x, df, element }, newline = Table[ DiffElem[ line[[i]], zerolist ], { i, 2, Length[ line ] } ]; { dvdfs, coeffs } = newline[[1]]; tn = lastdimpts[[2]]; x = lastdimpts[[1]]; order = Length[ coeffs ]; df = Interpolate[ x, dvdfs, coeffs, tn, order ]; element = { { df, 0 }, { 0 } }; PrependTo[ newline, element ]; Return[ newline ]; ] InterpolatingFunction /: Derivative[0,1][ InterpolatingFunction[ range_, table_ ] ] := Module[ { gridpoints, tbl, i, j, order, zerolist, lastdimpts, newtable,answer }, gridpoints = table[[1]]; lastdimpts = Last[ gridpoints ]; tbl = table[[2]]; order = Max[ Table[ Length[ tbl[[1,i,2]] ], { i, Length[ tbl[[1]] ] } ] ]; zerolist = Table[ Table[ 0, { j, i } ], { i, order } ]; newtable = Table[ DiffLine[ tbl[[i]], zerolist, lastdimpts ], { i, Length[ tbl ] } ]; answer = InterpolatingFunction[ range, { gridpoints, newtable } ]; Return[ answer ]; ]; InterpolatingFunction /: Derivative[1,0][InterpolatingFunction[ range_, table_ ] ] := Module[ { gridpoints, ifunc, data, i, j, x, y }, gridpoints = table[[1]]; ifunc = InterpolatingFunction[ range, table ]; data = Table[ { y = gridpoints[[2,j]], x = gridpoints[[1,i]], ifunc[x,y] }, { j, Length[ gridpoints[[2]] ] }, { i, Length[ gridpoints[[1]] ] } ]; data = Flatten[ data, 1 ]; ifunc = Interpolation[ data ]; ifunc = Derivative[0,1][ifunc]; data = Table[ { x = gridpoints[[1,i]], y = gridpoints[[2,j]], ifunc[y,x] }, { i, Length[ gridpoints[[1]] ] }, { j, Length[ gridpoints[[2]] ] } ]; data = Flatten[ data, 1 ]; ifunc = Interpolation[ data ]; Return[ ifunc ]; ]; End[] EndPackage[] Cheers, Paul _________________________________________________________________ Paul Abbott Department of Physics Phone: +61-9-380-2734 The University of Western Australia Fax: +61-9-380-1014 Nedlands WA 6907 paul at physics.uwa.edu.au AUSTRALIA http://www.pd.uwa.edu.au/Paul _________________________________________________________________ ==== [MESSAGE SEPARATOR] ====