hops
HitAndRunProposal.hpp
Go to the documentation of this file.
1 #ifndef HOPS_HITANDRUNPROPOSAL_HPP
2 #define HOPS_HITANDRUNPROPOSAL_HPP
3 
5 #include "../IsSetStepSizeAvailable.hpp"
6 #include "../../RandomNumberGenerator/RandomNumberGenerator.hpp"
7 #include <random>
8 
9 namespace hops {
10  template<typename MatrixType, typename VectorType, typename ChordStepDistribution = UniformStepDistribution<typename MatrixType::Scalar>, bool Precise = false>
12  public:
14 
16 
17  void propose(RandomNumberGenerator &randomNumberGenerator);
18 
19  void acceptProposal();
20 
21  StateType getState() const;
22 
23  StateType getProposal() const;
24 
25  void setState(StateType newState);
26 
27  void setStepSize(typename MatrixType::Scalar stepSize);
28 
29  [[nodiscard]] typename MatrixType::Scalar computeLogAcceptanceProbability() {
30  return chordStepDistribution.computeInverseNormalizationConstant(0, backwardDistance, forwardDistance)
31  - chordStepDistribution.computeInverseNormalizationConstant(0, backwardDistance - step,
32  forwardDistance - step);
33  }
34 
35  [[nodiscard]] typename MatrixType::Scalar getStepSize() const;
36 
38 
39 
40  protected:
41  // state and m_proposal are protected to allow RJMCMC mixins to set state and proposals
44 
45  private:
46  MatrixType A;
47  VectorType b;
48  VectorType slacks;
49  VectorType inverseDistances;
50 
51  VectorType updateDirection;
52  typename MatrixType::Scalar step = 0;
53  ChordStepDistribution chordStepDistribution;
54  std::normal_distribution<typename MatrixType::Scalar> normalDistribution;
55  typename MatrixType::Scalar forwardDistance;
56  typename MatrixType::Scalar backwardDistance;
57  };
58 
59  template<typename MatrixType, typename VectorType, typename ChordStepDistribution, bool Precise>
61  VectorType b_,
62  VectorType currentState_)
63  :
64  A(std::move(A_)),
65  b(std::move(b_)),
66  state(std::move(currentState_)) {
67  slacks = this->b - this->A * this->state;
68  updateDirection = state;
69  }
70 
71  template<typename MatrixType, typename VectorType, typename ChordStepDistribution, bool Precise>
73  RandomNumberGenerator &randomNumberGenerator) {
74  for (long i = 0; i < updateDirection.rows(); ++i) {
75  updateDirection(i) = normalDistribution(randomNumberGenerator);
76  }
77  updateDirection.normalize();
78 
79  inverseDistances = (A * updateDirection).cwiseQuotient(slacks);
80  forwardDistance = 1. / inverseDistances.maxCoeff();
81  backwardDistance = 1. / inverseDistances.minCoeff();
82  assert(backwardDistance <= 0 && forwardDistance >= 0);
83  assert(((b - A * state).array() >= 0).all());
84 
85  step = chordStepDistribution.draw(randomNumberGenerator, backwardDistance, forwardDistance);
86  m_proposal = state + updateDirection * step;
87  }
88 
89  template<typename MatrixType, typename VectorType, typename ChordStepDistribution, bool Precise>
91  state = m_proposal;
92  if (Precise) {
93  slacks = b - A * state;
94  if ((slacks.array() < 0).any()) {
95  throw std::runtime_error("Hit-and-Run sampled point outside of polytope.");
96  }
97  } else {
98  slacks.noalias() -= A * updateDirection * step;
99  }
100  }
101 
102  template<typename MatrixType, typename VectorType, typename ChordStepDistribution, bool Precise>
105  return state;
106  }
107 
108  template<typename MatrixType, typename VectorType, typename ChordStepDistribution, bool Precise>
111  return m_proposal;
112  }
113 
114  template<typename MatrixType, typename VectorType, typename ChordStepDistribution, bool Precise>
116  HitAndRunProposal::state = std::move(newState);
117  slacks = b - A * HitAndRunProposal::state;
118  }
119 
120  template<typename MatrixType, typename VectorType, typename ChordStepDistribution, bool Precise>
122  typename MatrixType::Scalar stepSize) {
124  chordStepDistribution.setStepSize(stepSize);
125  } else {
126  (void) stepSize;
127  throw std::runtime_error("Step size not available.");
128  }
129  }
130 
131  template<typename MatrixType, typename VectorType, typename ChordStepDistribution, bool Precise>
132  typename MatrixType::Scalar
135  return chordStepDistribution.getStepSize();
136  }
137  throw std::runtime_error("Step size not available.");
138  }
139 
140  template<typename MatrixType, typename VectorType, typename ChordStepDistribution, bool Precise>
142  return "Hit-and-Run";
143  }
144 }
145 
146 #endif //HOPS_HITANDRUNPROPOSAL_HPP
hops::HitAndRunProposal::getName
std::string getName()
Definition: HitAndRunProposal.hpp:141
hops::MatrixType
Eigen::MatrixXd MatrixType
Definition: MatrixType.hpp:7
hops::HitAndRunProposal::StateType
VectorType StateType
Definition: HitAndRunProposal.hpp:13
hops::HitAndRunProposal::propose
void propose(RandomNumberGenerator &randomNumberGenerator)
Definition: HitAndRunProposal.hpp:72
hops::HitAndRunProposal::state
StateType state
Definition: HitAndRunProposal.hpp:42
pcg_detail::engine
Definition: pcg_random.hpp:364
hops::HitAndRunProposal::m_proposal
StateType m_proposal
Definition: HitAndRunProposal.hpp:43
hops::HitAndRunProposal::getStepSize
MatrixType::Scalar getStepSize() const
Definition: HitAndRunProposal.hpp:133
hops::HitAndRunProposal::HitAndRunProposal
HitAndRunProposal(MatrixType A, VectorType b, VectorType currentState)
Definition: HitAndRunProposal.hpp:60
hops::HitAndRunProposal::acceptProposal
void acceptProposal()
Definition: HitAndRunProposal.hpp:90
hops::HitAndRunProposal
Definition: HitAndRunProposal.hpp:11
hops::HitAndRunProposal::getState
StateType getState() const
Definition: HitAndRunProposal.hpp:104
hops::HitAndRunProposal::setState
void setState(StateType newState)
Definition: HitAndRunProposal.hpp:115
hops
Definition: CsvReader.hpp:8
ChordStepDistributions.hpp
hops::HitAndRunProposal::setStepSize
void setStepSize(typename MatrixType::Scalar stepSize)
Definition: HitAndRunProposal.hpp:121
hops::IsSetStepSizeAvailable
Definition: IsSetStepSizeAvailable.hpp:8
string
NAME string(REPLACE ".cpp" "_bin" example_name ${example_filename}) if($
Definition: hops/Third-party/HighFive/src/examples/CMakeLists.txt:6
hops::VectorType
Eigen::VectorXd VectorType
Definition: VectorType.hpp:7
hops::HitAndRunProposal::computeLogAcceptanceProbability
MatrixType::Scalar computeLogAcceptanceProbability()
Definition: HitAndRunProposal.hpp:29
hops::HitAndRunProposal::getProposal
StateType getProposal() const
Definition: HitAndRunProposal.hpp:110