FIMS  v0.10.0
Loading...
Searching...
No Matches
rcpp_growth.hpp
Go to the documentation of this file.
1
9#ifndef FIMS_INTERFACE_RCPP_RCPP_OBJECTS_RCPP_GROWTH_HPP
10#define FIMS_INTERFACE_RCPP_RCPP_OBJECTS_RCPP_GROWTH_HPP
11
12#include <algorithm>
13#include <cmath>
14
15#include "common/fims_math.hpp"
19
25 public:
29 static uint32_t id_g;
33 uint32_t id;
39 static std::map<uint32_t, std::shared_ptr<GrowthInterfaceBase>> live_objects;
40
45 this->id = GrowthInterfaceBase::id_g++;
46 /* Create instance of map: key is id and value is pointer to
47 GrowthInterfaceBase */
48 // GrowthInterfaceBase::live_objects[this->id] =
49 // std::make_shared<GrowthInterfaceBase>(*this);
50 }
51
57 GrowthInterfaceBase(const GrowthInterfaceBase& other) : id(other.id) {}
58
63
67 virtual uint32_t get_id() = 0;
68
73 virtual double evaluate(double age) = 0;
74};
75
85 public:
87
95
97
98 protected:
99 template <typename Type>
104 std::shared_ptr<fims_popdy::GrowthDerivedObservationBase<Type>>
106 std::shared_ptr<fims_info::Information<Type>> info =
108
110 info->growth_models.find(this->id);
111 if (it == info->growth_models.end()) {
112 FIMS_WARNING_LOG("Growth-derived observation model " +
113 fims::to_string(this->id) +
114 " not found in Information.");
115 return nullptr;
116 }
117
118 std::shared_ptr<fims_popdy::GrowthDerivedObservationBase<Type>>
119 growth_observation = std::dynamic_pointer_cast<
121 if (!growth_observation) {
122 FIMS_WARNING_LOG("Growth-derived observation type mismatch for id " +
123 fims::to_string(this->id));
124 return nullptr;
125 }
126
127 return growth_observation;
128 }
129
130 template <typename Type>
137 growth_observation) const {
138 std::shared_ptr<fims_info::Information<Type>> info =
140 info->growth_models[growth_observation->id] = growth_observation;
141 }
142};
143
150 public:
168 std::shared_ptr<std::map<int, std::map<double, double>>> ewaa;
172 bool initialized = false;
173
178 this->ewaa = std::make_shared<std::map<int, std::map<double, double>>>();
180 std::make_shared<EWAAGrowthInterface>(*this);
182 std::make_shared<EWAAGrowthInterface>(*this));
183 }
184
191 : GrowthInterfaceBase(other),
192 weights(other.weights),
193 ages(other.ages),
194 n_years(other.n_years),
195 ewaa(other.ewaa),
196 initialized(other.initialized) {}
197
202
207 virtual uint32_t get_id() { return this->id; }
208
216 inline std::map<int, std::map<double, double>> make_map(RealVector ages,
219 std::map<int, std::map<double, double>> mymap;
220 const size_t n_years_plus_one = static_cast<size_t>(n_years.get() + 1);
221
222 // Reject invalid year counts because map keys are expected to include
223 // at least one model year.
224 if (n_years.get() < 1) {
225 Rcpp::stop("EWAA Error:: n_years must be at least 1");
226 }
227
228 // Reject empty vectors because we need at least one age-weight pair.
229 if (weights.size() == 0 || ages.size() == 0) {
230 Rcpp::stop("EWAA Error:: ages and weights must have at least one value");
231 }
232
233 // Accept either:
234 // 1) one weight vector by age (shared across years), or
235 // 2) a full year-by-age matrix flattened as (n_years + 1) * n_ages.
236 if ((weights.size() != ages.size() * n_years_plus_one) &&
237 (weights.size() != ages.size())) {
238 Rcpp::stop(
239 "weights size does not match ages size or ages size times "
240 "(n_years + 1), where the plus one is for the beginning "
241 "of the year after the terminal year spawning-biomass "
242 "calculations. weights size: " +
243 std::to_string(weights.size()) +
244 " ages size: " + std::to_string(ages.size()) +
245 " n_years: " + std::to_string(n_years.get()));
246 } else if (weights.size() == ages.size()) {
247 // One age-specific vector was provided, so replicate the same
248 // weight-at-age values for every year key (0 through n_years).
249 for (size_t y = 0; y < n_years_plus_one; y++) {
250 for (size_t i = 0; i < ages.size(); i++) {
251 mymap[y][ages[i]] = weights[i];
252 }
253 }
254 } else if (weights.size() == ages.size() * n_years_plus_one) {
255 // A flattened year-by-age matrix was provided, so map each block of
256 // n_ages values to the corresponding year key (0 through n_years).
257 for (size_t y = 0; y < n_years_plus_one; y++) {
258 for (size_t i = 0; i < ages.size(); i++) {
259 mymap[y][ages[i]] = weights[y * ages.size() + i];
260 }
261 }
262 }
263 return mymap;
264 }
265
271 virtual double evaluate(double age) {
273
274 // Build the EWAA map once from R inputs the first time evaluate() is
275 // called.
276 if (initialized == false) {
277 EWAAGrowth.ewaa = make_map(this->ages, this->weights, this->n_years);
278 initialized = true;
279 } else {
280 // Prevent re-initializing this object with a second evaluate() call.
281 Rcpp::stop("this empirical weight at age object is already initialized");
282 }
283 return EWAAGrowth.evaluate(0, age);
284 }
285
293 virtual std::string to_json() {
294 std::stringstream ss;
295 ss << "{\n";
296 ss << " \"module_name\": \"Growth\",\n";
297 ss << " \"module_type\": \"EWAA\",\n";
298 ss << " \"module_id\":" << this->id << ",\n";
299 ss << " \"parameters\": [\n{\n";
300 ss << " \"name\": \"weight_at_age\",\n";
301 ss << " \"id\": null,\n";
302 ss << " \"type\": \"vector\",\n";
303 ss << " \"dimensionality\": {\n";
304 ss << " \"header\": [\"n_years+1\",\"n_ages\"],\n";
305 ss << " \"dimensions\": [" << this->n_years.get() + 1 << ","
306 << this->ages.size() << "]\n},\n";
307
308 ss << " \"values\": [\n";
309 for (size_t i = 0; i < weights.size() - 1; i++) {
310 ss << "{\n";
311 ss << "\"id\": null,\n";
312 ss << "\"value\": " << weights[i] << ",\n";
313 ss << "\"estimated_value\": " << weights[i] << ",\n";
314 ss << "\"estimation_type\": \"constant\"\n";
315 ss << "},\n";
316 }
317 ss << "{\n";
318 ss << "\"id\": null,\n";
319 ss << "\"value\": " << weights[weights.size() - 1] << ",\n";
320 ss << "\"estimated_value\": " << weights[weights.size() - 1] << ",\n";
321 ss << "\"estimation_type\": \"constant\"\n";
322 ss << "}\n]\n";
323 ss << "}\n]\n}\n";
324 return ss.str();
325 }
326
327#ifdef TMB_MODEL
328
329 template <typename Type>
330 bool add_to_fims_tmb_internal() {
331 std::shared_ptr<fims_info::Information<Type>> info =
333
334 std::shared_ptr<fims_popdy::EWAAGrowth<Type>> ewaa_growth =
335 std::make_shared<fims_popdy::EWAAGrowth<Type>>();
336
337 // set relative info
338 ewaa_growth->id = this->id;
339 ewaa_growth->ewaa =
340 make_map(this->ages, this->weights, this->n_years); // this->ewaa;
341 // add to Information
342 info->growth_models[ewaa_growth->id] = ewaa_growth;
343
344 return true;
345 }
346
351 virtual bool add_to_fims_tmb() {
352 this->add_to_fims_tmb_internal<TMB_FIMS_REAL_TYPE>();
353 this->add_to_fims_tmb_internal<TMBAD_FIMS_TYPE>();
354
355 return true;
356 }
357
358#endif
359};
360
369 public:
376 // clang-format off
381 // clang-format on
423
429 // Variability inputs are optional and mutually exclusive by path, so
430 // leave them absent until a caller explicitly supplies one path.
431 this->length_at_age_sd_at_reference_ages.resize(0);
432 this->log_sd_mean_length_young.resize(0);
433 this->log_sd_mean_length_old.resize(0);
434 this->log_sd_growth_coefficient.resize(0);
435 this->mean_length_young_mean_length_old_logit_corr.resize(0);
436 this->mean_length_young_growth_coefficient_logit_corr.resize(0);
437 this->mean_length_old_growth_coefficient_logit_corr.resize(0);
438
439 // Register this interface instance in global registries so it can be
440 // discovered and linked by ID during model initialization.
442 std::make_shared<VonBertalanffySchnuteGrowthInterface>(*this);
444 std::make_shared<VonBertalanffySchnuteGrowthInterface>(*this));
445 }
446
473
475
476 // Return stable module ID used for linking this growth object to populations.
477 virtual uint32_t get_id() { return this->id; }
478
483 virtual void finalize() {
484 if (this->finalized) {
485 FIMS_WARNING_LOG("VonBertalanffySchnute Growth " +
486 fims::to_string(this->id) +
487 " has been finalized already.");
488 }
489
490 this->finalized = true;
491
492 std::shared_ptr<fims_popdy::GrowthDerivedObservationBase<double>>
493 growth_observation = this->GetGrowthObservationFromInfo<double>();
494 if (!growth_observation) {
495 return;
496 }
497
498 std::shared_ptr<fims_popdy::VonBertalanffySchnuteGrowthModelAdapter<double>>
499 vb = std::dynamic_pointer_cast<
501 growth_observation);
502 if (!vb) {
503 FIMS_WARNING_LOG("Growth model type mismatch for id " +
504 fims::to_string(this->id));
505 return;
506 }
507
508 auto set_final = [](VariableVector& pv, const fims::Vector<double>& src,
509 bool log_scale) {
510 for (size_t i = 0; i < pv.size(); i++) {
511 if (pv[i].estimation_type_m.get() == "constant") {
512 pv[i].final_value_m = pv[i].initial_value_m;
513 } else {
514 double v = src[i];
515 if (log_scale) {
516 v = fims_math::exp(v);
517 }
518 pv[i].final_value_m = v;
519 }
520 }
521 };
522
523 SetFinalLengthParameter(
524 this->mean_length_young,
525 FinalMeanLengthYoungFromWorkingScale(vb->MeanLengthYoungVector()));
526 SetFinalLengthParameter(
527 this->mean_length_old,
528 FinalMeanLengthOldFromWorkingScale(vb->MeanLengthYoungVector(),
529 vb->MeanLengthOldVector()));
530 set_final(this->growth_coefficient, vb->GrowthCoefficientVector(), true);
531 set_final(this->reference_age_for_length_young,
532 vb->ReferenceAgeForLengthYoungVector(), false);
533 set_final(this->reference_age_for_length_old,
534 vb->ReferenceAgeForLengthOldVector(), false);
535 set_final(this->length_weight_a, vb->LengthWeightAVector(), true);
536 set_final(this->length_weight_b, vb->LengthWeightBVector(), true);
537 set_final(this->length_at_age_sd_at_reference_ages,
538 vb->LengthAtAgeSdAtRefAgesVector(), true);
539 set_final(this->log_sd_mean_length_young,
540 vb->LogSdLengthAtRefAgeYoungVector(), false);
541 set_final(this->log_sd_mean_length_old, vb->LogSdLengthAtRefAgeOldVector(),
542 false);
543 set_final(this->log_sd_growth_coefficient,
544 vb->LogSdGrowthCoefficientVector(), false);
545 set_final(this->mean_length_young_mean_length_old_logit_corr,
546 vb->LogitCorrLengthAtRefAgeYoungLengthAtRefAgeOldVector(), false);
547 set_final(this->mean_length_young_growth_coefficient_logit_corr,
548 vb->LogitCorrLengthAtRefAgeYoungKVector(), false);
549 set_final(this->mean_length_old_growth_coefficient_logit_corr,
550 vb->LogitCorrLengthAtRefAgeOldKVector(), false);
551 }
552
553 virtual double evaluate(double age) {
554 if (age < 0.0) {
555 Rcpp::stop("Negative age not supported");
556 }
557 if (this->n_ages.get() <= 0) {
558 Rcpp::stop("n_ages not set");
559 }
560 const double age_round = std::round(age);
561 const double tol = 1e-8;
562 if (std::fabs(age - age_round) > tol) {
563 Rcpp::stop("Non-integer age not supported yet");
564 }
565 ValidateVonBertalanffySchnuteGrowthInputs(false);
566
568
569 vb.mean_length_young = this->mean_length_young[0].initial_value_m;
570 vb.mean_length_old = this->mean_length_old[0].initial_value_m;
571 vb.growth_coefficient = this->growth_coefficient[0].initial_value_m;
573 this->reference_age_for_length_young[0].initial_value_m;
575 this->reference_age_for_length_old[0].initial_value_m;
576
577 vb.length_weight_a = this->length_weight_a[0].initial_value_m;
578 vb.length_weight_b = this->length_weight_b[0].initial_value_m;
579
580 return vb.evaluate(0, age);
581 }
582
583 private:
584 enum class LengthReferenceParameterization {
585 kEstimatedReferenceLengths = 0,
586 kConstantLengthYoungEstimatedLengthOld,
587 kEstimatedLengthYoungBelowConstantLengthOld,
588 kBothConstant
589 };
590
591 bool IsEstimated(VariableVector& pv) {
592 return pv.size() > 0 && pv[0].estimation_type_m.get() != "constant";
593 }
594
595 double InitialLengthAtRefAgeYoung() {
596 return this->mean_length_young[0].initial_value_m;
597 }
598
599 double InitialLengthAtRefAgeOld() {
600 return this->mean_length_old[0].initial_value_m;
601 }
602
603 LengthReferenceParameterization GetLengthReferenceParameterization() {
604 const bool estimate_length_young = IsEstimated(this->mean_length_young);
605 const bool estimate_length_old = IsEstimated(this->mean_length_old);
606
607 if (estimate_length_young && estimate_length_old) {
608 return LengthReferenceParameterization::kEstimatedReferenceLengths;
609 }
610 if (!estimate_length_young && estimate_length_old) {
611 return LengthReferenceParameterization::
612 kConstantLengthYoungEstimatedLengthOld;
613 }
614 if (estimate_length_young && !estimate_length_old) {
615 return LengthReferenceParameterization::
616 kEstimatedLengthYoungBelowConstantLengthOld;
617 }
618 return LengthReferenceParameterization::kBothConstant;
619 }
620
621 double FinalMeanLengthYoungFromWorkingScale(
622 const fims::Vector<double>& mean_length_young_src) {
623 switch (GetLengthReferenceParameterization()) {
624 case LengthReferenceParameterization::kEstimatedReferenceLengths:
625 return fims_math::exp(mean_length_young_src[0]);
626
627 case LengthReferenceParameterization::
628 kConstantLengthYoungEstimatedLengthOld:
629 return InitialLengthAtRefAgeYoung();
630
631 case LengthReferenceParameterization::
632 kEstimatedLengthYoungBelowConstantLengthOld:
633 return fims_math::inv_logit(0.0, InitialLengthAtRefAgeOld(),
634 mean_length_young_src[0]);
635
636 case LengthReferenceParameterization::kBothConstant:
637 return InitialLengthAtRefAgeYoung();
638 }
639
640 return InitialLengthAtRefAgeYoung();
641 }
642
643 double FinalMeanLengthOldFromWorkingScale(
644 const fims::Vector<double>& mean_length_young_src,
645 const fims::Vector<double>& mean_length_old_src) {
646 switch (GetLengthReferenceParameterization()) {
647 case LengthReferenceParameterization::kEstimatedReferenceLengths:
648 case LengthReferenceParameterization::
649 kConstantLengthYoungEstimatedLengthOld:
650 return fims_math::exp(mean_length_old_src[0]);
651
652 case LengthReferenceParameterization::
653 kEstimatedLengthYoungBelowConstantLengthOld:
654 return InitialLengthAtRefAgeOld();
655
656 case LengthReferenceParameterization::kBothConstant:
657 return InitialLengthAtRefAgeOld();
658 }
659
660 return InitialLengthAtRefAgeOld();
661 }
662
663 void SetFinalLengthParameter(VariableVector& pv, double final_value) const {
664 for (size_t i = 0; i < pv.size(); i++) {
665 if (pv[i].estimation_type_m.get() == "constant") {
666 pv[i].final_value_m = pv[i].initial_value_m;
667 } else {
668 pv[i].final_value_m = final_value;
669 }
670 }
671 }
672
673 template <typename Type>
674 void ConfigureLengthReferenceParameterization(
675 const std::shared_ptr<
677 switch (GetLengthReferenceParameterization()) {
678 case LengthReferenceParameterization::kEstimatedReferenceLengths:
679 vb->UseEstimatedReferenceMeanLengths();
680 break;
681
682 case LengthReferenceParameterization::
683 kConstantLengthYoungEstimatedLengthOld:
684 vb->UseConstantMeanLengthYoungWithEstimatedMeanLengthOld(
685 static_cast<Type>(InitialLengthAtRefAgeYoung()));
686 break;
687
688 case LengthReferenceParameterization::
689 kEstimatedLengthYoungBelowConstantLengthOld:
690 vb->UseEstimatedMeanLengthYoungBelowConstantMeanLengthOld(
691 static_cast<Type>(InitialLengthAtRefAgeOld()));
692 break;
693
694 case LengthReferenceParameterization::kBothConstant:
695 vb->UseConstantReferenceMeanLengths(
696 static_cast<Type>(InitialLengthAtRefAgeYoung()),
697 static_cast<Type>(InitialLengthAtRefAgeOld()));
698 break;
699 }
700 }
701
702 void ValidateVonBertalanffySchnuteGrowthInputs(bool require_variability) {
703 if (this->mean_length_young.size() < 1 ||
704 this->mean_length_old.size() < 1 ||
705 this->growth_coefficient.size() < 1 ||
706 this->reference_age_for_length_young.size() < 1 ||
707 this->reference_age_for_length_old.size() < 1 ||
708 this->length_weight_a.size() < 1 || this->length_weight_b.size() < 1) {
709 Rcpp::stop("VonBertalanffySchnuteGrowth parameters not set");
710 }
711
712 const bool has_sd = this->length_at_age_sd_at_reference_ages.size() > 0;
713 const bool has_any_structured_delta =
714 this->log_sd_mean_length_young.size() > 0 ||
715 this->log_sd_mean_length_old.size() > 0 ||
716 this->log_sd_growth_coefficient.size() > 0 ||
717 this->mean_length_young_mean_length_old_logit_corr.size() > 0 ||
718 this->mean_length_young_growth_coefficient_logit_corr.size() > 0 ||
719 this->mean_length_old_growth_coefficient_logit_corr.size() > 0;
720 const bool has_structured_delta =
721 this->log_sd_mean_length_young.size() > 0 &&
722 this->log_sd_mean_length_old.size() > 0 &&
723 this->log_sd_growth_coefficient.size() > 0 &&
724 this->mean_length_young_mean_length_old_logit_corr.size() > 0 &&
725 this->mean_length_young_growth_coefficient_logit_corr.size() > 0 &&
726 this->mean_length_old_growth_coefficient_logit_corr.size() > 0;
727
728 if (require_variability && !has_sd && !has_any_structured_delta) {
729 Rcpp::stop(
730 "VonBertalanffySchnuteGrowth requires either "
731 "length_at_age_sd_at_reference_ages or the structured delta-method "
732 "growth variability inputs");
733 }
734
735 if (has_any_structured_delta && !has_structured_delta) {
736 Rcpp::stop(
737 "von Bertalanffy--Schnute growth requires all six structured "
738 "delta-method "
739 "variability inputs when using that path");
740 }
741
742 if (has_sd && has_structured_delta) {
743 Rcpp::stop(
744 "von Bertalanffy--Schnute growth requires variability inputs for "
745 "one supported path. Supply either the interpolation inputs "
746
747 "length_at_age_sd_at_reference_ages or the full delta-method "
748 "variability inputs, but not both");
749 }
750
751 if (has_sd && this->length_at_age_sd_at_reference_ages.size() != 2) {
752 Rcpp::stop("length_at_age_sd_at_reference_ages must have two values");
753 }
754
755 if (has_structured_delta &&
756 (this->log_sd_mean_length_young.size() != 1 ||
757 this->log_sd_mean_length_old.size() != 1 ||
758 this->log_sd_growth_coefficient.size() != 1 ||
759 this->mean_length_young_mean_length_old_logit_corr.size() != 1 ||
760 this->mean_length_young_growth_coefficient_logit_corr.size() != 1 ||
761 this->mean_length_old_growth_coefficient_logit_corr.size() != 1)) {
762 Rcpp::stop(
763 "VonBertalanffySchnuteGrowth currently supports a single structured "
764 "delta-method variability parameter set; expected size 1 for "
765 "each structured uncertainty input");
766 }
767
768 const double a1 = this->reference_age_for_length_young[0].initial_value_m;
769 const double a2 = this->reference_age_for_length_old[0].initial_value_m;
770 if (a2 <= a1) {
771 Rcpp::stop(
772 "VonBertalanffySchnuteGrowth reference_age_for_length_old must be > "
773 "reference_age_for_length_young");
774 }
775
776 auto check_positive = [](VariableVector& pv, const std::string& base_name) {
777 for (size_t i = 0; i < pv.size(); i++) {
778 if (pv[i].initial_value_m <= 0.0) {
779 Rcpp::stop((base_name + " must be > 0").c_str());
780 }
781 }
782 };
783
784 check_positive(this->mean_length_young, "mean_length_young");
785 check_positive(this->mean_length_old, "mean_length_old");
786 check_positive(this->growth_coefficient, "growth_coefficient");
787 check_positive(this->length_weight_a, "length_weight_a");
788 check_positive(this->length_weight_b, "length_weight_b");
789
790 if (this->mean_length_old[0].initial_value_m <=
791 this->mean_length_young[0].initial_value_m) {
792 Rcpp::stop(
793 "VonBertalanffySchnuteGrowth mean_length_old must be > "
794 "mean_length_young");
795 }
796
797 if (has_sd) {
798 check_positive(this->length_at_age_sd_at_reference_ages,
799 "length_at_age_sd_at_reference_ages");
800 }
801 }
802
803 public:
804 virtual std::string to_json() {
805 std::stringstream ss;
806
807 ss << "{\n";
808 ss << " \"module_name\":\"Growth\",\n";
809 ss << " \"module_type\": \"VonBertalanffySchnute\",\n";
810 ss << " \"module_id\": " << this->id << ",\n";
811
812 ss << " \"parameters\": [\n";
813
814 // mean_length_young
815 ss << "{\n";
816 ss << " \"name\": \"mean_length_young\",\n";
817 ss << " \"id\":" << this->mean_length_young.id_m << ",\n";
818 ss << " \"type\": \"vector\",\n";
819 ss << " \"dimensionality\": {\n";
820 ss << " \"header\": [null],\n";
821 ss << " \"dimensions\": [" << this->mean_length_young.size() << "]\n";
822 ss << " },\n";
823 ss << " \"values\":" << this->mean_length_young << "\n";
824 ss << "},\n";
825
826 // growth_coefficient
827 ss << "{\n";
828 ss << " \"name\": \"growth_coefficient\",\n";
829 ss << " \"id\":" << this->growth_coefficient.id_m << ",\n";
830 ss << " \"type\": \"vector\",\n";
831 ss << " \"dimensionality\": {\n";
832 ss << " \"header\": [null],\n";
833 ss << " \"dimensions\": [" << this->growth_coefficient.size() << "]\n";
834 ss << " },\n";
835 ss << " \"values\":" << this->growth_coefficient << "\n";
836 ss << "},\n";
837
838 // mean_length_old
839 ss << "{\n";
840 ss << " \"name\": \"mean_length_old\",\n";
841 ss << " \"id\":" << this->mean_length_old.id_m << ",\n";
842 ss << " \"type\": \"vector\",\n";
843 ss << " \"dimensionality\": {\n";
844 ss << " \"header\": [null],\n";
845 ss << " \"dimensions\": [" << this->mean_length_old.size() << "]\n";
846 ss << " },\n";
847 ss << " \"values\":" << this->mean_length_old << "\n";
848 ss << "},\n";
849
850 // reference_age_for_length_young
851 ss << "{\n";
852 ss << " \"name\": \"reference_age_for_length_young\",\n";
853 ss << " \"id\":" << this->reference_age_for_length_young.id_m << ",\n";
854 ss << " \"type\": \"vector\",\n";
855 ss << " \"dimensionality\": {\n";
856 ss << " \"header\": [null],\n";
857 ss << " \"dimensions\": [" << this->reference_age_for_length_young.size()
858 << "]\n";
859 ss << " },\n";
860 ss << " \"values\":" << this->reference_age_for_length_young << "\n";
861 ss << "},\n";
862
863 // reference_age_for_length_old
864 ss << "{\n";
865 ss << " \"name\": \"reference_age_for_length_old\",\n";
866 ss << " \"id\":" << this->reference_age_for_length_old.id_m << ",\n";
867 ss << " \"type\": \"vector\",\n";
868 ss << " \"dimensionality\": {\n";
869 ss << " \"header\": [null],\n";
870 ss << " \"dimensions\": [" << this->reference_age_for_length_old.size()
871 << "]\n";
872 ss << " },\n";
873 ss << " \"values\":" << this->reference_age_for_length_old << "\n";
874 ss << "},\n";
875
876 // length_weight_a
877 ss << "{\n";
878 ss << " \"name\": \"length_weight_a\",\n";
879 ss << " \"id\":" << this->length_weight_a.id_m << ",\n";
880 ss << " \"type\": \"vector\",\n";
881 ss << " \"dimensionality\": {\n";
882 ss << " \"header\": [null],\n";
883 ss << " \"dimensions\": [" << this->length_weight_a.size() << "]\n";
884 ss << " },\n";
885 ss << " \"values\":" << this->length_weight_a << "\n";
886 ss << "},\n";
887
888 // length_weight_b (last)
889 ss << "{\n";
890 ss << " \"name\": \"length_weight_b\",\n";
891 ss << " \"id\":" << this->length_weight_b.id_m << ",\n";
892 ss << " \"type\": \"vector\",\n";
893 ss << " \"dimensionality\": {\n";
894 ss << " \"header\": [null],\n";
895 ss << " \"dimensions\": [" << this->length_weight_b.size() << "]\n";
896 ss << " },\n";
897 ss << " \"values\":" << this->length_weight_b << "\n";
898 ss << "}";
899
900 // Optional variability parameters
901 auto append_optional_parameter = [&](const std::string& name,
902 VariableVector& pv) {
903 if (pv.size() == 0) {
904 return;
905 }
906
907 ss << ",\n";
908 ss << "{\n";
909 ss << " \"name\": \"" << name << "\",\n";
910 ss << " \"id\":" << pv.id_m << ",\n";
911 ss << " \"type\": \"vector\",\n";
912 ss << " \"dimensionality\": {\n";
913 ss << " \"header\": [null],\n";
914 ss << " \"dimensions\": [" << pv.size() << "]\n";
915 ss << " },\n";
916 ss << " \"values\":" << pv << "\n";
917 ss << "}";
918 };
919
920 append_optional_parameter("length_at_age_sd_at_reference_ages",
921 this->length_at_age_sd_at_reference_ages);
922 append_optional_parameter("log_sd_mean_length_young",
923 this->log_sd_mean_length_young);
924 append_optional_parameter("log_sd_mean_length_old",
925 this->log_sd_mean_length_old);
926 append_optional_parameter("log_sd_growth_coefficient",
927 this->log_sd_growth_coefficient);
928 append_optional_parameter(
929 "mean_length_young_mean_length_old_logit_corr",
930 this->mean_length_young_mean_length_old_logit_corr);
931 append_optional_parameter(
932 "mean_length_young_growth_coefficient_logit_corr",
933 this->mean_length_young_growth_coefficient_logit_corr);
934 append_optional_parameter(
935 "mean_length_old_growth_coefficient_logit_corr",
936 this->mean_length_old_growth_coefficient_logit_corr);
937
938 ss << "\n]\n";
939 ss << "}";
940
941 return ss.str();
942 }
943#ifdef TMB_MODEL
944 template <typename Type>
945 bool add_to_fims_tmb_internal() {
946 std::shared_ptr<fims_info::Information<Type>> info =
948
949 std::shared_ptr<fims_popdy::GrowthDerivedObservationBase<Type>>
950 growth_observation = std::make_shared<
952 std::shared_ptr<fims_popdy::VonBertalanffySchnuteGrowthModelAdapter<Type>>
953 vb = std::dynamic_pointer_cast<
955 growth_observation);
956 if (!vb) {
957 Rcpp::stop(
958 "Failed to create VonBertalanffySchnute growth-derived observation "
959 "model");
960 }
961
962 vb->id = this->id;
963
964 // Build parameter vectors and register if estimable. Growth variability
965 // must be supplied through either the legacy interpolation SD anchors or
966 // the transformed delta-method variability inputs.
967 ValidateVonBertalanffySchnuteGrowthInputs(true);
968
969 std::stringstream ss;
970 auto load_and_register = [&](VariableVector& pv, fims::Vector<Type>& target,
971 const std::string& base_name, bool log_scale) {
972 target.resize(pv.size());
973 for (size_t i = 0; i < pv.size(); i++) {
974 double v = pv[i].initial_value_m;
975 if (log_scale) {
976 if (v <= 0.0) {
977 Rcpp::stop((base_name + " must be > 0").c_str());
978 }
979 v = fims_math::log(v);
980 }
981 target[i] = static_cast<Type>(v);
982 if (pv[i].estimation_type_m.get() == "fixed_effects") {
983 ss.str("");
984 ss << "Growth." << this->id << "." << base_name << "." << pv[i].id_m;
985 info->RegisterParameterName(ss.str());
986 info->RegisterParameter(target[i]);
987 }
988 if (pv[i].estimation_type_m.get() == "random_effects") {
989 ss.str("");
990 ss << "Growth." << this->id << "." << base_name << "." << pv[i].id_m;
991 info->RegisterRandomEffectName(ss.str());
992 info->RegisterRandomEffect(target[i]);
993 }
994 }
995 info->variable_map[pv.id_m] = &target;
996 };
997
998 auto load_optional_and_register =
999 [&](VariableVector& pv, fims::Vector<Type>& target,
1000 const std::string& base_name, bool log_scale) {
1001 if (pv.size() == 0) {
1002 target.resize(0);
1003 return;
1004 }
1005 load_and_register(pv, target, base_name, log_scale);
1006 };
1007
1008 ConfigureLengthReferenceParameterization<Type>(vb);
1009
1010 load_and_register(this->mean_length_young, vb->MeanLengthYoungVector(),
1011 "mean_length_young", true);
1012 load_and_register(this->mean_length_old, vb->MeanLengthOldVector(),
1013 "mean_length_old", true);
1014 load_and_register(this->growth_coefficient, vb->GrowthCoefficientVector(),
1015 "growth_coefficient", true);
1016 load_and_register(this->reference_age_for_length_young,
1017 vb->ReferenceAgeForLengthYoungVector(),
1018 "reference_age_for_length_young", false);
1019 load_and_register(this->reference_age_for_length_old,
1020 vb->ReferenceAgeForLengthOldVector(),
1021 "reference_age_for_length_old", false);
1022 load_and_register(this->length_weight_a, vb->LengthWeightAVector(),
1023 "length_weight_a", true);
1024 load_and_register(this->length_weight_b, vb->LengthWeightBVector(),
1025 "length_weight_b", true);
1026 load_optional_and_register(this->length_at_age_sd_at_reference_ages,
1027 vb->LengthAtAgeSdAtRefAgesVector(),
1028 "length_at_age_sd_at_reference_ages", true);
1029 load_optional_and_register(this->log_sd_mean_length_young,
1030 vb->LogSdLengthAtRefAgeYoungVector(),
1031 "log_sd_mean_length_young", false);
1032 load_optional_and_register(this->log_sd_mean_length_old,
1033 vb->LogSdLengthAtRefAgeOldVector(),
1034 "log_sd_mean_length_old", false);
1035 load_optional_and_register(this->log_sd_growth_coefficient,
1036 vb->LogSdGrowthCoefficientVector(),
1037 "log_sd_growth_coefficient", false);
1038 load_optional_and_register(
1039 this->mean_length_young_mean_length_old_logit_corr,
1040 vb->LogitCorrLengthAtRefAgeYoungLengthAtRefAgeOldVector(),
1041 "mean_length_young_mean_length_old_logit_corr", false);
1042 load_optional_and_register(
1043 this->mean_length_young_growth_coefficient_logit_corr,
1044 vb->LogitCorrLengthAtRefAgeYoungKVector(),
1045 "mean_length_young_growth_coefficient_logit_corr", false);
1046 load_optional_and_register(
1047 this->mean_length_old_growth_coefficient_logit_corr,
1048 vb->LogitCorrLengthAtRefAgeOldKVector(),
1049 "mean_length_old_growth_coefficient_logit_corr", false);
1050
1051 this->RegisterGrowthObservationInInfo<Type>(growth_observation);
1052 return true;
1053 }
1054
1055 virtual bool add_to_fims_tmb() {
1056 this->add_to_fims_tmb_internal<TMB_FIMS_REAL_TYPE>();
1057 this->add_to_fims_tmb_internal<TMBAD_FIMS_TYPE>();
1058 return true;
1059 }
1060#endif
1061
1062}; // end class
1063
1064#endif
Rcpp interface for EWAAGrowth to instantiate the object from R: ewaa <- methods::new(EWAAGrowth)....
Definition rcpp_growth.hpp:149
virtual ~EWAAGrowthInterface()
The destructor.
Definition rcpp_growth.hpp:201
SharedInt n_years
An integer specifying the number of years.
Definition rcpp_growth.hpp:163
std::shared_ptr< std::map< int, std::map< double, double > > > ewaa
A map of empirical weight-at-age values allowing multiple modules to access and modify the weights wi...
Definition rcpp_growth.hpp:168
virtual uint32_t get_id()
Gets the ID of the interface base object.
Definition rcpp_growth.hpp:207
RealVector ages
Ages (years) for each age class.
Definition rcpp_growth.hpp:158
virtual double evaluate(double age)
Evaluate the growth using empirical weight at age.
Definition rcpp_growth.hpp:271
EWAAGrowthInterface(const EWAAGrowthInterface &other)
Construct a new EWAAGrowthInterface object.
Definition rcpp_growth.hpp:190
std::map< int, std::map< double, double > > make_map(RealVector ages, RealVector weights, SharedInt n_years)
Create a map of input numeric vectors.
Definition rcpp_growth.hpp:216
bool initialized
Have weight and age vectors been set? The default is false.
Definition rcpp_growth.hpp:172
RealVector weights
Weights (mt) for each age class.
Definition rcpp_growth.hpp:154
EWAAGrowthInterface()
The constructor.
Definition rcpp_growth.hpp:177
virtual std::string to_json()
Converts the data to json representation for the output.
Definition rcpp_growth.hpp:293
Base class for all interface objects.
Definition rcpp_interface_base.hpp:656
bool finalized
Is the object already finalized? The default is false.
Definition rcpp_interface_base.hpp:661
static std::vector< std::shared_ptr< FIMSRcppInterfaceBase > > fims_interface_objects
FIMS interface object vectors.
Definition rcpp_interface_base.hpp:666
virtual bool add_to_fims_tmb()
A virtual method to inherit to add objects to the TMB model.
Definition rcpp_interface_base.hpp:671
Rcpp interface base for growth models that can register a growth-derived observation capability with ...
Definition rcpp_growth.hpp:84
void RegisterGrowthObservationInInfo(const std::shared_ptr< fims_popdy::GrowthDerivedObservationBase< Type > > &growth_observation) const
Register a runtime growth-derived observation in Information.
Definition rcpp_growth.hpp:135
GrowthDerivedObservationInterfaceBase(const GrowthDerivedObservationInterfaceBase &other)
Copy constructor.
Definition rcpp_growth.hpp:92
std::shared_ptr< fims_popdy::GrowthDerivedObservationBase< Type > > GetGrowthObservationFromInfo() const
Look up the registered growth-derived observation object.
Definition rcpp_growth.hpp:105
Rcpp interface that serves as the parent class for Rcpp growth interfaces. This type should be inheri...
Definition rcpp_growth.hpp:24
static std::map< uint32_t, std::shared_ptr< GrowthInterfaceBase > > live_objects
The map associating the IDs of GrowthInterfaceBase to the objects. This is a live object,...
Definition rcpp_growth.hpp:39
virtual double evaluate(double age)=0
A method for each child growth interface object to inherit so each growth option can have an evaluate...
GrowthInterfaceBase(const GrowthInterfaceBase &other)
Construct a new Growth Interface Base object.
Definition rcpp_growth.hpp:57
static uint32_t id_g
The static id of the GrowthInterfaceBase object.
Definition rcpp_growth.hpp:29
virtual ~GrowthInterfaceBase()
The destructor.
Definition rcpp_growth.hpp:62
GrowthInterfaceBase()
The constructor.
Definition rcpp_growth.hpp:44
uint32_t id
The local id of the GrowthInterfaceBase object.
Definition rcpp_growth.hpp:33
virtual uint32_t get_id()=0
Get the ID for the child growth interface objects to inherit.
An Rcpp interface class that defines the RealVector class.
Definition rcpp_interface_base.hpp:432
size_t size()
Returns the size of a RealVector.
Definition rcpp_interface_base.hpp:603
A class that provides shared ownership of an integer value.
Definition rcpp_shared_primitive.hpp:29
int get() const
Retrieve the value of the integer.
Definition rcpp_shared_primitive.hpp:127
An Rcpp interface class that defines the VariableVector class.
Definition rcpp_interface_base.hpp:144
Variable & get(size_t pos)
An internal accessor for calling a position of a VariableVector from R.
Definition rcpp_interface_base.hpp:267
uint32_t id_m
The local ID of the Variable object.
Definition rcpp_interface_base.hpp:157
void resize(size_t size)
Resizes a VariableVector to the desired length.
Definition rcpp_interface_base.hpp:295
size_t size()
Returns the size of a VariableVector.
Definition rcpp_interface_base.hpp:288
Rcpp-facing VonBertalanffySchnute growth module. Inherits "derived observation" capability so this gr...
Definition rcpp_growth.hpp:368
VonBertalanffySchnuteGrowthInterface(const VonBertalanffySchnuteGrowthInterface &other)
Copy constructor.
Definition rcpp_growth.hpp:451
VariableVector log_sd_growth_coefficient
Working-scale von Bertalanffy–Schnute variability parameter for sd(log(growth_coefficient)).
Definition rcpp_growth.hpp:405
virtual void finalize()
Extracts derived quantities back to the Rcpp interface object from the Information object.
Definition rcpp_growth.hpp:483
VariableVector mean_length_young
Expected length at the first reference age.
Definition rcpp_growth.hpp:371
virtual uint32_t get_id()
Get the ID for the child growth interface objects to inherit.
Definition rcpp_growth.hpp:477
VariableVector log_sd_mean_length_young
Working-scale von Bertalanffy–Schnute variability parameter for sd(log(mean_length_young)).
Definition rcpp_growth.hpp:395
VariableVector reference_age_for_length_young
First reference age for the length parameterization.
Definition rcpp_growth.hpp:378
VariableVector mean_length_young_growth_coefficient_logit_corr
Working-scale von Bertalanffy–Schnute variability parameter for corr(log(mean_length_young),...
Definition rcpp_growth.hpp:415
VariableVector length_at_age_sd_at_reference_ages
Natural-scale SD values at the two reference ages for the legacy interpolation path.
Definition rcpp_growth.hpp:390
VariableVector growth_coefficient
Growth coefficient.
Definition rcpp_growth.hpp:375
virtual double evaluate(double age)
A method for each child growth interface object to inherit so each growth option can have an evaluate...
Definition rcpp_growth.hpp:553
VonBertalanffySchnuteGrowthInterface()
Construct a new VonBertalanffySchnute growth interface.
Definition rcpp_growth.hpp:427
SharedInt n_ages
Modeled number of ages used for validation.
Definition rcpp_growth.hpp:422
VariableVector reference_age_for_length_old
Second reference age for the length parameterization.
Definition rcpp_growth.hpp:380
VariableVector length_weight_a
Coefficient in the length-weight relationship, W = a * L^b.
Definition rcpp_growth.hpp:383
VariableVector log_sd_mean_length_old
Working-scale von Bertalanffy–Schnute variability parameter for sd(log(mean_length_old)).
Definition rcpp_growth.hpp:400
VariableVector mean_length_old_growth_coefficient_logit_corr
Working-scale von Bertalanffy–Schnute variability parameter for corr(log(mean_length_old),...
Definition rcpp_growth.hpp:420
VariableVector mean_length_young_mean_length_old_logit_corr
Working-scale von Bertalanffy–Schnute variability parameter for corr(log(mean_length_young),...
Definition rcpp_growth.hpp:410
VariableVector mean_length_old
Expected length at the second reference age.
Definition rcpp_growth.hpp:373
virtual std::string to_json()
Convert the data to json representation for the output.
Definition rcpp_growth.hpp:804
VariableVector length_weight_b
Exponent in the length-weight relationship, W = a * L^b.
Definition rcpp_growth.hpp:385
Definition fims_vector.hpp:27
std::map< uint32_t, std::shared_ptr< fims_popdy::GrowthBase< Type > > >::iterator growth_models_iterator
Definition information.hpp:96
std::map< uint32_t, std::shared_ptr< fims_popdy::GrowthBase< Type > > > growth_models
Definition information.hpp:91
static std::shared_ptr< Information< Type > > GetInstance()
Returns a singleton Information object for type T.
Definition information.hpp:269
Generic capability interface for growth models that can feed the growth-derived age-to-length convers...
Definition growth_model_adapter.hpp:26
von Bertalanffy–Schnute growth model adapter implementing the generic growth-derived observation capa...
Definition growth_model_adapter.hpp:79
#define FIMS_WARNING_LOG(MESSAGE)
Definition def.hpp:648
A collection of mathematical functions used in FIMS.
const Type inv_logit(const Type &a, const Type &b, const Type &logit_x)
An inverse logit function for bounding of parameters.
Definition fims_math.hpp:276
Establishes the FIMS Vector class.
Includes any .hpp files within the subfolders so that only this file needs to included in include sta...
The Rcpp interface to declare objects that are used ubiquitously throughout the Rcpp interface,...
EWAAGrowth class that returns the EWAA function value.
Definition ewaa.hpp:23
std::map< int, std::map< double, double > > ewaa
Definition ewaa.hpp:29
virtual const Type evaluate(int year, const double &a)
Returns the weight at age a (in kg) from the input vector.
Definition ewaa.hpp:44
VonBertalanffySchnute growth functor for length-at-age and weight-at-age.
Definition vonb_schnute.hpp:32
Type mean_length_young
Expected length at the first reference age.
Definition vonb_schnute.hpp:34
Type reference_age_for_length_old
Second reference age for the length parameterization.
Definition vonb_schnute.hpp:42
Type growth_coefficient
Growth coefficient.
Definition vonb_schnute.hpp:38
Type length_weight_b
Exponent in the length-weight relationship, W = a * L^b.
Definition vonb_schnute.hpp:47
Type reference_age_for_length_young
First reference age for the length parameterization.
Definition vonb_schnute.hpp:40
Type length_weight_a
Coefficient in the length-weight relationship, W = a * L^b.
Definition vonb_schnute.hpp:45
virtual const Type evaluate(int year, const double &a) override
Calculates the growth at the independent variable value.
Definition vonb_schnute.hpp:194
Type mean_length_old
Expected length at the second reference age.
Definition vonb_schnute.hpp:36