Quantum++  v1.0-rc2
A modern C++11 quantum computing library
statistics.h
Go to the documentation of this file.
1 /*
2  * Quantum++
3  *
4  * Copyright (c) 2013 - 2017 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 namespace qpp
31 {
38 inline std::vector<double> uniform(idx N)
39 {
40  // EXCEPTION CHECKS
41 
42  if (N == 0)
43  throw exception::ZeroSize("qpp::uniform()");
44  // END EXCEPTION CHECKS
45 
46  return std::vector<double>(N, 1. / N);
47 }
48 
57 inline std::vector<double> marginalX(const dmat& probXY)
58 {
59  // EXCEPTION CHECKS
60 
61  if (!internal::check_nonzero_size(probXY))
62  throw exception::ZeroSize("qpp::marginalX()");
63  // END EXCEPTION CHECKS
64 
65  std::vector<double> result(probXY.rows(), 0);
66  for (idx i = 0; i < static_cast<idx>(probXY.rows()); ++i)
67  {
68  for (idx j = 0; j < static_cast<idx>(probXY.cols()); ++j)
69  {
70  result[i] += probXY(i, j);
71  }
72  }
73 
74  return result;
75 }
76 
85 inline std::vector<double> marginalY(const dmat& probXY)
86 {
87  // EXCEPTION CHECKS
88 
89  if (!internal::check_nonzero_size(probXY))
90  throw exception::ZeroSize("qpp::marginalY()");
91  // END EXCEPTION CHECKS
92 
93  return marginalX(probXY.transpose());
94 }
95 
105 template<typename Container>
106 double avg(const std::vector<double>& prob, const Container& X,
107  typename std::enable_if<is_iterable<Container>::value>::type*
108  = nullptr)
109 {
110  // EXCEPTION CHECKS
111 
112  if (!internal::check_nonzero_size(prob))
113  throw exception::ZeroSize("qpp::avg()");
114  if (!internal::check_matching_sizes(prob, X))
115  throw exception::SizeMismatch("qpp::avg()");
116  // END EXCEPTION CHECKS
117 
118  double result = 0;
119  for (idx i = 0; i < prob.size(); ++i)
120  result += prob[i] * X[i];
121 
122  return result;
123 }
124 
135 template<typename Container>
136 double cov(const dmat& probXY,
137  const Container& X,
138  const Container& Y,
139  typename std::enable_if<is_iterable<Container>::value>::type*
140  = nullptr)
141 {
142  // EXCEPTION CHECKS
143 
145  throw exception::ZeroSize("qpp::cov()");
146  if (static_cast<idx>(probXY.rows()) != X.size() ||
147  static_cast<idx>(probXY.cols()) != Y.size())
148  throw exception::SizeMismatch("qpp::cov()");
149  // END EXCEPTION CHECKS
150 
151  std::vector<double> probX = marginalX(probXY); // marginals
152  std::vector<double> probY = marginalY(probXY); // marginals
153 
154  double result = 0;
155  for (idx i = 0; i < X.size(); ++i)
156  {
157  for (idx j = 0; j < Y.size(); ++j)
158  {
159  result += probXY(i, j) * X[i] * Y[j];
160  }
161  }
162 
163  return result - avg(probX, X) * avg(probY, Y);
164 }
165 
174 template<typename Container>
175 double var(const std::vector<double>& prob, const Container& X,
176  typename std::enable_if<is_iterable<Container>::value>::type*
177  = nullptr)
178 {
179  // EXCEPTION CHECKS
180 
181  if (!internal::check_nonzero_size(prob))
182  throw exception::ZeroSize("qpp::var()");
183  if (!internal::check_matching_sizes(prob, X))
184  throw exception::SizeMismatch("qpp::var()");
185  // END EXCEPTION CHECKS
186 
187  Eigen::VectorXd diag(prob.size());
188  for (idx i = 0; i < prob.size(); ++i)
189  diag(i) = prob[i];
190  dmat probXX = diag.asDiagonal();
191 
192  return cov(probXX, X, X);
193 }
194 
203 template<typename Container>
204 double sigma(const std::vector<double>& prob, const Container& X,
205  typename std::enable_if<is_iterable<Container>::value>::type*
206  = nullptr)
207 {
208  // EXCEPTION CHECKS
209 
210  if (!internal::check_nonzero_size(prob))
211  throw exception::ZeroSize("qpp::sigma()");
212  if (!internal::check_matching_sizes(prob, X))
213  throw exception::SizeMismatch("qpp::sigma()");
214  // END EXCEPTION CHECKS
215 
216  return std::sqrt(var(prob, X));
217 }
218 
229 template<typename Container>
230 double cor(const dmat& probXY,
231  const Container& X,
232  const Container& Y,
233  typename std::enable_if<is_iterable<Container>::value>::type*
234  = nullptr)
235 {
236  // EXCEPTION CHECKS
237 
239  throw exception::ZeroSize("qpp::cor()");
240  if (static_cast<idx>(probXY.rows()) != X.size() ||
241  static_cast<idx>(probXY.cols()) != Y.size())
242  throw exception::SizeMismatch("qpp::cor()");
243  // END EXCEPTION CHECKS
244 
245  return cov(probXY, X, Y) / (sigma(marginalX(probXY), X) *
246  sigma(marginalY(probXY), Y));
247 }
248 
249 } /* namespace qpp */
250 
251 #endif /* STATISTICS_H_ */
252 
bool check_nonzero_size(const T &x) noexcept
Definition: util.h:129
std::vector< double > uniform(idx N)
Uniform probability distribution vector.
Definition: statistics.h:38
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:65
Quantum++ main namespace.
Definition: codes.h:30
double sigma(const std::vector< double > &prob, const Container &X, typename std::enable_if< is_iterable< Container >::value >::type *=nullptr)
Standard deviation.
Definition: statistics.h:204
Checks whether T is compatible with an STL-like iterable container.
Definition: traits.h:63
bool check_matching_sizes(const T1 &lhs, const T2 &rhs) noexcept
Definition: util.h:136
double var(const std::vector< double > &prob, const Container &X, typename std::enable_if< is_iterable< Container >::value >::type *=nullptr)
Variance.
Definition: statistics.h:175
std::vector< double > marginalY(const dmat &probXY)
Marginal distribution.
Definition: statistics.h:85
Size mismatch exception.
Definition: exception.h:602
std::size_t idx
Non-negative integer index.
Definition: types.h:35
double cor(const dmat &probXY, const Container &X, const Container &Y, typename std::enable_if< is_iterable< Container >::value >::type *=nullptr)
Correlation.
Definition: statistics.h:230
double cov(const dmat &probXY, const Container &X, const Container &Y, typename std::enable_if< is_iterable< Container >::value >::type *=nullptr)
Covariance.
Definition: statistics.h:136
double avg(const std::vector< double > &prob, const Container &X, typename std::enable_if< is_iterable< Container >::value >::type *=nullptr)
Average.
Definition: statistics.h:106
Object has zero size exception.
Definition: exception.h:134