Partial derivative of an interpolated function (with Mathematica)

Join the discussion
Ask a follow-up here, or get your own question answered by working scientists, mathematicians and engineers — people, not an autocomplete.
Real named experts · corrections over time · the nuance an AI answer skips
6 replies · 10K views
evgenx
Messages
14
Reaction score
0
Hi,

I faced a problem (in Mathematica) when trying to plot a partial
derivative of a functiona (of two variables) obatined by "Interpolation".
More precisely, here is my input:

surf=Interpolation[{
{{160.0, 160.0}, 2.852688},
{{160.0, 170.0}, 2.827547},
{{160.0, 180.0}, 2.818931},
{{160.0, 190.0}, 2.826640},
{{160.0, 200.0}, 2.851483},

{{170.0, 160.0}, 2.861634},
{{170.0, 170.0}, 2.832750},
{{170.0, 180.0}, 2.822240},
{{170.0, 190.0}, 2.830275},
{{170.0, 200.0}, 2.858395},

{{180.0, 160.0}, 2.862344},
{{180.0, 170.0}, 2.831671},
{{180.0, 180.0}, 2.820786},
{{180.0, 190.0}, 2.831775},
{{180.0, 200.0}, 2.862605},

{{190.0, 160.0}, 2.857940},
{{190.0, 170.0}, 2.830020},
{{190.0, 180.0}, 2.822137},
{{190.0, 190.0}, 2.832657},
{{190.0, 200.0}, 2.861574},

{{200.0, 160.0}, 2.850865},
{{200.0, 170.0}, 2.826201},
{{200.0, 180.0}, 2.818547},
{{200.0, 190.0}, 2.827127},
{{200.0, 200.0}, 2.852228}
}]

s1=Function[{a,b},surf[a,b]]

da=Function[{a,b},D[s1[a,b],a]]

Plot3D[da[a, b], {a, 175.0, 185.0}, {b, 175.0, 185.0}]

When running this input Mathematica gives the error:
General::ivar: 175.00071499999999` is not a valid variable

Any help will be greatly appreciated !
Many thanks!


Evgeniy
 
Physics news on Phys.org
The problem is here:

da=Function[{a,b},D[s1[a,b],a]]

When you evaluate da[170,175] it translates this to D[s1[170,175],170]. Obviously, you cannot differentiate wrt 170, so it throws the error. What you want is for it to evaluate the partial derivative in advance and construct a new interpolating function object and simply evaluate that function as needed. You can do that as follows:

da=Function[{a,b},Evaluate[D[s1[a,b],a]]]
 
Hi,

Many thanks for your reply. It works now fine.

Well, there is an additional related question.
Namely, I'd like to find a point on the surf[a,b]
(i.e. values of a and b) where both dsurf/da=0
and d²surf/da²=0. Just simply solving:

s1=Function[{a,b},surf[a,b]]

da=Function[{a,b},Evaluate[D[s1[a,b],a]]]
dada=Function[{a,b},Evaluate[D[s1[a,b],{a,2}]]]

sol=FindRoot[{da==0,dada==0},{a, 180.0},{b, 165.0}]


gives the error:

The function value {Function[{a, b},
InterpolatingFunction[{{160., 200.}, {160., 200.}}, <>][a, b]],
Function[{a, b}, InterpolatingFunction[{{160., 200.}, {160., 200.}}, <>][
a, b]]} is not a list of numbers with dimensions {2} at {a, b} =
{180., 165.}.


What can I do wrong?
Thanks!


Evgeniy
 
sol=FindRoot[{da==0,dada==0},{a, 180.0},{b, 165.0}]

should be

sol=FindRoot[{da[a,b]==0,dada[a,b]==0},{a, 180.0},{b, 165.0}]

Since da and dada are pure functions you need to supply the arguments.
 
Great, everything works! Thanks a lot!

A-a, just the very last question ... When I tried to plot
da and dada (with Plot3D) they looked like the function (surf) has
discontinuities at a=180.0. I guess it has to do with the quality of
interpolation. After I added Method->"Spline" (as an option for Interpolation)
da became better but dada still has a crease at a=180.0. Don't you happen
to know how to improve it.

Best wishes,
Evgeniy
 
You may want to increase the order of the interpolation using the InterpolationOrder option. However, you should realize that what you are doing, taking the second derivative of a function with only 5 support points, is inherently unlikely to give very good results.
 
Ok, I see.
Thanks again for your help!