Python 2.7 尝试将正弦函数拟合到相位光曲线

Python 2.7 尝试将正弦函数拟合到相位光曲线,python-2.7,spyder,light,astronomy,trigonometry,Python 2.7,Spyder,Light,Astronomy,Trigonometry,我正在尝试将正弦函数拟合到一个研究项目的相位光曲线数据中。然而,我不确定我会错在哪里,我相信这取决于我的参数。拟合的振幅太大,周期太长。任何帮助都将不胜感激。谢谢大家! 这就是图形现在的样子(尝试将正弦函数拟合到我的数据集): 我们如何帮助您处理未注释的代码 我们如何知道什么是什么以及它应该做什么 您使用什么方法进行安装 数据在哪里?以什么形式 我将从计算近似的正弦波参数开始。假设您获得了一些数据,以n点的形式输入x,y坐标。想要适应正弦波: import numpy as np impor

我正在尝试将正弦函数拟合到一个研究项目的相位光曲线数据中。然而,我不确定我会错在哪里,我相信这取决于我的参数。拟合的振幅太大,周期太长。任何帮助都将不胜感激。谢谢大家!

这就是图形现在的样子(尝试将正弦函数拟合到我的数据集):


我们如何帮助您处理未注释的代码

  • 我们如何知道什么是什么以及它应该做什么
  • 您使用什么方法进行安装
  • 数据在哪里?以什么形式
我将从计算近似的正弦波参数开始。假设您获得了一些
数据
,以
n
点的形式输入
x,y
坐标。想要适应正弦波:

import numpy as np
import matplotlib.pyplot as plt
from lmfit import Model,Parameters


f2= "KELT_N16_lc_006261_V01_west_tfa.dat"    
t2="TIMES"   # file name

NewData2 = np.loadtxt(t2, dtype=float, unpack=True)
NewData = np.loadtxt(f2,dtype=float, unpack=True, usecols=(1,))

flux = NewData   
time= NewData2

new_flux=np.hstack([flux,flux])

# fold
period = 2.0232               # period (must be known already!)

foldTimes = ((time)/ period)  # divide by period to convert to phase
foldTimes = foldTimes % 1   # take fractional part of phase only (i.e. discard whole number part)


new_phase=np.hstack([foldTimes+1,foldTimes])

print len(new_flux)
print len(new_phase)


def Wave(x, new_flux,new_phase):
    wave = new_flux*np.sin(new_phase+x)
    return wave
model = Model(Wave)
print "Independent Vars:", model.independent_vars
print "Parameters:",model.param_names
p = Parameters()
p.add_many(('new_flux',13.42, True, None, None, None) )   
p.add_many(('new_phase',0,True, None, None, None) )   

result=model.fit(new_flux,x=new_phase,params=p,weights= None)


plt.scatter(new_phase,new_flux,marker='o',edgecolors='none',color='blue',s=5.0, label="Period: 2.0232  days")   
plt.ylim([13.42,13.54])
plt.xlim(0,2)
plt.gca().invert_yaxis()
plt.title('HD 240121 Light Curve with BJD Correction')
plt.ylabel('KELT Instrumental Magnitude')
plt.xlabel('Phase')
legend = plt.legend(loc='lower right', shadow=True)
plt.scatter(new_phase,result.best_fit,label="One Oscillation Fit", color='red',s=60.0)
plt.savefig('NewEpoch.png')
print result.fit_report()
其中,
y0
是y偏移,
x0
是相位偏移,
A
是振幅,
f
是角频率

我想:

  • 计算平均y值

    y(t) = y0+A*sin(x0+x(t)*f)
    
    这是表示正弦波可能的y偏移量
    y0
    的平均值

  • 计算到
    y0的平均距离

    y0 = sum(data[i].y)/n where i={0,1,2,...n-1}
    
    如果我记忆良好,这应该是振幅的有效值,因此:

    d = sum (|data[i].y-y0|)/n where i={0,1,2,...n-1}
    
  • 在数据集中查找零交叉点

    为此,数据集应按
    x
    进行排序,如果不是,则对其进行排序。记住索引
    i
    :第一次交叉
    i0
    ,最后一次交叉
    i1
    和找到的交叉数
    j
    ,由此我们可以估计频率和相位偏移:

    A = sqrt(2)*d
    
    为了确定哪一半正弦波,我们只需检查前两个过零点之间的中点符号即可

    f=M_PI*double(j-1)/(datax[i1]-datax[i0]);
    x0=-datax[i0]*f;
    
    和预览:

    点由噪声数据生成,蓝色曲线由正弦波拟合

    除此之外,您还可以构建管件以提高精度。无论使用哪种方法搜索找到的参数。例如,我会选择:


      • 有几点意见/建议:

        首先,几乎可以肯定的是,替换是更好的

        i1=i0+((i1-i0)/(j-1));
        if (datay[(i0+i1)>>1]<=y0) x0+=M_PI;
        

        第二,您的模型不包含直流偏移,但您的数据显然包含直流偏移。偏移量约为13.4,正弦波振幅约为0.05。进行此操作时,您可能希望在阶段中包含一个比例以及一个偏移,以便模型是

        p = Parameters()
        p.add('new_flux', value=13.42, vary=True)
        p.add('new_phase', value=0, vary=True)
        
        你不一定要改变所有这些,但是让你的模型更通用,可以看到相移和比例是如何关联的——考虑到你数据中的噪声水平,这可能很重要


        对于更通用的模型,您可以尝试使用几组参数值,使用
        model.eval()
        来评估具有一组参数的模型。一旦你有了更好的模型和合理的起点,你就应该得到合理的拟合。

        你能说明你收到了哪些错误吗?在代码上运行会产生什么?您希望它会产生什么?@mba12目前,我没有收到错误消息,这使得识别问题变得极其困难。运行我的代码将生成附加的图形。我希望它能生成一个拟合与数据一致的图形。
        p = Parameters()
        p.add('new_flux', value=13.42, vary=True)
        p.add('new_phase', value=0, vary=True)
        
        offset + amplitude * sin(scale*x + phase_shift)