2016-02-07 32 views
2

Использование SciPy-х splrep я могу легко поместить тест синусоиды:SciPy splrep() с весами не подгонки заданной кривой

import numpy as np 
from scipy.interpolate import splrep, splev 
import matplotlib.pyplot as plt 
plt.style.use("ggplot") 

# Generate test sinewave 
x = np.arange(0, 20, .1) 
y = np.sin(x) 

# Interpolate 
tck = splrep(x, y) 
x_spl = x + 0.05 # Just to show it wors 
y_spl = splev(x_spl, tck) 
plt.plot(x_spl, y_spl) 

Spline sinewave plot

splrep documentation states, что значение по умолчанию для параметра веса np.ones(len(x)). Однако, черчения это приводит к совершенно другому сюжету:

tck = splrep(x, y, w=np.ones(len(x_spl))) 
y_spl = splev(x_spl, tck) 
plt.plot(x_spl, y_spl) 

Plot with splev and weights

В документации также говорится, что условие сглаживающего s отличается, когда массив веса дается - но даже при установке s=len(x_spl) - np.sqrt(2*len(x_spl)) (значения по умолчанию без весового массива) результат не строго соответствует исходной кривой, как показано на графике.

Что мне нужно изменить в приведенном выше коде, чтобы сделать интерполяцию с весовым массивом (как указано выше), вывести тот же результат, что и интерполяция без весов? Я проверил это с scipy 0.17.0. Gist with a test IPython notebook

ответ

1

Вы только должны изменить одну строку кода, чтобы получить идентичный результат:

tck = splrep(x, y, w=np.ones(len(x_spl))) 

должен стать

tck = splrep(x, y, w=np.ones(len(x_spl)), s=0) 

Таким образом, единственное отличие состоит в том, что вы должны указать s вместо использования по умолчанию.

Когда вы смотрите на source code из splrep вы увидите, почему это необходимо:

if w is None: 
    w = ones(m, float) 
    if s is None: 
     s = 0.0 

else: 
    w = atleast_1d(w) 
    if s is None: 
     s = m - sqrt(2*m) 

, что означает, что, если предусмотрены ни веса, ни s, s устанавливается в 0, и если вы предоставите вес, но no s затем s = m - sqrt(2*m) где m = len(x).

Итак, в приведенном выше примере вы сравниваете выходы с одинаковыми весами, но с разными s (которые являются 0 и m - sqrt(2*m) соответственно).