2017-02-17 35 views
0

Я пытаюсь найти производные сплайна в нескольких точках, используя splev в scipy. Например:Производные сплайна: `scipy splev`

import numpy as np 
from scipy.interpolate import splprep, splev 
import matplotlib.pyplot as plt 

# function to normalize each row 
def normalized(a, axis=-1, order=2): 
    l2 = np.atleast_1d(np.linalg.norm(a, order, axis)) 
    l2[l2==0] = 1 
    return a/np.expand_dims(l2, axis) 

# points and spline 
pts = np.array([[0,0],[1,1],[2,np.sqrt(2)],[4,2],[9,3]]) 
tck, u = splprep(pts.T, u=None, k=3, s=0.0, per=0) 

# compute new points and derivatives 
u_new = np.linspace(u.min(), u.max(), 5*u.shape[0]) 
x_new, y_new = splev(u_new, tck, der=0) 
xp_num, yp_num = splev(pts, tck, der=1) # numerical derivatices 
xp_the, yp_the= pts[1:,0], 0.5/np.sqrt(pts[1:,0]) # analytical derivatives 
R = normalized(yp_num/xp_num) 
X,Y = pts[1:,0], pts[1:,1] 
U,V = X + R[1:,0], Y+R[1:,1] 

Я хотел бы построить касательные в данной точке:

plt.plot(x_new,y_new,'-b') 
plt.plot(pts[:,0],pts[:,1],'--ro') 
plt.quiver(X,Y,U,V, angles='xy', scale_units='xy') 

enter image description here

Я думаю, что эти касательные являются неправильными. Я понимаю, что xp_num и yp_num являются численными производными сплайна по отношению к x и y. Поэтому, чтобы найти dy/dx, я должен просто их разделить. Это верно?

В конце концов, я хотел бы найти касательные кривого, как this

+1

wh at делает 'normalized' делать? –

+0

@PaulPanzer: Он нормализует каждую строку. Я добавил определение 'normalize'. – Mahdi

+0

Странно, ваш код выглядит так, как будто он не должен создавать никаких векторов в сюжете вообще. 'yp_num' и' xp_num' равны 1d, не так ли? Таким образом, ваш 'R' должен быть 1 x-то, поэтому, когда вы нарезаете' R [1:, 0], вы должны получить пустой массив. Я что-то упустил? –

ответ

1

Вашей задачи (очевидно неправильные производные) не связаны с численной производной, так как вы не используете их, по крайней мере в коде вы вывесили , Что явно неправильно, если ваша normalized функция не делает что-то действительно магия ваш разделив yp_the на xp_the, поскольку первое действительно приращение, последняя не должна быть постоянной, чтобы получить

dy 
-- 
dx 

в отличие от вашей

dy 
---- 
x dx 

Вы, вероятно, исходя из формулы для параметрического кривой

.  dy 
     -- 
dy dt 
-- = ---- 
dx dx 
     -- 
     dt 

используется t=x, а затем пропущено, что dx/dx является постоянным. Вещь, которая случается с лучшими из нас.

+0

Удивительно, это точно, я думал о параметрической кривой! Благодаря! – Mahdi

1

вы не включили ваш R = normalized(yp_the/xp_the) источник

Я сделал это с linalg.norm

я изменил delta_Y для нормированной производной

и отказался от колчана

import numpy as np 
from scipy.interpolate import splprep, splev 
import matplotlib.pyplot as plt 

# points and spline 
pts = np.array([[0,0],[1,1],[2,np.sqrt(2)],[4,2],[9,3]]) 
tck, u = splprep(pts.T, u=None, k=3, s=0.0, per=0) 

# compute new points and derivatives 
u_new = np.linspace(u.min(), u.max(), 5*u.shape[0]) 
x_new, y_new = splev(u_new, tck, der=0) 
xp_num, yp_num = splev(pts, tck, der=1) # numerical derivatices 
xp_the, yp_the= pts[1:,0], 0.5/np.sqrt(pts[1:,0]) # analytical derivatives 
#R = normalized(yp_the/xp_the) 
N = np.linalg.norm(np.array([xp_the, yp_the]), axis=0) 

X,Y = pts[1:,0], pts[1:,1] 
#U,V = X + R[1:,0], Y+R[1:,1] 
U,V = X + xp_the/N, Y + X*yp_the/N # delta Y = dy/dx * x 

plt.axes().set_aspect('equal', 'datalim') 

plt.plot(x_new,y_new,'-b') 
plt.plot(pts[:,0],pts[:,1],'--ro') 
#plt.quiver(X,Y,U,V, scale=10, pivot='mid')# angles='xy', scale_units=’xy’, scale=1 

plt.plot((X, U), (Y, V), '-k', lw=3) 

enter image description here

+0

Извините за мою ошибку. Я имел в виду наложение касательных с помощью 'xp_num' и' yp_num'. – Mahdi