MIDI Pipeline Reference Manual  2.8.3
lomb_scargel.c
1 /*
2  * lomb_scargel.c
3  *
4  * Created on: Jul 30, 2009
5  * Author: agabasch
6  */
7 
8 
9 #ifdef HAVE_CONFIG_H
10 #include <config.h>
11 #endif
12 
13 #include <math.h>
14 #include <cpl.h>
15 #include "lomb_scargel.h"
16 #include "midiConst.h"
17 
18 /*----------------------------------------------------------------------------*/
28 /*----------------------------------------------------------------------------*/
29 
30 int lomb(double minf ,double maxf, int filling, cpl_array * x, cpl_array * y, cpl_array ** lomb_out)
31 {
32  cpl_array * filling_factor=NULL;
33  cpl_array * frequency_=NULL;
34  cpl_array * omega_=NULL;
35  cpl_array * significance_ =NULL;
36 
37  cpl_array * tau_ =NULL;
38  cpl_array * power_=NULL;
39 
40  double * px=NULL;
41  double * py=NULL;
42  double * pomega_=NULL;
43  double * ptau_=NULL;
44  double * ppower_=NULL;
45 
46  double yvar_=0.;
47  double ymean_=0.;
48  int i=0;
49  int x_i=0;
50  double o2_i=0;
51  int dimen_x=0;
52  int omega_i=0;
53  double sum_sin=0;
54  double sum_cos=0;
55  double y2v =0.;
56  double ym = 0.;
57  double o_i = 0.;
58  double t_i = 0.;
59  double s_y_c=0;
60  double s_y_s=0.;
61  double s_c2 =0.;
62  double s_s2 =0.;
63  double c =0.;
64  double s =0.;
65  double dy = 0.;
66  double odx = 0.;
67 
68 
69 /* const int n_=(ilogb(1.0+(maxf / minf)) * filling); */
70  const int n_=filling;
71  const double spacing=(double)(maxf-minf)/filling;
72 
73  filling_factor =cpl_array_new(n_, CPL_TYPE_DOUBLE);
74  for(i=0;i<n_;i++){
75  cpl_array_set_double(filling_factor, i, minf+(spacing*i)+DBL_EPSILON);
76 
77  }
78 
79  frequency_ =cpl_array_duplicate(filling_factor);
80 /* cpl_array_multiply_scalar(frequency_,minf); */
81 
82  omega_ =cpl_array_duplicate(frequency_);
83  cpl_array_multiply_scalar(omega_, 2.0*MIDI_PI);
84 
85  tau_ =cpl_array_new(n_, CPL_TYPE_DOUBLE);
86  power_ =cpl_array_new(n_, CPL_TYPE_DOUBLE);
87  significance_ =cpl_array_new(n_, CPL_TYPE_DOUBLE);
88 
89  cpl_array_fill_window(tau_, 0, n_, 0.);
90  cpl_array_fill_window(power_, 0, n_, 0.);
91  cpl_array_fill_window(significance_, 0, n_, 0.);
92 
93  px =cpl_array_get_data_double(x);
94  pomega_ =cpl_array_get_data_double(omega_);
95  ptau_ =cpl_array_get_data_double(tau_);
96  ppower_ =cpl_array_get_data_double(power_);
97 
98  dimen_x=cpl_array_get_size(x);
99 
100  sum_sin=0;
101  sum_cos=0;
102  for(omega_i=0;omega_i<n_;omega_i++){
103  o2_i = (*pomega_) * 2.0;
104 
105  for(i=0;i<dimen_x;i++){
106  sum_sin+=(sin(o2_i * (*px)));
107  sum_cos+=(cos(o2_i * (*px)));
108  }
109 
110  *ptau_ = atan( sum_sin / sum_cos ) / o2_i;
111  ++ptau_;
112  ++pomega_;
113 
114  }
115 
116  ymean_=cpl_array_get_mean(y);
117  yvar_=pow(cpl_array_get_stdev(y),2);
118  y2v = 2.0 * yvar_;
119  ym = ymean_;
120 
121 /* Resetting to pointer to the first address */
122  pomega_ =cpl_array_get_data_double(omega_);
123  ptau_ =cpl_array_get_data_double(tau_);
124  ppower_ =cpl_array_get_data_double(power_);
125 
126  px =cpl_array_get_data_double(x);
127  py =cpl_array_get_data_double(y);
128 
129  for(omega_i=0;omega_i<n_;omega_i++){
130  o_i = *pomega_;
131  t_i = *ptau_;
132  s_y_c=0;
133  s_y_s=0.;
134  s_c2 =0.;
135  s_s2 =0.;
136 /* Resetting to pointer to the first address */
137  px =cpl_array_get_data_double(x);
138  py =cpl_array_get_data_double(y);
139 
140  for(x_i=0;x_i<dimen_x;x_i++){
141  dy = *py - ym;
142  odx = (*px - t_i) * o_i;
143 
144  s = sin(odx);
145  s_s2 += (s*s);
146  s_y_s += dy * s;
147 
148  c = cos(odx);
149  s_c2 += (c*c);
150  s_y_c += dy * c;
151 
152  ++px;
153  ++py;
154  }
155 
156  *ppower_ = ( (s_y_c*s_y_c) / s_c2 +
157  (s_y_s*s_y_s) / s_s2 ) / y2v;
158  ++ppower_;
159  ++ptau_;
160  ++pomega_;
161 
162  }
163 
164 
165 /* cpl_msg_info(cpl_func,"n_: %d", n_); */
166 /* cpl_msg_info(cpl_func,"%g %g %g",s_c2,s_s2,y2v); */
167 
168 /* for(i=0;i<n_;i++){ */
169 /* cpl_msg_info(cpl_func,"filling_factor, frequency, omega, tau, POWER: %g, %g, %g, %g, %g", */
170 /* cpl_array_get_double(filling_factor,i,NULL), */
171 /* cpl_array_get_double(frequency_,i,NULL), */
172 /* cpl_array_get_double(omega_,i,NULL), */
173 /* cpl_array_get_double(tau_,i,NULL), */
174 /* cpl_array_get_double(power_,i,NULL)); */
175 
176 /* } */
177 
178 /* for(i=0;i<n_;i++){ */
179 /* cpl_msg_info(cpl_func,"frequency: %g POWER: %g", */
180 
181 /* cpl_array_get_double(frequency_,i,NULL), */
182 /* cpl_array_get_double(power_,i,NULL)); */
183 
184 /* } */
185 
186 
187 
188  lomb_out[0]=frequency_;
189  lomb_out[1]=power_;
190 
191  cpl_array_delete(filling_factor);
192  cpl_array_delete(omega_);
193  cpl_array_delete(tau_);
194  cpl_array_delete(significance_);
195 
196 
197 
198  return 0;
199 }