20 #include <boost/numeric/ublas/matrix_proxy.hpp>
21 #include <boost/numeric/ublas/io.hpp>
24 FreqEstimation::genSpectrum(
const std::vector<std::complex<double> >& memin,
25 std::vector<std::complex<double> >& memout,
26 int t0,
double tol, FFT::twindowfunc windowfunc,
double windowlength) {
28 int n = memout.size();
31 throw XKameError(i18n(
"Too large size to allocate a matrix."), __FILE__, __LINE__);
34 wpoints = std::min(std::max(wpoints, t/100 + 1), t);
38 for(
int i = 0; i < t; i++) {
39 tpoworg += std::norm(memin[i]);
42 std::vector<std::complex<double> > rx(t);
43 autoCorrelation(memin, rx);
48 ublas::matrix<std::complex<double> > r(p, p);
49 for(
int i = 0; i < p; i++) {
50 ublas::matrix_row<ublas::matrix<std::complex<double> > > rrow(r, i);
51 for(
int j = i; j < p; j++) {
55 ublas::matrix<std::complex<double> > eigv;
56 ublas::vector<double> lambda;
57 double tol_lambda = tol * std::abs(rx[0]) * 0.1;
58 eigHermiteRRR(r, lambda, eigv, tol_lambda);
65 double sumlambda = 0.0, sumloglambda = 1.0;
66 for(
int i = 0; i < p; i++) {
67 sumlambda += lambda[i];
68 sumloglambda += log(lambda[i]);
70 double logl = t * (p - q) * (sumloglambda / (
double)(p - q) - log(sumlambda / (
double)(p - q)));
71 double ic = m_funcIC(logl, q * (2*p - q), wpoints);
77 numsig *= windowlength;
78 numsig = std::max(std::min(numsig, p - 1), 0);
85 std::vector<std::complex<double> > fftin(t, 0.0), fftout(t), acsum(t, 0.0);
86 for(
int i = 0; i < p - numsig; i++) {
87 ublas::matrix_column<ublas::matrix<std::complex<double> > > eigvcol(eigv, i);
88 assert(fabs(norm_2(eigvcol) - 1.0) < 0.1);
89 for(
int j = 0; j < p; j++) {
90 fftin[j] = eigvcol(j);
92 autoCorrelation(fftin, fftout);
94 z = std::max(z, tol_lambda);
95 z = (m_eigenvalue_method) ? (1.0 / z) : 1.0;
96 for(
int k = 0; k < p; k++) {
97 acsum[k] += fftout[k] * z;
100 std::vector<std::complex<double> > zffftin(n, 0.0), zffftout(n);
101 std::vector<double> ip(n), dy(n);
102 acsum[0] /= (double)2;
103 std::copy(acsum.begin(), acsum.end(), zffftin.begin());
104 m_ifftN->exec(zffftin, zffftout);
105 for(
int i = 0; i < n; i++)
106 ip[i] = std::real(zffftout[i]);
107 for(
int i = 0; i < p; i++)
108 zffftin[i] = (
double)((i >= n/2) ? (i - n) : i) * acsum[i] * std::complex<double>(0, 1);
109 m_ifftN->exec(zffftin, zffftout);
110 for(
int i = 0; i < n; i++)
111 dy[i] = std::real(zffftout[i]);
114 std::vector<double> psd(n);
116 for(
int i = 0; i < n; i++) {
117 double z = 1.0 / ip[i];
121 double normalize = n * tpoworg / tpow;
122 for(
int i = 0; i < n; i++) {
126 double coeff =
lspe(memin, t0, psd, memout, tol,
true, windowfunc);
127 normalize *= coeff * coeff;
130 for(
int ip = 0; ip < n; ip++) {
131 int in = (ip + 1) % n;
132 if((dy[ip] < 0) && (dy[in] > 0)) {
133 double dx = - dy[ip] / (dy[in] - dy[ip]);
134 if((dx >= 0) && (dx <= 1.0)) {
135 std::complex<double> z = 0.0, xn = 1.0,
136 x = std::polar(1.0, 2 * M_PI * (dx + ip) / (
double)n);
137 for(
int j = 0; j < p; j++) {
141 double r = sqrt(normalize * std::max(1.0 / std::real(z), 0.0));
142 m_peaks.push_back(std::pair<double, double>(r, dx + ip));