FIMS  v0.10.0
Loading...
Searching...
No Matches
growth_model.hpp
Go to the documentation of this file.
1
8#ifndef POPULATION_DYNAMICS_GROWTH_MODEL_HPP
9#define POPULATION_DYNAMICS_GROWTH_MODEL_HPP
10
11#include <cstddef>
12#include <stdexcept>
13
14#include "growth_model_base.hpp"
15#include "growth_products.hpp"
17#include "../../common/def.hpp"
18
19namespace fims_popdy {
20
30template <typename Type>
31class GrowthModel : public GrowthModelBase<Type> {
32 public:
39 GrowthModel(std::size_t n_years, std::size_t n_ages, std::size_t n_sexes = 1)
40 : n_years_(n_years),
41 n_ages_(n_ages),
42 n_sexes_(n_sexes),
43 products_(n_years, n_ages, n_sexes) {}
44
47 Type mean_length_old,
48 Type growth_coefficient,
49 Type reference_age_for_length_young,
50 Type reference_age_for_length_old) {
51 vb_.mean_length_young = mean_length_young;
52 vb_.mean_length_old = mean_length_old;
53 vb_.growth_coefficient = growth_coefficient;
54 vb_.reference_age_for_length_young = reference_age_for_length_young;
55 vb_.reference_age_for_length_old = reference_age_for_length_old;
56 needs_update_ = true;
57 }
58
60 void SetLengthWeightParameters(Type length_weight_a, Type length_weight_b) {
61 vb_.length_weight_a = length_weight_a;
62 vb_.length_weight_b = length_weight_b;
63 needs_update_ = true;
64 }
65
70 length_at_age_sd_at_reference_age_young_ =
72 length_at_age_sd_at_reference_age_old_ =
74 needs_update_ = true;
75 }
76
92 ValidateGrowthParameterCovariance(
98
99 mean_length_young_variance_ = mean_length_young_variance;
100 mean_length_young_mean_length_old_covariance_ =
102 mean_length_young_growth_coefficient_covariance_ =
104 mean_length_old_variance_ = mean_length_old_variance;
105 mean_length_old_growth_coefficient_covariance_ =
107 growth_coefficient_variance_ = growth_coefficient_variance;
108 use_delta_method_variability_ = true;
109 needs_update_ = true;
110 }
111
115 mean_length_young_variance_ = static_cast<Type>(0.0);
116 mean_length_young_mean_length_old_covariance_ = static_cast<Type>(0.0);
117 mean_length_young_growth_coefficient_covariance_ = static_cast<Type>(0.0);
118 mean_length_old_variance_ = static_cast<Type>(0.0);
119 mean_length_old_growth_coefficient_covariance_ = static_cast<Type>(0.0);
120 growth_coefficient_variance_ = static_cast<Type>(0.0);
121 use_delta_method_variability_ = false;
122 needs_update_ = true;
123 }
124
126 void Prepare() override {
127 if (!needs_update_) return;
128
129 if (n_ages_ == 0) {
130 throw std::runtime_error(
131 "VonBertalanffySchnuteGrowth requires n_ages > 0");
132 }
133 if (vb_.reference_age_for_length_old <=
134 vb_.reference_age_for_length_young) {
135 throw std::runtime_error(
136 "VonBertalanffySchnuteGrowth reference_age_for_length_old must be > "
137 "reference_age_for_length_young");
138 }
139
140 Type laa_min = Type(0.0);
141 Type slope = Type(0.0);
142
143 if (!use_delta_method_variability_) {
144 laa_min = vb_.length_at_age(vb_.reference_age_for_length_young);
145 const Type laa_max = vb_.length_at_age(vb_.reference_age_for_length_old);
146 const Type laa_delta_safe = fims_math::ad_max(
147 fims_math::ad_fabs(laa_max - laa_min), static_cast<Type>(1e-8));
148 slope = (n_ages_ > 1) ? (length_at_age_sd_at_reference_age_old_ -
149 length_at_age_sd_at_reference_age_young_) /
151 : Type(0.0);
152 }
153
154 // Fill mean length-at-age, sd, and mean weight-at-age.
155 for (std::size_t y = 0; y < n_years_; ++y) {
156 for (std::size_t a = 0; a < n_ages_; ++a) {
157 for (std::size_t s = 0; s < n_sexes_; ++s) {
158 const Type age = static_cast<Type>(a) + age_offset_;
159
160 // log-scale params live upstream; laa here is natural scale
161 const Type laa = vb_.length_at_age(age);
162 const Type sd_laa = ComputeLengthSdAtAge(age, laa, laa_min, slope);
163 const Type waa = vb_.weight_at_age(age);
164
165 products_.MeanLAA(y, a, s) = laa;
166 products_.SdLAA(y, a, s) = sd_laa;
167 products_.MeanWAA(y, a, s) = waa;
168 }
169 }
170 }
171
172 needs_update_ = false;
173 }
174
175 const GrowthProducts<Type>& GetProducts() const override { return products_; }
176
177 private:
181 void ValidateGrowthParameterCovariance(
188 if (mean_length_young_variance < Type(0.0) ||
191 throw std::runtime_error("Growth parameter variances must be >= 0");
192 }
193
197 throw std::runtime_error(
198 "Growth covariance between mean_length_young and "
199 "mean_length_old is inconsistent with the supplied variances");
200 }
201
205 throw std::runtime_error(
206 "Growth covariance between mean_length_young and "
207 "growth_coefficient is inconsistent with the supplied variances");
208 }
209
213 throw std::runtime_error(
214 "Growth covariance between mean_length_old and "
215 "growth_coefficient is inconsistent with the supplied variances");
216 }
217
218 const Type determinant =
233
234 if (determinant < Type(0.0)) {
235 throw std::runtime_error(
236 "Growth parameter covariance matrix must be positive "
237 "semi-definite");
238 }
239 }
240
243 Type ComputeLengthSdAtAge(const Type& age, const Type& laa,
244 const Type& laa_min, const Type& slope) const {
245 if (use_delta_method_variability_) {
246 const Type log_var = ComputeLogLengthVarianceAtAge(age);
247 const Type log_var_safe =
248 fims_math::ad_max(log_var, static_cast<Type>(0.0));
249 const Type sd_laa = laa * fims_math::sqrt(log_var_safe);
250 return fims_math::ad_max(sd_laa, static_cast<Type>(1e-8));
251 }
252
253 const Type sd_laa =
254 (n_ages_ > 1)
255 ? length_at_age_sd_at_reference_age_young_ + slope * (laa - laa_min)
256 : length_at_age_sd_at_reference_age_young_;
257
258 return fims_math::ad_max(sd_laa, static_cast<Type>(1e-8));
259 }
260
263 Type ComputeLogLengthVarianceAtAge(const Type& age) const {
267
268 vb_.log_length_at_age_logscale_gradient(age, d_log_laa_d_log_length_young,
271
273 mean_length_young_variance_ +
276 mean_length_young_mean_length_old_covariance_ +
278 mean_length_young_growth_coefficient_covariance_ +
280 mean_length_old_variance_ +
282 mean_length_old_growth_coefficient_covariance_ +
283 d_log_laa_d_log_k * d_log_laa_d_log_k * growth_coefficient_variance_;
284 }
285
286 std::size_t n_years_;
287 std::size_t n_ages_;
288 std::size_t n_sexes_;
289
290 GrowthProducts<Type> products_;
291
292 // Phase 1 functor
294
295 // Caching state
296 bool needs_update_ = true;
297 Type length_at_age_sd_at_reference_age_young_ = static_cast<Type>(3.0);
298 Type length_at_age_sd_at_reference_age_old_ = static_cast<Type>(7.0);
299 bool use_delta_method_variability_ = false;
300 Type mean_length_young_variance_ = static_cast<Type>(0.0);
301 Type mean_length_young_mean_length_old_covariance_ = static_cast<Type>(0.0);
302 Type mean_length_young_growth_coefficient_covariance_ =
303 static_cast<Type>(0.0);
304 Type mean_length_old_variance_ = static_cast<Type>(0.0);
305 Type mean_length_old_growth_coefficient_covariance_ = static_cast<Type>(0.0);
306 Type growth_coefficient_variance_ = static_cast<Type>(0.0);
307 Type age_offset_ = static_cast<Type>(0.0);
308
309 public:
312 age_offset_ = offset;
313 needs_update_ = true;
314 }
315};
316
317} // namespace fims_popdy
318
319#endif /* POPULATION_DYNAMICS_GROWTH_MODEL_HPP */
Growth module boundary (product-oriented).
Definition growth_model_base.hpp:24
Concrete growth model using VonBertalanffySchnute growth (Phase 1).
Definition growth_model.hpp:31
void SetLengthSdParams(Type length_at_age_sd_at_reference_age_young, Type length_at_age_sd_at_reference_age_old)
Definition growth_model.hpp:68
GrowthModel(std::size_t n_years, std::size_t n_ages, std::size_t n_sexes=1)
Construct a growth model with fixed dimensions.
Definition growth_model.hpp:39
void Prepare() override
Compute and cache growth products.
Definition growth_model.hpp:126
void ClearGrowthParameterCovariance()
Definition growth_model.hpp:114
void SetLengthWeightParameters(Type length_weight_a, Type length_weight_b)
fixed length-weight params (phase 1)
Definition growth_model.hpp:60
const GrowthProducts< Type > & GetProducts() const override
Read-only access to cached growth products.
Definition growth_model.hpp:175
void SetGrowthParameterCovariance(Type mean_length_young_variance, Type mean_length_young_mean_length_old_covariance, Type mean_length_young_growth_coefficient_covariance, Type mean_length_old_variance, Type mean_length_old_growth_coefficient_covariance, Type growth_coefficient_variance)
Definition growth_model.hpp:85
void SetVonBertalanffySchnuteParameters(Type mean_length_young, Type mean_length_old, Type growth_coefficient, Type reference_age_for_length_young, Type reference_age_for_length_old)
Set fixed VonBertalanffySchnute parameters (explicit reference ages).
Definition growth_model.hpp:46
void SetAgeOffset(Type offset)
Set an age offset if population ages do not start at zero.
Definition growth_model.hpp:311
const Type ad_max(const Type &a, const Type &b, Type C=1e-5)
Definition fims_math.hpp:365
Declares the GrowthModelBase interface. This is the growth module boundary that downstream code consu...
Declares the GrowthProducts struct holding growth "products" that downstream population dynamics code...
The population dynamics of FIMS.
Definition catch_at_age.hpp:45
std::shared_ptr< AgeToLengthConversionBase< Type > > BuildAgeToLengthConversionFleet(const std::shared_ptr< Population< Type > > &population, const std::shared_ptr< Fleet< Type > > &fleet)
Build the active age-to-length conversion for a fleet from the current population and fleet state.
Definition runtime.hpp:44
Growth "products" in a consistent (year, age, sex) space.
Definition growth_products.hpp:26
Defines the VonBertalanffySchnuteGrowth class, which inherits from the GrowthBase class.