FIMS  v0.11.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
15
16namespace fims_distributions {
37template <typename Type>
44
48
51 virtual ~MultinomialLPMF() {}
52
64 virtual const Type evaluate() {
65 // set dims using data_observed_values if no user input
66 if (dims.size() != 2) {
67 dims.resize(2);
68 dims[0] = this->data_observed_values->get_imax();
69 dims[1] = this->data_observed_values->get_jmax();
70 }
71
72 // setup vector for recording the log probability density function values
73 this->lpdf = static_cast<Type>(0.0);
75 this->lpdf_vec.resize(dims[0] * dims[1]);
76 std::fill(this->lpdf_vec.begin(), this->lpdf_vec.end(), 0);
77 size_t lpdf_vec_idx = 0;
78 // Dimension checks
79 if (this->input_type == "data") {
80 if (this->data_expected_values) {
81 if (dims[0] * dims[1] != this->data_expected_values->size()) {
82 throw std::invalid_argument(
83 "MultinomialLPDF: Vector index out of bounds. The dimension of "
84 "the "
85 "number of rows times the number of columns is of size " +
86 std::to_string(dims[0] * dims[1]) +
87 " and the expected vector is of size " +
88 std::to_string(this->data_expected_values->size()));
89 }
90 }
91 } else {
92 if (dims[0] * dims[1] != this->observed_values.size()) {
93 throw std::invalid_argument(
94 "MultinomialLPDF: Vector index out of bounds. The dimension of the "
95 "number of rows times the number of columns is of size " +
96 std::to_string(dims[0] * dims[1]) +
97 " and the observed vector is of size " +
98 std::to_string(this->observed_values.size()));
99 }
100 if (this->observed_values.size() != this->expected_values.size()) {
101 throw std::invalid_argument(
102 "MultinomialLPDF: Vector index out of bounds. The dimension of the "
103 "observed vector of size " +
104 std::to_string(this->observed_values.size()) +
105 " and the expected vector is of size " +
106 std::to_string(this->expected_values.size()));
107 }
108 }
109
110 for (size_t i = 0; i < dims[0]; i++) {
111 // for each row, create new observed_values and prob vectors
112 fims::Vector<Type> observed_values_vector;
113 fims::Vector<Type> prob_vector;
114 observed_values_vector.resize(dims[1]);
115 prob_vector.resize(dims[1]);
116
117 // Skips the entire row if any values are NA
118 bool containsNA = false;
119
120#ifdef TMB_MODEL
121 for (size_t j = 0; j < dims[1]; j++) {
122 if (this->input_type == "data") {
123 // if data, check if there are any NA values and skip lpdf calculation
124 // for entire row if there are
125 if (this->get_observed(static_cast<size_t>(i),
126 static_cast<size_t>(j)) ==
127 this->data_observed_values->na_value) {
128 containsNA = true;
129 break;
130 }
131 if (!containsNA) {
132 size_t idx = (i * dims[1]) + j;
133 observed_values_vector[j] = this->get_observed(i, j);
134 prob_vector[j] = this->get_expected(idx);
135 }
136 } else {
137 // if not data (i.e. prior or process), use observed_values vector
138 // instead of data_observed_values
139 size_t idx = (i * dims[1]) + j;
140 observed_values_vector[j] = this->get_observed(idx);
141 prob_vector[j] = this->get_expected(idx);
142 }
143 }
144
145 if (!containsNA) {
146 Type row_lpmf = dmultinom(observed_values_vector.to_tmb(),
147 prob_vector.to_tmb(), true);
148 // The row log-probability mass has no unique split across bins because
149 // the log(n!) term belongs to the whole row. Each bin reports an equal
150 // share so that summing lpdf_vec over a composition counts each row
151 // once.
152 std::fill(this->lpdf_vec.begin() + lpdf_vec_idx,
153 this->lpdf_vec.begin() + lpdf_vec_idx + dims[1],
154 row_lpmf / static_cast<Type>(dims[1]));
155
156 this->lpdf += row_lpmf;
157 }
158 lpdf_vec_idx += dims[1];
159/*
160if (this->simulate_flag)
161{
162 FIMS_SIMULATE_F(this->of)
163 {
164 fims::Vector<Type> sim_observed;
165 sim_observed.resize(dims[1]);
166 sim_observed = rmultinom(prob_vector);
167 sim_observed.resize(this->observed_values.size());
168 for (size_t j = 0; j < dims[1]; j++)
169 {
170 idx = (i * dims[1]) + j;
171 this->observed_values[idx] = sim_observed[j];
172 }
173 }
174}
175*/
176#endif
177 }
178
179#ifdef TMB_MODEL
180#endif
181 return (this->lpdf);
182 }
183};
184} // namespace fims_distributions
185#endif
Definition fims_vector.hpp:27
void resize(size_t s)
Changes the number of elements stored.
Definition fims_vector.hpp:401
std::vector< Type > to_tmb() const
Convert fims::Vector to TMB vector type.
Definition fims_vector.hpp:494
Declares the DensityComponentBase class, which is the base class for all distribution functors.
Establishes the FIMS Vector class.
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
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
fims::Vector< Type > * data_expected_values
Expected value vector for data pathways.
Definition density_components_base.hpp:53
DensityComponentBase()
Constructor, which initializes default prior pointer state and ID.
Definition density_components_base.hpp:217
Type & get_observed(size_t i)
Retrieve one observed value based on input_type.
Definition density_components_base.hpp:83
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
virtual const Type evaluate()
Evaluates the multinomial log probability mass function.
Definition multinomial_lpmf.hpp:64
virtual ~MultinomialLPMF()
Destructor.
Definition multinomial_lpmf.hpp:51
fims::Vector< size_t > dims
Dimensions of the number of rows and columns of the multivariate dataset.
Definition multinomial_lpmf.hpp:43
MultinomialLPMF()
Constructor.
Definition multinomial_lpmf.hpp:47