v2.0.0
Loading...
Searching...
No Matches
dpss.cpp
Go to the documentation of this file.
1//=============================================================================================================
33
34//=============================================================================================================
35// INCLUDES
36//=============================================================================================================
37
38#include "dpss.h"
39
40//=============================================================================================================
41// EIGEN INCLUDES
42//=============================================================================================================
43
44#include <Eigen/Core>
45#include <Eigen/Eigenvalues>
46
47//=============================================================================================================
48// STD INCLUDES
49//=============================================================================================================
50
51#include <cmath>
52
53//=============================================================================================================
54// USED NAMESPACES
55//=============================================================================================================
56
57using namespace UTILSLIB;
58using namespace Eigen;
59
60namespace
61{
62constexpr double DPSS_PI = 3.14159265358979323846;
63}
64
65//=============================================================================================================
66// DEFINE MEMBER METHODS
67//=============================================================================================================
68
69DpssResult Dpss::compute(int N, double halfBandwidth, int nTapers)
70{
71 if (nTapers < 0)
72 nTapers = static_cast<int>(std::floor(2.0 * halfBandwidth - 1.0));
73
74 const double W = halfBandwidth / static_cast<double>(N);
75
76 // Build the symmetric tridiagonal matrix T
77 // Diagonal: d(i) = ((N-1-2*i)/2)^2 * cos(2*pi*W)
78 // Off-diagonal: e(i) = (i+1)*(N-i-1)/2
79 VectorXd diag(N);
80 VectorXd offdiag(N > 1 ? N - 1 : 0);
81
82 const double cosW = std::cos(2.0 * DPSS_PI * W);
83
84 for (int i = 0; i < N; ++i) {
85 const double val = (static_cast<double>(N - 1) - 2.0 * static_cast<double>(i)) / 2.0;
86 diag[i] = val * val * cosW;
87 }
88
89 for (int i = 0; i < N - 1; ++i) {
90 offdiag[i] = static_cast<double>(i + 1) * static_cast<double>(N - i - 1) / 2.0;
91 }
92
93 // Construct tridiagonal matrix and solve eigenvalue problem
94 MatrixXd T = MatrixXd::Zero(N, N);
95 for (int i = 0; i < N; ++i)
96 T(i, i) = diag[i];
97 for (int i = 0; i < N - 1; ++i) {
98 T(i, i + 1) = offdiag[i];
99 T(i + 1, i) = offdiag[i];
100 }
101
102 SelfAdjointEigenSolver<MatrixXd> solver(T);
103
104 // Eigenvalues are sorted ascending; we want the largest nTapers
105 const VectorXd& allEigenvalues = solver.eigenvalues();
106 const MatrixXd& allEigenvectors = solver.eigenvectors();
107
108 DpssResult result;
109 result.matTapers.resize(nTapers, N);
110 result.vecEigenvalues.resize(nTapers);
111
112 for (int k = 0; k < nTapers; ++k) {
113 const int idx = N - 1 - k; // largest eigenvalue first
114 result.vecEigenvalues[k] = allEigenvalues[idx];
115
116 // Extract eigenvector as a row, normalize to unit L2 norm
117 VectorXd taper = allEigenvectors.col(idx);
118 const double norm = taper.norm();
119 if (norm > 0.0)
120 taper /= norm;
121
122 // Sign convention: first element should be positive
123 if (taper[0] < 0.0)
124 taper = -taper;
125
126 result.matTapers.row(k) = taper.transpose();
127 }
128
129 return result;
130}
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.
Definition dpss.h:62
Eigen::MatrixXd matTapers
nTapers × N, each row is a unit-norm taper
Definition dpss.h:63
Eigen::VectorXd vecEigenvalues
Concentration ratios, length nTapers.
Definition dpss.h:64
static DpssResult compute(int N, double halfBandwidth, int nTapers=-1)
Definition dpss.cpp:69