v2.0.0
Loading...
Searching...
No Matches
granger_causality.cpp
Go to the documentation of this file.
1//=============================================================================================================
34
35//=============================================================================================================
36// INCLUDES
37//=============================================================================================================
38
39#include "granger_causality.h"
40#include "mvar_model.h"
43#include "../network/network.h"
45
46//=============================================================================================================
47// QT INCLUDES
48//=============================================================================================================
49
50#include <QDebug>
51
52//=============================================================================================================
53// EIGEN INCLUDES
54//=============================================================================================================
55
56#include <Eigen/Dense>
57
58//=============================================================================================================
59// USED NAMESPACES
60//=============================================================================================================
61
62using namespace CONNLIB;
63using namespace Eigen;
64
65//=============================================================================================================
66// DEFINE GLOBAL METHODS
67//=============================================================================================================
68
69//=============================================================================================================
70// DEFINE MEMBER METHODS
71//=============================================================================================================
72
76
77//=============================================================================================================
78
80{
81 Network finalNetwork("GC");
82
83 if(connectivitySettings.isEmpty()) {
84 qDebug() << "GrangerCausality::calculate - Input data is empty";
85 return finalNetwork;
86 }
87
88 finalNetwork.setSamplingFrequency(connectivitySettings.getSamplingFrequency());
89
90 // Average trial data for MVAR fitting
91 const int nTrials = connectivitySettings.size();
92 MatrixXd matDataAvg = connectivitySettings.at(0).matData;
93 for(int t = 1; t < nTrials; ++t) {
94 matDataAvg += connectivitySettings.at(t).matData;
95 }
96 matDataAvg /= static_cast<double>(nTrials);
97
98 const int nCh = static_cast<int>(matDataAvg.rows());
99 const int iNfft = connectivitySettings.getFFTSize();
100 const int iNFreqs = static_cast<int>(std::floor(iNfft / 2.0)) + 1;
101
102 finalNetwork.setFFTSize(iNFreqs);
103 finalNetwork.setUsedFreqBins(iNFreqs);
104
105 // Create nodes
106 RowVectorXf rowVert = RowVectorXf::Zero(3);
107 for(int i = 0; i < nCh; ++i) {
108 rowVert = RowVectorXf::Zero(3);
109 if(connectivitySettings.getNodePositions().rows() != 0 && i < connectivitySettings.getNodePositions().rows()) {
110 rowVert(0) = connectivitySettings.getNodePositions().row(i)(0);
111 rowVert(1) = connectivitySettings.getNodePositions().row(i)(1);
112 rowVert(2) = connectivitySettings.getNodePositions().row(i)(2);
113 }
114 finalNetwork.append(NetworkNode::SPtr(new NetworkNode(i, rowVert)));
115 }
116
117 // Fit MVAR model
118 MvarModel model;
119 model.fit(matDataAvg);
120
121 // Compute transfer function and spectral matrix at normalized frequencies
122 VectorXd vecFreqs = VectorXd::LinSpaced(iNFreqs, 0.0, 0.5);
123 QVector<MatrixXcd> vecH = model.transferFunction(vecFreqs);
124 QVector<MatrixXcd> vecS = model.spectralMatrix(vecFreqs);
125 MatrixXd matSigma = model.noiseCov();
126
127 // Compute spectral Granger causality for each directed pair
128 // GC_{j->i}(f) = ln( S_{ii}(f) / (S_{ii}(f) - gamma_{ij} * |H_{ij}(f)|^2) )
129 // where gamma_{ij} = Sigma_{jj} - Sigma_{ij}^2 / Sigma_{ii}
130 for(int i = 0; i < nCh; ++i) {
131 for(int j = 0; j < nCh; ++j) {
132 if(i == j) {
133 continue;
134 }
135
136 MatrixXd matWeight(iNFreqs, 1);
137
138 const double gammaIJ = matSigma(j, j) - (matSigma(i, j) * matSigma(i, j)) / matSigma(i, i);
139
140 for(int fi = 0; fi < iNFreqs; ++fi) {
141 const double sII = vecS[fi](i, i).real();
142 const double hIJ2 = std::norm(vecH[fi](i, j));
143 const double denom = sII - gammaIJ * hIJ2;
144
145 if(denom > 0.0 && sII > 0.0) {
146 matWeight(fi, 0) = std::log(sII / denom);
147 } else {
148 matWeight(fi, 0) = 0.0;
149 }
150 }
151
152 QSharedPointer<NetworkEdge> pEdge =
153 QSharedPointer<NetworkEdge>(new NetworkEdge(j, i, matWeight));
154
155 finalNetwork.getNodeAt(j)->append(pEdge);
156 finalNetwork.getNodeAt(i)->append(pEdge);
157 finalNetwork.append(pEdge);
158 }
159 }
160
161 return finalNetwork;
162}
ConnectivitySettings class declaration.
NetworkNode class declaration.
NetworkEdge class declaration.
Network class declaration.
GrangerCausality class declaration.
MvarModel class declaration.
Functional connectivity metrics (coherence, PLV, cross-correlation, etc.).
This class is a container for connectivity settings.
const IntermediateTrialData & at(int i) const
const Eigen::MatrixX3f & getNodePositions() const
static Network calculate(ConnectivitySettings &connectivitySettings)
MVAR model fitting for directed connectivity metrics.
Definition mvar_model.h:82
Eigen::MatrixXd noiseCov() const
QVector< Eigen::MatrixXcd > spectralMatrix(const Eigen::VectorXd &freqs) const
QVector< Eigen::MatrixXcd > transferFunction(const Eigen::VectorXd &freqs) const
void fit(const Eigen::MatrixXd &data, int p=0)
This class holds information about a network, can compute a distance table and provide network metric...
Definition network.h:92
void append(QSharedPointer< NetworkEdge > newEdge)
void setUsedFreqBins(int iNumberFreqBins)
Definition network.cpp:513
void setFFTSize(int iFFTSize)
Definition network.cpp:520
void setSamplingFrequency(float fSFreq)
Definition network.cpp:499
QSharedPointer< NetworkNode > getNodeAt(int i)
Definition network.cpp:163
This class holds an object to describe the edge of a network.
Definition networkedge.h:80
This class holds an object to describe the node of a network.
Definition networknode.h:82
QSharedPointer< NetworkNode > SPtr
Definition networknode.h:85