FIMS  v0.8.0
Loading...
Searching...
No Matches
multinomial_lpmf.hpp
Go to the documentation of this file.
1
10#ifndef MULTINOMIAL_LPMF
11#define MULTINOMIAL_LPMF
12
14#include "../../common/fims_vector.hpp"
15#include "../../common/def.hpp"
16
17namespace fims_distributions {
21template <typename Type>
23 Type lpdf = static_cast<Type>(0.0);
31
34 virtual ~MultinomialLPMF() {}
35
39 virtual const Type evaluate() {
40 // set dims using observed_values if no user input
41 if (dims.size() != 2) {
42 dims.resize(2);
43 dims[0] = this->observed_values->get_imax();
44 dims[1] = this->observed_values->get_jmax();
45 }
46
47 // setup vector for recording the log probability density function values
48 Type lpdf = static_cast<Type>(0.0);
50 this->lpdf_vec.resize(dims[0]);
51 this->report_lpdf_vec.clear();
52 std::fill(this->lpdf_vec.begin(), this->lpdf_vec.end(), 0);
53
54 // Dimension checks
55 if (this->input_type == "data") {
56 if (this->data_expected_values) {
57 if (dims[0] * dims[1] != this->data_expected_values->size()) {
58 throw std::invalid_argument(
59 "MultinomialLPDF: Vector index out of bounds. The dimension of "
60 "the "
61 "number of rows times the number of columns is of size " +
62 fims::to_string(dims[0] * dims[1]) +
63 " and the expected vector is of size " +
64 fims::to_string(this->data_expected_values->size()));
65 }
66 }
67 } else {
68 if (dims[0] * dims[1] != this->x.size()) {
69 throw std::invalid_argument(
70 "MultinomialLPDF: Vector index out of bounds. The dimension of the "
71 "number of rows times the number of columns is of size " +
72 fims::to_string(dims[0] * dims[1]) +
73 " and the observed vector is of size " +
74 fims::to_string(this->x.size()));
75 }
76 if (this->x.size() != this->expected_values.size()) {
77 throw std::invalid_argument(
78 "MultinomialLPDF: Vector index out of bounds. The dimension of the "
79 "observed vector of size " +
80 fims::to_string(this->x.size()) +
81 " and the expected vector is of size " +
82 fims::to_string(this->expected_values.size()));
83 }
84 }
85
86 for (size_t i = 0; i < dims[0]; i++) {
87 // for each row, create new x and prob vectors
88 fims::Vector<Type> x_vector;
89 fims::Vector<Type> prob_vector;
90 x_vector.resize(dims[1]);
91 prob_vector.resize(dims[1]);
92
93 bool containsNA = false;
95#ifdef TMB_MODEL
96 for (size_t j = 0; j < dims[1]; j++) {
97 if (this->input_type == "data") {
98 // if data, check if there are any NA values and skip lpdf calculation
99 // for entire row if there are
100 if (this->get_observed(static_cast<size_t>(i),
101 static_cast<size_t>(j)) ==
102 this->observed_values->na_value) {
103 containsNA = true;
104 break;
105 }
106 if (!containsNA) {
107 size_t idx = (i * dims[1]) + j;
108 x_vector[j] = this->get_observed(i, j);
109 prob_vector[j] = this->get_expected(idx);
110 }
111 } else {
112 // if not data (i.e. prior or process), use x vector instead of
113 // observed_values
114 size_t idx = (i * dims[1]) + j;
115 x_vector[j] = this->get_observed(idx);
116 prob_vector[j] = this->get_expected(idx);
117 }
118 }
119
120 if (!containsNA) {
121 this->lpdf_vec[i] =
122 dmultinom(x_vector.to_tmb(), prob_vector.to_tmb(), true);
123 } else {
124 this->lpdf_vec[i] = 0;
125 }
126 // track the values for output, e.g., report_lpdf_vec
127 this->report_lpdf_vec.insert(this->report_lpdf_vec.end(), dims[1],
128 this->lpdf_vec[i]);
129 lpdf += this->lpdf_vec[i];
130/*
131if (this->simulate_flag)
132{
133 FIMS_SIMULATE_F(this->of)
134 {
135 fims::Vector<Type> sim_observed;
136 sim_observed.resize(dims[1]);
137 sim_observed = rmultinom(prob_vector);
138 sim_observed.resize(this->x);
139 for (size_t j = 0; j < dims[1]; j++)
140 {
141 idx = (i * dims[1]) + j;
142 this->x[idx] = sim_observed[j];
143 }
144 }
145}
146*/
147#endif
148 }
149
150#ifdef TMB_MODEL
151#endif
152 this->lpdf = lpdf;
153 return (lpdf);
154 }
155};
156} // namespace fims_distributions
157#endif
Definition fims_vector.hpp:27
void resize(size_t s)
Changes the number of elements stored.
Definition fims_vector.hpp:375
std::vector< Type > to_tmb() const
Convert fims::Vector to TMB vector type.
Definition fims_vector.hpp:468
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.
Base class for all module_name functors.
Definition density_components_base.hpp:152
fims::Vector< Type > lpdf_vec
Definition density_components_base.hpp:160
fims::Vector< Type > report_lpdf_vec
Definition density_components_base.hpp:162
Type & get_observed(size_t i)
Definition density_components_base.hpp:55
fims::Vector< Type > * data_expected_values
Definition density_components_base.hpp:38
std::shared_ptr< fims_data_object::DataObject< Type > > observed_values
Definition density_components_base.hpp:32
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 multinomial_lpmf.hpp:22
virtual const Type evaluate()
Evaluates the multinomial probability mass function.
Definition multinomial_lpmf.hpp:39
virtual ~MultinomialLPMF()
Destructor.
Definition multinomial_lpmf.hpp:34
fims::Vector< size_t > dims
Definition multinomial_lpmf.hpp:25
MultinomialLPMF()
Constructor.
Definition multinomial_lpmf.hpp:30
Type lpdf
Definition multinomial_lpmf.hpp:23