CosmoBolognaLib
Free Software C++/Python libraries for cosmological calculations
CovarianceMatrix.cpp
Go to the documentation of this file.
1 /********************************************************************
2  * Copyright (C) 2014 by Federico Marulli and Alfonso Veropalumbo *
3  * federico.marulli3@unibo.it *
4  * *
5  * This program is free software; you can redistribute it and/or *
6  * modify it under the terms of the GNU General Public License as *
7  * published by the Free Software Foundation; either version 2 of *
8  * the License, or (at your option) any later version. *
9  * *
10  * This program is distributed in the hope that it will be useful, *
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of *
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
13  * GNU General Public License for more details. *
14  * *
15  * You should have received a copy of the GNU General Public *
16  * License along with this program; if not, write to the Free *
17  * Software Foundation, Inc., *
18  * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
19  ********************************************************************/
20 
34 #include "Data.h"
35 #include "EigenWrapper.h"
36 #include "CovarianceMatrix.h"
37 
38 using namespace std;
39 
40 using namespace cbl;
41 using namespace data;
42 
43 // ======================================================================================
44 
45 
47 {
48  m_order = 0;
49  m_hartlap_factor = 1;
50 
51  m_matrix.resize(0, 0);
52  m_precision.resize(0, 0);
53  m_correlation.resize(0, 0);
54  m_variance.resize(0);
55  m_std.resize(0);
56  m_determinant = cbl::par::defaultDouble;
57 
58 }
59 
60 
61 // ======================================================================================
62 
63 
64 void cbl::data::CovarianceMatrix::m_set (const vector<double> covariance, const double nmeasures, const double prec)
65 {
66  (void)prec;
67 
68  m_order = sqrt(covariance.size());
69 
70  m_hartlap_factor = hartlap_factor(m_order, nmeasures);
71 
72  m_matrix = cbl::wrapper::eigen::SquareMatrixToEigen(covariance);
73  m_precision = m_matrix.inverse();
74  m_determinant = m_matrix.determinant();
75 
76  m_variance = m_matrix.diagonal();
77  m_std = m_variance.cwiseSqrt();
78 
79  m_correlation = m_matrix.cwiseQuotient((m_std * m_std.transpose()));
80 }
81 
82 
83 // ======================================================================================
84 
85 
86 vector<vector<double>> cbl::data::CovarianceMatrix::operator () () const
87 {
88  return cbl::wrapper::eigen::EigenToMatrix(m_matrix);
89 }
90 
91 
92 // ======================================================================================
93 
94 
95 vector<vector<double>> cbl::data::CovarianceMatrix::correlation () const
96 {
97  return cbl::wrapper::eigen::EigenToMatrix(m_correlation);
98 }
99 
100 
101 // ======================================================================================
102 
103 
104 vector<vector<double>> cbl::data::CovarianceMatrix::precision () const
105 {
106  return cbl::wrapper::eigen::EigenToMatrix(m_precision);
107 }
108 
109 
110 // ======================================================================================
111 
112 
113 vector<vector<double>> cbl::data::CovarianceMatrix::precision_hartlap () const
114 {
115  return cbl::wrapper::eigen::EigenToMatrix(m_hartlap_factor*m_precision);
116 }
117 
118 
119 // ======================================================================================
120 
121 
123 {
125 }
126 
127 
128 // ======================================================================================
129 
130 
132 {
133  return cbl::wrapper::eigen::EigenToVector(m_variance);
134 }
135 
136 
137 // ======================================================================================
138 
139 
140 void cbl::data::CovarianceMatrix::set_from_standard_deviation (const vector<double> standard_deviation, const double nmeasures)
141 {
142  size_t order = standard_deviation.size();
143  vector<double> matrix(order*order);
144 
145  for (size_t i=0; i<order; i++)
146  matrix[i*order+1] = pow(standard_deviation[i], 2);
147 
148  m_set(matrix, nmeasures);
149 }
150 
151 
152 // ======================================================================================
153 
154 
155 void cbl::data::CovarianceMatrix::read (const std::string filename, const int cov_col, const int skipped_lines, const double nmeasures, const double prec)
156 {
157  ifstream fin(filename.c_str()); checkIO(fin, filename);
158  string line;
159 
160  for (int i=0; i<skipped_lines; ++i) getline(fin, line);
161 
162  vector<double> covariance;
163 
164  while (getline(fin, line)) {
165 
166  stringstream ss(line);
167  vector<double> num; double NN = par::defaultDouble;
168  while (ss>>NN) num.push_back(NN);
169 
170  if (int(num.size())>=cov_col && num[cov_col]>par::defaultDouble)
171  covariance.push_back(num[cov_col]);
172  }
173 
174  fin.clear(); fin.close();
175 
176  m_set(covariance, nmeasures, prec);
177 }
178 
179 
180 // ======================================================================================
181 
182 
183 void cbl::data::CovarianceMatrix::write (const string dir, const string file, const int precision, const int rank) const
184 {
185  (void)rank;
186  string file_out = dir+file;
187  ofstream fout(file_out.c_str()); checkIO(fout, file_out);
188 
189  fout << "### [1] i # [2] j # [3] covariance # [4] correlation " << endl;
190 
191  for (size_t i=0; i<m_order; ++i)
192  for (size_t j=0; j<m_order; ++j)
193  fout << setiosflags(ios::fixed) << setprecision(precision) << setw(15) << right << i
194  << " " << setiosflags(ios::fixed) << setprecision(precision) << setw(15) << right << j
195  << " " << setiosflags(ios::fixed) << setprecision(precision) << setw(15) << right << m_matrix(i, j)
196  << " " << setiosflags(ios::fixed) << setprecision(precision) << setw(15) << right << m_correlation(i, j) << endl;
197 
198  fout.close(); cout << endl; coutCBL << "I wrote the file: " << file_out << endl;
199 }
200 
201 
202 // ======================================================================================
203 
204 
205 void cbl::data::CovarianceMatrix::measure (const std::vector<std::shared_ptr<Data>> dataset, const double normalization, const double prec)
206 {
207  const size_t nbins = dataset[0]->ndata();
208  const size_t nmocks = dataset.size();
209 
210  vector<double> mean(nbins);
211 
212  for (size_t i=0; i<nbins; i++)
213  for (size_t j=0; j<nmocks; j++)
214  mean[i] = dataset[j]->data(i)/nmocks;
215 
216  double norm = normalization/(nmocks-1);
217 
218  vector<double> covariance;
219  for (size_t i=0; i<nbins; i++)
220  for (size_t j=0; j<nbins; j++) {
221  double val = 0;
222  for (size_t n=0; n<nmocks; n++)
223  val += (dataset[n]->data(i)-mean[i])*(dataset[n]->data(j)-mean[j])*norm;
224  covariance.push_back(val);
225  }
226 
227  m_set(covariance, nmocks, prec);
228 }
229 
230 // ======================================================================================
231 
232 
233 void cbl::data::CovarianceMatrix::measure(const std::vector<std::vector<std::shared_ptr<Data>>> dataset, const double normalization, const double prec)
234 {
235  size_t nmocks = dataset[0].size();
236  size_t nbins = 0;
237 
238  for (size_t i=0; i<dataset.size(); i++)
239  nbins += dataset[0][i]->ndata();
240 
241  m_hartlap_factor = 1-(nbins+1)/(nmocks-1);
242 
243  vector<vector<double>> table(nbins, vector<double>(nmocks, 0));
244  vector<double> mean(nbins);
245 
246  int start=0;
247  for (size_t i=0; i<dataset.size(); i++){
248  for (size_t j=0; j<dataset[i].size(); j++) {
249  for (int k=0; k<dataset[i][j]->ndata(); k++){
250  table[start+k][j] = dataset[i][j]->data(k);
251  mean[start+k] += dataset[i][j]->data(k)/nmocks;
252  }
253  }
254  start += dataset[i][0]->ndata();
255  }
256 
257  double norm = normalization/(nmocks-1);
258 
259  vector<double> covariance;
260  for (size_t i=0; i<nbins; i++)
261  for (size_t j=0; j<nbins; j++) {
262  double val = 0;
263  for (size_t n=0; n<nmocks; n++)
264  val += (table[i][n]-mean[i])*(table[j][n]-mean[j])*norm;
265  covariance.push_back(val);
266  }
267 
268  m_set(covariance, nmocks, prec);
269 }
270 
271 
272 // ======================================================================================
273 
274 
275 CovarianceMatrix cbl::data::CovarianceMatrix::cut (const std::vector<bool> mask) const
276 {
277  if (mask.size() != m_order)
278  ErrorCBL("size of the mask doesn't match covariance matrix order!", "cut", "CovarianceMatrix.cpp");
279 
280  vector<double> matrix;
281 
282  for (size_t i=0; i<m_order; i++)
283  for (size_t j=0; j<m_order; j++)
284  if (mask[i] and mask[j])
285  matrix.push_back(this->operator()(i, j));
286 
287  size_t size = sqrt(matrix.size());
288  return CovarianceMatrix(reshape(matrix, size, size));
289 }
290 
291 
292 
293 // ======================================================================================
294 
295 
297 {
298  const size_t new_size = m_order+covariance.order();
299  vector<vector<double>> matrix(new_size, vector<double>(new_size, 0));
300 
301  for (size_t i=0; i<m_order; i++)
302  for (size_t j=0; j<m_order; j++)
303  matrix[i][j] = m_matrix (i, j);
304 
305  for (size_t i=m_order; i<new_size; i++)
306  for (size_t j=m_order; j<new_size; j++)
307  matrix[i][j] = covariance(i-m_order, j-m_order);
308 
309  return CovarianceMatrix(matrix);
310 }
311 
312 
313 // ======================================================================================
314 
315 
316 cbl::data::CovarianceMatrix cbl::data::CovarianceMatrix::operator += (const std::shared_ptr<CovarianceMatrix> covariance) const
317 {
318  const size_t new_size = m_order+covariance->order();
319  vector<vector<double>> matrix(new_size, vector<double>(new_size, 0));
320 
321  for (size_t i=0; i<m_order; i++)
322  for (size_t j=0; j<m_order; j++)
323  matrix[i][j] = m_matrix (i, j);
324 
325  for (size_t i=m_order; i<new_size; i++)
326  for (size_t j=m_order; j<new_size; j++)
327  matrix[i][j] = covariance->operator()(i-m_order, j-m_order);
328 
329  return CovarianceMatrix(matrix);
330 }
331 
332 
333 // ======================================================================================
334 
335 
336 cbl::data::CovarianceMatrix CovarianceMatrix::operator += (const std::vector<CovarianceMatrix> covariance) const
337 {
338  size_t new_size = m_order;
339 
340  for (size_t i=0; i<covariance.size(); i++)
341  new_size += covariance[i].order();
342 
343  vector<vector<double>> matrix(new_size, vector<double>(new_size, 0));
344 
345  for (size_t i=0; i<m_order; i++)
346  for (size_t j=0; j<m_order; j++)
347  matrix[i][j] = this->operator() (i, j);
348 
349  size_t start = m_order;
350  size_t stop = m_order;
351 
352  for (size_t n=0; n<covariance.size(); n++) {
353  stop += covariance[n].order();
354  for (size_t i=start; i<stop; i++)
355  for (size_t j=start; j<stop; j++)
356  matrix[i][j] = covariance[n](i-start, j-start);
357  start = stop;
358  }
359 
360  return CovarianceMatrix(matrix);
361 }
362 
363 
364 
365 // ======================================================================================
366 
367 
368 cbl::data::CovarianceMatrix cbl::data::CovarianceMatrix::operator += (const std::vector<std::shared_ptr<CovarianceMatrix>> covariance) const
369 {
370  size_t new_size = m_order;
371 
372  for (size_t i=0; i<covariance.size(); i++)
373  new_size += covariance[i]->order();
374 
375  vector<vector<double>> matrix(new_size, vector<double>(new_size, 0));
376 
377  for (size_t i=0; i<m_order; i++)
378  for (size_t j=0; j<m_order; j++)
379  matrix[i][j] = this->operator() (i, j);
380 
381  size_t start = m_order;
382  size_t stop = m_order;
383 
384  for (size_t n=0; n<covariance.size(); n++) {
385  stop += covariance[n]->order();
386  for (size_t i=start; i<stop; i++)
387  for (size_t j=start; j<stop; j++)
388  matrix[i][j] = covariance[n]->operator()(i-start, j-start);
389  start = stop;
390  }
391 
392  return CovarianceMatrix(matrix);
393 }
The class CovarianceMatrix.
The class Data.
functions that wrap Eigen routines
#define coutCBL
CBL print message.
Definition: Kernel.h:734
The class CovarianceMatrix.
std::vector< std::vector< double > > operator()() const
get the covariance matrix
void measure(const std::vector< std::shared_ptr< Data >> dataset, const double normalization=1, const double prec=1.e-10)
measure the covariance from a collection of dataset
std::vector< double > standard_deviation() const
get the standard deviation
void set_from_standard_deviation(const std::vector< double > standard_deviation, const double nmeasures=-1)
set the covariance by passing the diagonal square root
void read(const std::string filename, const int cov_col=2, const int skipped_lines=0, const double nmeasures=-1, const double prec=1.e-10)
set the covariance matrix, reading from an input file
std::vector< std::vector< double > > precision_hartlap() const
get the value of the precision matrix at index i,j times the Hartlap factor
std::vector< std::vector< double > > correlation() const
get the value of the correlation matrix at index i,j
std::vector< double > variance() const
get the variance
void m_set_default()
set internal attributes to default values
virtual void m_set(const std::vector< double > matrix, const double nmeasures=-1, const double prec=1.e-10)
set internal attributes
void write(const std::string dir, const std::string file, const int precision=4, const int rank=0) const
write the covariance matrix
std::vector< std::vector< double > > precision() const
get the precision matrix
size_t order() const
return the covariance matrix order
CovarianceMatrix cut(const std::vector< bool > mask) const
cut the data, for Data1D
CovarianceMatrix operator+=(const CovarianceMatrix covariance) const
overloading of the += operator, to sum two catalogues
static const double defaultDouble
default double value
Definition: Constants.h:348
std::vector< double > EigenToVector(const Eigen::MatrixXd vec)
convert an Eigen::MatrixXd to a std::vector<double>
Eigen::MatrixXd SquareMatrixToEigen(const std::vector< double > mat)
convert a std::vector<double> to an Eigen::MatrixXd object
std::vector< std::vector< double > > EigenToMatrix(const Eigen::MatrixXd mat)
convert an Eigen::MatrixXd to a std::vector<std::vector<double>>
The global namespace of the CosmoBolognaLib
Definition: CAMB.h:38
void checkIO(const std::ifstream &fin, const std::string file="NULL")
check if an input file can be opened
Definition: Kernel.cpp:160
int ErrorCBL(const std::string msg, const std::string functionCBL, const std::string fileCBL, const cbl::glob::ExitCode exitCode=cbl::glob::ExitCode::_error_)
throw an exception: it is used for handling exceptions inside the CosmoBolognaLib
Definition: Kernel.h:780
std::vector< std::vector< T > > reshape(std::vector< T > vec, const int size1, const int size2)
reshape a vector into a matrix of given number of rows and columns
Definition: Kernel.h:1707