49#include <unsupported/Eigen/FFT>
75 const int nChannels =
static_cast<int>(matData.rows());
76 const int nTimes =
static_cast<int>(matData.cols());
79 stepSize = windowSize / 2;
81 const int nFreqs = windowSize / 2 + 1;
85 const int nTap =
static_cast<int>(dpss.
matTapers.rows());
88 double weightSum = 0.0;
89 for (
int t = 0; t < nTap; ++t)
94 for (
int start = 0; start + windowSize <= nTimes; start += stepSize)
101 for (
int k = 0; k < nFreqs; ++k)
102 result.
vecFreqs[k] =
static_cast<double>(k) * sfreq /
static_cast<double>(windowSize);
106 for (
int s = 0; s < nSteps; ++s) {
107 const int start = s * stepSize;
108 const double centre =
static_cast<double>(start) +
static_cast<double>(windowSize - 1) / 2.0;
109 result.
vecTimes[s] = centre / sfreq;
113 Eigen::FFT<double> fft;
115 result.
tfrData.reserve(nChannels);
116 for (
int ch = 0; ch < nChannels; ++ch) {
117 MatrixXd tfr = MatrixXd::Zero(nFreqs, nSteps);
120 for (
int start = 0; start + windowSize <= nTimes; start += stepSize) {
122 VectorXd segment = matData.row(ch).segment(start, windowSize).transpose();
125 RowVectorXd psd = RowVectorXd::Zero(nFreqs);
127 for (
int t = 0; t < nTap; ++t) {
128 VectorXd tapered = segment.array()
129 * dpss.
matTapers.row(t).transpose().array();
132 fft.fwd(spec, tapered);
135 for (
int k = 0; k < nFreqs; ++k)
136 psd[k] += w * std::norm(spec[k]);
140 const double dNorm = 1.0 / (weightSum * sfreq);
144 for (
int k = 1; k < nFreqs - 1; ++k)
147 tfr.col(stepIdx) = psd.transpose();
MultitaperTfr class declaration — sliding-window multitaper time-frequency representation.
Dpss class declaration — Discrete Prolate Spheroidal Sequences (Slepian tapers).
Shared utilities (I/O helpers, spectral analysis, layout management, warp algorithms).
Result of a DPSS taper computation.
Eigen::MatrixXd matTapers
nTapers × N, each row is a unit-norm taper
Eigen::VectorXd vecEigenvalues
Concentration ratios, length nTapers.
static DpssResult compute(int N, double halfBandwidth, int nTapers=-1)
Result of a multitaper TFR computation.
QVector< Eigen::MatrixXd > tfrData
One matrix per channel, each: n_freqs × n_times.
Eigen::RowVectorXd vecTimes
Time axis in seconds (window centres).
Eigen::RowVectorXd vecFreqs
Frequency axis in Hz.
static MultitaperTfrResult compute(const Eigen::MatrixXd &matData, double sfreq, int windowSize=256, int stepSize=-1, double halfBandwidth=4.0, int nTapers=-1)