lomb_scargel.c
00001
00002
00003
00004
00005
00006
00007
00008
00009 #ifdef HAVE_CONFIG_H
00010 #include <config.h>
00011 #endif
00012
00013 #include <math.h>
00014 #include <cpl.h>
00015 #include "lomb_scargel.h"
00016 #include "midiConst.h"
00017
00018
00028
00029
00030 int lomb(double minf ,double maxf, int filling, cpl_array * x, cpl_array * y, cpl_array ** lomb_out)
00031 {
00032 cpl_array * filling_factor=NULL;
00033 cpl_array * frequency_=NULL;
00034 cpl_array * omega_=NULL;
00035 cpl_array * significance_ =NULL;
00036
00037 cpl_array * tau_ =NULL;
00038 cpl_array * power_=NULL;
00039
00040 double * px=NULL;
00041 double * py=NULL;
00042 double * pomega_=NULL;
00043 double * ptau_=NULL;
00044 double * ppower_=NULL;
00045
00046 double yvar_=0.;
00047 double ymean_=0.;
00048 int i=0;
00049 int x_i=0;
00050 double o2_i=0;
00051 int dimen_x=0;
00052 int omega_i=0;
00053 double sum_sin=0;
00054 double sum_cos=0;
00055 double y2v =0.;
00056 double ym = 0.;
00057 double o_i = 0.;
00058 double t_i = 0.;
00059 double s_y_c=0;
00060 double s_y_s=0.;
00061 double s_c2 =0.;
00062 double s_s2 =0.;
00063 double c =0.;
00064 double s =0.;
00065 double dy = 0.;
00066 double odx = 0.;
00067
00068
00069
00070 const int n_=filling;
00071 const double spacing=(double)(maxf-minf)/filling;
00072
00073 filling_factor =cpl_array_new(n_, CPL_TYPE_DOUBLE);
00074 for(i=0;i<n_;i++){
00075 cpl_array_set_double(filling_factor, i, minf+(spacing*i)+DBL_EPSILON);
00076
00077 }
00078
00079 frequency_ =cpl_array_duplicate(filling_factor);
00080
00081
00082 omega_ =cpl_array_duplicate(frequency_);
00083 cpl_array_multiply_scalar(omega_, 2.0*MIDI_PI);
00084
00085 tau_ =cpl_array_new(n_, CPL_TYPE_DOUBLE);
00086 power_ =cpl_array_new(n_, CPL_TYPE_DOUBLE);
00087 significance_ =cpl_array_new(n_, CPL_TYPE_DOUBLE);
00088
00089 cpl_array_fill_window(tau_, 0, n_, 0.);
00090 cpl_array_fill_window(power_, 0, n_, 0.);
00091 cpl_array_fill_window(significance_, 0, n_, 0.);
00092
00093 px =cpl_array_get_data_double(x);
00094 pomega_ =cpl_array_get_data_double(omega_);
00095 ptau_ =cpl_array_get_data_double(tau_);
00096 ppower_ =cpl_array_get_data_double(power_);
00097
00098 dimen_x=cpl_array_get_size(x);
00099
00100 sum_sin=0;
00101 sum_cos=0;
00102 for(omega_i=0;omega_i<n_;omega_i++){
00103 o2_i = (*pomega_) * 2.0;
00104
00105 for(i=0;i<dimen_x;i++){
00106 sum_sin+=(sin(o2_i * (*px)));
00107 sum_cos+=(cos(o2_i * (*px)));
00108 }
00109
00110 *ptau_ = atan( sum_sin / sum_cos ) / o2_i;
00111 ++ptau_;
00112 ++pomega_;
00113
00114 }
00115
00116 ymean_=cpl_array_get_mean(y);
00117 yvar_=pow(cpl_array_get_stdev(y),2);
00118 y2v = 2.0 * yvar_;
00119 ym = ymean_;
00120
00121
00122 pomega_ =cpl_array_get_data_double(omega_);
00123 ptau_ =cpl_array_get_data_double(tau_);
00124 ppower_ =cpl_array_get_data_double(power_);
00125
00126 px =cpl_array_get_data_double(x);
00127 py =cpl_array_get_data_double(y);
00128
00129 for(omega_i=0;omega_i<n_;omega_i++){
00130 o_i = *pomega_;
00131 t_i = *ptau_;
00132 s_y_c=0;
00133 s_y_s=0.;
00134 s_c2 =0.;
00135 s_s2 =0.;
00136
00137 px =cpl_array_get_data_double(x);
00138 py =cpl_array_get_data_double(y);
00139
00140 for(x_i=0;x_i<dimen_x;x_i++){
00141 dy = *py - ym;
00142 odx = (*px - t_i) * o_i;
00143
00144 s = sin(odx);
00145 s_s2 += (s*s);
00146 s_y_s += dy * s;
00147
00148 c = cos(odx);
00149 s_c2 += (c*c);
00150 s_y_c += dy * c;
00151
00152 ++px;
00153 ++py;
00154 }
00155
00156 *ppower_ = ( (s_y_c*s_y_c) / s_c2 +
00157 (s_y_s*s_y_s) / s_s2 ) / y2v;
00158 ++ppower_;
00159 ++ptau_;
00160 ++pomega_;
00161
00162 }
00163
00164
00165
00166
00167
00168
00169
00170
00171
00172
00173
00174
00175
00176
00177
00178
00179
00180
00181
00182
00183
00184
00185
00186
00187
00188 lomb_out[0]=frequency_;
00189 lomb_out[1]=power_;
00190
00191 cpl_array_delete(filling_factor);
00192 cpl_array_delete(omega_);
00193 cpl_array_delete(tau_);
00194 cpl_array_delete(significance_);
00195
00196
00197
00198 return 0;
00199 }