2013-05-01 3 views
5

나는 1 차원 데이터를 가지고 있으며 스플라인으로 맞 춥니 다. 그런 다음 굴곡 점 (안장 점을 무시함)을 찾으려고합니다. 이제 splev가 생성 한 많은 값에 scipy.signal.argrelmin (및 argrelmax)을 사용하여 첫 번째 파생어를 극한값으로 검색하고 있습니다.스플라인 장착 된 1d 데이터의 변곡점 찾기

import scipy.interpolate 
import scipy.optimize 
import scipy.signal 
import numpy as np 
import matplotlib.pyplot as plt 
import operator 

y = [-1, 5, 6, 4, 2, 5, 8, 5, 1] 
x = np.arange(0, len(y)) 
tck = scipy.interpolate.splrep(x, y, s=0) 

print 'roots', scipy.interpolate.sproot(tck) 
# output: 
# [0.11381478] 

xnew = np.arange(0, len(y), 0.01) 
ynew = scipy.interpolate.splev(xnew, tck, der=0) 

ynew_deriv = scipy.interpolate.splev(xnew, tck, der=1) 

min_idxs = scipy.signal.argrelmin(ynew_deriv) 
max_idxs = scipy.signal.argrelmax(ynew_deriv) 
mins = zip(xnew[min_idxs].tolist(), ynew_deriv[min_idxs].tolist()) 
maxs = zip(xnew[max_idxs].tolist(), ynew_deriv[max_idxs].tolist()) 
inflection_points = sorted(mins + maxs, key=operator.itemgetter(0)) 

print 'inflection_points', inflection_points 
# output: 
# [(3.13, -2.9822449358974357), 
# (5.03, 4.3817785256410255) 
# (7.13, -4.867132628205128)] 

plt.legend(['data','Cubic Spline', '1st deriv']) 
plt.plot(x, y, 'o', 
     xnew, ynew, '-', 
     xnew, ynew_deriv, '-') 
plt.show() 

하지만이 느낌은 대단히 잘못되었습니다. 나는 많은 가치를 창출하지 않으면 서 내가 찾고있는 것을 발견 할 가능성이 있다고 생각한다. sproot와 같은 것이지만 아마 두 번째 파생에 적용 할 수 있을까요?

+0

긍정 여기

이를 수행하기위한 코드이다. ;-) –

답변

4

derivative of a B-spline is also a B-spline. 따라서 먼저 데이터에 스플라인을 맞춘 다음 파생 공식을 사용하여 파생 스플라인 계수를 만들고 마지막으로 스플라인 루트 찾기를 사용하여 파생 스플라인의 근원을 얻습니다. 다음은 원래 곡선의 최대/최소값입니다. https://gist.github.com/pv/5504366

계수의 중요한 계산은 :

t, c, k = scipys_spline_representation 
# Compute the denominator in the differentiation formula. 
dt = t[k+1:-1] - t[1:-k-1] 
# Compute the new coefficients 
d = (c[1:-1-k] - c[:-2-k]) * k/dt 
# Adjust knots 
t2 = t[1:-1] 
# Pad coefficient array to same size as knots (FITPACK convention) 
d = np.r_[d, [0]*k] 
# Done, a new spline 
new_spline_repr = t2, d, k-1 

Finding inflection points of a curve via derivative splines

+1

와우, 정말 고마워. 나는 몰랐다. 스플라인을 구별하는 것은 "쉽다". roots()는 3 차에서만 작동하기 때문에 극한과 변곡점을 찾고 싶다면 다른 스플라인을 사용해야한다고 생각합니다.하지만 지금은 문제가 아닙니다. 어떤 사람이 코드로 내 문제를 해결할 수있는 방법에 관심이있는 경우 : https://ideone.com/qKja7X 및 http://s21.postimg.org/mbc96qcxj/out.png 및 https://ideone.com/ m757q9 –