88 kEstimatedReferenceLengths = 0,
89 kConstantLengthYoungEstimatedLengthOld,
90 kEstimatedLengthYoungBelowConstantLengthOld,
98 length_reference_parameterization_ =
99 LengthReferenceParameterization::kEstimatedReferenceLengths;
100 growth_products_prepared_ =
false;
111 length_reference_parameterization_ =
112 LengthReferenceParameterization::kConstantLengthYoungEstimatedLengthOld;
114 growth_products_prepared_ =
false;
125 length_reference_parameterization_ = LengthReferenceParameterization::
126 kEstimatedLengthYoungBelowConstantLengthOld;
128 growth_products_prepared_ =
false;
141 length_reference_parameterization_ =
142 LengthReferenceParameterization::kBothConstant;
145 growth_products_prepared_ =
false;
154 use_param_vectors_ =
true;
155 vb_params_set_ =
true;
156 growth_products_prepared_ =
false;
157 return mean_length_young_vector_;
165 use_param_vectors_ =
true;
166 vb_params_set_ =
true;
167 growth_products_prepared_ =
false;
168 return mean_length_old_vector_;
177 use_param_vectors_ =
true;
178 vb_params_set_ =
true;
179 growth_products_prepared_ =
false;
180 return growth_coefficient_vector_;
188 use_param_vectors_ =
true;
189 vb_params_set_ =
true;
190 growth_products_prepared_ =
false;
191 return reference_age_for_length_young_vector_;
199 use_param_vectors_ =
true;
200 vb_params_set_ =
true;
201 growth_products_prepared_ =
false;
202 return reference_age_for_length_old_vector_;
210 use_param_vectors_ =
true;
211 lw_params_set_ =
true;
212 growth_products_prepared_ =
false;
213 return length_weight_a_vector_;
221 use_param_vectors_ =
true;
222 lw_params_set_ =
true;
223 growth_products_prepared_ =
false;
224 return length_weight_b_vector_;
233 use_param_vectors_ =
true;
234 growth_products_prepared_ =
false;
235 return length_at_age_sd_at_reference_ages_vector_;
243 use_param_vectors_ =
true;
244 growth_products_prepared_ =
false;
245 return log_sd_mean_length_young_vector_;
253 use_param_vectors_ =
true;
254 growth_products_prepared_ =
false;
255 return log_sd_mean_length_old_vector_;
263 use_param_vectors_ =
true;
264 growth_products_prepared_ =
false;
265 return log_sd_growth_coefficient_vector_;
274 use_param_vectors_ =
true;
275 growth_products_prepared_ =
false;
276 return mean_length_young_mean_length_old_logit_corr_vector_;
285 use_param_vectors_ =
true;
286 growth_products_prepared_ =
false;
287 return mean_length_young_growth_coefficient_logit_corr_vector_;
296 use_param_vectors_ =
true;
297 growth_products_prepared_ =
false;
298 return mean_length_old_growth_coefficient_logit_corr_vector_;
306 age_offset_ = min_age;
307 age_offset_set_ =
true;
308 growth_products_prepared_ =
false;
310 model_->SetAgeOffset(
static_cast<Type>(age_offset_));
321 std::size_t n_sexes = 1)
override {
324 throw std::runtime_error(
325 "VonBertalanffySchnuteGrowthModelAdapter currently supports n_sexes "
331 growth_products_prepared_ =
false;
332 model_ = std::make_shared<GrowthModel<Type>>(n_years, n_ages, n_sexes);
334 if (age_offset_set_) {
335 model_->SetAgeOffset(
static_cast<Type>(age_offset_));
348 throw std::runtime_error(
"Negative age not supported");
350 const double a_round = std::round(
a);
351 const double tol = 1
e-8;
353 throw std::runtime_error(
"Non-integer age not supported yet");
359 throw std::runtime_error(
360 "VonBertalanffySchnuteGrowth reference_age_for_length_old must be > "
361 "reference_age_for_length_young");
365 return EvaluateWithFunctor(
year,
a);
370 const auto&
p = model_->GetProducts();
371 const double offset = age_offset_set_ ? age_offset_ : 0.0;
379 (
year >= 0 &&
static_cast<std::size_t
>(
year) <
p.n_years)
380 ?
static_cast<std::size_t
>(
year)
381 :
static_cast<std::size_t
>(0);
387 return EvaluateWithFunctor(
year,
a);
394 growth_products_prepared_ =
false;
397 throw std::runtime_error(
"Growth model not initialized; n_ages is 0");
399 Initialize(n_years_ == 0 ? 1 : n_years_, n_ages_,
400 n_sexes_ == 0 ? 1 : n_sexes_);
404 growth_products_prepared_ =
true;
412 if (!model_ || !growth_products_prepared_) {
415 return &(model_->GetProducts());
431 return CurrentLengthWeightA() *
432 fims_math::pow(
length_safe, CurrentLengthWeightB());
453 bool use_param_vectors_ =
false;
455 LengthReferenceParameterization::kEstimatedReferenceLengths;
456 Type constant_mean_length_young_ =
Type(0.0);
457 Type constant_mean_length_old_ =
Type(0.0);
458 std::size_t n_years_ = 0;
459 std::size_t n_ages_ = 0;
460 std::size_t n_sexes_ = 1;
461 double age_offset_ = 0.0;
462 bool age_offset_set_ =
false;
463 bool vb_params_set_ =
false;
464 bool lw_params_set_ =
false;
465 bool growth_products_prepared_ =
false;
467 mutable std::shared_ptr<GrowthModel<Type>> model_;
469 Type EvaluateWithFunctor(
int year,
const double&
a)
const {
473 vb.mean_length_old = CurrentMeanLengthOld();
474 vb.growth_coefficient = CurrentGrowthCoefficient();
475 vb.reference_age_for_length_young = CurrentReferenceAgeForLengthYoung();
476 vb.reference_age_for_length_old = CurrentReferenceAgeForLengthOld();
477 vb.length_weight_a = CurrentLengthWeightA();
478 vb.length_weight_b = CurrentLengthWeightB();
482 void SyncParamsToModel()
const {
486 model_->SetVonBertalanffySchnuteParameters(
487 CurrentMeanLengthYoung(), CurrentMeanLengthOld(),
488 CurrentGrowthCoefficient(), CurrentReferenceAgeForLengthYoung(),
489 CurrentReferenceAgeForLengthOld());
490 model_->SetLengthWeightParameters(CurrentLengthWeightA(),
491 CurrentLengthWeightB());
493 if (HasInterpolationSdInputs()) {
494 model_->SetLengthSdParams(CurrentLengthAtAgeSdAtReferenceAge1(),
495 CurrentLengthAtAgeSdAtReferenceAge2());
498 if (HasStructuredDeltaMethodInputs()) {
499 model_->SetGrowthParameterCovariance(
500 CurrentMeanLengthYoungVariance(),
501 CurrentMeanLengthYoungLengthAtRefAgeOldCovariance(),
502 CurrentMeanLengthYoungKCovariance(), CurrentMeanLengthOldVariance(),
503 CurrentMeanLengthOldKCovariance(),
504 CurrentGrowthCoefficientVariance());
506 model_->ClearGrowthParameterCovariance();
510 Type CurrentMeanLengthYoungStorage()
const {
511 return fims_math::exp(mean_length_young_vector_[0]);
514 Type CurrentMeanLengthOldStorage()
const {
515 return fims_math::exp(mean_length_old_vector_[0]);
518 Type CurrentMeanLengthYoung()
const {
519 switch (length_reference_parameterization_) {
520 case LengthReferenceParameterization::kEstimatedReferenceLengths:
521 return CurrentMeanLengthYoungStorage();
523 case LengthReferenceParameterization::
524 kConstantLengthYoungEstimatedLengthOld:
525 return constant_mean_length_young_;
527 case LengthReferenceParameterization::
528 kEstimatedLengthYoungBelowConstantLengthOld:
530 constant_mean_length_old_,
531 mean_length_young_vector_[0]);
533 case LengthReferenceParameterization::kBothConstant:
534 return constant_mean_length_young_;
537 return CurrentMeanLengthYoungStorage();
540 Type CurrentMeanLengthOld()
const {
541 switch (length_reference_parameterization_) {
542 case LengthReferenceParameterization::kEstimatedReferenceLengths:
543 case LengthReferenceParameterization::
544 kConstantLengthYoungEstimatedLengthOld:
545 return CurrentMeanLengthOldStorage();
547 case LengthReferenceParameterization::
548 kEstimatedLengthYoungBelowConstantLengthOld:
549 return constant_mean_length_old_;
551 case LengthReferenceParameterization::kBothConstant:
552 return constant_mean_length_old_;
555 return CurrentMeanLengthOldStorage();
558 Type CurrentGrowthCoefficient()
const {
559 return fims_math::exp(growth_coefficient_vector_[0]);
561 Type CurrentReferenceAgeForLengthYoung()
const {
562 return reference_age_for_length_young_vector_[0];
564 Type CurrentReferenceAgeForLengthOld()
const {
565 return reference_age_for_length_old_vector_[0];
567 Type CurrentLengthWeightA()
const {
568 return fims_math::exp(length_weight_a_vector_[0]);
570 Type CurrentLengthWeightB()
const {
571 return fims_math::exp(length_weight_b_vector_[0]);
573 Type CurrentLengthAtAgeSdAtReferenceAge1()
const {
574 return fims_math::exp(length_at_age_sd_at_reference_ages_vector_[0]);
576 Type CurrentLengthAtAgeSdAtReferenceAge2()
const {
577 return fims_math::exp(length_at_age_sd_at_reference_ages_vector_[1]);
579 Type CurrentSdLengthAtRefAgeYoung()
const {
580 return fims_math::exp(log_sd_mean_length_young_vector_[0]);
583 Type CurrentSdLengthAtRefAgeOld()
const {
584 return fims_math::exp(log_sd_mean_length_old_vector_[0]);
587 Type CurrentSdGrowthCoefficient()
const {
588 return fims_math::exp(log_sd_growth_coefficient_vector_[0]);
591 Type CurrentCorrLengthAtRefAgeYoungLengthAtRefAgeOld()
const {
593 static_cast<Type>(-1.0),
static_cast<Type>(1.0),
594 mean_length_young_mean_length_old_logit_corr_vector_[0]);
597 Type CurrentCorrLengthAtRefAgeYoungK()
const {
599 static_cast<Type>(-1.0),
static_cast<Type>(1.0),
600 mean_length_young_growth_coefficient_logit_corr_vector_[0]);
603 Type CurrentCorrLengthAtRefAgeOldK()
const {
605 static_cast<Type>(-1.0),
static_cast<Type>(1.0),
606 mean_length_old_growth_coefficient_logit_corr_vector_[0]);
609 Type CurrentMeanLengthYoungVariance()
const {
610 const Type sd = CurrentSdLengthAtRefAgeYoung();
614 Type CurrentMeanLengthOldVariance()
const {
615 const Type sd = CurrentSdLengthAtRefAgeOld();
619 Type CurrentGrowthCoefficientVariance()
const {
620 const Type sd = CurrentSdGrowthCoefficient();
624 Type CurrentMeanLengthYoungLengthAtRefAgeOldCovariance()
const {
625 return CurrentCorrLengthAtRefAgeYoungLengthAtRefAgeOld() *
626 CurrentSdLengthAtRefAgeYoung() * CurrentSdLengthAtRefAgeOld();
629 Type CurrentMeanLengthYoungKCovariance()
const {
630 return CurrentCorrLengthAtRefAgeYoungK() * CurrentSdLengthAtRefAgeYoung() *
631 CurrentSdGrowthCoefficient();
634 Type CurrentMeanLengthOldKCovariance()
const {
635 return CurrentCorrLengthAtRefAgeOldK() * CurrentSdLengthAtRefAgeOld() *
636 CurrentSdGrowthCoefficient();
639 bool HasInterpolationSdInputs()
const {
640 return length_at_age_sd_at_reference_ages_vector_.
size() > 0;
643 bool HasAnyStructuredDeltaMethodInput()
const {
644 return log_sd_mean_length_young_vector_.
size() > 0 ||
645 log_sd_mean_length_old_vector_.
size() > 0 ||
646 log_sd_growth_coefficient_vector_.
size() > 0 ||
647 mean_length_young_mean_length_old_logit_corr_vector_.
size() > 0 ||
648 mean_length_young_growth_coefficient_logit_corr_vector_.
size() > 0 ||
649 mean_length_old_growth_coefficient_logit_corr_vector_.
size() > 0;
652 bool HasStructuredDeltaMethodInputs()
const {
653 return log_sd_mean_length_young_vector_.
size() > 0 &&
654 log_sd_mean_length_old_vector_.
size() > 0 &&
655 log_sd_growth_coefficient_vector_.
size() > 0 &&
656 mean_length_young_mean_length_old_logit_corr_vector_.
size() > 0 &&
657 mean_length_young_growth_coefficient_logit_corr_vector_.
size() > 0 &&
658 mean_length_old_growth_coefficient_logit_corr_vector_.
size() > 0;
661 void EnsureParamsSet()
const {
662 if (!use_param_vectors_ || mean_length_young_vector_.
size() < 1 ||
663 mean_length_old_vector_.
size() < 1 ||
664 growth_coefficient_vector_.
size() < 1 ||
665 reference_age_for_length_young_vector_.
size() < 1 ||
666 reference_age_for_length_old_vector_.
size() < 1 ||
667 length_weight_a_vector_.
size() < 1 ||
668 length_weight_b_vector_.
size() < 1) {
669 throw std::runtime_error(
670 "VonBertalanffySchnuteGrowth parameters not set");
673 if (mean_length_young_vector_.
size() != 1 ||
674 mean_length_old_vector_.
size() != 1 ||
675 growth_coefficient_vector_.
size() != 1 ||
676 reference_age_for_length_young_vector_.
size() != 1 ||
677 reference_age_for_length_old_vector_.
size() != 1 ||
678 length_weight_a_vector_.
size() != 1 ||
679 length_weight_b_vector_.
size() != 1) {
680 throw std::runtime_error(
681 "VonBertalanffySchnuteGrowthModelAdapter currently supports a single "
682 "growth pattern; expected size 1 for von Bertalanffy--Schnute and "
683 "length-weight parameter vectors");
686 const bool has_sd = HasInterpolationSdInputs();
691 throw std::runtime_error(
692 "VonBertalanffySchnuteGrowthModelAdapter requires either "
693 "length_at_age_sd_at_reference_ages or the structured delta-method "
694 "growth variability inputs");
698 throw std::runtime_error(
699 "VonBertalanffySchnuteGrowthModelAdapter requires all six structured "
700 "delta-method variability inputs when using that path");
704 throw std::runtime_error(
705 "von Bertalanffy--Schnute growth adapter requires variability inputs "
706 "for exactly one supported path. Supply either the interpolation "
707 "inputs length_at_age_sd_at_reference_ages or the full delta-method "
708 "variability inputs, but not both");
711 if (
has_sd && length_at_age_sd_at_reference_ages_vector_.
size() != 2) {
712 throw std::runtime_error(
713 "VonBertalanffySchnuteGrowthModelAdapter expected exactly 2 "
714 "length_at_age_sd_at_reference_ages values");
718 (log_sd_mean_length_young_vector_.
size() != 1 ||
719 log_sd_mean_length_old_vector_.
size() != 1 ||
720 log_sd_growth_coefficient_vector_.
size() != 1 ||
721 mean_length_young_mean_length_old_logit_corr_vector_.
size() != 1 ||
722 mean_length_young_growth_coefficient_logit_corr_vector_.
size() != 1 ||
723 mean_length_old_growth_coefficient_logit_corr_vector_.
size() != 1)) {
724 throw std::runtime_error(
725 "VonBertalanffySchnuteGrowthModelAdapter currently supports a single "
726 "structured delta-method variability parameter set; expected "
727 "size 1 for each structured uncertainty input");