josdejong / mathjs

An extensive math library for JavaScript and Node.js
https://mathjs.org
Apache License 2.0
14.33k stars 1.24k forks source link

Implement of "lerp" ? #549

Closed tommyZZM closed 2 years ago

tommyZZM commented 8 years ago

is a useful function

https://msdn.microsoft.com/en-us/library/bb509618(VS.85).aspx

josdejong commented 8 years ago

Thanks for you suggestion!

mDantas commented 8 years ago

I'd be happy to take this on - I'll try to have a PR out sometime this week.

josdejong commented 8 years ago

Thanks Matthew. I guess we can still discuss the best name (lerp, interp, interpolate, ...) for this function and the exact API, maybe you can do a proposal?

mDantas commented 8 years ago

Sure thing, Jos. I'll give it some thought and will post back.

mDantas commented 8 years ago

Hey Jos,

A few thoughts... along with the caveat emptor that it's been 5ish years since my math undergrad. I hope this is helpful - I'm excited to help!

Problem Scope & Naming

A lerp as it shows up appears in computer graphics to be a special case of linear interpolation. A 'lerp' is the linear interpolation between the known points (0, y0) and (1, y1). I don't see why we shouldn't implement the more general linear interpolation between (x0, y0) and (x1, y1).

We could then add a lerp wrapper around the more general linear interpolation (linearInterpolate)?

API

A preliminary sketch... I'm sure there will have to be more thought given to where the rubber meets the floating point computation.

There would be 3 inputs - 2 known 'points' and a point-at-which-to-interpolate. As long as those 3 'points' are of all of the same type - scalar or square matrix - I think we can return a meaningful linear interpolation with the usual caveats of large error or uncomputability when dealing with matrices (large condition number or non invertibility of (X1-X0), respectively - assuming a form for the linear interpolation as given below).

Y = (Y1 - Y0)*inv(X1 - X0)*(X - X0) + Y0

where all variables are square matrices of the same dimensions

We can also accept the case where the function being interpolated is a mapping from scalars to vectors or matrices of the same dimensions. In this case the above would reduce to:

Y = (Y1 - Y0)/(x1 - x0)*(x - x0) + Y0

where x, x1, and x0 are scalars and all other variables are of the same type (same-dimensioned matrix or vector)

In the case of the lerp - where x0 is 0 and x1 is 1 and x is just a fraction between 0 and 1 this can reduce to

Y = Y1*x + Y0*(1 - x)

The Scope Creep that Wasn't

I initially thought it'd be a good idea to go ahead implement polynomial interpolation (using Lagrange polynomials) since linear interpolation is the special case but given that polynomial interpolants can get so wiggly as their order increases, I wonder if this would be all that helpful to users of the library. So maybe we should indeed just stick to the n = 1 case as that (I'm guessing) will be most helpful to most users (e.g. in linear/bilinear interpolation betw tabulated data). And then there's dealing with things beyond scalars and my head's starting to hurt.

josdejong commented 8 years ago

Sounds indeed good to write a more generic method for linear interpolation. Similar to the function distance which also accepts different sorts of inputs.

I think we should start simple, but design the function such that we can extend in the future without having to break the API. So how would this function be used, what would be the API? How about:

y = math.interpolate(x, point1, point2)

Where point1 and point2 are 2d points in a format [x, y] or {x: x, y: y}. x can be a scalar, or a matrix/array in which case the interpolation is performed element wise on all values in the matrix.

For inspiration: http://docs.scipy.org/doc/scipy/reference/tutorial/interpolate.html http://docs.scipy.org/doc/numpy-1.10.1/reference/generated/numpy.interp.html https://msdn.microsoft.com/en-us/library/microsoft.xna.framework.mathhelper.lerp.aspx

mDantas commented 8 years ago

Hey @josdejong, it's been a while :) - I'm picking this back up. Hope all's well.

josdejong commented 8 years ago

great :)

gwhitney commented 2 years ago

Given the age of this issue and that the PR #663 aimed at implementing it never came to fruition, it is being closed but if someone is interested in adding a general (linear) interpolation facility to mathjs, a revival of this issue and consideration of a new PR would certainly be possible.