Смещение для SciPy.optimize наименьших квадратов не является правильным

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

Это включает в себя фазовое свертывание, использование оптимизации SciPy для соответствия синусоидальной кривой, а затем экстраполяцию подобранной кривой из фазового пространства на исходную кривую много синусоидальной волны, а затем вычитание этого подбора для детрендирования данных.

Я повторяю этот процесс так, чтобы в конечном итоге, когда сигнал на LombScargle был менее чем в 3 раза больше предварительно сгенерированной высоты шума, итерация останавливается. (эквивалентно тому, что отношение сигнал / шум становится слишком маленьким).

Но после 1-й итерации фаза подобранной кривой еще не закончена! Я не понимаю, почему это происходит. Кто-нибудь может помочь?

import matplotlib.pyplot as plt

import numpy as np
import math

from scipy.optimize import leastsq
from astropy.stats import LombScargle

t = np.linspace(15,30,1000)
y = 5 * np.sin(2*np.pi * 1./2. * (t + 1)) + 30
y1 = 11 * np.sin(2*np.pi * 1./3. * (t + 1))
y4 = 2 * np.sin(2*np.pi * 1./7. * (t + 1))
sampl = np.random.uniform(low = 0, high = 2.5, size = len(t))

y2 = y+y1+y4+sampl
y2 = y2/np.nanmedian(y2)

freq = np.linspace(1./150.,1./0.5,10000)

power2 = LombScargle(t,sampl).power(freq)

for _ in range(5):

    plt.figure()


    plt.subplot(221)
    plt.plot(t,y2,'-')
    plt.grid()
    power = LombScargle(t,y2).power(freq)


    p = 1./freq[np.argmax(power)]
    plt.title(p)
    plt.subplot(222)
    plt.plot(1./freq,power)
    plt.grid()
#    print p

    if np.max(power) <= np.max(power2)*3:
        print 'done'
        break

    else:


        foldtimes = (t - t[0])/p
        FoldTimes = foldtimes % 1

        p_0 = np.min(FoldTimes)
        dp = 0.01
        its = math.ceil((np.max(FoldTimes)-p_0)/dp)
        n = np.linspace(0,its,its+1)

        binned_flux = []
        binned_phase = []

        for i in range(len(n)):

            indices = np.where(((p_0 + (n[i]*dp)) <= FoldTimes) & (FoldTimes <= (p_0 + (n[i]*dp)+dp)))[0]

            if len(indices)>1:

                binned_flux.append( np.nanmedian(y2[indices])) ##continuously adds the averaged fluxes to list

                binned_phase.append (np.mean(FoldTimes[indices])) #same for hjs averages


        binned_flux = np.array(binned_flux)
        binned_phase = np.array(binned_phase)

        plt.subplot(223)
        plt.grid()
        plt.plot(binned_phase,binned_flux,'.',linestyle='None')

        plt.ylabel('Relative Flux')
        plt.xlabel('Phase')

        guess_mean = np.mean(y2)
        guess_A =  (np.max(y2) - np.min(y2))/2.
        guess_phase = 0

        optimize_func = lambda x: ((x[0] * np.sin(2*np.pi*(np.sort(binned_phase) + x[1]))) + x[2]) - binned_flux

        est_A, est_phase, est_mean = leastsq(optimize_func, [guess_A,guess_phase,guess_mean])[0]

        print est_phase

        fit = (est_A*np.sin(2*np.pi*(1./p)*(t+ (est_phase*p)))) + est_mean
        fit_p = (est_A*np.sin(2*np.pi*(1.)*(np.sort(binned_phase)+(est_phase)))) + est_mean

        plt.plot(binned_phase,fit_p)

        plt.subplot(224)
        plt.plot(t,y2,'-')
        plt.plot(t,fit)
        plt.grid()


        y2 = (y2 - fit) + est_mean #rewrites the original curve minus the fit

0 ответов

Другие вопросы по тегам