MNE-CPP  0.1.9
A Framework for Electrophysiology
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 
60 using namespace INVERSELIB;
61 using namespace Eigen;
62 
63 //=============================================================================================================
64 // DEFINE GLOBAL METHODS
65 //=============================================================================================================
66 
67 //=============================================================================================================
68 // DEFINE MEMBER METHODS
69 //=============================================================================================================
70 
71 MatrixXd 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 
92 bool 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 
104 bool 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 
120 bool 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 
134 void SignalModel::selectModelAndCompute()
135 {
136  if(m_modelParameters.bBasic()) {
137  computeInverseBasicModel();
138  } else {
139  computeInverseAdvancedModel();
140  }
141 }
142 
143 //=============================================================================================================
144 
145 void 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 
163 void 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 }
INVERSELIB::HpiModelParameters
Brief description of this class.
Definition: hpimodelparameters.h:75
hpimodelparameters.h
HpiModelParameters class declaration.
INVERSELIB::HpiModelParameters::vecHpiFreqs
QVector< int > vecHpiFreqs() const
Definition: hpimodelparameters.h:150
INVERSELIB::SignalModel::fitData
Eigen::MatrixXd fitData(const HpiModelParameters &hpiModelParameters, const Eigen::MatrixXd &matData)
Definition: signalmodel.cpp:71
UTILSLIB::MNEMath::pinv
static Eigen::Matrix< T, Eigen::Dynamic, Eigen::Dynamic > pinv(const Eigen::Matrix< T, Eigen::Dynamic, Eigen::Dynamic > &a)
Definition: mnemath.h:755
mnemath.h
MNEMath class declaration.
signalmodel.h
SignalModel class declaration.