Skip to content

ENH: Rbf interpolation of large multi-dimensional data #9215

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
May 20, 2019

Conversation

jrsassen
Copy link
Contributor

@jrsassen jrsassen commented Sep 3, 2018

So far, scipy.interpolate.Rbf could only be used to interpolate one-dimensional functions, I added the capability to also interpolate multi-dimensional functions.
Furthermore, I changed the way the norm is computed in Rbf to exploit the much faster implementations from scipy.spatial.distance.
Lastly, I also aligned the interface of Rbf to other interpolations in scipy.interpolate such as griddata or LinearNDInterpolator.

Example usage:

>>> from scipy.interpolate import Rbf
>>> x = np.random.rand(50,)*4-2
>>> y = np.random.rand(50,)*4-2
>>> z0 = x*np.exp(-x**2-1j*y**2)
>>> z1 = y*np.exp(-y**2-1j*x**2)
>>> z = np.vstack([z0, z1]).T
>>> rbf = Rbf((x, y), z, epsilon=2)
>>> zi = rbf((x, y))
>>> zi.shape
(50, 2)

@jrsassen jrsassen force-pushed the master branch 2 times, most recently from d067cb9 to bf6aee4 Compare September 3, 2018 12:49
@rgommers rgommers added the enhancement A new feature or improvement label Sep 3, 2018
@rgommers
Copy link
Member

rgommers commented Sep 3, 2018

Thanks @jrsassen.

So far, scipy.interpolate.Rbf could only be used to interpolate one-dimensional functions, I added the capability to also interpolate multi-dimensional functions.

sounds good

Furthermore, I changed the way the norm is computed in Rbf to exploit the much faster implementations from scipy.spatial.distance.

yes that makes sense

Lastly, I also aligned the interface of Rbf to other interpolations in scipy.interpolate such as griddata or LinearNDInterpolator.

Unfortunately we cannot do this - it will break Rbf for all current users. Could you undo this change?

@jrsassen
Copy link
Contributor Author

jrsassen commented Sep 3, 2018

Thanks for the feedback, @rgommers

Unfortunately we cannot do this - it will break Rbf for all current users. Could you undo this change?

Yes, you're right, that was a bit extreme. At first I thought it would be necessary, but I was mistaken. I have removed this change.

@rgommers
Copy link
Member

rgommers commented Sep 4, 2018

@jrsassen if you don't mind, could you open a separate PR for just the performance improvement with spatial.distance? That can be merged very quickly, and then this one is a bit easier to review (squash and rebase on top of the merged one).

array of distance. E.g, the default: 'euclidean', such that the result
is a matrix of the distances from each point in ``x1`` to each point in
``x2``. For more options, see documentation of
scipy.spatial.distances.cdist.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

typo, plus use backticks to create a link: `scipy.spatial.distance.cdist`

@rgommers
Copy link
Member

rgommers commented Sep 4, 2018

CI failure is unrelated

@rgommers
Copy link
Member

rgommers commented Sep 4, 2018

Sorry, not awake yet - CI failure is in Rbf. Looks like this should keep working:

import numpy as np
from scipy.interpolate import Rbf
import matplotlib.pyplot as plt
from matplotlib import cm

# 2-d tests - setup scattered data
x = np.random.rand(100)*4.0-2.0
y = np.random.rand(100)*4.0-2.0
z = x*np.exp(-x**2-y**2)
ti = np.linspace(-2.0, 2.0, 100)
XI, YI = np.meshgrid(ti, ti)

# use RBF
rbf = Rbf(x, y, z, epsilon=2)
ZI = rbf(XI, YI)

# plot the result
plt.subplot(1, 1, 1)
plt.pcolor(XI, YI, ZI, cmap=cm.jet)
plt.scatter(x, y, 100, z, cmap=cm.jet)
plt.title('RBF interpolation - multiquadrics')
plt.xlim(-2, 2)
plt.ylim(-2, 2)
plt.colorbar()

@jrsassen
Copy link
Contributor Author

jrsassen commented Sep 4, 2018

I have opened a separate PR #9222 for the 'spatial.distance' part as requested.

I also understand the problem CI turns up, the interface (esp. the return value of __call__) before my multidimensional changes was a bit different than it is now. I will try to come up with compatible way for this.

@rgommers
Copy link
Member

gh-9222 is merged, this can now be rebased on master

@jrsassen
Copy link
Contributor Author

Finally got around to it, also fixed the problem that CI reported before.
Let me know if anything else is needed.

@rgommers
Copy link
Member

Thanks @jrsassen. I just opened gh-9283 to document what are public attributes, needed that to help figure out what's ok/nok here.

@@ -192,9 +193,14 @@ def __init__(self, *args, **kwargs):
self.xi = np.asarray([np.asarray(a, dtype=np.float_).flatten()
for a in args[:-1]])
self.N = self.xi.shape[-1]
self.di = np.asarray(args[-1]).flatten()
self.di = np.asarray(args[-1])
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks like a backwards compatibility break, in two ways:

  • di is public, and you're changing its shape for >1-D input
  • you're using di.ndim as an indication that the interpolation should now be multi-dimensional.

This should be avoided. I suspect that there's no better way than adding a new keyword argument (e.g. flatten=True or `mode='1-D') that preserves backwards compat but allows the user to enable multi-dim interpolation.

@ev-br
Copy link
Member

ev-br commented Sep 19, 2018

Needs a rebase again

So far, Rbf only allowed for the interpolation of one-dimensional data.
This commit introduces the necessary changes to allow component-wise
interpolation of multi-dimensional data.
The resulting linear system has to be solved onces per target dimension,
hence LU factorization is used.
@jrsassen
Copy link
Contributor Author

Hey, I rebased and introduced mode as keyword argument, which determines whether we would like one-dim or multi-dim interpolation.

@ev-br ev-br merged commit 7af05cb into scipy:master May 20, 2019
@ev-br
Copy link
Member

ev-br commented May 20, 2019

Looks good. Let's get this in before it needs one more rebase. Sorry it took so long @jrsassen, and thanks!

@ev-br ev-br added this to the 1.4.0 milestone May 20, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement A new feature or improvement scipy.interpolate
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants