MNE-CPP 0.1.9
A Framework for Electrophysiology
Loading...
Searching...
No Matches
signalmodel.cpp
Go to the documentation of this file.
1//=============================================================================================================
35//=============================================================================================================
36// INCLUDES
37//=============================================================================================================
38
39#include "hpimodelparameters.h"
40#include "signalmodel.h"
41#include <utils/mnemath.h>
42#include <iostream>
43
44//=============================================================================================================
45// QT INCLUDES
46//=============================================================================================================
47
48#include <qmath.h>
49
50//=============================================================================================================
51// EIGEN INCLUDES
52//=============================================================================================================
53
54#include <Eigen/Core>
55
56//=============================================================================================================
57// USED NAMESPACES
58//=============================================================================================================
59
60using namespace INVERSELIB;
61using namespace Eigen;
62
63//=============================================================================================================
64// DEFINE GLOBAL METHODS
65//=============================================================================================================
66
67//=============================================================================================================
68// DEFINE MEMBER METHODS
69//=============================================================================================================
70
71MatrixXd SignalModel::fitData(const HpiModelParameters& hpiModelParameters, const MatrixXd& matData)
72{
73
74 if(checkEmpty(hpiModelParameters)) {
75 return MatrixXd();
76 }
77
78 const bool bParametersChanged = m_modelParameters != hpiModelParameters;
79 const bool bDimensionsChanged = m_iCurrentModelCols != matData.cols();
80
81 if(bDimensionsChanged || bParametersChanged) {
82 m_iCurrentModelCols = matData.cols();
83 m_modelParameters = hpiModelParameters;
84 selectModelAndCompute();
85 }
86
87 return m_matInverseSignalModel * matData.transpose();
88}
89
90//=============================================================================================================
91
92bool SignalModel::checkDataDimensions(const int iCols)
93{
94 bool bHasChanged = false;
95 if(iCols != m_iCurrentModelCols) {
96 m_iCurrentModelCols = iCols;
97 bHasChanged = true;
98 }
99 return bHasChanged;
100}
101
102//=============================================================================================================
103
104bool SignalModel::checkModelParameters(const HpiModelParameters& hpiModelParameters)
105{
106 bool bHasChanged = false;
107 if((m_modelParameters.iSampleFreq() != hpiModelParameters.iSampleFreq()) ||
108 (m_modelParameters.iLineFreq() != hpiModelParameters.iLineFreq()) ||
109 (m_modelParameters.iNHpiCoils() != hpiModelParameters.iNHpiCoils()) ||
110 (m_modelParameters.vecHpiFreqs() != hpiModelParameters.vecHpiFreqs()) ||
111 (m_modelParameters.bBasic() != hpiModelParameters.bBasic())) {
112 bHasChanged = true;
113 m_modelParameters = hpiModelParameters;
114 }
115 return bHasChanged;
116}
117
118//=============================================================================================================
119
120bool SignalModel::checkEmpty(const HpiModelParameters& hpiModelParameters)
121{
122 if(hpiModelParameters.vecHpiFreqs().empty()) {
123 std::cout << "SignalModel::checkEmpty - no Hpi frequencies set" << std::endl;
124 return true;
125 } else if(hpiModelParameters.iSampleFreq() == 0) {
126 std::cout << "SignalModel::checkEmpty - no sampling frequencies set" << std::endl;
127 return true;
128 }
129 return false;
130}
131
132//=============================================================================================================
133
134void SignalModel::selectModelAndCompute()
135{
136 if(m_modelParameters.bBasic()) {
137 computeInverseBasicModel();
138 } else {
139 computeInverseAdvancedModel();
140 }
141}
142
143//=============================================================================================================
144
145void SignalModel::computeInverseBasicModel()
146{
147 const int iNumCoils = m_modelParameters.iNHpiCoils();
148 MatrixXd matSimsig;
149 const VectorXd vecTime = VectorXd::LinSpaced(m_iCurrentModelCols, 0, m_iCurrentModelCols-1) *1.0/m_modelParameters.iSampleFreq();
150
151 // Generate simulated data Matrix
152 matSimsig.conservativeResize(m_iCurrentModelCols,iNumCoils*2);
153
154 for(int i = 0; i < iNumCoils; ++i) {
155 matSimsig.col(i) = sin(2*M_PI*m_modelParameters.vecHpiFreqs()[i]*vecTime.array());
156 matSimsig.col(i+iNumCoils) = cos(2*M_PI*m_modelParameters.vecHpiFreqs()[i]*vecTime.array());
157 }
158 m_matInverseSignalModel = UTILSLIB::MNEMath::pinv(matSimsig);
159}
160
161//=============================================================================================================
162
163void SignalModel::computeInverseAdvancedModel()
164{
165 const int iNumCoils = m_modelParameters.iNHpiCoils();
166 const int iSampleFreq = m_modelParameters.iSampleFreq();
167 MatrixXd matSimsig;
168 MatrixXd matSimsigInvTemp;
169
170 const VectorXd vecTime = VectorXd::LinSpaced(m_iCurrentModelCols, 0, m_iCurrentModelCols-1) *1.0/iSampleFreq;
171
172 // add linefreq + harmonics + DC part to model
173 matSimsig.conservativeResize(m_iCurrentModelCols,iNumCoils*4+2);
174 for(int i = 0; i < iNumCoils; ++i) {
175 matSimsig.col(i) = sin(2*M_PI*m_modelParameters.vecHpiFreqs()[i]*vecTime.array());
176 matSimsig.col(i+iNumCoils) = cos(2*M_PI*m_modelParameters.vecHpiFreqs()[i]*vecTime.array());
177 matSimsig.col(i+2*iNumCoils) = sin(2*M_PI*m_modelParameters.iLineFreq()*(i+1)*vecTime.array());
178 matSimsig.col(i+3*iNumCoils) = cos(2*M_PI*m_modelParameters.iLineFreq()*(i+1)*vecTime.array());
179 }
180 matSimsig.col(iNumCoils*4) = RowVectorXd::LinSpaced(m_iCurrentModelCols, -0.5, 0.5);
181 matSimsig.col(iNumCoils*4+1).fill(1);
182 matSimsigInvTemp = UTILSLIB::MNEMath::pinv(matSimsig);
183 m_matInverseSignalModel = matSimsigInvTemp.block(0,0,iNumCoils*2,m_iCurrentModelCols);
184}
MNEMath class declaration.
HpiModelParameters class declaration.
SignalModel class declaration.
Brief description of this class.
QVector< int > vecHpiFreqs() const
Eigen::MatrixXd fitData(const HpiModelParameters &hpiModelParameters, const Eigen::MatrixXd &matData)
static Eigen::Matrix< T, Eigen::Dynamic, Eigen::Dynamic > pinv(const Eigen::Matrix< T, Eigen::Dynamic, Eigen::Dynamic > &a)
Definition mnemath.h:755