FIMS  v0.9.3
Loading...
Searching...
No Matches
lognormal_lpdf.hpp
Go to the documentation of this file.
1
10#ifndef LOGNORMAL_LPDF
11#define LOGNORMAL_LPDF
12
14#include "../../common/fims_vector.hpp"
15
16namespace fims_distributions {
33template <typename Type>
34struct LogNormalLPDF : public DensityComponentBase<Type> {
42
46
49 virtual ~LogNormalLPDF() {}
50
62 virtual const Type evaluate() {
63 // set vector size based on input type (prior, process, or data)
64 size_t n_x = this->get_n_x();
65 // get expected value vector size
66 size_t n_expected = this->get_n_expected();
67 // setup vector for recording the log probability density function values
68 this->lpdf_vec.resize(n_x);
69 std::fill(this->lpdf_vec.begin(), this->lpdf_vec.end(),
70 static_cast<Type>(0));
71 this->lpdf = static_cast<Type>(0);
72
73 // Dimension checks
74 // TODO: fix dimension check as expected values no longer used for data
75 if (n_x != n_expected) {
76 if (n_expected == 1) {
77 n_expected = n_x;
78 } else if (n_x > n_expected) {
79 n_x = n_expected;
80 }
81 }
82
83 if (this->log_sd.size() > 1 && n_x != this->log_sd.size()) {
84 throw std::invalid_argument(
85 "LognormalLPDF::Vector index out of bounds. The size of observed "
86 "data does not equal the size of the log_sd vector. The observed "
87 "data vector is of size " +
88 std::to_string(n_x) + " and the log_sd vector is of size " +
89 std::to_string(this->log_sd.size()));
90 }
91
92 for (size_t i = 0; i < n_x; i++) {
93#ifdef TMB_MODEL
94 if (this->input_type == "data") {
95 // if data, check if there are any NA values and skip lpdf calculation
96 // https://doi.org/10.1016/j.fishres.2015.12.002 for the use of
97 // lognormal constant
98 if (this->get_observed(i) != this->data_observed_values->na_value) {
99 this->lpdf_vec[i] =
100 dnorm(log(this->get_observed(i)), this->get_expected(i),
101 fims_math::exp(log_sd.get_force_scalar(i)), true) -
102 log(this->get_observed(i));
103 } else {
104 this->lpdf_vec[i] = 0;
105 }
106 } else {
107 if (this->input_type == "random_effects") {
108 // if random effects, no lognormal constant needs to be applied
109 this->lpdf_vec[i] =
110 dnorm(log(this->get_observed(i)), this->get_expected(i),
111 fims_math::exp(log_sd.get_force_scalar(i)), true);
112 } else {
113 this->lpdf_vec[i] =
114 dnorm(log(this->get_observed(i)), this->get_expected(i),
115 fims_math::exp(log_sd.get_force_scalar(i)), true) -
116 log(this->get_observed(i));
117 }
118 }
119
120 this->lpdf += this->lpdf_vec[i];
121 if (this->simulate_flag) {
122 FIMS_SIMULATE_F(this->of) { // preprocessor definition in interface.hpp
123 // this simulates data that is mean biased
124 if (this->input_type == "data") {
125 this->data_observed_values->at(i) = fims_math::exp(
126 rnorm(this->get_expected(i),
127 fims_math::exp(log_sd.get_force_scalar(i))));
128 }
129 if (this->input_type == "random_effects") {
130 (*this->re)[i] = fims_math::exp(
131 rnorm(this->get_expected(i),
132 fims_math::exp(log_sd.get_force_scalar(i))));
133 }
134 if (this->input_type == "prior") {
135 (*(this->priors[i]))[0] = fims_math::exp(
136 rnorm(this->get_expected(i),
137 fims_math::exp(log_sd.get_force_scalar(i))));
138 }
139 }
140 }
141#endif
142 }
143#ifdef TMB_MODEL
144 vector<Type> lognormal_observed_values = this->observed_values.to_tmb();
145 // FIMS_REPORT_F(lognormal_observed_values, this->of);
146#endif
147 return (this->lpdf);
148 }
149};
150} // namespace fims_distributions
151#endif
Definition fims_vector.hpp:27
size_type size() const
Returns the number of elements.
Definition fims_vector.hpp:273
Declares the DensityComponentBase class, which is the base class for all distribution functors.
#define FIMS_SIMULATE_F(F)
TMB macro that simulates data.
Definition interface.hpp:71
Base class for all module_name functors.
Definition density_components_base.hpp:32
fims::Vector< Type > lpdf_vec
Vector storing observation-level log-likelihood contributions.
Definition density_components_base.hpp:190
fims::Vector< Type > observed_values
Input value of distribution function for priors or random effects.
Definition density_components_base.hpp:61
bool simulate_flag
Boolean; if true, data are simulated from the distribution.
Definition density_components_base.hpp:200
Type & get_expected(size_t i)
Retrieve one expected value based on input_type and use_mean.
Definition density_components_base.hpp:122
Type lpdf
Total log probability density contribution of the distribution.
Definition density_components_base.hpp:180
size_t get_n_expected()
Get length of the active expected input vector.
Definition density_components_base.hpp:155
size_t get_n_x()
Get length of the active observed input vector.
Definition density_components_base.hpp:138
Type & get_observed(size_t i)
Retrieve one observed value based on input_type.
Definition density_components_base.hpp:83
fims::Vector< Type > * re
Pointer to random effects vector.
Definition density_components_base.hpp:47
std::string input_type
Classification of the input pathway for this distribution object. Options used by accessor methods ar...
Definition density_components_base.hpp:38
std::shared_ptr< fims_data_object::DataObject< Type > > data_observed_values
Observed data.
Definition density_components_base.hpp:41
std::vector< fims::Vector< Type > * > priors
Vector of pointers where each entry points to a prior parameter.
Definition density_components_base.hpp:56
Implements the LogNormalLPDF distribution functor used by FIMS to evaluate observation-level and tota...
Definition lognormal_lpdf.hpp:34
virtual ~LogNormalLPDF()
Destructor.
Definition lognormal_lpdf.hpp:49
LogNormalLPDF()
Constructor.
Definition lognormal_lpdf.hpp:45
fims::Vector< Type > log_sd
Natural log of the standard deviation of the distribution on the log scale. The argument can be a vec...
Definition lognormal_lpdf.hpp:41
virtual const Type evaluate()
Evaluates the lognormal log probability density function.
Definition lognormal_lpdf.hpp:62