void roots(const vec &p, cvec &r) { int n = p.size(), m, l; ivec f = find(p != 0.0); m = f.size(); vec v = p; mat A; if (m > 0 && n > 1) { v = v(f(0), f(m - 1)); l = v.size(); if (l > 1) { A = diag(ones(l - 2), -1); A.set_row(0, -v(1, l - 1) / v(0)); r = eig(A); cvec d; cmat V; eig(A, d , V); if (f(m - 1) < n) r = concat(r, zeros_c(n - f(m - 1) - 1)); } else { r.set_size(n - f(m - 1) - 1, false); r.zeros(); } } else r.set_size(0, false); }
void roots(const cvec &p, cvec &r) { int n = p.size(), m, l; ivec f; // find all non-zero elements for (int i = 0; i < n; i++) if (p(i) != 0.0) f = concat(f, i); m = f.size(); cvec v = p; cmat A; if (m > 0 && n > 1) { v = v(f(0), f(m - 1)); l = v.size(); if (l > 1) { A = diag(ones_c(l - 2), -1); A.set_row(0, -v(1, l - 1) / v(0)); r = eig(A); if (f(m - 1) < n) r = concat(r, zeros_c(n - f(m - 1) - 1)); } else { r.set_size(n - f(m - 1) - 1, false); r.zeros(); } } else r.set_size(0, false); }
void Matlab_Engine::get(cvec &v, const char *name){ mxArray *T; if((T = engGetArray(e, name)) == NULL) cout << "No variable with the given name exists in the Matlab workspace!\n"; else{ const int *dims = mxGetDimensions(T); const int ndims = mxGetNumberOfDimensions(T); if((ndims>2) || !((dims[0]==1)||(dims[1]==1))) cout << "The requested variable is not a vector!\n"; if(!mxIsComplex(T)) cout << "The requested variable is real-valued!\n"; double *pt_r = (double*) mxGetPr(T); double *pt_i = (double*) mxGetPi(T); const int N = mxGetNumberOfElements(T); v.set_size(N, false); if(mxIsComplex(T)) // Copy both real and imaginary part. for(int k=0; k<N; k++){ complex<double> value(*pt_r++, *pt_i++); v(k) = value; } else // Copy only the real part. for(int k=0; k<N; k++){ complex<double> value(*pt_r++, 0); v(k) = value; } } }
void poly(const cvec &r, cvec &p) { int n = r.size(); p.set_size(n + 1, false); p.zeros(); p(0) = 1.0; for (int i = 0; i < n; i++) p.set_subvector(1, p(1, i + 1) - r(i)*p(0, i)); }
void auto_correlation(const cvec &a, cvec &x) { int k = a.size(); x.set_size(k); for (int i = 0; i < k; ++i) { x[i] = 0; for (int j = 0; j < k - i; ++j) x[i] += a[j] * conj(a[j + i]); for (int j = k - i; j < k; ++j) x[i] += a[j] * conj(a[j - k + i]); } }
//Correlation void xcorr(const cvec &x, const cvec &y, cvec &out, const int max_lag, const std::string scaleopt, bool autoflag) { int N = std::max(x.length(), y.length()); //Compute the FFT size as the "next power of 2" of the input vector's length (max) int b = ceil_i(::log2(2.0 * N - 1)); int fftsize = pow2i(b); int end = fftsize - 1; cvec temp2; if (autoflag == true) { //Take FFT of input vector cvec X = fft(zero_pad(x, fftsize)); //Compute the abs(X).^2 and take the inverse FFT. temp2 = ifft(elem_mult(X, conj(X))); } else { //Take FFT of input vectors cvec X = fft(zero_pad(x, fftsize)); cvec Y = fft(zero_pad(y, fftsize)); //Compute the crosscorrelation temp2 = ifft(elem_mult(X, conj(Y))); } // Compute the total number of lags to keep. We truncate the maximum number of lags to N-1. int maxlag; if ((max_lag == -1) || (max_lag >= N)) maxlag = N - 1; else maxlag = max_lag; //Move negative lags to the beginning of the vector. Drop extra values from the FFT/IFFt if (maxlag == 0) { out.set_size(1, false); out = temp2(0); } else out = concat(temp2(end - maxlag + 1, end), temp2(0, maxlag)); //Scale data if (scaleopt == "biased") //out = out / static_cast<double_complex>(N); out = out / static_cast<std::complex<double> >(N); else if (scaleopt == "unbiased") { //Total lag vector vec lags = linspace(-maxlag, maxlag, 2 * maxlag + 1); cvec scale = to_cvec(static_cast<double>(N) - abs(lags)); out /= scale; } else if (scaleopt == "coeff") { if (autoflag == true) // Normalize by Rxx(0) out /= out(maxlag); else { //Normalize by sqrt(Rxx(0)*Ryy(0)) double rxx0 = sum(abs(elem_mult(x, x))); double ryy0 = sum(abs(elem_mult(y, y))); out /= std::sqrt(rxx0 * ryy0); } } else if (scaleopt == "none") {} else it_warning("Unknow scaling option in XCORR, defaulting to <none> "); }
void lte_zadoff(int u, cvec &a) { a.set_size(N_zc); for (int i = 0; i < N_zc; ++i) a[i] = polar(1.0, (-1) * PI * u * i * (i + 1) / N_zc); }