Quantum++  v0.8.2
C++11 quantum computing library
statistics.h
Go to the documentation of this file.
1 /*
2  * Quantum++
3  *
4  * Copyright (c) 2013 - 2015 Vlad Gheorghiu (vgheorgh@gmail.com)
5  *
6  * This file is part of Quantum++.
7  *
8  * Quantum++ is free software: you can redistribute it and/or modify
9  * it under the terms of the GNU General Public License as published by
10  * the Free Software Foundation, either version 3 of the License, or
11  * (at your option) any later version.
12  *
13  * Quantum++ is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with Quantum++. If not, see <http://www.gnu.org/licenses/>.
20  */
21 
27 #ifndef STATISTICS_H_
28 #define STATISTICS_H_
29 
30 // Collection of statistics-related functions
31 
32 namespace qpp
33 {
34 
41 inline std::vector <double> uniform(idx N)
42 {
43  if (N == 0)
44  throw Exception("qpp::uniform", Exception::Type::ZERO_SIZE);
45 
46  return std::vector<double>(N, 1. / N);
47 }
48 
57 inline std::vector <double> marginalX(const dmat& probXY)
58 {
59  if (!internal::_check_nonzero_size(probXY))
60  throw Exception("qpp::marginalX", Exception::Type::ZERO_SIZE);
61 
62  std::vector <double> result(probXY.rows(), 0);
63  for (idx i = 0; i < static_cast<idx>(probXY.rows()); ++i)
64  {
65  for (idx j = 0; j < static_cast<idx>(probXY.cols()); ++j)
66  {
67  result[i] += probXY(i, j);
68  }
69  }
70 
71  return result;
72 }
73 
82 inline std::vector <double> marginalY(const dmat& probXY)
83 {
84  if (!internal::_check_nonzero_size(probXY))
85  throw Exception("qpp::marginalY", Exception::Type::ZERO_SIZE);
86 
87  return marginalX(probXY.transpose());
88 }
89 
97 template<typename Container>
98 double avg(const std::vector <double>& prob, const Container& X)
99 {
101  throw Exception("qpp:avg", Exception::Type::ZERO_SIZE);
102  if (!internal::_check_matching_sizes(prob, X))
103  throw Exception("qpp:avg", Exception::Type::SIZE_MISMATCH);
104 
105  double result = 0;
106  for (idx i = 0; i < prob.size(); ++i)
107  result += prob[i] * X[i];
108 
109  return result;
110 }
111 
122 template<typename Container>
123 double cov(const dmat& probXY,
124  const Container& X,
125  const Container& Y)
126 {
128  throw Exception("qpp:cov", Exception::Type::ZERO_SIZE);
129  if (static_cast<idx>(probXY.rows()) != X.size() ||
130  static_cast<idx>(probXY.cols()) != Y.size())
131  throw Exception("qpp:cov", Exception::Type::SIZE_MISMATCH);
132 
133  std::vector <double> probX = marginalX(probXY); // marginals
134  std::vector <double> probY = marginalY(probXY); // marginals
135 
136  double result = 0;
137  for (idx i = 0; i < X.size(); ++i)
138  {
139  for (idx j = 0; j < Y.size(); ++j)
140  {
141  result += probXY(i, j) * X[i] * Y[j];
142  }
143  }
144 
145  return result - avg(probX, X) * avg(probY, Y);
146 }
147 
156 template<typename Container>
157 double var(const std::vector <double>& prob, const Container& X)
158 {
160  throw Exception("qpp:var", Exception::Type::ZERO_SIZE);
161  if (!internal::_check_matching_sizes(prob, X))
162  throw Exception("qpp:var", Exception::Type::SIZE_MISMATCH);
163 
164  Eigen::VectorXd diag(prob.size());
165  for (idx i = 0; i < prob.size(); ++i)
166  diag(i) = prob[i];
167  dmat probXX = diag.asDiagonal();
168 
169  return cov(probXX, X, X);
170 }
171 
180 template<typename Container>
181 double sigma(const std::vector <double>& prob, const Container& X)
182 {
184  throw Exception("qpp:sigma", Exception::Type::ZERO_SIZE);
185  if (!internal::_check_matching_sizes(prob, X))
186  throw Exception("qpp:sigma", Exception::Type::SIZE_MISMATCH);
187 
188  return std::sqrt(var(prob, X));
189 }
190 
201 template<typename Container>
202 double cor(const dmat& probXY,
203  const Container& X,
204  const Container& Y)
205 {
207  throw Exception("qpp:cor", Exception::Type::ZERO_SIZE);
208  if (static_cast<idx>(probXY.rows()) != X.size() ||
209  static_cast<idx>(probXY.cols()) != Y.size())
210  throw Exception("qpp:cor", Exception::Type::SIZE_MISMATCH);
211 
212  return cov(probXY, X, Y) / (sigma(marginalX(probXY), X) *
213  sigma(marginalX(probXY), Y));
214 }
215 
216 } /* namespace qpp */
217 
218 #endif /* STATISTICS_H_ */
219 
std::vector< double > uniform(idx N)
Uniform probability distribution vector.
Definition: statistics.h:41
bool _check_matching_sizes(const T1 &lhs, const T2 &rhs) noexcept
Definition: util.h:120
std::vector< double > marginalX(const dmat &probXY)
Marginal distribution.
Definition: statistics.h:57
Eigen::MatrixXd dmat
Real (double precision) dynamic Eigen matrix.
Definition: types.h:71
double cov(const dmat &probXY, const Container &X, const Container &Y)
Covariance.
Definition: statistics.h:123
Quantum++ main namespace.
Definition: codes.h:30
double var(const std::vector< double > &prob, const Container &X)
Variance.
Definition: statistics.h:157
double avg(const std::vector< double > &prob, const Container &X)
Average.
Definition: statistics.h:98
double sigma(const std::vector< double > &prob, const Container &X)
Standard deviation.
Definition: statistics.h:181
Generates custom exceptions, used when validating function parameters.
Definition: exception.h:39
bool _check_nonzero_size(const T &x) noexcept
Definition: util.h:113
std::vector< double > marginalY(const dmat &probXY)
Marginal distribution.
Definition: statistics.h:82
std::size_t idx
Non-negative integer index.
Definition: types.h:36
double cor(const dmat &probXY, const Container &X, const Container &Y)
Correlation.
Definition: statistics.h:202