XACC
statistics.h
Go to the documentation of this file.
1 /*
2  * This file is part of Quantum++.
3  *
4  * MIT License
5  *
6  * Copyright (c) 2013 - 2020 Vlad Gheorghiu.
7  *
8  * Permission is hereby granted, free of charge, to any person obtaining a copy
9  * of this software and associated documentation files (the "Software"), to deal
10  * in the Software without restriction, including without limitation the rights
11  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
12  * copies of the Software, and to permit persons to whom the Software is
13  * furnished to do so, subject to the following conditions:
14  *
15  * The above copyright notice and this permission notice shall be included in
16  * all copies or substantial portions of the Software.
17  *
18  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
21  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
24  * SOFTWARE.
25  */
26 
32 #ifndef STATISTICS_H_
33 #define STATISTICS_H_
34 
35 namespace qpp {
42 inline std::vector<double> uniform(idx N) {
43  // EXCEPTION CHECKS
44 
45  if (N == 0)
46  throw exception::ZeroSize("qpp::uniform()");
47  // END EXCEPTION CHECKS
48 
49  return std::vector<double>(N, 1. / N);
50 }
51 
60 inline std::vector<double> marginalX(const dmat& probXY) {
61  // EXCEPTION CHECKS
62 
63  if (!internal::check_nonzero_size(probXY))
64  throw exception::ZeroSize("qpp::marginalX()");
65  // END EXCEPTION CHECKS
66 
67  std::vector<double> result(probXY.rows(), 0);
68  for (idx i = 0; i < static_cast<idx>(probXY.rows()); ++i) {
69  for (idx j = 0; j < static_cast<idx>(probXY.cols()); ++j) {
70  result[i] += probXY(i, j);
71  }
72  }
73 
74  return result;
75 }
76 
85 inline std::vector<double> marginalY(const dmat& probXY) {
86  // EXCEPTION CHECKS
87 
88  if (!internal::check_nonzero_size(probXY))
89  throw exception::ZeroSize("qpp::marginalY()");
90  // END EXCEPTION CHECKS
91 
92  return marginalX(probXY.transpose());
93 }
94 
104 template <typename Container>
105 double
106 avg(const std::vector<double>& prob, const Container& X,
107  typename std::enable_if<is_iterable<Container>::value>::type* = nullptr) {
108  // EXCEPTION CHECKS
109 
110  if (!internal::check_nonzero_size(prob))
111  throw exception::ZeroSize("qpp::avg()");
112  if (!internal::check_matching_sizes(prob, X))
113  throw exception::SizeMismatch("qpp::avg()");
114  // END EXCEPTION CHECKS
115 
116  double result = 0;
117  for (idx i = 0; i < prob.size(); ++i)
118  result += prob[i] * X[i];
119 
120  return result;
121 }
122 
133 template <typename Container>
134 double
135 cov(const dmat& probXY, const Container& X, const Container& Y,
136  typename std::enable_if<is_iterable<Container>::value>::type* = nullptr) {
137  // EXCEPTION CHECKS
138 
139  if (!internal::check_nonzero_size(X) || !internal::check_nonzero_size(Y))
140  throw exception::ZeroSize("qpp::cov()");
141  if (static_cast<idx>(probXY.rows()) != X.size() ||
142  static_cast<idx>(probXY.cols()) != Y.size())
143  throw exception::SizeMismatch("qpp::cov()");
144  // END EXCEPTION CHECKS
145 
146  std::vector<double> probX = marginalX(probXY); // marginals
147  std::vector<double> probY = marginalY(probXY); // marginals
148 
149  double result = 0;
150  for (idx i = 0; i < X.size(); ++i) {
151  for (idx j = 0; j < Y.size(); ++j) {
152  result += probXY(i, j) * X[i] * Y[j];
153  }
154  }
155 
156  return result - avg(probX, X) * avg(probY, Y);
157 }
158 
167 template <typename Container>
168 double
169 var(const std::vector<double>& prob, const Container& X,
170  typename std::enable_if<is_iterable<Container>::value>::type* = nullptr) {
171  // EXCEPTION CHECKS
172 
173  if (!internal::check_nonzero_size(prob))
174  throw exception::ZeroSize("qpp::var()");
175  if (!internal::check_matching_sizes(prob, X))
176  throw exception::SizeMismatch("qpp::var()");
177  // END EXCEPTION CHECKS
178 
179  Eigen::VectorXd diag(prob.size());
180  for (idx i = 0; i < prob.size(); ++i)
181  diag(i) = prob[i];
182  dmat probXX = diag.asDiagonal();
183 
184  return cov(probXX, X, X);
185 }
186 
195 template <typename Container>
196 double
197 sigma(const std::vector<double>& prob, const Container& X,
198  typename std::enable_if<is_iterable<Container>::value>::type* = nullptr) {
199  // EXCEPTION CHECKS
200 
201  if (!internal::check_nonzero_size(prob))
202  throw exception::ZeroSize("qpp::sigma()");
203  if (!internal::check_matching_sizes(prob, X))
204  throw exception::SizeMismatch("qpp::sigma()");
205  // END EXCEPTION CHECKS
206 
207  return std::sqrt(var(prob, X));
208 }
209 
220 template <typename Container>
221 double
222 cor(const dmat& probXY, const Container& X, const Container& Y,
223  typename std::enable_if<is_iterable<Container>::value>::type* = nullptr) {
224  // EXCEPTION CHECKS
225 
226  if (!internal::check_nonzero_size(X) || !internal::check_nonzero_size(Y))
227  throw exception::ZeroSize("qpp::cor()");
228  if (static_cast<idx>(probXY.rows()) != X.size() ||
229  static_cast<idx>(probXY.cols()) != Y.size())
230  throw exception::SizeMismatch("qpp::cor()");
231  // END EXCEPTION CHECKS
232 
233  return cov(probXY, X, Y) /
234  (sigma(marginalX(probXY), X) * sigma(marginalY(probXY), Y));
235 }
236 
237 } /* namespace qpp */
238 
239 #endif /* STATISTICS_H_ */
Quantum++ main namespace.
Definition: circuits.h:35