16 template <
class Context>
20 template <
class Context>
23 int t0,
double tol, FFT::twindowfunc windowfunc,
double windowlength) {
25 int n = memout.size();
27 int wpoints = lrint(numberOfNoises(memin));
28 wpoints = std::min(std::max(wpoints, t/100 + 1), t);
32 taps_div = std::max(taps_div / 10, 1);
33 shared_ptr<Context> context(
new Context);
35 std::fill(context->a.begin(), context->a.end(), std::complex<double>(0.0));
38 context->sigma2 = 0.0;
39 for(
unsigned int i = 0; i < t; i++) {
40 context->sigma2 += std::norm(memin[i]) / (double)t;
43 first(memin, context);
44 unsigned int taps = 0;
46 for(
unsigned int p = 0; p < t - 2; p++) {
47 if(p % taps_div == 0) {
48 m_contexts.push_back(std::make_shared<Context>(*context));
49 if(taps + taps_div/2 < p)
54 if(context->sigma2 < 0)
56 double new_ic = arIC(context->sigma2, context->p, wpoints);
62 taps = std::min((
int)lrint(windowlength * taps), (
int)t - 2);
63 int cidx = std::min((
int)taps / taps_div, (
int)m_contexts.size() - 1);
64 context = m_contexts[cidx];
66 for(
unsigned int p = cidx * taps_div; p < taps; p++) {
67 assert(context->p == p);
71 dbgPrint(formatString(
"MEM/AR: t=%d, taps=%d, IC_min=%g, IC=%g\n", t, taps, ic, m_funcARIC(context->sigma2, context->p, t)));
73 std::vector<std::complex<double> > zfbuf(n), fftbuf(n);
74 std::fill(zfbuf.begin(), zfbuf.end(), std::complex<double>(0.0));
75 for(
int i = 0; i < taps + 1; i++) {
76 zfbuf[i] = context->a[i];
78 m_fftN->exec(zfbuf, fftbuf);
81 std::vector<double> psd(n);
82 for(
int i = 0; i < n; i++) {
83 double z = t * context->sigma2 / (std::norm(fftbuf[i]));
84 psd[i] = std::max(z, 0.0);
87 double coeff = lspe(memin, t0, psd, memout, tol,
true, windowfunc);
90 std::fill(zfbuf.begin(), zfbuf.end(), std::complex<double>(0.0));
91 for(
int i = 0; i < taps + 1; i++) {
92 zfbuf[i] = context->a[i] * (double)((i >= n/2) ? (i - n) : i) * std::complex<double>(0, -1);
94 std::vector<std::complex<double> > fftbuf2(n);
95 m_fftN->exec(zfbuf, fftbuf2);
97 double dy_old = std::real(fftbuf2[0] * std::conj(fftbuf[0]));
98 for(
int ip = 0; ip < n; ip++) {
99 int in = (ip + 1) % n;
100 double dy = std::real(fftbuf2[in] * std::conj(fftbuf[in]));
101 if((dy_old < 0) && (dy > 0)) {
102 double dx = - dy_old / (dy - dy_old);
103 if((dx >= 0) && (dx <= 1.0)) {
104 std::complex<double> z = 0.0, xn = 1.0,
105 x = std::polar(1.0, -2 * M_PI * (dx + ip) / (
double)n);
106 for(
int i = 0; i < taps + 1; i++) {
107 z += context->a[i] * xn;
110 double r = coeff * sqrt(std::max(t * context->sigma2 / std::norm(z), 0.0));
111 m_peaks.push_back(std::pair<double, double>(r, dx + ip));
123 const std::vector<std::complex<double> >& memin,
const shared_ptr<MEMBurgContext> &context) {
124 unsigned int t = context->t;
125 context->epsilon.resize(t);
126 context->eta.resize(t);
127 std::copy(memin.begin(), memin.end(), context->epsilon.begin());
128 std::copy(memin.begin(), memin.end(), context->eta.begin());
132 unsigned int t = context->t;
133 unsigned int p = context->p;
134 std::complex<double> x = 0.0, y = 0.0;
135 for(
unsigned int i = p + 1; i < t; i++) {
136 x += context->epsilon[i] * std::conj(context->eta[i-1]);
137 y += std::norm(context->epsilon[i]) + std::norm(context->eta[i-1]);
139 std::complex<double> alpha = x / y;
141 for(
unsigned int i = t - 1; i >= p + 1; i--) {
142 context->eta[i] = context->eta[i-1] + std::conj(alpha) * context->epsilon[i];
143 context->epsilon[i] += alpha * context->eta[i-1];
145 std::vector<std::complex<double> > a_next(p + 2);
146 for(
unsigned int i = 0; i < p + 2; i++) {
147 a_next[i] = context->a[i] + alpha * std::conj(context->a[p + 1 - i]);
149 std::copy(a_next.begin(), a_next.end(), context->a.begin());
150 context->sigma2 *= 1 - std::norm(alpha);
154 const std::vector<std::complex<double> >& memin,
const shared_ptr<ARContext> &context) {
155 unsigned int t = context->t;
157 autoCorrelation(memin,
m_rx);
161 unsigned int p = context->p;
162 std::complex<double> delta = 0.0;
163 for(
unsigned int i = 0; i < p + 1; i++) {
164 delta += context->a[i] *
m_rx[p + 1 - i];
166 std::vector<std::complex<double> > a_next(p + 2);
167 for(
unsigned int i = 0; i < p + 2; i++) {
168 a_next[i] = context->a[i] - delta/context->sigma2 * std::conj(context->a[p + 1 - i]);
170 std::copy(a_next.begin(), a_next.end(), context->a.begin());
171 context->sigma2 += - std::norm(delta) / context->sigma2;