Hamiltonian Monte Carlo

auxiliary.cpp
Go to the documentation of this file.
1 // Created by Lars Gebraad on 7/10/17.
2 
3 #include <utility>
4 #include <vector>
5 #include <iostream>
6 #include <cmath>
7 #include <fstream>
8 #include "auxiliary.hpp"
9 #include "linearalgebra.hpp"
10 
11 #pragma clang diagnostic push
12 #pragma ide diagnostic ignored "OCUnusedGlobalDeclarationInspection"
13 
14 /* ----------------------------------------------------------------------------------------------------------------------- *
15  * Class for Gaussian Distributed prior information about model parameters for a VSP probabilistic inversion. *
16  * ----------------------------------------------------------------------------------------------------------------------- */
17 prior::~prior() = default;
18 
19 prior::prior() = default;
20 
21 // Setting prior data manually
22 prior::prior(std::vector<double> mean, std::vector<double> std) {
23  _mean.clear();
24  _std.clear();
25  _mean = std::move(mean);
26  _std = std::move(std);
27  _numberParameters = _mean.size();
29 }
30 
31 double prior::misfit(std::vector<double> parameters) {
32  std::vector<double> parameterDifference = (std::move(parameters) - _mean);
33  return 0.5 * (parameterDifference * (_inverseCovarianceMatrix * parameterDifference));
34 }
35 
36 std::vector<double> prior::gradientMisfit(std::vector<double> parameters) {
37  std::vector<double> parameters_diff = (parameters - _mean);
38  std::vector<double> gradient;
39  gradient.clear();
40  for (int q = 0; q < parameters.size(); q++) {
41  gradient.push_back(0.5 * ((GetMatrixColumn(_inverseCovarianceMatrix, q) * parameters_diff) +
42  (GetMatrixRow(_inverseCovarianceMatrix, q) * parameters_diff)));
43  }
44  return gradient;
45 }
46 
47 // Set prior inverse covariance matrix, or mass matrix. Only diagonal entries are filled, no correlation is described.
49  std::vector<double> zeroRow(_numberParameters, 0.0);
50  for (int i = 0; i < _numberParameters; i++) {
51  _inverseCovarianceMatrix.push_back(zeroRow);
52  _inverseCovarianceMatrix[i][i] = 1 / (_std[i] * _std[i]);
53  }
54 }
55 
56 // Copy constructor
57 prior::prior(const prior &in_prior) {
58  _mean = in_prior._mean;
59  _std = in_prior._std;
62 }
63 
64 /* -----------------------------------------------------------------------------------------------------------------------
65  * Data class, for generating new data or loading previously generated data. Also calculates inverse data covariance
66  * matrix and is able to compute data misfits.
67  * ----------------------------------------------------------------------------------------------------------------------- */
68 data::data(const char *filename) {
69  readData(filename);
70 }
71 
72 data::data(const char *filename, double percentage) {
73  readData(filename);
74  setICDMatrix_percentual(percentage);
75 }
76 
77 data::data() = default;
78 
79 double data::misfit(std::vector<double> q, forwardModel m) {
80  std::vector<double> dataDifference = m.calculateData(std::move(q)) - _observedData;
81  return 0.5 * (dataDifference * (_inverseCD * dataDifference));
82 }
83 
84 void data::setICDMatrix(double std) {
85  std::vector<double> zeroRow((unsigned long) _numberData, 0.0);
86  _inverseCD.clear();
87  for (int i = 0; i < _numberData; i++) {
88  _inverseCD.push_back(zeroRow);
89  _inverseCD[i][i] = 1 / (std * std); // computing inverse variance
90  }
91 }
92 
93 void data::setICDMatrix_percentual(double percentage) {
94  double std;
95  std::vector<double> zeroRow((unsigned long) _numberData, 0.0);
96  _inverseCD.clear();
97  for (int i = 0; i < _numberData; i++) {
98  _inverseCD.push_back(zeroRow);
99  std = _observedData[i] * (percentage / 100.0);
100  _inverseCD[i][i] = 1 / (std * std); // computing inverse variance
101  }
102 }
103 
104 void data::readData(const char *filename) {
105  // Read file for observed data
106  double a;
107  _observedData.clear();
108  std::ifstream infile(filename);
109 
110  // Ignore first two lines
111  infile.ignore(500,'\n');
112  infile.ignore(500,'\n');
113  infile.ignore(500,'\n');
114 
115  infile >> _numberData;
116  for (int i = 0; i < _numberData; i++) {
117  infile >> a;
118  _observedData.push_back(a);
119  }
120  infile.close();
121 }
122 
123 void data::writeData(const char *filename) {
124  // Write data
125  std::ofstream outfile;
126  outfile.open(filename);
127 
128  outfile << "# Data generated from hardcoded class, which reads from matrix.txt" << std::endl;
129  outfile << "# Line 4: number of data points. Line 5: data in sequential order." << std::endl;
130  outfile << "# The first three lines are always ignored, no matter the characters (up to 500 characters per line)." << std::endl;
131 
132  outfile << _numberData << std::endl;
133  for (int i = 0; i < _numberData; i++) {
134  outfile << _observedData[i] << " ";
135  }
136  outfile.close();
137 }
138 
139 void data::setMisfitParameterDataMatrix(std::vector<std::vector<double>> designMatrix) {
140  _misfitParameterDataMatrix = TransposeMatrix(designMatrix) * _inverseCD;
141  setMisfitParameterMatrix(designMatrix);
142 }
143 
144 void data::setMisfitParameterMatrix(std::vector<std::vector<double>> designMatrix) {
145  _misfitParameterMatrix = _misfitParameterDataMatrix * std::move(designMatrix);
146 }
147 
148 std::vector<double> data::gradientMisfit(std::vector<double> parameters) {
149  std::vector<double> gradient;
150  gradient.clear();
151  for (int q = 0; q < parameters.size(); q++) {
152  // I am -fairly- sure of this matrix equation derivative
153  gradient.push_back(0.5 * (GetMatrixColumn(_misfitParameterMatrix, q) * parameters +
154  GetMatrixRow(_misfitParameterMatrix, q) * parameters +
155  -2 * (GetMatrixRow(_misfitParameterDataMatrix, q) * _observedData)
156  ));
157  }
158  return gradient;
159 };
160 
161 /* -----------------------------------------------------------------------------------------------------------------------
162  * Forward model class.
163  * ----------------------------------------------------------------------------------------------------------------------- */
164 void forwardModel::constructUnitDesignMatrix(int numberParameters) {
165  // Make square zero matrix
166  _designMatrix.clear();
167  std::vector<double> zeroRow((unsigned long) numberParameters, 0);
168  _designMatrix.insert(_designMatrix.end(), (unsigned long) numberParameters, zeroRow);
169 
170  // Set diagonal entries to 1
171  for (int i = 0; i < numberParameters; i++) {
172  _designMatrix[i][i] = 1;
173  }
174 }
175 
176 forwardModel::forwardModel(int numberParameters) {
177  _numberParameters = numberParameters;
178  constructUnitDesignMatrix(numberParameters);
179 }
180 
181 std::vector<double> forwardModel::calculateData(std::vector<double> parameters) {
182  return (_designMatrix * std::move(parameters));
183 }
184 
185 forwardModel::forwardModel(const char *filename) {
186  // Read file for observed data
187  double element;
188  std::vector<double> row;
189  int numberData;
190  _designMatrix.clear();
191 
192  std::ifstream infile(filename);
193 
194  // Ignore first two lines
195  infile.ignore(500,'\n');
196  infile.ignore(500,'\n');
197  infile.ignore(500,'\n');
198 
199  infile >> numberData;
200  infile >> _numberParameters;
201  for (int i = 0; i < numberData; i++) {
202  for (int j = 0; j < _numberParameters; j++) {
203  infile >> element;
204  row.push_back(element);
205  }
206  _designMatrix.push_back(row);
207  row.clear();
208  }
209  infile.close();
210 }
211 
212 forwardModel::forwardModel() = default;
213 
214 double posterior::misfit(std::vector<double> parameters, prior &in_prior, data &in_data, forwardModel m) {
215  return in_prior.misfit(parameters) + in_data.misfit(parameters, std::move(m));
216 }
217 
218 std::vector<double> posterior::gradientMisfit(std::vector<double> parameters, prior &in_prior, data &in_data) {
219  return (in_data.gradientMisfit(parameters) + in_prior.gradientMisfit(parameters));
220 }
221 
222 void printVector(std::vector<double> A) {
223  for (int i = 0; i < A.size(); i++) {
224  std::cout << "Component " << i + 1 << ": " << A[i] << std::endl;
225  }
226 }
227 
228 #pragma clang diagnostic pop
void setInverseCovarianceMatrix()
Definition: auxiliary.cpp:48
std::vector< double > _mean
Definition: auxiliary.hpp:24
void setICDMatrix(double std)
Definition: auxiliary.cpp:84
std::vector< std::vector< double > > _inverseCovarianceMatrix
Definition: auxiliary.hpp:26
double misfit(std::vector< double > parameters)
Definition: auxiliary.cpp:31
STL namespace.
std::vector< double > _std
Definition: auxiliary.hpp:25
std::vector< double > gradientMisfit(std::vector< double > parameters)
Definition: auxiliary.cpp:148
std::vector< std::vector< double > > TransposeMatrix(std::vector< std::vector< double > > M)
std::vector< double > GetMatrixColumn(std::vector< std::vector< double >> M, int column)
Function to get a column from a matrix.
std::vector< double > GetMatrixRow(std::vector< std::vector< double >> M, int row)
Function to get a row from a matrix.
void constructUnitDesignMatrix(int numberParameters)
Definition: auxiliary.cpp:164
std::vector< double > gradientMisfit(std::vector< double > parameters)
Definition: auxiliary.cpp:36
void setMisfitParameterDataMatrix(std::vector< std::vector< double >> designMatrix)
Definition: auxiliary.cpp:139
double misfit(std::vector< double > parameters, prior &in_prior, data &in_data, forwardModel m)
Definition: auxiliary.cpp:214
std::vector< double > calculateData(std::vector< double > parameters)
Definition: auxiliary.cpp:181
Linear algebra functions operating on standard library containers.
void readData(const char *filename)
Definition: auxiliary.cpp:104
Prior information in parameter space.
Definition: auxiliary.hpp:20
void writeData(const char *filename)
Definition: auxiliary.cpp:123
unsigned long _numberParameters
Definition: auxiliary.hpp:23
double misfit(std::vector< double > in_parameters, forwardModel m)
Definition: auxiliary.cpp:79
void setMisfitParameterMatrix(std::vector< std::vector< double >> designMatrix)
Definition: auxiliary.cpp:144
void printVector(std::vector< double > A)
Definition: auxiliary.cpp:222
void setICDMatrix_percentual(double percentage)
Definition: auxiliary.cpp:93
std::vector< double > gradientMisfit(std::vector< double > parameters, prior &in_prior, data &in_data)
Definition: auxiliary.cpp:218