One end clamped and other end free cubic spline using scipy.interpolate.splprep and splev

旧时模样 提交于 2021-02-08 07:25:44

问题


I have the following data:

x_old = [  0.00000000e+00,  -5.96880765e-24,  -8.04361605e-23,
    -2.11167774e-22,  -2.30386081e-22,  -7.86854147e-23,
     1.17548440e-22,   1.93009272e-22,   1.49906866e-22,
     9.66877465e-23,   1.48495705e-23]
y_old = [ 0.        ,  0.03711505,  0.03780602,  0.02524459,  0.01349815,
    0.00964215,  0.00972842,  0.0168793 ,  0.02577024,  0.02761626,
    0.02141961]


z_old = [ 0.        ,  0.29834302,  0.59805918,  0.89773519,  1.19755092,
    1.49749325,  1.79750314,  2.09741402,  2.39727031,  2.69726787,
    2.99719479]

I want to find the 3-D spline between these points so that the initial coordinate (0, 0, 0) remains fixed (clamped) and the other end is free.

I did:

 from scipy.interpolate import splprep, splev
 import numpy as np

 # find the knot points
 tckp,u = splprep([x_old,y_old,z_old],s=3.0,k=3,nest=-1)
 # evaluate spline.
 xnew,ynew,znew = splev(np.linspace(0,1,400),tckp)

Graph:

from mpl_toolkits.mplot3d import Axes3D
import matplotlib.pyplot as plt

ax.plot(xnew, ynew, znew, label='first iteration')
plt.scatter(x_old, y_old, z_old, color='blue', label='given')
ax.legend()

plt.show()

Question 1. In the above graph, the initial point is certainly not fixed. Mathematically, I know that I need to specify boundary conditions so that I get the 3-D spline I want. How can I do this in scipy?. Is there any optional arguments I can use in splprep and splev that I can specify to achieve this or do I need a completely new way to do this?

Question 2 : If I wanted both ends to be clamped then how do I achieve that?

Some Math : 'Clamped at the initial point' means that the first derivative at the initial point is zero and 'free at the terminal' point means that the second derivative there is zero.


回答1:


It seems you want an interpolating spline, which means the smoothing parameter s should be set to 0.

tckp, u = splprep([x_old,y_old,z_old], s=0.0, k=3, nest=-1)

A clamped spline (or a spline with other boundary conditions) can be made with make_interp_spline. Below, the parameters l, r are the boundary conditions at the left and right end. I prescribe zero first derivative at the left end, and zero second derivative at the right.

l, r = [(1, (0, 0, 0))], [(2, (0, 0, 0))]
clamped_spline = make_interp_spline(u, np.array([x_old, y_old, z_old]).T, bc_type=(l, r))
xnew2, ynew2, znew2 = clamped_spline(np.linspace(0,1,400)).T

Notice that I used the parameter u from the first spline, expecting it to perform better than a random linearly-spaced array. (u is computed based on the data points.)

Plotting both for comparison:

from mpl_toolkits.mplot3d import Axes3D as ax
import matplotlib.pyplot as plt
fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')
ax.plot(xnew, ynew, znew, label='first iteration')
ax.plot(xnew2, ynew2, znew2, color='red', label='second iteration')
ax.scatter(x_old, y_old, z_old, color='blue', label='given')
ax.legend()
plt.show()

The clamping condition clearly had some effect near that end.



来源:https://stackoverflow.com/questions/47089749/one-end-clamped-and-other-end-free-cubic-spline-using-scipy-interpolate-splprep

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!