Non-Piecewise interpolation over 3 points

367 Views Asked by At

I am trying to write an algorithm that interpolates between 3 values.

The interpolation will be over the interval [0,1].

What I would like to do is: (Hopefully this makes sense)

  • at x = 0, y = [start value]
  • at x = [peak location], y = [middle value]
  • at x = 1, y = [end value].

This is easy to do if the [peak location] is 0.5 and the [start value] = [end value] since I can just fit a parabola. But I have been trying to do something along the lines of: [start value] = 0.3, [middle value] = 0.9, [peak location] = 0.2, and [end value] = 0.1

I am trying to do this in a non piecewise way. I have looked into Beziér Curves, but I cannot use x as an input.

Apologies for this may not being clear, but I'm hoping someone can point me in the right direction.

EDIT: one more thing I just noticed: It appears that the maximum of the Bezier Curve does not occur at 0.2 (my desired peak location). So I don't think Bezier curves are what my solution is.

Close, but not quite what I am looking for with Bezier Curves

EDIT2: I was able to get much closer with Catcall-Rom splines: enter image description here

4

There are 4 best solutions below

1
On BEST ANSWER

Let's use the notation from Fang's answer. Given $y_0$, $y_m$, $y_1$, and $m$, we want to find a function $f$ such that $f(0) = y_0$, $f(m) = y_m$, and $f(1) = y_1$.

It sounds like you already know how to find a quadratic polynomial $g$ and a value $x_m$ such that $g(0) = y_0$, $g(x_m) = y_m$, $g(1) = y_1$, and $g'(x_m) = 0$.

This parabola has all the right properties, except that it doesn't achieve it's maximum at the right $x$-value: we wanted the maximum to occur at $x=m$, and it's occurring at $x=x_m$ instead.

So, now the idea is that we reparameterize by distorting the $x$-axis. We construct a monotone function $\alpha$ such that $\alpha(0) = 0$, $\alpha(m) = x_m$, and $\alpha(1) = 1$. Then, if we define $f(x) = g(\alpha(x))$, the function $f$ will have the desired properties.

The remaining question is how to construct the function $\alpha$. In most situations, a quadratic polynomial will work, but there is some danger that it won't be monotone in extreme cases. A better choice would probably be a Moebius transformation of the form $\alpha(x) = x/(cx+d)$. You can adjust $c$ and $d$ to get the right properties. The final function $f$ will then be a rational quadratic (the quotient of two quadratic polynomials). Actually, you could probably just construct this rational quadratic directly, without all the reparameterization fuss outlined above.

1
On

You ca use two parabolas: one on the interval $[0,\text{midloc}]$ and another on $[\text{midloc},1]$. That is $$ y(x)=\begin{cases}a\,x^2+b\,x+\text{start} & 0\le x\le\text{midloc}\\ c\,(x-1)^2+d\,(x-1)+\text{end} & \text{midloc}\le x\le1\end{cases} $$ The coefficients $a,b,c,d$ are found imposing that the value at $x=\text{midloc}$ is $y=\text{mid}$ and that the derivative at $x=\text{midloc}$ is $0$. This is the picture for your example: enter image description here

2
On

Besides the 3 points to interpolate, you also want the value at the middle point to be the peak. Therefore, you actually have 4 equations to satisfy:

$f(0) = y_0$
$f(m) = y_m$
$f(1) = y_1$
$f'(m)=0 $

where $y_0$, $y_1$ and $y_m$ are the $y$ values at $x=0$, $x=1$ and peak location $x=m$.

Therefore, if you really want a non-piecewise solution that satisfies all these 4 equations, you should at least go with cubic polynomial. Using a quadratic polynomial to interpolate the 3 points only will not give you peak value at the location you desired in general.

However, going with cubic polynomial has its downside: you might also get a "valley" (minimum) value in the [0,1] interval. For your example where $y_0=0.3, y_m=0.9, y_1=0.1$ and $m=0.2$, it will lead to a cubic polynomial $f(x)= \frac{55}{4}x^3-\frac{41}{2}x^2+\frac{131}{20}x+\frac{3}{20}$, which will have a peak and also a valley within [0,1].

If you only want a single peak (and no valley) within [0,1], going with piecewise solution will be a much easier approach. You can either use two quadratic polynomials (as already posted) or two cubic polynomials (similar to the Catmull-Rom spline you had tried).

1
On

Judging by the spline solutions you have tried, it appears that you're willing to use parametric curves, rather than just ones of the form $y=f(x)$. If that's the case, the problem can be solved using a quadratic Bezier curve (i.e. a rotated parabola).

Let $a$, $b$, $c$ denote the start value, the peak value, and the end value respectively. A suitable Bezier quadratic is $\mathbf{P}(t) = \big(x(t),y(t)\big)$, where $$ x(t) = (0)(1-t)^2+ (h)2t(1-t) + (1)t^2 = 2ht(1-t) $$ $$ y(t) = (a)(1-t)^2 + (k)2t(1-t) + (c)t^2 $$ This curve has control points $(0,a)$, $(h,k)$ and $(1,c)$. It is easy to check that $\mathbf{P}(0) = (0,a)$ and $\mathbf{P}(1) = (1,c)$, so we have the correct values at the end-points.

Suppose we want the peak value $b$ to occur at $x=m$. This will happen if there exists a parameter value $t=u$ such that $x(u) = m$, $y(u) = b$ and $y'(u) = 0$.

So, we need to solve the three equations $$ x(u) = m \quad;\quad y(u) = b \quad;\quad y'(u) = 0 $$ for $h$, $k$, and $u$.

I used Mathematica to get the solutions: $$ h = \frac{b-a +2m\sqrt{((b-a)(b-c)} + m[(b-a)+(b-c)]}{2\sqrt{(b-a)(b-c)}} $$ $$ k = b + \sqrt{(b-a)(b-c)} $$ $$ u = \frac{b-a - \sqrt{(b-a)(b-c)}}{c-a} $$ If we define $r = \sqrt{(b-a)(b-c)}$, these formulae simplify to $$ h = \frac{b-a +2mr + m[(b-a)+(b-c)]}{2r} $$ $$ k = b + r $$ $$ u = \frac{b-a - r}{c-a} $$ In your example, we have $a=0.3$, $b=0.9$, $c=0.1$, and $m = 0.2$. Plugging these values into our formulae, we get $h= -0.0309401$, $k = 1.59282$, $u=0.464102$.

Here's a picture of the resulting curve enter image description here