hops
CoordinateHitAndRunProposal.hpp
Go to the documentation of this file.
1 #ifndef HOPS_COORDINATEHITANDRUNPROPOSAL_HPP
2 #define HOPS_COORDINATEHITANDRUNPROPOSAL_HPP
3 
5 #include "../IsSetStepSizeAvailable.hpp"
6 #include "../../RandomNumberGenerator/RandomNumberGenerator.hpp"
7 #include <random>
8 #include "../../FileWriter/CsvWriter.hpp"
9 
10 namespace hops {
11  template<typename MatrixType, typename VectorType, typename ChordStepDistribution = UniformStepDistribution<typename MatrixType::Scalar>>
13  public:
15 
23 
24  void propose(RandomNumberGenerator &randomNumberGenerator);
25 
26  void acceptProposal();
27 
28  StateType getState() const;
29 
30  StateType getProposal() const;
31 
32  void setState(StateType newState);
33 
34  void setStepSize(typename MatrixType::Scalar stepSize);
35 
36  typename MatrixType::Scalar getStepSize() const;
37 
38  [[nodiscard]] typename MatrixType::Scalar computeLogAcceptanceProbability() {
39  return chordStepDistribution.computeInverseNormalizationConstant(0, backwardDistance, forwardDistance)
40  - chordStepDistribution.computeInverseNormalizationConstant(0, backwardDistance - step,
41  forwardDistance - step);
42  }
43 
45 
46  private:
47  MatrixType A;
48  VectorType b;
49  StateType state;
50  VectorType slacks;
51  VectorType inverseDistances;
52 
53  long coordinateToUpdate = 0;
54  typename MatrixType::Scalar step = 0;
55  ChordStepDistribution chordStepDistribution;
56  typename MatrixType::Scalar forwardDistance;
57  typename MatrixType::Scalar backwardDistance;
58  };
59 
60  template<typename MatrixType, typename VectorType, typename ChordStepDistribution>
62  MatrixType A_,
63  VectorType b_,
64  VectorType currentState_) :
65  A(std::move(A_)),
66  b(std::move(b_)),
67  state(std::move(currentState_)) {
68  slacks = this->b - this->A * this->state;
69  }
70 
71  template<typename MatrixType, typename VectorType, typename ChordStepDistribution>
73  RandomNumberGenerator &randomNumberGenerator) {
74  ++coordinateToUpdate %= state.rows();
75 
76  inverseDistances = A.col(coordinateToUpdate).cwiseQuotient(slacks);
77  forwardDistance = 1. / inverseDistances.maxCoeff();
78  backwardDistance = 1. / inverseDistances.minCoeff();
79  assert(backwardDistance < 0 && forwardDistance > 0);
80  assert(((b - A * state).array() > 0).all());
81 
82  step = chordStepDistribution.draw(randomNumberGenerator, backwardDistance, forwardDistance);
83  }
84 
85  template<typename MatrixType, typename VectorType, typename ChordStepDistribution>
86  void
88  state(coordinateToUpdate) += step;
89  slacks.noalias() -= A.col(coordinateToUpdate) * step;
90  step = 0;
91  }
92 
93  template<typename MatrixType, typename VectorType, typename ChordStepDistribution>
96  return state;
97  }
98 
99  template<typename MatrixType, typename VectorType, typename ChordStepDistribution>
102  StateType m_proposal = state;
103  m_proposal(coordinateToUpdate) += step;
104  return m_proposal;
105  }
106 
107  template<typename MatrixType, typename VectorType, typename ChordStepDistribution>
109  CoordinateHitAndRunProposal::state = std::move(newState);
110  slacks = b - A * CoordinateHitAndRunProposal::state;
111  }
112 
113  template<typename MatrixType, typename VectorType, typename ChordStepDistribution>
115  typename MatrixType::Scalar stepSize) {
117  chordStepDistribution.setStepSize(stepSize);
118  } else {
119  (void)stepSize;
120  throw std::runtime_error("Step size not available.");
121  }
122  }
123 
124  template<typename MatrixType, typename VectorType, typename ChordStepDistribution>
125  typename MatrixType::Scalar
128  return chordStepDistribution.getStepSize();
129  }
130  throw std::runtime_error("Step size not available.");
131  }
132 
133  template<typename MatrixType, typename VectorType, typename ChordStepDistribution>
135  return "Coordinate Hit-and-Run";
136  }
137 }
138 
139 #endif //HOPS_COORDINATEHITANDRUNPROPOSAL_HPP
hops::CoordinateHitAndRunProposal::CoordinateHitAndRunProposal
CoordinateHitAndRunProposal(MatrixType A, VectorType b, VectorType currentState)
Constructs Coordinate Hit and Run m_proposal mechanism on polytope defined as Ax<b.
Definition: CoordinateHitAndRunProposal.hpp:61
hops::CoordinateHitAndRunProposal::acceptProposal
void acceptProposal()
Definition: CoordinateHitAndRunProposal.hpp:87
hops::MatrixType
Eigen::MatrixXd MatrixType
Definition: MatrixType.hpp:7
hops::CoordinateHitAndRunProposal
Definition: CoordinateHitAndRunProposal.hpp:12
pcg_detail::engine
Definition: pcg_random.hpp:364
hops::CoordinateHitAndRunProposal::getState
StateType getState() const
Definition: CoordinateHitAndRunProposal.hpp:95
hops::CoordinateHitAndRunProposal::setStepSize
void setStepSize(typename MatrixType::Scalar stepSize)
Definition: CoordinateHitAndRunProposal.hpp:114
hops::CoordinateHitAndRunProposal::StateType
VectorType StateType
Definition: CoordinateHitAndRunProposal.hpp:14
hops::CoordinateHitAndRunProposal::computeLogAcceptanceProbability
MatrixType::Scalar computeLogAcceptanceProbability()
Definition: CoordinateHitAndRunProposal.hpp:38
hops::CoordinateHitAndRunProposal::propose
void propose(RandomNumberGenerator &randomNumberGenerator)
Definition: CoordinateHitAndRunProposal.hpp:72
hops::CoordinateHitAndRunProposal::setState
void setState(StateType newState)
Definition: CoordinateHitAndRunProposal.hpp:108
hops
Definition: CsvReader.hpp:8
ChordStepDistributions.hpp
hops::IsSetStepSizeAvailable
Definition: IsSetStepSizeAvailable.hpp:8
hops::CoordinateHitAndRunProposal::getStepSize
MatrixType::Scalar getStepSize() const
Definition: CoordinateHitAndRunProposal.hpp:126
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::CoordinateHitAndRunProposal::getName
std::string getName()
Definition: CoordinateHitAndRunProposal.hpp:134
hops::CoordinateHitAndRunProposal::getProposal
StateType getProposal() const
Definition: CoordinateHitAndRunProposal.hpp:101