39 GrowthModel(std::size_t n_years, std::size_t n_ages, std::size_t n_sexes = 1)
43 products_(n_years, n_ages, n_sexes) {}
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;
61 vb_.length_weight_a = length_weight_a;
62 vb_.length_weight_b = length_weight_b;
69 Type length_at_age_sd_at_reference_age_old) {
70 length_at_age_sd_at_reference_age_young_ =
71 length_at_age_sd_at_reference_age_young;
72 length_at_age_sd_at_reference_age_old_ =
73 length_at_age_sd_at_reference_age_old;
86 Type mean_length_young_variance,
87 Type mean_length_young_mean_length_old_covariance,
88 Type mean_length_young_growth_coefficient_covariance,
89 Type mean_length_old_variance,
90 Type mean_length_old_growth_coefficient_covariance,
91 Type growth_coefficient_variance) {
92 ValidateGrowthParameterCovariance(
93 mean_length_young_variance,
94 mean_length_young_mean_length_old_covariance,
95 mean_length_young_growth_coefficient_covariance,
96 mean_length_old_variance, mean_length_old_growth_coefficient_covariance,
97 growth_coefficient_variance);
99 mean_length_young_variance_ = mean_length_young_variance;
100 mean_length_young_mean_length_old_covariance_ =
101 mean_length_young_mean_length_old_covariance;
102 mean_length_young_growth_coefficient_covariance_ =
103 mean_length_young_growth_coefficient_covariance;
104 mean_length_old_variance_ = mean_length_old_variance;
105 mean_length_old_growth_coefficient_covariance_ =
106 mean_length_old_growth_coefficient_covariance;
107 growth_coefficient_variance_ = growth_coefficient_variance;
108 use_delta_method_variability_ =
true;
109 needs_update_ =
true;
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;
127 if (!needs_update_)
return;
130 throw std::runtime_error(
131 "VonBertalanffySchnuteGrowth requires n_ages > 0");
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");
140 Type laa_min = Type(0.0);
141 Type slope = Type(0.0);
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);
148 slope = (n_ages_ > 1) ? (length_at_age_sd_at_reference_age_old_ -
149 length_at_age_sd_at_reference_age_young_) /
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_;
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);
165 products_.MeanLAA(y, a, s) = laa;
166 products_.SdLAA(y, a, s) = sd_laa;
167 products_.MeanWAA(y, a, s) = waa;
172 needs_update_ =
false;
181 void ValidateGrowthParameterCovariance(
182 Type mean_length_young_variance,
183 Type mean_length_young_mean_length_old_covariance,
184 Type mean_length_young_growth_coefficient_covariance,
185 Type mean_length_old_variance,
186 Type mean_length_old_growth_coefficient_covariance,
187 Type growth_coefficient_variance)
const {
188 if (mean_length_young_variance < Type(0.0) ||
189 mean_length_old_variance < Type(0.0) ||
190 growth_coefficient_variance < Type(0.0)) {
191 throw std::runtime_error(
"Growth parameter variances must be >= 0");
194 if (mean_length_young_mean_length_old_covariance *
195 mean_length_young_mean_length_old_covariance >
196 mean_length_young_variance * mean_length_old_variance) {
197 throw std::runtime_error(
198 "Growth covariance between mean_length_young and "
199 "mean_length_old is inconsistent with the supplied variances");
202 if (mean_length_young_growth_coefficient_covariance *
203 mean_length_young_growth_coefficient_covariance >
204 mean_length_young_variance * growth_coefficient_variance) {
205 throw std::runtime_error(
206 "Growth covariance between mean_length_young and "
207 "growth_coefficient is inconsistent with the supplied variances");
210 if (mean_length_old_growth_coefficient_covariance *
211 mean_length_old_growth_coefficient_covariance >
212 mean_length_old_variance * growth_coefficient_variance) {
213 throw std::runtime_error(
214 "Growth covariance between mean_length_old and "
215 "growth_coefficient is inconsistent with the supplied variances");
218 const Type determinant =
219 mean_length_young_variance *
220 (mean_length_old_variance * growth_coefficient_variance -
221 mean_length_old_growth_coefficient_covariance *
222 mean_length_old_growth_coefficient_covariance) -
223 mean_length_young_mean_length_old_covariance *
224 (mean_length_young_mean_length_old_covariance *
225 growth_coefficient_variance -
226 mean_length_young_growth_coefficient_covariance *
227 mean_length_old_growth_coefficient_covariance) +
228 mean_length_young_growth_coefficient_covariance *
229 (mean_length_young_mean_length_old_covariance *
230 mean_length_old_growth_coefficient_covariance -
231 mean_length_young_growth_coefficient_covariance *
232 mean_length_old_variance);
234 if (determinant < Type(0.0)) {
235 throw std::runtime_error(
236 "Growth parameter covariance matrix must be positive "
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 =
249 const Type sd_laa = laa * fims_math::sqrt(log_var_safe);
255 ? length_at_age_sd_at_reference_age_young_ + slope * (laa - laa_min)
256 : length_at_age_sd_at_reference_age_young_;
263 Type ComputeLogLengthVarianceAtAge(
const Type& age)
const {
264 Type d_log_laa_d_log_length_young = Type(0.0);
265 Type d_log_laa_d_log_length_old = Type(0.0);
266 Type d_log_laa_d_log_k = Type(0.0);
268 vb_.log_length_at_age_logscale_gradient(age, d_log_laa_d_log_length_young,
269 d_log_laa_d_log_length_old,
272 return d_log_laa_d_log_length_young * d_log_laa_d_log_length_young *
273 mean_length_young_variance_ +
274 Type(2.0) * d_log_laa_d_log_length_young *
275 d_log_laa_d_log_length_old *
276 mean_length_young_mean_length_old_covariance_ +
277 Type(2.0) * d_log_laa_d_log_length_young * d_log_laa_d_log_k *
278 mean_length_young_growth_coefficient_covariance_ +
279 d_log_laa_d_log_length_old * d_log_laa_d_log_length_old *
280 mean_length_old_variance_ +
281 Type(2.0) * d_log_laa_d_log_length_old * d_log_laa_d_log_k *
282 mean_length_old_growth_coefficient_covariance_ +
283 d_log_laa_d_log_k * d_log_laa_d_log_k * growth_coefficient_variance_;
286 std::size_t n_years_;
288 std::size_t n_sexes_;
290 GrowthProducts<Type> products_;
293 VonBertalanffySchnuteGrowth<Type> vb_;
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);
312 age_offset_ = offset;
313 needs_update_ =
true;