Comments on: Splines and Pchips https://blogs.mathworks.com/cleve/2012/07/16/splines-and-pchips/?s_tid=feedtopost Cleve Moler is the author of the first MATLAB, one of the founders of MathWorks, and is currently Chief Mathematician at the company. He writes here about MATLAB, scientific computing and interesting mathematics. Sat, 25 Feb 2017 01:10:29 +0000 hourly 1 https://wordpress.org/?v=6.2.2 By: John D'Errico https://blogs.mathworks.com/cleve/2012/07/16/splines-and-pchips/#comment-23 Sun, 22 Jul 2012 10:24:29 +0000 https://blogs.mathworks.com/cleve/?p=196#comment-23 Some thoughts I forgot to add in my previous response…

First of all, did I say how happy I am to see Cleve writing these blogs? I’ll bet that many others have been reading and enjoying these blogs just like me. I hope to see many more blogs from Cleve in the future.

Next, I would add that my own SLM tools use an idea under the hood that I took from Fritsch and Carlson to generate monotone approximations. They showed that a cubic segment will be monotone on an interval if the coefficients (when transformed properly) fall inside a convex region with an elliptical boundary. SLM approximates that elliptical region with a slightly smaller (6 sided) polygonal domain that still enforces true monotonicity, creating a set of sufficient constraints that can be implemented with a solver like lsqlin.

]]>
By: John D'Errico https://blogs.mathworks.com/cleve/2012/07/16/splines-and-pchips/#comment-22 Sun, 22 Jul 2012 10:02:45 +0000 https://blogs.mathworks.com/cleve/?p=196#comment-22 I’ve been using pchip since I first found it in the early 80s. The funny thing is in most cases, most users won’t see those subtle second derivative discontinuities, but they do prefer the good behavior of a shape preserving tool like pchip. For example, given data with a simple sigmoid shape like that of erf. For an interpolant here, especially if the transition is a sharp one that happens over only a few points, pchip is nice to have. Try this as an example:

x = -4:4;
y = erf(1.5*x);
plot(x,y,’o’)

It is a curve that is well behaved, but very difficult for a tool like spline to model.

yhats = interp1(x,y,xhat,’spline’);
yhatp = interp1(x,y,xhat,’pchip’);
plot(x,y,’o’,xhat,yhats,’-r’,xhat,yhatp,’-b’)

If that monotone behavior is of paramount importance to you, then there is no choice, use pchip. In fact, that is a fundamental curve shape that I used to see all the time when I worked at Eastman Kodak. See that the spline generates ringing (like that of Gibb’s phenomena) that would be objectionable to a client who needed those flat tails, but pchip does a beautiful job.

However, there are some places where the properties of pchip become a problem. I once had a client who was bothered by those tiny second derivative discontinuities. But more importantly, try this curve out:

x = -4:4;
y2 = exp(-(x-.5).^2);
plot(x,y2,’o’)

One basic result/artifact of the shape preserving property of pchip is when the curve goes through a maximum or a minimum, the extremum of the interpolant occurs exactly at the extremal data point. A second characteristic of that tool is when there are two consecutive points with the same value, the interpolant is constant over that interval.

yhat2p = interp1(x,y2,xhat,’pchip’);
yhat2s = interp1(x,y2,xhat,’spline’);
plot(x,y2,’o’,xhat,yhat2s,’-r’,xhat,yhat2p,’-b’)

Here I don’t terribly like either of the interpolants. See that pchip did what I would want along the baseline, where we see no ringing. But at the peak, where I know that my function actually hits exactly 1.0, the interpolant misses the behavior I want to see. Even if that exponential had been shifted a bit so it would have peaked at 0.3, pchip would still have produced an interpolant that lacked a well shaped peak.

One solution is to employ a different shape preserving interpolant. For many years I used a rational quadratic spline, based on the ideas of Delbourgo and Gregory.

J.A.Gregory,R.Delbourgo, Piecewise rational quadratic interpolation to monotonic data, IMA Journal of Numerical Analysis, 2(1982),123-130.

A rational quadratic interpolant based on that paper is a bit smoother than pchip, in fact generally C2. Its a bit slower to generate than pchip (which can be blazingly fast, even compared to a cubic spline) and often a bit slower to generate than a cubic spline too. As well, you need to trap for singularities over intervals where the function is constant. There are some other shape preserving interpolants that have been generated over the years, but any interpolant with C2 behavior will please some users. However at a flat topped peak like the data above, these shape preserving interpolants still tend to fail. They simply don’t “know” when it is right to generate a nicely shaped peak that falls between a pair of data points, yet still not create a curve that rings like a bell in other places.

A common source of data with a shape like that of the Gaussian I generated above is seen by anyone who works with illuminant spectral power functions. For example, look at the spectral curve for a fluorescent lamp. Some examples are given in this link:

http://www.konicaminolta.eu/en/measuring-instruments/learning-centre/light-measurement/light/light-sources-and-illuminants.html

The last curve, shown as CIE illuminant F11 is a good example of one with sharp peaks, but also valleys that go down to zero. While we won’t wish to see an interpolant for that curve that goes negative in the valleys, we might also want an interpolant that models the peaks well, yet does not generate severe ringing in other places.

One trick that can work on SOME problems is to recognize that a transformation may be appropriate. Thus, do your interpolation in a domain where ringing is not an issue. For example, on my Gaussian curve, I VERY much prefer the curve I get from a log transformation, then a retransformation via an exponential.

yhat2t = exp(interp1(x,log(y2),xhat,’spline’));
plot(x,y2,’o’,xhat,yhat2s,’-r’,xhat,yhat2p,’-b’,xhat,yhat2t,’-g’)

I think most people will prefer the green curve. It has the behavior one expects near a zero baseline, yet it hits my peak quite well too.

]]>