是否可能使用GSL或类似的库来拟合A*sin(B*t+C)函数?
我想获取4096个样本(8位)中正弦波的A和C参数,并且可以提供B的良好近似值。
我认为可以使用GSL的非线性多次拟合来实现,但是我不理解所有与雅可比矩阵相关的数学背景...
是否可能使用GSL或类似的库来拟合A*sin(B*t+C)函数?
我想获取4096个样本(8位)中正弦波的A和C参数,并且可以提供B的良好近似值。
我认为可以使用GSL的非线性多次拟合来实现,但是我不理解所有与雅可比矩阵相关的数学背景...
int sine_f (const gsl_vector * x, void *data,
gsl_vector * f){
...
for(...){
...
double Yi = A * sin(B*t +C);
gsl_vector_set (f, i, (Yi - y[i])/sigma[i]);
}
...
}
然后对目标函数关于参数的导数进行求解。
int
sine_df (const gsl_vector * x, void *data,
gsl_matrix * J)
//the derivatives of Asin(Bt +C) wrt A,B,C for each t
谢谢Alexandre,你帮了我很多!
这是我现在正在使用的代码:
typedef struct{
uint32 u32_n;
float64* pf64_y;
float64* pf64_sigma;
}ST_DATA;
int expb_f (const gsl_vector* x, void* p_data, gsl_vector* f)
{
ST_DATA* pst_data = (ST_DATA*)p_data;
uint32 u32_n = pst_data->u32_n;
float64* pf64_y = pst_data->pf64_y;
float64* pf64_sigma = pst_data->pf64_sigma;
float64 A = /* x[0] */ gsl_vector_get (x, 0);
float64 B = /* x[1] */ gsl_vector_get (x, 1);
float64 C = /* x[2] */ gsl_vector_get (x, 2);
float64 Yi,Fi;
uint32 i;
for (i=0; i<u32_n; i++)
{
Yi = A * sin(B*i + C);
Fi = (Yi - pf64_y[i])/pf64_sigma[i];
/* f[i] = Fi; */ gsl_vector_set(f,i,Fi);
}
return GSL_SUCCESS;
}
int expb_df (const gsl_vector* x, void* p_data, gsl_matrix* J)
{
ST_DATA* pst_data = (ST_DATA*)p_data;
uint32 u32_n = pst_data->u32_n;
float64* pf64_y = pst_data->pf64_y;
float64* pf64_sigma = pst_data->pf64_sigma;
float64 A = /* x[0] */ gsl_vector_get (x, 0);
float64 B = /* x[1] */ gsl_vector_get (x, 1);
float64 C = /* x[2] */ gsl_vector_get (x, 2);
float64 Yi;
uint32 i;
for (i=0; i<u32_n; i++)
{
/* J[i][0] = sin(B*i+C); */gsl_matrix_set (J, i, 0, sin(B*i+C) );
/* J[i][1] = A*cos(B*i+C)*i; */gsl_matrix_set (J, i, 1, A*cos(B*i+C)*i);
/* J[i][2] = A*cos(B*i+C); */gsl_matrix_set (J, i, 2, A*cos(B*i+C) );
}
return GSL_SUCCESS;
}
int expb_fdf (const gsl_vector * x, void *data, gsl_vector * f, gsl_matrix * J)
{
expb_f(x, data, f);
expb_df(x, data, J);
return GSL_SUCCESS;
}