CMP++: Uncertainty Quantification & Bayesian Calibration
Loading...
Searching...
No Matches
prior++.h
Go to the documentation of this file.
1#ifndef PRIORPP_H
2#define PRIORPP_H
3
4#include <cmp_defines.h>
5#include <distribution.h>
6
11namespace cmp::prior {
26class Prior {
27 public:
28 virtual ~Prior() = default;
29 virtual double eval(const Eigen::VectorXd &par) const = 0;
30 virtual double evalGradient(const Eigen::VectorXd &par, const size_t &i) const = 0;
31 virtual double evalHessian(const Eigen::VectorXd &par, const size_t &i, const size_t &j) const = 0;
32};
33
48class Product : public Prior {
49 private:
50 std::shared_ptr<Prior> leftPrior_;
51 std::shared_ptr<Prior> rightPrior_;
52 public:
53
54 Product() = default;
55 Product(const Product&) = default;
56 Product(Product&&) = default;
57 Product& operator=(const Product&) = default;
58 Product& operator=(Product&&) = default;
59
60 Product(std::shared_ptr<Prior> p1, std::shared_ptr<Prior> p2) : leftPrior_(p1), rightPrior_(p2) {};
61
62 double eval(const Eigen::VectorXd &par) const {
63 return leftPrior_->eval(par) + rightPrior_->eval(par);
64 }
65
66 double evalGradient(const Eigen::VectorXd &par, const size_t &i) const {
67 return leftPrior_->evalGradient(par, i) + rightPrior_->evalGradient(par, i);
68 }
69
70 double evalHessian(const Eigen::VectorXd &par, const size_t &i, const size_t &j) const {
71 return leftPrior_->evalHessian(par, i, j) + rightPrior_->evalHessian(par, i, j);
72 }
73
74 static std::shared_ptr<Prior> make(std::shared_ptr<Prior> p1, std::shared_ptr<Prior> p2) {
75 return std::make_shared<Product>(p1, p2);
76 }
77};
78
93class Uniform : public Prior {
94 public:
95 Uniform(const Uniform&) = default;
96 Uniform(Uniform&&) = default;
97 Uniform& operator=(const Uniform&) = default;
98 Uniform& operator=(Uniform&&) = default;
99
100 Uniform() = default;
101
102 double eval(const Eigen::VectorXd &par) const {
103 return 0;
104 }
105
106 double evalGradient(const Eigen::VectorXd &par, const size_t &i) const {
107 return 0;
108 }
109
110 double evalHessian(const Eigen::VectorXd &par, const size_t &i, const size_t &j) const {
111 return 0;
112 }
113
114 static std::shared_ptr<Prior> make() {
115 return std::make_shared<Uniform>();
116 }
117};
118
134template <typename DistType>
135class FromDistribution : public Prior {
136 private:
137 DistType dist_;
138 size_t paramIndex_;
139
140 public:
141// Delete default constructor since we need a valid distribution
143
148
154 FromDistribution(const DistType& dist, size_t paramIndex)
155 : dist_(dist), paramIndex_(paramIndex) {}
156
157 double eval(const Eigen::VectorXd &par) const override {
158 // Ensure index is within bounds (optional, but safe)
159 if(paramIndex_ >= par.size()) {
160 throw std::out_of_range("Parameter index out of bounds in FromDistribution::eval");
161 }
162 return dist_.logPDF(par(paramIndex_));
163 }
164
165 double evalGradient(const Eigen::VectorXd &par, const size_t &i) const override {
166 if(i == paramIndex_) {
167 return dist_.dLogPDF(par(paramIndex_));
168 }
169 // If taking the gradient with respect to a different parameter, it's 0
170 return 0.0;
171 }
172
173 double evalHessian(const Eigen::VectorXd &par, const size_t &i, const size_t &j) const override {
174 if(i == paramIndex_ && j == paramIndex_) {
175 return dist_.ddLogPDF(par(paramIndex_));
176 }
177 // Cross-derivatives and derivatives for other parameters are 0
178 return 0.0;
179 }
180
181// Factory method matching your other Prior classes
182 static std::shared_ptr<Prior> make(const DistType& dist, size_t paramIndex) {
183 return std::make_shared<FromDistribution<DistType>>(dist, paramIndex);
184 }
185};
186
195template <typename DistType>
196std::shared_ptr<Prior> make(const DistType& dist, size_t paramIndex) {
197 return FromDistribution<DistType>::make(dist, paramIndex);
198}
199
207std::shared_ptr<Prior> operator*(std::shared_ptr<Prior> p1, std::shared_ptr<Prior> p2);
208
209}
210
211
214#endif
Adapts a univariate probability distribution to act as a prior on a single coordinate.
Definition prior++.h:135
FromDistribution(const FromDistribution &)=default
FromDistribution & operator=(const FromDistribution &)=default
FromDistribution & operator=(FromDistribution &&)=default
double evalGradient(const Eigen::VectorXd &par, const size_t &i) const override
Definition prior++.h:165
FromDistribution(const DistType &dist, size_t paramIndex)
Constructs a Prior from a Univariate Distribution.
Definition prior++.h:154
DistType dist_
Underlying univariate distribution.
Definition prior++.h:137
static std::shared_ptr< Prior > make(const DistType &dist, size_t paramIndex)
Definition prior++.h:182
double eval(const Eigen::VectorXd &par) const override
Definition prior++.h:157
double evalHessian(const Eigen::VectorXd &par, const size_t &i, const size_t &j) const override
Definition prior++.h:173
FromDistribution(FromDistribution &&)=default
size_t paramIndex_
Parameter vector coordinate index.
Definition prior++.h:138
Base class for prior probability distributions.
Definition prior++.h:26
virtual ~Prior()=default
virtual double eval(const Eigen::VectorXd &par) const =0
virtual double evalHessian(const Eigen::VectorXd &par, const size_t &i, const size_t &j) const =0
virtual double evalGradient(const Eigen::VectorXd &par, const size_t &i) const =0
Represents the product (sum of logs) of two independent prior distributions.
Definition prior++.h:48
double eval(const Eigen::VectorXd &par) const
Definition prior++.h:62
double evalHessian(const Eigen::VectorXd &par, const size_t &i, const size_t &j) const
Definition prior++.h:70
Product(std::shared_ptr< Prior > p1, std::shared_ptr< Prior > p2)
Definition prior++.h:60
Product(Product &&)=default
std::shared_ptr< Prior > rightPrior_
Right factor independent prior.
Definition prior++.h:51
Product(const Product &)=default
Product & operator=(const Product &)=default
double evalGradient(const Eigen::VectorXd &par, const size_t &i) const
Definition prior++.h:66
static std::shared_ptr< Prior > make(std::shared_ptr< Prior > p1, std::shared_ptr< Prior > p2)
Definition prior++.h:74
std::shared_ptr< Prior > leftPrior_
Left factor independent prior.
Definition prior++.h:50
Product & operator=(Product &&)=default
Represents an improper flat (uniform) prior.
Definition prior++.h:93
double evalGradient(const Eigen::VectorXd &par, const size_t &i) const
Definition prior++.h:106
Uniform(const Uniform &)=default
double eval(const Eigen::VectorXd &par) const
Definition prior++.h:102
static std::shared_ptr< Prior > make()
Definition prior++.h:114
double evalHessian(const Eigen::VectorXd &par, const size_t &i, const size_t &j) const
Definition prior++.h:110
Uniform(Uniform &&)=default
Uniform & operator=(const Uniform &)=default
Uniform & operator=(Uniform &&)=default
Definition prior++.h:11
std::shared_ptr< Prior > operator*(std::shared_ptr< Prior > p1, std::shared_ptr< Prior > p2)
Multiplies two prior distributions (returns a Product prior).
Definition prior++.cpp:3
std::shared_ptr< Prior > make(const DistType &dist, size_t paramIndex)
Helper template function to create a FromDistribution prior.
Definition prior++.h:196