v2.0.0
Loading...
Searching...
No Matches
inv_signal_model.cpp
Go to the documentation of this file.
1//=============================================================================================================
18
19//=============================================================================================================
20// INCLUDES
21//=============================================================================================================
22
24#include "inv_signal_model.h"
25#include <math/linalg.h>
26#include <iostream>
27
28//=============================================================================================================
29// QT INCLUDES
30//=============================================================================================================
31
32#include <qmath.h>
33
34//=============================================================================================================
35// EIGEN INCLUDES
36//=============================================================================================================
37
38#include <Eigen/Core>
39
40//=============================================================================================================
41// USED NAMESPACES
42//=============================================================================================================
43
44using namespace INVLIB;
45using namespace Eigen;
46
47//=============================================================================================================
48// DEFINE GLOBAL METHODS
49//=============================================================================================================
50
51//=============================================================================================================
52// DEFINE MEMBER METHODS
53//=============================================================================================================
54
55MatrixXd InvSignalModel::fitData(const InvHpiModelParameters& hpiModelParameters, const MatrixXd& matData)
56{
57
58 if(checkEmpty(hpiModelParameters)) {
59 return MatrixXd();
60 }
61
62 const bool bParametersChanged = m_modelParameters != hpiModelParameters;
63 const bool bDimensionsChanged = m_iCurrentModelCols != matData.cols();
64
65 if(bDimensionsChanged || bParametersChanged) {
66 m_iCurrentModelCols = matData.cols();
67 m_modelParameters = hpiModelParameters;
68 selectModelAndCompute();
69 }
70
71 return m_matInverseSignalModel * matData.transpose();
72}
73
74//=============================================================================================================
75
76bool InvSignalModel::checkDataDimensions(const int iCols)
77{
78 bool bHasChanged = false;
79 if(iCols != m_iCurrentModelCols) {
80 m_iCurrentModelCols = iCols;
81 bHasChanged = true;
82 }
83 return bHasChanged;
84}
85
86//=============================================================================================================
87
88bool InvSignalModel::checkModelParameters(const InvHpiModelParameters& hpiModelParameters)
89{
90 bool bHasChanged = false;
91 if((m_modelParameters.iSampleFreq() != hpiModelParameters.iSampleFreq()) ||
92 (m_modelParameters.iLineFreq() != hpiModelParameters.iLineFreq()) ||
93 (m_modelParameters.iNHpiCoils() != hpiModelParameters.iNHpiCoils()) ||
94 (m_modelParameters.vecHpiFreqs() != hpiModelParameters.vecHpiFreqs()) ||
95 (m_modelParameters.bBasic() != hpiModelParameters.bBasic())) {
96 bHasChanged = true;
97 m_modelParameters = hpiModelParameters;
98 }
99 return bHasChanged;
100}
101
102//=============================================================================================================
103
104bool InvSignalModel::checkEmpty(const InvHpiModelParameters& hpiModelParameters)
105{
106 if(hpiModelParameters.vecHpiFreqs().empty()) {
107 std::cout << "InvSignalModel::checkEmpty - no Hpi frequencies set" << std::endl;
108 return true;
109 } else if(hpiModelParameters.iSampleFreq() == 0) {
110 std::cout << "InvSignalModel::checkEmpty - no sampling frequencies set" << std::endl;
111 return true;
112 }
113 return false;
114}
115
116//=============================================================================================================
117
118void InvSignalModel::selectModelAndCompute()
119{
120 if(m_modelParameters.bBasic()) {
121 computeInverseBasicModel();
122 } else {
123 computeInverseAdvancedModel();
124 }
125}
126
127//=============================================================================================================
128
129void InvSignalModel::computeInverseBasicModel()
130{
131 const int iNumCoils = m_modelParameters.iNHpiCoils();
132 MatrixXd matSimsig;
133 const VectorXd vecTime = VectorXd::LinSpaced(m_iCurrentModelCols, 0, m_iCurrentModelCols-1) *1.0/m_modelParameters.iSampleFreq();
134
135 // Generate simulated data Matrix
136 matSimsig.conservativeResize(m_iCurrentModelCols,iNumCoils*2);
137
138 for(int i = 0; i < iNumCoils; ++i) {
139 matSimsig.col(i) = sin(2*M_PI*m_modelParameters.vecHpiFreqs()[i]*vecTime.array());
140 matSimsig.col(i+iNumCoils) = cos(2*M_PI*m_modelParameters.vecHpiFreqs()[i]*vecTime.array());
141 }
142 m_matInverseSignalModel = UTILSLIB::Linalg::pinv(matSimsig);
143}
144
145//=============================================================================================================
146
147void InvSignalModel::computeInverseAdvancedModel()
148{
149 const int iNumCoils = m_modelParameters.iNHpiCoils();
150 const int iSampleFreq = m_modelParameters.iSampleFreq();
151 MatrixXd matSimsig;
152 MatrixXd matSimsigInvTemp;
153
154 const VectorXd vecTime = VectorXd::LinSpaced(m_iCurrentModelCols, 0, m_iCurrentModelCols-1) *1.0/iSampleFreq;
155
156 // add linefreq + harmonics + DC part to model
157 matSimsig.conservativeResize(m_iCurrentModelCols,iNumCoils*4+2);
158 for(int i = 0; i < iNumCoils; ++i) {
159 matSimsig.col(i) = sin(2*M_PI*m_modelParameters.vecHpiFreqs()[i]*vecTime.array());
160 matSimsig.col(i+iNumCoils) = cos(2*M_PI*m_modelParameters.vecHpiFreqs()[i]*vecTime.array());
161 matSimsig.col(i+2*iNumCoils) = sin(2*M_PI*m_modelParameters.iLineFreq()*(i+1)*vecTime.array());
162 matSimsig.col(i+3*iNumCoils) = cos(2*M_PI*m_modelParameters.iLineFreq()*(i+1)*vecTime.array());
163 }
164 matSimsig.col(iNumCoils*4) = RowVectorXd::LinSpaced(m_iCurrentModelCols, -0.5, 0.5);
165 matSimsig.col(iNumCoils*4+1).fill(1);
166 matSimsigInvTemp = UTILSLIB::Linalg::pinv(matSimsig);
167 m_matInverseSignalModel = matSimsigInvTemp.block(0,0,iNumCoils*2,m_iCurrentModelCols);
168}
#define M_PI
Sinusoidal HPI signal model — builds and inverts the regressor matrix that extracts coil amplitudes f...
Immutable configuration for the HPI signal model — coil drive frequencies, sample rate,...
Static linear-algebra helpers: SVD-based conditioning, block-diagonal assembly, sorted index pairs.
Inverse source estimation (MNE, dSPM, sLORETA, dipole fitting).
Configuration parameters for the HPI signal model (line frequency, coil frequencies,...
Eigen::MatrixXd fitData(const InvHpiModelParameters &hpiModelParameters, const Eigen::MatrixXd &matData)
static Eigen::Matrix< T, Eigen::Dynamic, Eigen::Dynamic > pinv(const Eigen::Matrix< T, Eigen::Dynamic, Eigen::Dynamic > &a)
Definition linalg.h:384