14 #include "freqestleastsquare.h"
17 FreqEstLeastSquare::genSpectrum(
const std::vector<std::complex<double> >& memin,
18 std::vector<std::complex<double> >& memout,
19 int t0,
double tol, FFT::twindowfunc windowfunc,
double windowlength) {
21 int n = memout.size();
24 t0a += (-t0a / n + 1) * n;
27 std::vector<double> weight;
28 window(t, t0, windowfunc, windowlength, weight);
29 double wsum = 0.0, w2sum = 0.0;
30 for(
int i = 0; i < t; i++) {
32 w2sum += weight[i] * weight[i];
34 int wpoints = wsum*wsum/w2sum;
36 wpoints = std::min(std::max(wpoints, t/100 + 1), t);
41 for(
int i = 0; i < t; i++) {
42 sigma2 += std::norm(memin[i]) * weight[i];
47 std::fill(m_ifft.begin(), m_ifft.end(), std::complex<double>(0.0));
48 std::vector<std::complex<double> > convwnd(m_ifft);
49 for(
int i = 0; i < t; i++) {
50 m_ifft[(t0a + i) % n] = memin[i] * weight[i];
52 m_fftN->exec(m_ifft, memout);
53 for(
int i = 0; i < n; i++) {
57 std::vector<std::complex<double> > wave(memin);
58 std::deque<std::complex<double> > zlist;
61 for(
int lp = 0; lp < 32; lp++) {
62 int npeaks = m_peaks.size();
63 double loglikelifood = -wpoints * (log(2*M_PI) + 1.0 + log(sigma2));
64 double ic_new = m_funcIC(loglikelifood, npeaks * 3.0, wpoints * 2.0);
75 std::complex<double> z(0.0);
77 for(
int i = 0; i < n; i++) {
78 if(normz < std::norm(memout[i])) {
84 freq *= t / (double)n;
87 std::vector<std::complex<double> > coeff(t);
88 double p = -2.0 * M_PI / (double)t * freq;
89 for(
int i = 0; i < t;) {
90 std::complex<double> x = std::polar(1.0, (i + t0) * p);
91 std::complex<double> y = std::polar(1.0, p);
92 for(
int j = 0; (j < 1024) && (i < t); j++) {
100 for(
int i = 0; i < t; i++) {
101 sigma2 += std::norm(wave[i] - z * std::conj(coeff[i])) * weight[i];
109 for(
int it = 0; it < 10; it++) {
115 double d2s2df2 = 0.0;
118 double d2s2dfx = 0.0;
119 double d2s2dfy = 0.0;
121 double kstep = 2.0 * M_PI / (double)t;
122 double k = kstep * t0;
123 for(
int i = 0; i < t; i++) {
125 std::complex<double> yew = wave[i] * coeff[i] * weight[i];
126 std::complex<double> yewzk = std::conj(z) * yew * k;
127 ds2df -= std::imag(yewzk);
128 std::complex<double> a = -yew + z * weight[i];
129 ds2dx += std::real(a);
130 ds2dy += std::imag(a);
131 d2s2df2 += std::real(yewzk * k);
133 d2s2dfx -= std::imag(a);
134 d2s2dfy += std::real(a);
142 double detJ = d2s2df2 - d2s2dfx*d2s2dfx - d2s2dfy*d2s2dfy;
143 double df = -ds2df + ds2dx * d2s2dfx + ds2dy * d2s2dfy;
145 double dx = ds2df * d2s2dfx - ds2dx * (d2s2df2 - d2s2dfy*d2s2dfy) - ds2dy * d2s2dfx*d2s2dfy;
147 double dy = ds2df * d2s2dfy - ds2dx * d2s2dfx*d2s2dfy - ds2dy * (d2s2df2 - d2s2dfx*d2s2dfx);
154 sor = std::min(sor, 0.4 / fabs(df));
155 sor = std::min(sor, 0.2*sqrt(std::norm(z)/fabs(dx*dx+dy*dy)));
160 z += std::complex<double>(dx, dy);
162 double p = -2.0 * M_PI / (double)t * freq;
163 for(
int i = 0; i < t;) {
164 std::complex<double> x = std::polar(1.0, (i + t0) * p);
165 std::complex<double> y = std::polar(1.0, p);
166 for(
int j = 0; (j < 1024) && (i < t); j++) {
176 if((df < 0.001) && (dx*dx+dy*dy < tol*tol*std::norm(z))) {
183 for(
int i = 0; i < t; i++) {
184 sigma2 += std::norm(wave[i] - z * std::conj(coeff[i])) * weight[i];
188 m_peaks.push_back(std::pair<double, double>(std::abs(z) * n, freq / t * n));
191 for(
int i = 0; i < t; i++) {
192 wave[i] -= z * std::conj(coeff[i]);
196 std::fill(m_ifft.begin(), m_ifft.end(), std::complex<double>(0.0));
197 for(
int i = 0; i < t; i++) {
198 m_ifft[(t0a + i) % n] = wave[i] * weight[i];
200 m_fftN->exec(m_ifft, memout);
201 for(
int i = 0; i < n; i++) {
205 std::fill(m_ifft.begin(), m_ifft.end(), std::complex<double>(0.0));
206 for(
int i = 0; i < m_peaks.size(); i++) {
207 double freq = m_peaks[i].second;
208 std::complex<double> z(zlist[i]);
209 double p = 2.0 * M_PI / (double)n * freq;
210 for(
int i = 0; i < n;) {
211 std::complex<double> x = std::polar(1.0, (i + n/2 - n) * p);
212 std::complex<double> y = std::polar(1.0, p);
214 for(
int j = 0; (j < 1024) && (i < n); j++) {
215 m_ifft[(i + n/2) % n] += x;
221 m_fftN->exec(m_ifft, memout);