1 #ifndef HOPS_HITANDRUNPROPOSAL_HPP
2 #define HOPS_HITANDRUNPROPOSAL_HPP
5 #include "../IsSetStepSizeAvailable.hpp"
6 #include "../../RandomNumberGenerator/RandomNumberGenerator.hpp"
10 template<
typename MatrixType,
typename VectorType,
typename ChordStepDistribution = UniformStepDistribution<
typename MatrixType::Scalar>,
bool Precise = false>
27 void setStepSize(
typename MatrixType::Scalar stepSize);
30 return chordStepDistribution.computeInverseNormalizationConstant(0, backwardDistance, forwardDistance)
31 - chordStepDistribution.computeInverseNormalizationConstant(0, backwardDistance - step,
32 forwardDistance - step);
35 [[nodiscard]]
typename MatrixType::Scalar
getStepSize()
const;
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;
59 template<
typename MatrixType,
typename VectorType,
typename ChordStepDistribution,
bool Precise>
66 state(std::move(currentState_)) {
67 slacks = this->b - this->A * this->
state;
68 updateDirection =
state;
71 template<
typename MatrixType,
typename VectorType,
typename ChordStepDistribution,
bool Precise>
74 for (
long i = 0; i < updateDirection.rows(); ++i) {
75 updateDirection(i) = normalDistribution(randomNumberGenerator);
77 updateDirection.normalize();
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());
85 step = chordStepDistribution.draw(randomNumberGenerator, backwardDistance, forwardDistance);
86 m_proposal = state + updateDirection * step;
89 template<
typename MatrixType,
typename VectorType,
typename ChordStepDistribution,
bool 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.");
98 slacks.noalias() -= A * updateDirection * step;
102 template<
typename MatrixType,
typename VectorType,
typename ChordStepDistribution,
bool Precise>
108 template<
typename MatrixType,
typename VectorType,
typename ChordStepDistribution,
bool Precise>
114 template<
typename MatrixType,
typename VectorType,
typename ChordStepDistribution,
bool Precise>
120 template<
typename MatrixType,
typename VectorType,
typename ChordStepDistribution,
bool Precise>
122 typename MatrixType::Scalar stepSize) {
124 chordStepDistribution.setStepSize(stepSize);
127 throw std::runtime_error(
"Step size not available.");
131 template<
typename MatrixType,
typename VectorType,
typename ChordStepDistribution,
bool Precise>
132 typename MatrixType::Scalar
135 return chordStepDistribution.getStepSize();
137 throw std::runtime_error(
"Step size not available.");
140 template<
typename MatrixType,
typename VectorType,
typename ChordStepDistribution,
bool Precise>
142 return "Hit-and-Run";
146 #endif //HOPS_HITANDRUNPROPOSAL_HPP