XACC
dwave_rbm_mcmc_expectations.hpp
1 /*******************************************************************************
2  * Copyright (c) 2019 UT-Battelle, LLC.
3  * All rights reserved. This program and the accompanying materials
4  * are made available under the terms of the Eclipse Public License v1.0
5  * and Eclipse Distribution License v1.0 which accompanies this
6  * distribution. The Eclipse Public License is available at
7  * http://www.eclipse.org/legal/epl-v10.html and the Eclipse Distribution
8  *License is available at https://eclipse.org/org/documents/edl-v10.php
9  *
10  * Contributors:
11  * Alexander J. McCaskey - initial API and implementation
12  *******************************************************************************/
13 #ifndef XACC_ALGORITHM_RBM_CLASSIFICATION_DWAVE_MCMCEXP_HPP_
14 #define XACC_ALGORITHM_RBM_CLASSIFICATION_DWAVE_MCMCEXP_HPP_
15 
16 #include "rbm_classification.hpp"
17 
18 namespace xacc {
19 namespace algorithm {
20 
22 protected:
23  // def sample_arr(probs, a=-1, b=1):
24  // rand_sample = np.random.random(probs.shape)
25  // A = np.ones(probs.shape)*b
26  // A[rand_sample > probs] = a
27  // return A
28 
29  Eigen::VectorXi sampleArray(Eigen::VectorXd &probs) {
30 
31  Eigen::VectorXd random = Eigen::VectorXd::Random(probs.size());
32  Eigen::VectorXi A = Eigen::VectorXi::Ones(probs.size());
33 
34  for (int i = 0; i < probs.size(); i++) {
35  A(i) = random(i) > probs(i) ? -1 : A(i);
36  }
37 
38  return A;
39  }
40 
41  Eigen::VectorXi sampleHGivenV(Eigen::VectorXi &v, Eigen::VectorXd &b,
42  Eigen::MatrixXd &w) {
43  Eigen::VectorXd tmp = 2 * (b + w * v.cast<double>());
44  for (int i = 0; i < tmp.size(); i++) {
45  tmp(i) = 1. / (1. + std::exp(-tmp(i)));
46  }
47  Eigen::VectorXd h_probs = tmp;
48  return sampleArray(h_probs);
49  }
50  Eigen::VectorXi sampleVGivenH(Eigen::VectorXi &h, Eigen::VectorXd &a,
51  Eigen::MatrixXd &w) {
52  Eigen::VectorXd tmp = 2 * (a + w * h.cast<double>());
53  for (int i = 0; i < tmp.size(); i++) {
54  tmp(i) = 1. / (1. + std::exp(-tmp(i)));
55  }
56  Eigen::VectorXd v_probs = tmp;
57  return sampleArray(v_probs);
58  }
59 
60 public:
61  const std::string name() const override { return "dwave-mcmc"; }
62  const std::string description() const override { return ""; }
63 
64  std::tuple<Eigen::MatrixXd, Eigen::VectorXd, Eigen::VectorXd>
65  compute(Eigen::MatrixXd &features, Eigen::MatrixXd &w, Eigen::VectorXd &v,
66  Eigen::VectorXd &h, HeterogeneousMap options = {}) override {
67 
68  int nSamples = options.keyExists<int>("n-samples")
69  ? options.get<int>("n-samples")
70  : 10;
71 
72  Eigen::VectorXi curr_v = Eigen::VectorXi::Ones(v.size());
73  Eigen::VectorXd tmp = Eigen::VectorXd::Random(v.size());
74  for (int i = 0; i < tmp.size(); i++) {
75  curr_v(i) = tmp(i) > .5 ? curr_v(i) : -1;
76  }
77  std::vector<Eigen::VectorXi> vs, hs;
78  for (int i = 0; i < nSamples; i++) {
79  vs.push_back(curr_v);
80  Eigen::VectorXi curr_h = sampleHGivenV(curr_v, h, w);
81  hs.push_back(curr_h);
82  curr_v = sampleVGivenH(curr_h, v, w);
83  }
84 
85  Eigen::MatrixXi visibles = Eigen::MatrixXi::Zero(nSamples, v.size());
86  for (int i = 0; i < nSamples; i++) {
87  visibles.row(i) = vs[i];
88  }
89  Eigen::MatrixXi hidden = Eigen::MatrixXi::Zero(nSamples, h.size());
90  for (int i = 0; i < nSamples; i++) {
91  hidden.row(i) = hs[i];
92  }
93 
94  // sum v
95  Eigen::VectorXd sum_v = Eigen::VectorXd::Zero(v.size());
96  for (int i = 0; i < v.size(); i++) {
97  sum_v(i) = visibles.col(i).sum();
98  }
99 
100  // sum h
101  Eigen::VectorXd sum_h = Eigen::VectorXd::Zero(h.size());
102  for (int i = 0; i < h.size(); i++) {
103  sum_h(i) = hidden.col(i).sum();
104  }
105 
106  // sum v * h
107  Eigen::MatrixXd sum_vh = (visibles.transpose() * hidden).cast<double>();
108 
109  // exp w = sumvh / nsamples
110  Eigen::MatrixXd expW = sum_vh / nSamples;
111  Eigen::VectorXd expv = sum_v / nSamples;
112  Eigen::VectorXd exph = sum_h / nSamples;
113  // exp v = sumv / nsamples
114  // exp h = sumh / nsamples
115 
116  return std::make_tuple(expW, expv, exph);
117  }
118 };
119 } // namespace algorithm
120 } // namespace xacc
121 #endif
const std::string description() const override
Definition: dwave_rbm_mcmc_expectations.hpp:62
const std::string name() const override
Definition: dwave_rbm_mcmc_expectations.hpp:61
Definition: dwave_rbm_mcmc_expectations.hpp:21
Definition: Accelerator.hpp:25
Definition: rbm_classification.hpp:24
Definition: heterogeneous.hpp:45