1 #ifndef HOPS_DIKINPROPOSAL_HPP
2 #define HOPS_DIKINPROPOSAL_HPP
6 #include "../../RandomNumberGenerator/RandomNumberGenerator.hpp"
10 template<
typename MatrixType,
typename VectorType>
37 void setStepSize(
typename MatrixType::Scalar newStepSize);
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;
52 typename MatrixType::Scalar stepSize = 0.075;
53 typename MatrixType::Scalar geometricFactor;
54 typename MatrixType::Scalar covarianceFactor;
55 constexpr
static typename MatrixType::Scalar boundaryCushion = 0;
57 std::normal_distribution<typename MatrixType::Scalar> normalDistribution{0., 1.};
61 template<
typename MatrixType,
typename VectorType>
67 dikinEllipsoidCalculator(this->A, this->b) {
73 template<
typename MatrixType,
typename VectorType>
75 for (
long i = 0; i < m_proposal.rows(); ++i) {
76 m_proposal(i) = normalDistribution(randomNumberGenerator);
78 m_proposal = state + covarianceFactor *
79 stateCholeskyOfDikinEllipsoid.template triangularView<Eigen::Lower>().solve(m_proposal);
82 template<
typename MatrixType,
typename VectorType>
84 state.swap(m_proposal);
85 stateCholeskyOfDikinEllipsoid = std::move(proposalCholeskyOfDikinEllipsoid);
86 stateLogSqrtDeterminant = proposalLogSqrtDeterminant;
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();
97 auto choleskyResult = dikinEllipsoidCalculator.computeCholeskyFactorOfDikinEllipsoid(m_proposal);
98 if (!choleskyResult.first) {
99 return -std::numeric_limits<typename MatrixType::Scalar>::infinity();
101 proposalCholeskyOfDikinEllipsoid = std::move(choleskyResult.second);
103 proposalLogSqrtDeterminant = proposalCholeskyOfDikinEllipsoid.diagonal().array().log().sum();
104 VectorType stateDifference = state - m_proposal;
106 return proposalLogSqrtDeterminant
107 - stateLogSqrtDeterminant
108 + geometricFactor * ((stateCholeskyOfDikinEllipsoid * stateDifference).squaredNorm()
109 - (proposalCholeskyOfDikinEllipsoid * stateDifference).squaredNorm()
113 template<
typename MatrixType,
typename VectorType>
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.");
126 stateCholeskyOfDikinEllipsoid = std::move(choleskyResult.second);
127 stateLogSqrtDeterminant = stateCholeskyOfDikinEllipsoid.diagonal().array().log().sum();
130 template<
typename MatrixType,
typename VectorType>
136 template<
typename MatrixType,
typename VectorType>
141 template<
typename MatrixType,
typename VectorType>
143 stepSize = newStepSize;
144 geometricFactor = A.cols() / (2 * stepSize);
145 covarianceFactor = std::sqrt(stepSize / A.cols());
148 template<
typename MatrixType,
typename VectorType>
154 #endif //HOPS_DIKINPROPOSAL_HPP