1 #ifndef HOPS_ADAPTIVEMETROPOLISPROPOSAL_HPP
2 #define HOPS_ADAPTIVEMETROPOLISPROPOSAL_HPP
4 #include "../IsSetStepSizeAvailable.hpp"
5 #include "../../RandomNumberGenerator/RandomNumberGenerator.hpp"
6 #include "../../FileWriter/CsvWriter.hpp"
7 #include "../../Polytope/MaximumVolumeEllipsoid.hpp"
11 template<
typename MatrixType,
typename VectorType>
30 typename MatrixType::Scalar stepSize = 1,
31 typename MatrixType::Scalar eps = 1.e-3,
32 unsigned long warmUp = 100);
44 void setStepSize(
typename MatrixType::Scalar stepSize);
68 typename MatrixType::Scalar stateLogSqrtDeterminant;
69 typename MatrixType::Scalar proposalLogSqrtDeterminant;
74 typename MatrixType::Scalar eps;
75 typename MatrixType::Scalar stepSize;
76 constexpr
static typename MatrixType::Scalar boundaryCushion = 1e-10;
78 std::normal_distribution<typename MatrixType::Scalar> normal;
81 assert(t > 0 &&
"cannot update covariance without samples having been drawn");
84 StateType newMean = (t * mean + newState) / (t + 1);
85 MatrixType newCovariance = ((t - 1) * covariance
86 + t * (mean * mean.transpose())
87 - (t + 1) * (newMean * newMean.transpose())
88 + newState * newState.transpose()
89 + eps * maximumVolumeEllipsoid) / t;
94 template<
typename MatrixType,
typename VectorType>
98 typename MatrixType::Scalar stepSize_,
99 typename MatrixType::Scalar eps_,
100 unsigned long warmUp_) :
103 state(std::move(currentState_)),
104 m_proposal(this->state),
107 stepSize(stepSize_) {
108 normal = std::normal_distribution<typename MatrixType::Scalar>(0, stepSize);
111 eps = eps_ / A.cols();
116 Eigen::LLT<Eigen::Matrix<typename MatrixType::Scalar, Eigen::Dynamic, Eigen::Dynamic>> solverMaximumVolumeEllipsoid(maximumVolumeEllipsoid);
117 choleskyOfMaximumVolumeEllipsoid = solverMaximumVolumeEllipsoid.matrixL();
119 stateCovariance = maximumVolumeEllipsoid;
120 Eigen::LLT<Eigen::Matrix<typename MatrixType::Scalar, Eigen::Dynamic, Eigen::Dynamic>> solverStateCovariance(stateCovariance);
121 stateCholeskyOfCovariance = solverStateCovariance.matrixL();
123 stateLogSqrtDeterminant = stateCholeskyOfCovariance.diagonal().array().log().sum();
126 template<
typename MatrixType,
typename VectorType>
129 stateMean = (t * stateMean + state) / (t + 1);
131 for (
long i = 0; i < m_proposal.rows(); ++i) {
132 m_proposal(i) = normal(randomNumberGenerator);
136 m_proposal = state + stateCholeskyOfCovariance * m_proposal;
138 m_proposal = state + eps * choleskyOfMaximumVolumeEllipsoid.template triangularView<Eigen::Lower>().solve(m_proposal);
144 template<
typename MatrixType,
typename VectorType>
147 state.swap(m_proposal);
148 stateCovariance = proposalCovariance;
149 stateCholeskyOfCovariance = proposalCholeskyOfCovariance;
150 stateLogSqrtDeterminant = proposalLogSqrtDeterminant;
153 template<
typename MatrixType,
typename VectorType>
154 typename MatrixType::Scalar
156 bool isProposalInteriorPoint = ((A * m_proposal - b).array() < -boundaryCushion).all();
157 if (!isProposalInteriorPoint) {
158 return -std::numeric_limits<typename MatrixType::Scalar>::infinity();
161 proposalCovariance = updateCovariance(stateCovariance, stateMean, m_proposal);
162 Eigen::LLT<Eigen::Matrix<typename MatrixType::Scalar, Eigen::Dynamic, Eigen::Dynamic>> solver(proposalCovariance);
163 if (solver.info() != Eigen::Success) {
164 return -std::numeric_limits<typename MatrixType::Scalar>::infinity();
166 proposalCholeskyOfCovariance = solver.matrixL();
168 proposalLogSqrtDeterminant = proposalCholeskyOfCovariance.diagonal().array().log().sum();
169 StateType stateDifference = m_proposal - state;
175 alpha = stateLogSqrtDeterminant
176 - proposalLogSqrtDeterminant
178 proposalCholeskyOfCovariance.template triangularView<Eigen::Lower>().solve(stateDifference).squaredNorm()
179 - stateCholeskyOfCovariance.template triangularView<Eigen::Lower>().solve(stateDifference).squaredNorm()
186 template<
typename MatrixType,
typename VectorType>
192 template<
typename MatrixType,
typename VectorType>
198 template<
typename MatrixType,
typename VectorType>
200 AdaptiveMetropolisProposal::state = std::move(newState);
203 template<
typename MatrixType,
typename VectorType>
205 typename MatrixType::Scalar newStepSize) {
206 stepSize = newStepSize;
207 normal = std::normal_distribution<typename MatrixType::Scalar>(0, stepSize);
210 template<
typename MatrixType,
typename VectorType>
211 typename MatrixType::Scalar
216 template<
typename MatrixType,
typename VectorType>
218 return "AdaptiveMetropolis";
222 #endif //HOPS_ADAPTIVEMETROPOLISPROPOSAL_HPP