28#include <unsupported/Eigen/FFT>
54 const int nChannels =
static_cast<int>(matData.rows());
55 const int nTimes =
static_cast<int>(matData.cols());
58 stepSize = windowSize / 2;
60 const int nFreqs = windowSize / 2 + 1;
64 const int nTap =
static_cast<int>(dpss.
matTapers.rows());
67 double weightSum = 0.0;
68 for (
int t = 0; t < nTap; ++t)
73 for (
int start = 0; start + windowSize <= nTimes; start += stepSize)
80 for (
int k = 0; k < nFreqs; ++k)
81 result.
vecFreqs[k] =
static_cast<double>(k) * sfreq /
static_cast<double>(windowSize);
85 for (
int s = 0; s < nSteps; ++s) {
86 const int start = s * stepSize;
87 const double centre =
static_cast<double>(start) +
static_cast<double>(windowSize - 1) / 2.0;
92 Eigen::FFT<double> fft;
94 result.
tfrData.reserve(nChannels);
95 for (
int ch = 0; ch < nChannels; ++ch) {
96 MatrixXd tfr = MatrixXd::Zero(nFreqs, nSteps);
99 for (
int start = 0; start + windowSize <= nTimes; start += stepSize) {
101 VectorXd segment = matData.row(ch).segment(start, windowSize).transpose();
104 RowVectorXd psd = RowVectorXd::Zero(nFreqs);
106 for (
int t = 0; t < nTap; ++t) {
107 VectorXd tapered = segment.array()
108 * dpss.
matTapers.row(t).transpose().array();
111 fft.fwd(spec, tapered);
114 for (
int k = 0; k < nFreqs; ++k)
115 psd[k] += w * std::norm(spec[k]);
119 const double dNorm = 1.0 / (weightSum * sfreq);
123 for (
int k = 1; k < nFreqs - 1; ++k)
126 tfr.col(stepIdx) = psd.transpose();
Discrete Prolate Spheroidal Sequences (Slepian tapers) for multitaper spectral estimation.
Sliding-window multitaper time-frequency representation.
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)