14 namespace pt = boost::property_tree;
21 InverseGammaProposal::InverseGammaProposal(pt::ptree pt,
22 std::shared_ptr<AbstractSamplingProblem> prob) :
MCMCProposal(pt,prob),
23 alpha(ExtractAlpha(prob,pt.
get<std::string>(
"InverseGammaNode"))),
24 beta(ExtractBeta(prob,pt.
get<std::string>(
"InverseGammaNode"))),
25 gaussInfo(ExtractGaussInfo(prob,pt.
get<std::string>(
"GaussianNode"))),
26 varModel(ExtractVarianceModel(prob,pt.
get<std::string>(
"GaussianNode"),pt.
get<std::string>(
"InverseGammaNode"))),
27 gaussMean(ExtractMean(prob,pt.
get<std::string>(
"GaussianNode")))
32 Eigen::VectorXd InverseGammaProposal::GetGaussianInput(std::shared_ptr<SamplingState>
const& currentState)
const
37 inputs.push_back(std::cref(currentState->state.at(ind)));
48 std::vector<Eigen::VectorXd> props = currentState->state;
51 Eigen::VectorXd varOnes = Eigen::VectorXd::Ones(
varModel->outputSizes(0));
52 Eigen::VectorXd varZeros = Eigen::VectorXd::Zero(
varModel->inputSizes(0));
54 Eigen::VectorXd newAlpha =
alpha + 0.5*
varModel->Gradient(0,0,varZeros,varOnes);
55 Eigen::VectorXd newBeta =
beta + 0.5*
varModel->Gradient(0,0,varZeros, (gaussState -
gaussMean).array().pow(2).matrix().eval());
60 return std::make_shared<SamplingState>(props, 1.0);
64 std::shared_ptr<SamplingState>
const& propState) {
66 Eigen::VectorXd
const& sigmaState = propState->state.at(
blockInd);
68 Eigen::VectorXd varOnes = Eigen::VectorXd::Ones(
varModel->outputSizes(0));
69 Eigen::VectorXd varZeros = Eigen::VectorXd::Zero(
varModel->inputSizes(0));
71 Eigen::VectorXd newAlpha =
alpha + 0.5*
varModel->Gradient(0,0,varZeros,varOnes);
73 Eigen::VectorXd newBeta =
beta + 0.5*
varModel->Gradient(0,0,varZeros, (gaussState -
gaussMean).array().pow(2).matrix().eval());
79 std::string
const& gaussNode)
82 std::shared_ptr<SamplingProblem> prob2 = std::dynamic_pointer_cast<SamplingProblem>(
prob);
84 throw std::runtime_error(
"Could not downcast AbstractSamplingProblem to SamplingProblem.");
88 std::shared_ptr<ModPiece> targetDens = prob2->GetDistribution();
89 std::shared_ptr<ModGraphPiece> targetDens2 = std::dynamic_pointer_cast<ModGraphPiece>(targetDens);
90 if(targetDens2==
nullptr){
91 throw std::runtime_error(
"Could not downcast target density to ModGraphPiece.");
95 auto graph = targetDens2->GetGraph();
98 auto gaussPiece = graph->GetPiece(gaussNode);
99 if(gaussPiece==
nullptr){
100 throw std::runtime_error(
"Could not find " + gaussNode +
" node.");
104 auto dens = std::dynamic_pointer_cast<Density>(gaussPiece);
106 throw std::runtime_error(
"Could not convert specified Gausssian ModPiece to Density.");
109 auto gaussDist = std::dynamic_pointer_cast<Gaussian>(dens->GetDistribution());
110 if(gaussDist==
nullptr){
111 throw std::runtime_error(
"Could not cast Gausssian ModPiece to Gaussian.");
114 return gaussDist->GetMean();
120 std::shared_ptr<SamplingProblem> prob2 = std::dynamic_pointer_cast<SamplingProblem>(
prob);
122 throw std::runtime_error(
"Could not downcast AbstractSamplingProblem to SamplingProblem.");
126 std::shared_ptr<ModPiece> targetDens = prob2->GetDistribution();
127 std::shared_ptr<ModGraphPiece> targetDens2 = std::dynamic_pointer_cast<ModGraphPiece>(targetDens);
128 if(targetDens2==
nullptr){
129 throw std::runtime_error(
"Could not downcast target density to ModGraphPiece.");
133 auto graph = targetDens2->GetGraph();
136 auto piece = graph->GetPiece(igNode);
138 throw std::runtime_error(
"Could not find " + igNode +
" node.");
142 auto dens = std::dynamic_pointer_cast<Density>(piece);
144 throw std::runtime_error(
"Could not convert specified InverseGamma ModPiece to Density.");
147 auto dist = std::dynamic_pointer_cast<InverseGamma>(dens->GetDistribution());
149 throw std::runtime_error(
"Could not convert specified InverseGamma ModPiece to InverseGamma distribution.");
169 std::shared_ptr<SamplingProblem> prob2 = std::dynamic_pointer_cast<SamplingProblem>(
prob);
171 throw std::runtime_error(
"Could not downcast AbstractSamplingProblem to SamplingProblem.");
175 std::shared_ptr<ModPiece> targetDens = prob2->GetDistribution();
176 std::shared_ptr<ModGraphPiece> targetDens2 = std::dynamic_pointer_cast<ModGraphPiece>(targetDens);
177 if(targetDens2==
nullptr){
178 throw std::runtime_error(
"Could not downcast target density to ModGraphPiece.");
182 auto graph = targetDens2->GetGraph();
185 std::string inputName = graph->GetParent(gaussNode,0);
187 std::shared_ptr<ModPiece> gaussInputPiece;
188 std::vector<int> inputInds;
189 if(inputName==gaussNode+
"_0"){
190 auto piece = std::dynamic_pointer_cast<ModPiece>(graph->GetPiece(gaussNode));
191 assert(piece!=
nullptr);
193 gaussInputPiece = std::make_shared<IdentityOperator>(piece->inputSizes(0));
194 inputInds = std::vector<int>{0};
196 auto graphPiece = targetDens2->GetSubModel(inputName);
197 inputInds = targetDens2->MatchInputs(graphPiece);
198 gaussInputPiece = std::dynamic_pointer_cast<ModPiece>(graphPiece);
203 for(
auto& ind : inputInds){
205 throw std::runtime_error(
"Something went wrong in constructing Gaussian input model and not all inputs could be matched to the original graph.");
211 for(
auto edge : graph->GetEdges(inputName, gaussNode)){
218 return std::make_tuple(gaussInputPiece, inputInds, gaussInd);
223 std::shared_ptr<SamplingProblem> prob2 = std::dynamic_pointer_cast<SamplingProblem>(
prob);
225 throw std::runtime_error(
"Could not downcast AbstractSamplingProblem to SamplingProblem.");
229 std::shared_ptr<ModPiece> targetDens = prob2->GetDistribution();
230 std::shared_ptr<ModGraphPiece> targetDens2 = std::dynamic_pointer_cast<ModGraphPiece>(targetDens);
231 if(targetDens2==
nullptr){
232 throw std::runtime_error(
"Could not downcast target density to ModGraphPiece.");
236 auto graph = targetDens2->GetGraph();
239 std::string inputName = graph->GetParent(gaussNode,1);
240 auto varPiece = targetDens2->GetSubModel(inputName);
243 if(varPiece->inputSizes.size()!=1){
244 throw std::runtime_error(
"The Gaussian variance can only depend on one input parameter.");
247 if(varPiece->outputSizes.size()!=1){
248 throw std::runtime_error(
"The Gaussian variance can only have one output.");
252 auto hyperPrior = targetDens2->GetSubModel(igNode);
253 std::vector<int> sharedInds = varPiece->MatchInputs(hyperPrior);
255 if((sharedInds.size()!=1)||(sharedInds.at(0)<0)){
256 throw std::runtime_error(
"Something is strange with the WorkGraph. Could not match the input of the hyperprior with a path to the variance of the Gaussian node.");
REGISTER_MCMC_PROPOSAL(InverseGammaProposal) InverseGammaProposal
virtual double LogDensity(ref_vector< Eigen::VectorXd > const &inputs)
Evaluate the log-density.
Eigen::VectorXd Sample(ref_vector< Eigen::VectorXd > const &inputs)
Sample the distribution.
Defines a proposal using the analytic conditional Inverse Gamma distribution for the variance of a Ga...
const Eigen::VectorXd alpha
The prior value of alpha.
virtual Eigen::VectorXd GetGaussianInput(std::shared_ptr< SamplingState > const ¤tState) const
virtual std::shared_ptr< SamplingState > Sample(std::shared_ptr< SamplingState > const ¤tState) override
static std::shared_ptr< muq::Modeling::ModPiece > ExtractVarianceModel(std::shared_ptr< AbstractSamplingProblem > prob, std::string const &gaussNode, std::string const &igNode)
const Eigen::VectorXd beta
The prior value of beta.
std::tuple< std::shared_ptr< muq::Modeling::ModPiece >, std::vector< int >, int > gaussInfo
The index of the Gaussian block.
static Eigen::VectorXd ExtractMean(std::shared_ptr< AbstractSamplingProblem > prob, std::string const &gaussNode)
std::shared_ptr< muq::Modeling::ModPiece > varModel
A ModPiece containing an orthogonal matrix mapping the parameters to Gaussian variance.
virtual double LogDensity(std::shared_ptr< SamplingState > const &currState, std::shared_ptr< SamplingState > const &propState) override
static std::tuple< std::shared_ptr< muq::Modeling::ModPiece >, std::vector< int >, int > ExtractGaussInfo(std::shared_ptr< AbstractSamplingProblem > prob, std::string const &gaussNode)
static Eigen::VectorXd ExtractBeta(std::shared_ptr< AbstractSamplingProblem > prob, std::string const &igNode)
static Eigen::VectorXd ExtractAlpha(std::shared_ptr< AbstractSamplingProblem > prob, std::string const &igNode)
const Eigen::VectorXd gaussMean
The mean of the Gaussian distribution.
static std::shared_ptr< muq::Modeling::InverseGamma > ExtractInverseGamma(std::shared_ptr< AbstractSamplingProblem > prob, std::string const &igNode)
std::shared_ptr< AbstractSamplingProblem > prob
std::vector< std::reference_wrapper< const T > > ref_vector
A vector of references to something ...
auto get(const nlohmann::detail::iteration_proxy_value< IteratorType > &i) -> decltype(i.key())