9#ifndef FIMS_POPULATION_DYNAMICS_SIZE_BIN_MAPPING_HPP
10#define FIMS_POPULATION_DYNAMICS_SIZE_BIN_MAPPING_HPP
37 static double OverlapWidth(
double left_a,
double right_a,
double left_b,
40 0.0, (std::min)(right_a, right_b) - (std::max)(left_a, left_b));
50 if (edges.
size() < 2) {
54 for (std::size_t i = 0; i + 1 < edges.
size(); ++i) {
55 if (!(edges[i + 1] > edges[i])) {
83 throw std::runtime_error(
84 "SizeBinMapping requires strictly increasing source and "
89 throw std::runtime_error(
90 "SizeBinMapping requires destination edges to cover the full "
94 const std::size_t n_source_bins = source_edges.
size() - 1;
95 const std::size_t n_destination_bins = destination_edges.
size() - 1;
98 weights.
resize(n_destination_bins);
100 for (std::size_t i = 0; i < n_destination_bins; ++i) {
101 weights[i].
resize(n_source_bins);
103 for (std::size_t j = 0; j < n_source_bins; ++j) {
104 const double source_left = source_edges[j];
105 const double source_right = source_edges[j + 1];
106 const double destination_left = destination_edges[i];
107 const double destination_right = destination_edges[i + 1];
108 const double source_width = source_right - source_left;
110 source_left, source_right, destination_left, destination_right);
112 weights[i][j] = source_width > 0.0 ? overlap / source_width : 0.0;
133 return destination_edges[0] <= source_edges[0] &&
134 destination_edges[destination_edges.
size() - 1] >=
135 source_edges[source_edges.
size() - 1];
157 throw std::runtime_error(
158 "SizeBinMapping requires strictly increasing source and "
159 "destination edges");
164 if (expanded_edges[0] > source_edges[0]) {
165 expanded_edges[0] = source_edges[0];
168 const std::size_t last_destination_edge = expanded_edges.
size() - 1;
169 const std::size_t last_source_edge = source_edges.
size() - 1;
171 if (expanded_edges[last_destination_edge] <
172 source_edges[last_source_edge]) {
173 expanded_edges[last_destination_edge] = source_edges[last_source_edge];
176 return expanded_edges;
211 template <
typename Type>
216 destination_mass.
resize(weights.size());
218 for (std::size_t i = 0; i < weights.size(); ++i) {
219 Type total = Type(0.0);
221 if (weights[i].size() != source_mass.
size()) {
222 throw std::runtime_error(
223 "SizeBinMapping weight rows must match source mass length");
226 for (std::size_t j = 0; j < source_mass.
size(); ++j) {
227 total += source_mass[j] * weights[i][j];
230 destination_mass[i] = total;
233 return destination_mass;
Definition fims_vector.hpp:27
void resize(size_t s)
Changes the number of elements stored.
Definition fims_vector.hpp:401
size_type size() const
Returns the number of elements.
Definition fims_vector.hpp:299
Establishes the FIMS Vector class.
The population dynamics of FIMS.
Definition catch_at_age.hpp:45
Defines the SizeGrid container for population-level biological size support.
Helper for mapping population biological size bins to observed fleet bins.
Definition size_bin_mapping.hpp:28
static bool HasStrictlyIncreasingEdges(const fims::Vector< double > &edges)
Check that a bin-edge vector is usable for geometric mapping.
Definition size_bin_mapping.hpp:49
static fims::Vector< fims::Vector< double > > BuildRebinWeights(const fims::Vector< double > &source_edges, const fims::Vector< double > &destination_edges)
Build overlap-based rebin weights from source bins to destination bins.
Definition size_bin_mapping.hpp:78
static double OverlapWidth(double left_a, double right_a, double left_b, double right_b)
Return the overlap width between two 1-D closed-open intervals.
Definition size_bin_mapping.hpp:37
static bool DestinationCoversSourceRange(const fims::Vector< double > &source_edges, const fims::Vector< double > &destination_edges)
Check that the destination edges fully cover the source-bin range.
Definition size_bin_mapping.hpp:125
static fims::Vector< Type > ApplyRebinWeights(const fims::Vector< fims::Vector< double > > &weights, const fims::Vector< Type > &source_mass)
Apply a source-to-destination bin mapping to a size-mass vector.
Definition size_bin_mapping.hpp:212
static fims::Vector< double > ExpandDestinationEdgesToCoverSourceRange(const fims::Vector< double > &source_edges, const fims::Vector< double > &destination_edges)
Return explicit mapping edges whose support covers the source range while preserving the canonical de...
Definition size_bin_mapping.hpp:152