sigfun.cpp
Go to the documentation of this file.
#include <itpp/signal/sigfun.h>
#include <itpp/signal/transforms.h>
#include <itpp/signal/window.h>
#include <itpp/base/converters.h>
#include <itpp/base/math/elem_math.h>
#include <itpp/base/matfunc.h>
#include <itpp/base/specmat.h>
#include <itpp/base/itcompat.h>
#include <itpp/stat/misc_stat.h>
namespace itpp
{
vec xcorr_old(const vec &x, const int max_lag, const std::string scaleopt)
{
vec out;
xcorr_old(x, x, out, max_lag, scaleopt);
return out;
}
vec xcorr(const vec &x, const int max_lag, const std::string scaleopt)
{
cvec out(2*x.length() - 1); //Initial size does ont matter, it will get adjusted
xcorr(to_cvec(x), to_cvec(x), out, max_lag, scaleopt, true);
return real(out);
}
cvec xcorr(const cvec &x, const int max_lag, const std::string scaleopt)
{
cvec out(2*x.length() - 1); //Initial size does ont matter, it will get adjusted
xcorr(x, x, out, max_lag, scaleopt, true);
return out;
}
vec xcorr(const vec &x, const vec &y, const int max_lag, const std::string scaleopt)
{
cvec out(2*x.length() - 1); //Initial size does ont matter, it will get adjusted
xcorr(to_cvec(x), to_cvec(y), out, max_lag, scaleopt, false);
return real(out);
}
cvec xcorr(const cvec &x, const cvec &y, const int max_lag, const std::string scaleopt)
{
cvec out(2*x.length() - 1); //Initial size does ont matter, it will get adjusted
xcorr(x, y, out, max_lag, scaleopt, false);
return out;
}
void xcorr(const vec &x, const vec &y, vec &out, const int max_lag, const std::string scaleopt)
{
cvec xx = to_cvec(x);
cvec yy = to_cvec(y);
cvec oo = to_cvec(out);
xcorr(xx, yy, oo, max_lag, scaleopt, false);
out = real(oo);
}
void xcorr_old(const vec &x, const vec &y, vec &out, const int max_lag, const std::string scaleopt)
{
int m, n;
double s_plus, s_minus, M_double, coeff_scale = 0.0;
int M, N;
M = x.size();
M = std::max(x.size(), y.size());
M_double = double(M);
if (max_lag == -1) {
N = std::max(x.size(), y.size());
}
else {
N = max_lag + 1;
}
out.set_size(2*N - 1, false);
it_assert(N <= std::max(x.size(), y.size()), "max_lag cannot be as large as, or larger than, the maximum length of x and y.");
if (scaleopt == "coeff") {
coeff_scale = std::sqrt(energy(x)) * std::sqrt(energy(y));
}
for (m = 0; m < N; m++) {
s_plus = 0;
s_minus = 0;
for (n = 0;n < M - m;n++) {
s_minus += index_zero_pad(x, n) * index_zero_pad(y, n + m);
s_plus += index_zero_pad(x, n + m) * index_zero_pad(y, n);
}
if (scaleopt == "none") {
out(N + m - 1) = s_plus;
out(N - m - 1) = s_minus;
}
else if (scaleopt == "biased") {
out(N + m - 1) = s_plus / M_double;
out(N - m - 1) = s_minus / M_double;
}
else if (scaleopt == "unbiased") {
out(N + m - 1) = s_plus / double(M - m);
out(N - m - 1) = s_minus / double(M - m);
}
else if (scaleopt == "coeff") {
out(N + m - 1) = s_plus / coeff_scale;
out(N - m - 1) = s_minus / coeff_scale;
}
else
it_error("Incorrect scaleopt specified.");
}
}
vec xcorr_old(const vec &x, const vec &y, const int max_lag, const std::string scaleopt)
{
vec out;
xcorr_old(x, y, out, max_lag, scaleopt);
return out;
}
//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> ");
}
mat cov(const mat &X, bool is_zero_mean)
{
int d = X.cols(), n = X.rows();
mat R(d, d), m2(n, d);
vec tmp;
R = 0.0;
if (!is_zero_mean) {
// Compute and remove mean
for (int i = 0; i < d; i++) {
tmp = X.get_col(i);
m2.set_col(i, tmp - mean(tmp));
}
// Calc corr matrix
for (int i = 0; i < d; i++) {
for (int j = 0; j <= i; j++) {
for (int k = 0; k < n; k++) {
R(i, j) += m2(k, i) * m2(k, j);
}
R(j, i) = R(i, j); // When i=j this is unnecassary work
}
}
}
else {
// Calc corr matrix
for (int i = 0; i < d; i++) {
for (int j = 0; j <= i; j++) {
for (int k = 0; k < n; k++) {
R(i, j) += X(k, i) * X(k, j);
}
R(j, i) = R(i, j); // When i=j this is unnecassary work
}
}
}
R /= n;
return R;
}
vec spectrum(const vec &v, int nfft, int noverlap)
{
it_assert_debug(pow2i(levels2bits(nfft)) == nfft,
"nfft must be a power of two in spectrum()!");
vec P(nfft / 2 + 1), w(nfft), wd(nfft);
P = 0.0;
w = hanning(nfft);
double w_energy = nfft == 1 ? 1 : (nfft + 1) * .375; // Hanning energy
if (nfft > v.size()) {
P = sqr(abs(fft(to_cvec(elem_mult(zero_pad(v, nfft), w)))(0, nfft / 2)));
P /= w_energy;
}
else {
int k = (v.size() - noverlap) / (nfft - noverlap), idx = 0;
for (int i = 0; i < k; i++) {
wd = elem_mult(v(idx, idx + nfft - 1), w);
P += sqr(abs(fft(to_cvec(wd))(0, nfft / 2)));
idx += nfft - noverlap;
}
P /= k * w_energy;
}
P.set_size(nfft / 2 + 1, true);
return P;
}
vec spectrum(const vec &v, const vec &w, int noverlap)
{
int nfft = w.size();
it_assert_debug(pow2i(levels2bits(nfft)) == nfft,
"The window size must be a power of two in spectrum()!");
vec P(nfft / 2 + 1), wd(nfft);
P = 0.0;
double w_energy = energy(w);
if (nfft > v.size()) {
P = sqr(abs(fft(to_cvec(elem_mult(zero_pad(v, nfft), w)))(0, nfft / 2)));
P /= w_energy;
}
else {
int k = (v.size() - noverlap) / (nfft - noverlap), idx = 0;
for (int i = 0; i < k; i++) {
wd = elem_mult(v(idx, idx + nfft - 1), w);
P += sqr(abs(fft(to_cvec(wd))(0, nfft / 2)));
idx += nfft - noverlap;
}
P /= k * w_energy;
}
P.set_size(nfft / 2 + 1, true);
return P;
}
vec filter_spectrum(const vec &a, int nfft)
{
vec s = sqr(abs(fft(to_cvec(a), nfft)));
s.set_size(nfft / 2 + 1, true);
return s;
}
vec filter_spectrum(const vec &a, const vec &b, int nfft)
{
vec s = sqr(abs(elem_div(fft(to_cvec(a), nfft), fft(to_cvec(b), nfft))));
s.set_size(nfft / 2 + 1, true);
return s;
}
} // namespace itpp
converters.h
Definitions of converters between different vector and matrix types.
elem_math.h
Elementary mathematical functions - header file.
it_error
#define it_error(s)
Abort unconditionally.
Definition: itassert.h:126
it_warning
#define it_warning(s)
Display a warning message.
Definition: itassert.h:173
it_assert_debug
#define it_assert_debug(t, s)
Abort if t is not true and NDEBUG is not defined.
Definition: itassert.h:107
it_assert
#define it_assert(t, s)
Abort if t is not true.
Definition: itassert.h:94
itpp::ifft
ITPP_EXPORT void ifft(const cvec &in, cvec &out)
Inverse Fast Fourier Transform.
itpp::fft
ITPP_EXPORT void fft(const cvec &in, cvec &out)
Fast Fourier Transform.
itpp::pow2i
int pow2i(int x)
Calculate two to the power of x (2^x); x is integer.
Definition: log_exp.h:53
itpp::log2
vec log2(const vec &x)
log-2 of the elements
Definition: log_exp.cpp:36
itpp::levels2bits
int levels2bits(int n)
Calculate the number of bits needed to represent n different values (levels).
Definition: log_exp.h:92
itpp::index_zero_pad
T index_zero_pad(const Vec< T > &v, const int index)
Definition: matfunc.h:297
itpp::sum
T sum(const Vec< T > &v)
Sum of all elements in the vector.
Definition: matfunc.h:59
itpp::zero_pad
Vec< T > zero_pad(const Vec< T > &v, int n)
Zero-pad a vector to size n.
Definition: matfunc.h:257
itpp::max
T max(const Vec< T > &v)
Maximum value of vector.
Definition: min_max.h:45
itpp::real
vec real(const cvec &data)
Real part of complex values.
Definition: elem_math.cpp:157
itpp::sqr
vec sqr(const cvec &data)
Absolute square of elements.
Definition: elem_math.cpp:36
itpp::conj
cvec conj(const cvec &x)
Conjugate of complex value.
Definition: elem_math.h:226
itpp::sqrt
vec sqrt(const vec &x)
Square root of the elements.
Definition: elem_math.h:123
itpp::filter_spectrum
vec filter_spectrum(const vec &a, int nfft)
Power spectrum calculation of a filter.
Definition: sigfun.cpp:325
itpp::spectrum
vec spectrum(const vec &v, int nfft, int noverlap)
Power spectrum calculation.
Definition: sigfun.cpp:267
itpp::cov
mat cov(const mat &X, bool is_zero_mean)
Covariance matrix calculation.
Definition: sigfun.cpp:226
itpp::xcorr_old
vec xcorr_old(const vec &x, const int max_lag, const std::string scaleopt)
Auto-correlation calculation.
Definition: sigfun.cpp:43
itpp::xcorr
vec xcorr(const vec &x, const int max_lag, const std::string scaleopt)
Auto-correlation calculation.
Definition: sigfun.cpp:50
itpp::linspace
vec linspace(double from, double to, int points)
linspace (works in the same way as the MATLAB version)
Definition: specmat.cpp:106
itpp::energy
double energy(const Vec< T > &v)
Calculate the energy: squared 2-norm. energy(v)=sum(abs(v).^2)
Definition: misc_stat.h:253
itpp::mean
double mean(const vec &v)
The mean value.
Definition: misc_stat.cpp:36
itpp::hanning
vec hanning(int n)
Hanning window.
Definition: window.cpp:56
itcompat.h
IT++ compatibility types and functions.
matfunc.h
Various functions on vectors and matrices - header file.
misc_stat.h
Miscellaneous statistics functions and classes - header file.
itpp
itpp namespace
Definition: itmex.h:37
itpp::to_cvec
cvec to_cvec(const Vec< T > &v)
Converts a Vec<T> to cvec.
Definition: converters.h:107
itpp::concat
const Array< T > concat(const Array< T > &a, const T &e)
Append element e to the end of the Array a.
Definition: array.h:486
itpp::ceil_i
int ceil_i(double x)
The nearest larger integer.
Definition: converters.h:339
itpp::elem_div
Mat< Num_T > elem_div(const Mat< Num_T > &m1, const Mat< Num_T > &m2)
Element wise division of two matrices.
Definition: mat.h:1688
itpp::elem_mult
Mat< Num_T > elem_mult(const Mat< Num_T > &m1, const Mat< Num_T > &m2)
Element wise multiplication of two matrices.
Definition: mat.h:1582
itpp::abs
bin abs(const bin &inbin)
absolute value of bin
Definition: binary.h:174
sigfun.h
Definitions of signal processing functions.
specmat.h
Definitions of special vectors and matrices.
transforms.h
Fourier, Hadamard, Walsh-Hadamard, and 2D Hadamard transforms - header file.
window.h
Definitions of window functions.

Generated on Tue Aug 17 2021 10:59:15 for IT++ by Doxygen 1.9.1