Подгонка Numpy Leastsq, возвращающая неизменное начальное предположение во всех случаях

Я пытаюсь подогнать функцию, используя Leastsq, чтобы соответствовать нескольким соответствующим точкам в fft. Проблема в том, что, независимо от того, насколько хорошо или плохо подходит, параметры абсолютно не меняются. Другими словами, метод наименьших квадратов выполняет 6 итераций и ничего не делает ни на одной из них, а затем возвращает начальные значения параметров. Я не могу определить, почему ничего не происходит.

guess = [per_guess,thresh_guess,cen_guess] #parameter guesses, all real numbers    
res, stuff = leastsq(fitting, guess)

Функция подгонки имеет ряд манипуляций для поиска правильных индексов, которые я не буду воспроизводить здесь для экономии места, но она возвращает список комплексных чисел:

M, freq= fft(real_gv, zf)
def fitting(guess):
    gi, trial_gv = gen_pat(size, guess[0], guess[1], guess[2])
    trial_gv = trial_gv*private.han #apply hanning window
    F, freq= fft(trial_gv, zf) 
    #stuff that picks the right indices
    return M[left_fit target:right_fit_target]-F[left_fit target:right_fit_target]

В какой-то момент я попытался использовать приведение массива в возврате, но я постоянно получал ошибки о приведении между сложными и реальными числами с плавающей запятой, хотя я ничего не просил. Даже при использовании этого метода я иногда получаю комплексные предупреждения.

РЕДАКТИРОВАТЬ:

По просьбе выкладываю gen_pat:

def gen_pat(num, period, threshold, pos = 0, step = 1.0, subdivide=10.0, blur = 1.0):
x= np.arange(-num/2,num/2,step) #grid indexes
j=np.zeros((len(x),subdivide))
for i in range(len(x)):
    j[i]=np.linspace(x[i]-0.5*blur,x[i]+0.5*blur,subdivide) #around each discrete point take a subvision. This will be averaged to get the antialiased point. blur allows for underlap (<1) or overlap of pxels
holder = -np.sin(2*np.pi*np.abs(j-pos)/period) #map a sin function for the region
holder = holder < 2.0*threshold-1.0 #map to 1 or 0 based on the fraction of the period that is 0
y = np.sum(holder, axis=1)/float(subdivide) #take the average of the values at the sub-points to get the anti-aliased value at the point i
y= np.array(y)
x= np.array(x)
return x,y

РЕДАКТИРОВАТЬ 2:

Удалось настроить работу, используя res = fmin_powell(fitting, guess, direc=[[1,0,0],[0,0.1,0],[0,0,1]]) и модифицированный возврат. Все еще хотел бы знать, почему lestsq не работал.

return np.sum((M[fit_start_index:fit_end_index].real-F[fit_start_index:fit_end_index].real)**2+(M[fit_start_index:fit_end_index].imag-F[fit_start_index:fit_end_index].imag)**2)

person Elliot    schedule 15.01.2014    source источник
comment
Вы имеете в виду scipy.optimize.leastsq (docs.scipy.org/doc /scipy/reference/generated/)?   -  person Warren Weckesser    schedule 16.01.2014
comment
Обратите внимание, что M и F имеют комплексное значение. Пробовали ли вы возвращать abs(M[left_freq2_index]-F[left_freq2_index]), чтобы он соответствовал PSD, или возвращать в два раза больше элементов, например (M[left_freq2_index]-F[left_freq2_index]).real,(M[left_freq2_index]-F[left_freq2_index]).imag, чтобы он соответствовал фазе?   -  person gg349    schedule 16.01.2014
comment
return [(M[left_freq2_index].real-F[left_freq2_index].real),(M[left_freq2_index].imag-F[left_freq2_index].imag)...] Тоже не работает. Тот же результат, абсолютно никакого движения параметров.   -  person Elliot    schedule 16.01.2014
comment
Возможный вывод состоит в том, что gen_pat() не влияет на компоненты Фурье на целевых частотах. Не могли бы вы опубликовать эту функцию?   -  person gg349    schedule 16.01.2014


Ответы (1)


Предоставленная функция gen_pat(x1,x2,x3,x4) возвращает горизонтальную линию со значением 1 для нескольких значений ввода (x1,x2,x3,x4), которые я пробовал. Его фурье-компоненты (за исключением, конечно, 0-го компонента) всегда равны нулю независимо от параметров. Тогда алгоритм наименьшего квадрата терпит неудачу, так как изменение 4 параметров не влияет на компоненты Фурье, которые вы пытаетесь оптимизировать.

Вы делаете что-то не так в gen_pat(), либо кодирующую, либо концептуальную ошибку, например, выбирая неправильную аппроксимирующую кривую.

person gg349    schedule 16.01.2014
comment
Gen_pat создает двоичную сетку со смещением и фазовым сдвигом pi/2 в центре. Я знаю, что это дает желаемый результат. Конечно, можно выбрать очень плохие значения любой функции, у которой порог полностью равен 1 или 0, но это неотъемлемая проблема создания сетки такого типа. Я не знаю, каким образом я мог бы сгенерировать такую ​​сетку таким образом, чтобы это не могло произойти, учитывая необходимый результат. Моя первоначальная догадка далека от этой области (1024,40,0.5,0), поэтому тот факт, что он никогда даже не пробовал ни одного варианта, необычен. - person Elliot; 16.01.2014
comment
@ Эллиот, можешь ли ты высказать свое первоначальное предположение? - person gg349; 17.01.2014
comment
Это было в предыдущем комментарии. (1024,40,0.5,0) - person Elliot; 17.01.2014
comment
Ok. Теперь я вижу, что функция действительно меняется вокруг этого предположения (я пробовал другие значения). Однако это не означает, что конкретный компонент Фурье, который вы извлекаете, также изменится. Из любопытства, близко ли окончательное решение к этой догадке? - person gg349; 17.01.2014
comment
Зависит от того, какой шаблон я использую. Я мог бы выбрать тот, который близок или нет. Очевидно, что если я проверяю сходимость, я использую тот, который близок. Также вы заметите, что я выбрал диапазон вокруг цели, чтобы соответствовать более новым версиям (отредактированный вступительный пост), а не только несколько конкретных. - person Elliot; 17.01.2014
comment
Рассмотрим, что означают переменные. Размер — это размер паттерна, период — это период синусоидальной волны, порог — это то, где на синусоидальной волне нужно сместиться от 0 до 1, а центр — это место, где нужно поместить фазовое дерьмо. Так что, конечно, если вы установите порог около 1, вы получите линию на 1. Вы также можете испортить предполагаемый сдвиг, установив порог ‹.5, который открывает разрыв в центральной верхней точке. - person Elliot; 17.01.2014