FIMS  v0.8.0
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#include "../../common/def.hpp"
16
17namespace fims_distributions {
21template <typename Type>
22struct LogNormalLPDF : public DensityComponentBase<Type> {
26 Type lpdf = static_cast<Type>(0.0);
28 // data_indicator<tmbutils::vector<Type> , Type> keep; /**< Indicator used in
29 // TMB one-step-ahead residual calculations */
30
34
37 virtual ~LogNormalLPDF() {}
38
42 virtual const Type evaluate() {
43 // set vector size based on input type (prior, process, or data)
44 size_t n_x = this->get_n_x();
45 // get expected value vector size
46 size_t n_expected = this->get_n_expected();
47 // setup vector for recording the log probability density function values
48 this->lpdf_vec.resize(n_x);
49 this->report_lpdf_vec.resize(n_x);
50 std::fill(this->lpdf_vec.begin(), this->lpdf_vec.end(),
51 static_cast<Type>(0));
52 std::fill(this->report_lpdf_vec.begin(), this->report_lpdf_vec.end(),
53 static_cast<Type>(0));
54 this->lpdf = static_cast<Type>(0);
55
56 // Dimension checks
57 // TODO: fix dimension check as expected values no longer used for data
58 if (n_x != n_expected) {
59 if (n_expected == 1) {
60 n_expected = n_x;
61 } else if (n_x > n_expected) {
62 n_x = n_expected;
63 }
64 }
65
66 if (this->log_sd.size() > 1 && n_x != this->log_sd.size()) {
67 throw std::invalid_argument(
68 "LognormalLPDF::Vector index out of bounds. The size of observed "
69 "data does not equal the size of the log_sd vector. The observed "
70 "data vector is of size " +
71 fims::to_string(n_x) + " and the log_sd vector is of size " +
72 fims::to_string(this->log_sd.size()));
73 }
74
75 for (size_t i = 0; i < n_x; i++) {
76#ifdef TMB_MODEL
77 if (this->input_type == "data") {
78 // if data, check if there are any NA values and skip lpdf calculation
79 // if there are See Deroba and Miller, 2016
80 // (https://doi.org/10.1016/j.fishres.2015.12.002) for the use of
81 // lognormal constant
82 if (this->get_observed(i) != this->observed_values->na_value) {
83 this->lpdf_vec[i] =
84 dnorm(log(this->get_observed(i)), this->get_expected(i),
85 fims_math::exp(log_sd.get_force_scalar(i)), true) -
86 log(this->get_observed(i));
87 } else {
88 this->lpdf_vec[i] = 0;
89 }
90 } else {
91 if (this->input_type == "random_effects") {
92 // if random effects, no lognormal constant needs to be applied
93 this->lpdf_vec[i] =
94 dnorm(log(this->get_observed(i)), this->get_expected(i),
95 fims_math::exp(log_sd.get_force_scalar(i)), true);
96 } else {
97 this->lpdf_vec[i] =
98 dnorm(log(this->get_observed(i)), this->get_expected(i),
99 fims_math::exp(log_sd.get_force_scalar(i)), true) -
100 log(this->get_observed(i));
101 }
102 }
103
104 this->report_lpdf_vec[i] = this->lpdf_vec[i];
105 lpdf += this->lpdf_vec[i];
106 if (this->simulate_flag) {
107 FIMS_SIMULATE_F(this->of) { // preprocessor definition in interface.hpp
108 // this simulates data that is mean biased
109 if (this->input_type == "data") {
110 this->observed_values->at(i) = fims_math::exp(
111 rnorm(this->get_expected(i),
112 fims_math::exp(log_sd.get_force_scalar(i))));
113 }
114 if (this->input_type == "random_effects") {
115 (*this->re)[i] = fims_math::exp(
116 rnorm(this->get_expected(i),
117 fims_math::exp(log_sd.get_force_scalar(i))));
118 }
119 if (this->input_type == "prior") {
120 (*(this->priors[i]))[0] = fims_math::exp(
121 rnorm(this->get_expected(i),
122 fims_math::exp(log_sd.get_force_scalar(i))));
123 }
124 }
125 }
126#endif
127 }
128#ifdef TMB_MODEL
129 vector<Type> lognormal_x = this->x.to_tmb();
130 // FIMS_REPORT_F(lognormal_x, this->of);
131#endif
132 return (lpdf);
133 }
134};
135} // namespace fims_distributions
136#endif
Definition fims_vector.hpp:27
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:70
Base class for all module_name functors.
Definition density_components_base.hpp:152
fims::Vector< Type > lpdf_vec
Definition density_components_base.hpp:160
bool simulate_flag
Definition density_components_base.hpp:165
fims::Vector< Type > report_lpdf_vec
Definition density_components_base.hpp:162
size_t get_n_x()
Definition density_components_base.hpp:114
Type & get_observed(size_t i)
Definition density_components_base.hpp:55
std::vector< fims::Vector< Type > * > priors
Definition density_components_base.hpp:40
size_t get_n_expected()
Definition density_components_base.hpp:131
std::shared_ptr< fims_data_object::DataObject< Type > > observed_values
Definition density_components_base.hpp:32
fims::Vector< Type > * re
Definition density_components_base.hpp:35
std::string input_type
Definition density_components_base.hpp:28
fims::Vector< Type > x
Definition density_components_base.hpp:41
Type & get_expected(size_t i)
Definition density_components_base.hpp:98
Definition lognormal_lpdf.hpp:22
virtual ~LogNormalLPDF()
Destructor.
Definition lognormal_lpdf.hpp:37
Type lpdf
Definition lognormal_lpdf.hpp:26
LogNormalLPDF()
Constructor.
Definition lognormal_lpdf.hpp:33
fims::Vector< Type > log_sd
Definition lognormal_lpdf.hpp:24
virtual const Type evaluate()
Evaluates the lognormal probability density function.
Definition lognormal_lpdf.hpp:42