Наименьшее количество проблем при передаче параметров Python
Я пытаюсь соответствовать следующей функции: Снижение SNR в мои данные. C1, C2 и h - параметры, которые мне нужно получить из метода наименьшего количества. C1 и C2 просты, но проблема в том, что мой h(t) в действительности: , Я хочу получить коэффициенты hj внутри этой функции (в моем случае есть 35 различных hj). Эта функция является суммой различных базовых B-сплайнов, каждый из которых имеет различный вес, и количество коэффициентов равно количеству узлов B-сплайна. Поскольку я хочу получить C1, C2 и h1..35, я делаю следующее:
funcLine = lambda tpl, eix_x: (tpl[0]*np.sin((4*math.pi*np.sum(bsplines_evaluades * np.transpose([tpl[2],tpl[3],tpl[4],tpl[5],tpl[6],tpl[7],tpl[8],tpl[9],tpl[10],tpl[11],tpl[12],tpl[13],tpl[14],tpl[15],tpl[16],tpl[17],tpl[18],tpl[19],tpl[20],tpl[21],tpl[22],tpl[23],tpl[24],tpl[25],tpl[26],tpl[27],tpl[28],tpl[29],tpl[30],tpl[31],tpl[32],tpl[33],tpl[34],tpl[35],tpl[36],tpl[37]]) , axis=0))*eix_x/lambda1) + tpl[1]*np.cos((4*math.pi*np.sum(bsplines_evaluades * np.transpose([tpl[2],tpl[3],tpl[4],tpl[5],tpl[6],tpl[7],tpl[8],tpl[9],tpl[10],tpl[11],tpl[12],tpl[13],tpl[14],tpl[15],tpl[16],tpl[17],tpl[18],tpl[19],tpl[20],tpl[21],tpl[22],tpl[23],tpl[24],tpl[25],tpl[26],tpl[27],tpl[28],tpl[29],tpl[30],tpl[31],tpl[32],tpl[33],tpl[34],tpl[35],tpl[36],tpl[37]]) , axis=0))*eix_x/lambda1))*np.exp(-4*np.power(k, 2)*lambda_big*np.power(eix_x, 2))
func = funcLine
ErrorFunc = lambda tpl, eix_x, ydata: np.power(func(tpl, eix_x) - ydata,2)
tplFinal1, success = leastsq(ErrorFunc, [2, -2, 8.2*np.ones(35)], args=(eix_x, ydata))
tpl (0) = C1, tpl (1) = C2 и tpl(2..35)= мои коэффициенты. bsplines_evaluades - это матрица [35,86000], где каждая строка является временной функцией каждого базисного b-сплайна, поэтому я взвешиваю каждую строку с ее индивидуальным коэффициентом, 86000 - это длина eix_x. ydata(eix_x) - это функция, которую я хочу приблизить. лямбда1= 0,1903; lambda_big= 2; к =2* пи / lambda1. Выходными данными являются те же исходные параметры, которые не являются логическими. Может кто-нибудь мне помочь? Я тоже пробовал с Curvefit, но он не работает. Данные находятся по адресу: http://www.filedropper.com/data_5>http://www.filedropper.com/download_button.png width = 127 height = 145 border = 0 />
http://www.filedropper.com> онлайн резервное хранилище
РЕДАКТИРОВАТЬ Код прямо сейчас:
lambda1 = 0.1903
k = 2 * math.pi / lambda1
lambda_big = 2
def funcLine(tpl, eix_x):
C1, C2, h = tpl[0], tpl(1), tpl[2:]
hsum = np.sum(bsplines_evaluades * h, axis=1) # weight each
theta = 4 * np.pi * np.array(hsum) * np.array(eix_x) / lambda1
return (C1*np.sin(theta)+C2*np.cos(theta))*np.exp(-4*lambda_big*(k*eix_x)**2) # lambda_big = 2
if len(eix_x) != 0:
ErrorFunc = lambda tpl, eix_x, ydata: funcLine(tpl, eix_x) - ydata
param_values = 7.5 * np.ones(37)
param_values[0] = 2
param_values(1) = -2
tplFinal2, success = leastsq(ErrorFunc, param_values, args=(eix_x, ydata))
Проблема в том, что выходные параметры не меняются относительно исходных. Данные (x_axis,ydata,bsplines_evaluades): gist.github.com/hect1995/dcd36a4237fe57791d996bd70e7a9fc7 gist.github.com/hect1995/39ae4768ebb32c27f1ddea97e24d96af gist.githbb1000_f1_1d0361d0251d0355257
2 ответа
Всегда полезно (как для себя, так и для нас) предоставить понятный пример, который является достаточно полным, чтобы его можно было запустить. Ваш пример с lambda
s и очень длинная строка определенно не читается, поэтому вам очень легко пропустить простые ошибки. Одним из пунктов использования Python является упрощение чтения кода.
Хорошо иметь сплайн-коэффициенты в качестве подгоночных переменных, но вы хотите, чтобы np.ndarray переменных был точно одномерным. Таким образом, ваш массив параметров должен быть
param_values = 8.2 * np.ones(37)
param_values[0] = 2
param_values[1] = -2.
result_params, success = leastsq(errorFunc, param_values, ....)
Также должно быть хорошо использовать curve_fit(). Кроме того, трудно оказать большую помощь, поскольку вы не предоставляете ни полностью работоспособную программу (оставляющую множество терминов неопределенной), ни вывод или сообщения об ошибках при запуске вашего кода.
Здесь может быть несколько вещей: я не уверен, что вы индексируете tpl
массив правильно (если он имеет 37 записей, индексы должны быть 0:36
). И ваш errorFunc, вероятно, должен возвращать остаток, а не квадратный остаток.
Наконец, я думаю, что ваша h-сумма может быть неправильной: вы хотите суммировать по оси $N$, но не по оси $ x $, верно?
Вы можете привести в порядок свой код следующим образом и посмотреть, поможет ли он (без каких-либо данных это сложно проверить самостоятельно):
def funcLine(tpl, eix_x):
C1, C2, h = tpl[0], tpl[1], tpl[2:]
hsum = np.sum(bsplines_evaluades * h, axis=1)
theta = 4 * np.pi * hsum * eix_x / lambda1
return (C1 * np.sin(theta) + C2 * np.cos(theta)) * np.exp(-4 *lambda_big *
(k * eix_x)**2)
errorFunc = lambda tpl, eix_x, ydata: funcLine(tpl, eix_x) - ydata
tplFinal2, success = leastsq(errorFunc, [2, -2, 8.2*np.ones(35)],
args=(eix_x, ydata))