8

The well known Hermite interpolation uses piecewise cubic polynomials and fits the knot values and derivatives.

In contrast the Mathematica piecewise Interpolation

data= {1, 5, 7, 2, 3, 1};
Show[{Plot[Interpolation[data, Method -> "Hermite", InterpolationOrder -> 3][x], {x, 1, 6}], ListPlot[data]}] 

shows non continuous derivative non continuous derivative

I'm aware, that the derivatives in the interpolation must be estimated in the example. Is there any explanation for this unexpected result?

Henrik Schumacher
  • 106,770
  • 7
  • 179
  • 309
Ulrich Neumann
  • 53,729
  • 2
  • 23
  • 55

1 Answers1

9

See Extracting the function from InterpolatingFunction object:

data = {1, 5, 7, 2, 3, 1};
data2 = MapIndexed[Flatten[{#2, #1}] &, data];

pwf = Piecewise[
     Map[{InterpolatingPolynomial[#, x], x < #[[3, 1]]} &, Most[#]], 
     InterpolatingPolynomial[Last@#, x]
     ] &@Partition[data2, 4, 1];

Show[{Plot[
  {Interpolation[data, Method -> "Hermite", InterpolationOrder -> 3][x], 
   pwf},
  {x, 1, 6}], ListPlot[data]}]

Mathematica graphics

Plot[
 Interpolation[data, Method -> "Hermite", InterpolationOrder -> 3][x] - pwf,
 {x, 1, 6}, PlotRange -> All]

Mathematica graphics

Perhaps you want the Hermite interpolation in which derivatives at the nodes are specified:

data3 = Thread[{
    List /@ Range@Length@data,
    data,
    NDSolve`FiniteDifferenceDerivative[1, Range@Length@data, data]}];
Show[Plot[Interpolation[data3][x], {x, 1, 6}], ListPlot[data]]

Mathematica graphics

If you examine the first code for the Piecewise function, which was taken from the documentation as explained in the linked question, you'll see that when just the function values are supplied, the polynomial for an interval is constructed by interpolating the four points adjacent to the interval (the endpoint plus the next one on each side), except at the end intervals which use the first four or last four points. It's not hard to see that this scheme does not produce a continuous derivative, except by accident.

In the second form in which the values of the derivatives are specified, the left and right derivatives at an interior node will equal the specified value at the node. This can be done because the function values and derivative values at the end points of an interval represent four conditions that determine the four coefficients of a cubic polynomial. Thus this method, the classic Hermite method, has a continuous first derivative, but generally not a continuous second derivative. By specifying higher order derivative values, one can construct smoother interpolations, if desired. When NDSolve computes the solution to an ODE, it adds all the derivative values it computes in the normal, non-dense output, which will be up to the order of the ODE.

Michael E2
  • 235,386
  • 17
  • 334
  • 747
  • Thank you! The use of 2 neighbor points to calculate the 'inner' hermite polynom is the point. Wouldn't it be easier (and smoother) to estimate the deviation in a point and then use the hermite interpolation function 'with derivatives'. Thereby the knot derivative could be defined as an average of the slope of the neighboring secants... – Ulrich Neumann Dec 09 '17 at 09:57
  • @UlrichNeumann It would be smoother certainly; not sure if it's easier. It's more or less what is done in interpolating data3 above; the derivative approximation is of 4th order by default, but that can be changed with the option "DifferenceOrder" -> 2 in FiniteDifferenceDerivative. I think MATLAB's pchip does something like you suggest. I don't know what influences Mathematica's design decisions. – Michael E2 Dec 09 '17 at 16:58
  • In my attempt (something like pchip) the estimation y'[x1]~ ((-x0+x1)^2 (-y0+y1)+(-x1+x2)^2 (-y1+y2))/((-x0+x1)^3+(-x1+x2)^3) gives quite good results! Thank you for your contribution – Ulrich Neumann Dec 09 '17 at 17:30
  • @Ulrich, you might be interested in my implementation of pchip() here. – J. M.'s missing motivation Mar 25 '18 at 17:41
  • @J. M. Thank you for your pchip-implemetation. – Ulrich Neumann Mar 26 '18 at 07:19
  • I usually do a preliminary interpolation using data without derivatives, then compute average of the left and right limits of the derivative of the interpolating function at each point, and then interpolate that data again but with those average derivatives provided for each point. Usually it gives a result that visually better matches the data (has fewer erratic bumps between points) than using NDSolve`FiniteDifferenceDerivative. – Vladimir Reshetnikov Jun 11 '20 at 20:03