hops
DikinProposal.hpp
Go to the documentation of this file.
1 #ifndef HOPS_DIKINPROPOSAL_HPP
2 #define HOPS_DIKINPROPOSAL_HPP
3 
4 #include <Eigen/LU>
6 #include "../../RandomNumberGenerator/RandomNumberGenerator.hpp"
7 #include <random>
8 
9 namespace hops {
10  template<typename MatrixType, typename VectorType>
11  class DikinProposal {
12  public:
14 
21  DikinProposal(MatrixType A, VectorType b, VectorType currentState);
22 
23  void propose(RandomNumberGenerator &randomNumberGenerator);
24 
25  void acceptProposal();
26 
27  typename MatrixType::Scalar computeLogAcceptanceProbability();
28 
29  StateType getState() const;
30 
31  void setState(StateType newState);
32 
33  StateType getProposal() const;
34 
35  typename MatrixType::Scalar getStepSize() const;
36 
37  void setStepSize(typename MatrixType::Scalar newStepSize);
38 
40 
41  private:
42  MatrixType A;
43  VectorType b;
44 
45  StateType state;
46  StateType m_proposal;
47  typename MatrixType::Scalar stateLogSqrtDeterminant = 0;
48  typename MatrixType::Scalar proposalLogSqrtDeterminant = 0;
49  Eigen::Matrix<typename MatrixType::Scalar, Eigen::Dynamic, Eigen::Dynamic> stateCholeskyOfDikinEllipsoid;
50  Eigen::Matrix<typename MatrixType::Scalar, Eigen::Dynamic, Eigen::Dynamic> proposalCholeskyOfDikinEllipsoid;
51 
52  typename MatrixType::Scalar stepSize = 0.075; // value from dikin walk publication
53  typename MatrixType::Scalar geometricFactor;
54  typename MatrixType::Scalar covarianceFactor;
55  constexpr static typename MatrixType::Scalar boundaryCushion = 0;
56 
57  std::normal_distribution<typename MatrixType::Scalar> normalDistribution{0., 1.};
58  DikinEllipsoidCalculator<MatrixType, VectorType> dikinEllipsoidCalculator;
59  };
60 
61  template<typename MatrixType, typename VectorType>
63  VectorType b,
64  VectorType currentState) :
65  A(std::move(A)),
66  b(std::move(b)),
67  dikinEllipsoidCalculator(this->A, this->b) {
68  setStepSize(1.);
69  setState(std::move(currentState));
70  m_proposal = state;
71  }
72 
73  template<typename MatrixType, typename VectorType>
75  for (long i = 0; i < m_proposal.rows(); ++i) {
76  m_proposal(i) = normalDistribution(randomNumberGenerator);
77  }
78  m_proposal = state + covarianceFactor *
79  stateCholeskyOfDikinEllipsoid.template triangularView<Eigen::Lower>().solve(m_proposal);
80  }
81 
82  template<typename MatrixType, typename VectorType>
84  state.swap(m_proposal);
85  stateCholeskyOfDikinEllipsoid = std::move(proposalCholeskyOfDikinEllipsoid);
86  stateLogSqrtDeterminant = proposalLogSqrtDeterminant;
87  }
88 
89  template<typename MatrixType, typename VectorType>
90  typename MatrixType::Scalar
92  bool isProposalInteriorPoint = ((A * m_proposal - b).array() < -boundaryCushion).all();
93  if (!isProposalInteriorPoint) {
94  return -std::numeric_limits<typename MatrixType::Scalar>::infinity();
95  }
96 
97  auto choleskyResult = dikinEllipsoidCalculator.computeCholeskyFactorOfDikinEllipsoid(m_proposal);
98  if (!choleskyResult.first) {
99  return -std::numeric_limits<typename MatrixType::Scalar>::infinity();
100  }
101  proposalCholeskyOfDikinEllipsoid = std::move(choleskyResult.second);
102 
103  proposalLogSqrtDeterminant = proposalCholeskyOfDikinEllipsoid.diagonal().array().log().sum();
104  VectorType stateDifference = state - m_proposal;
105 
106  return proposalLogSqrtDeterminant
107  - stateLogSqrtDeterminant
108  + geometricFactor * ((stateCholeskyOfDikinEllipsoid * stateDifference).squaredNorm()
109  - (proposalCholeskyOfDikinEllipsoid * stateDifference).squaredNorm()
110  );
111  }
112 
113  template<typename MatrixType, typename VectorType>
116  return state;
117  }
118 
119  template<typename MatrixType, typename VectorType>
121  state.swap(newState);
122  auto choleskyResult = dikinEllipsoidCalculator.computeCholeskyFactorOfDikinEllipsoid(state);
123  if (!choleskyResult.first) {
124  throw std::runtime_error("Could not compute cholesky factorization for newState.");
125  }
126  stateCholeskyOfDikinEllipsoid = std::move(choleskyResult.second);
127  stateLogSqrtDeterminant = stateCholeskyOfDikinEllipsoid.diagonal().array().log().sum();
128  }
129 
130  template<typename MatrixType, typename VectorType>
133  return m_proposal;
134  }
135 
136  template<typename MatrixType, typename VectorType>
137  typename MatrixType::Scalar DikinProposal<MatrixType, VectorType>::getStepSize() const {
138  return stepSize;
139  }
140 
141  template<typename MatrixType, typename VectorType>
142  void DikinProposal<MatrixType, VectorType>::setStepSize(typename MatrixType::Scalar newStepSize) {
143  stepSize = newStepSize;
144  geometricFactor = A.cols() / (2 * stepSize);
145  covarianceFactor = std::sqrt(stepSize / A.cols());
146  }
147 
148  template<typename MatrixType, typename VectorType>
150  return "Dikin Walk";
151  }
152 }
153 
154 #endif //HOPS_DIKINPROPOSAL_HPP
hops::DikinProposal::getName
std::string getName()
Definition: DikinProposal.hpp:149
hops::MatrixType
Eigen::MatrixXd MatrixType
Definition: MatrixType.hpp:7
hops::DikinProposal::getProposal
StateType getProposal() const
Definition: DikinProposal.hpp:132
pcg_detail::engine
Definition: pcg_random.hpp:364
hops::DikinProposal::propose
void propose(RandomNumberGenerator &randomNumberGenerator)
Definition: DikinProposal.hpp:74
hops::DikinProposal::acceptProposal
void acceptProposal()
Definition: DikinProposal.hpp:83
hops::DikinProposal::setState
void setState(StateType newState)
Definition: DikinProposal.hpp:120
hops::DikinProposal::getState
StateType getState() const
Definition: DikinProposal.hpp:115
hops
Definition: CsvReader.hpp:8
hops::DikinEllipsoidCalculator
Definition: DikinEllipsoidCalculator.hpp:11
hops::DikinProposal::StateType
VectorType StateType
Definition: DikinProposal.hpp:13
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::DikinProposal::DikinProposal
DikinProposal(MatrixType A, VectorType b, VectorType currentState)
Constructs Gaussian Dikin m_proposal mechanism on polytope defined as Ax<b.
Definition: DikinProposal.hpp:62
hops::DikinProposal::setStepSize
void setStepSize(typename MatrixType::Scalar newStepSize)
Definition: DikinProposal.hpp:142
DikinEllipsoidCalculator.hpp
hops::DikinProposal::getStepSize
MatrixType::Scalar getStepSize() const
Definition: DikinProposal.hpp:137
hops::DikinProposal
Definition: DikinProposal.hpp:11
hops::DikinProposal::computeLogAcceptanceProbability
MatrixType::Scalar computeLogAcceptanceProbability()
Definition: DikinProposal.hpp:91