FIMS  v0.11.0
Loading...
Searching...
No Matches
size_grid_builder.hpp
Go to the documentation of this file.
1
9#ifndef FIMS_POPULATION_DYNAMICS_SIZE_GRID_BUILDER_HPP
10#define FIMS_POPULATION_DYNAMICS_SIZE_GRID_BUILDER_HPP
11
12#include <stdexcept>
13
14#include "../size_grid.hpp"
15
16namespace fims_popdy {
17
31 if (edges.size() < 2) {
32 throw std::runtime_error(
33 "SizeGridBuilder requires at least 2 edges to define a size grid");
34 }
35
36 SizeGrid grid;
37 grid.n_bins = edges.size() - 1;
38 grid.edges = edges;
39 grid.centers.resize(grid.n_bins);
40
41 for (std::size_t i = 0; i < grid.n_bins; ++i) {
42 grid.centers[i] = 0.5 * (grid.edges[i] + grid.edges[i + 1]);
43 }
44
45 if (!grid.IsConsistent()) {
46 throw std::runtime_error(
47 "SizeGridBuilder produced an inconsistent population size grid");
48 }
49
50 return grid;
51 }
52
61 static SizeGrid BuildRegularGrid(double lower_edge, double upper_edge,
62 double bin_width) {
63 if (!(upper_edge > lower_edge)) {
64 throw std::runtime_error(
65 "SizeGridBuilder requires upper_edge > lower_edge");
66 }
67
68 if (!(bin_width > 0.0)) {
69 throw std::runtime_error("SizeGridBuilder requires bin_width > 0");
70 }
71
73 edges.emplace_back(lower_edge);
74
75 const double span = upper_edge - lower_edge;
76 const double tolerance = 1e-12 * (span > 1.0 ? span : 1.0);
77
78 std::size_t bin_index = 1;
79 while (true) {
80 const double next_edge = lower_edge + bin_index * bin_width;
81
82 if (next_edge >= upper_edge - tolerance) {
83 break;
84 }
85
86 edges.emplace_back(next_edge);
87 ++bin_index;
88 }
89
90 edges.emplace_back(upper_edge);
91
92 return BuildFromEdges(edges);
93 }
94
113 const fims::Vector<double>& lower_edges) {
114 if (lower_edges.size() < 2) {
115 throw std::runtime_error(
116 "SizeGridBuilder requires at least 2 observation-bin lower edges to "
117 "build fleet edges");
118 }
119
120 for (std::size_t edge_index = 1; edge_index < lower_edges.size();
121 ++edge_index) {
122 if (!(lower_edges[edge_index] > lower_edges[edge_index - 1])) {
123 throw std::runtime_error(
124 "SizeGridBuilder requires observation-bin lower edges to be "
125 "strictly increasing");
126 }
127 }
128
129 const std::size_t n_bins = lower_edges.size();
130 fims::Vector<double> edges = lower_edges;
131 edges.emplace_back(lower_edges[n_bins - 1] +
132 (lower_edges[n_bins - 1] - lower_edges[n_bins - 2]));
133
134 return edges;
135 }
136
156 const fims::Vector<fims::Vector<double>>& fleet_edges) {
157 if (fleet_edges.size() == 0) {
158 throw std::runtime_error(
159 "SizeGridBuilder requires at least 1 fleet edge vector to build the "
160 "default population size grid");
161 }
162
163 double min_lower_edge = 0.0;
164 double max_upper_edge = 0.0;
165 bool first_fleet = true;
166
167 for (std::size_t fleet_index = 0; fleet_index < fleet_edges.size();
168 ++fleet_index) {
169 const fims::Vector<double>& edges = fleet_edges[fleet_index];
170
171 if (edges.size() < 2) {
172 throw std::runtime_error(
173 "SizeGridBuilder requires each fleet edge vector to contain at "
174 "least 2 edges");
175 }
176
177 for (std::size_t edge_index = 1; edge_index < edges.size();
178 ++edge_index) {
179 if (!(edges[edge_index] > edges[edge_index - 1])) {
180 throw std::runtime_error(
181 "SizeGridBuilder requires fleet edge vectors to be strictly "
182 "increasing");
183 }
184 }
185
186 const double fleet_lower_edge = edges[0];
187 const double fleet_upper_edge = edges[edges.size() - 1];
188
189 if (first_fleet) {
190 min_lower_edge = fleet_lower_edge;
191 max_upper_edge = fleet_upper_edge;
192 first_fleet = false;
193 } else {
194 if (fleet_lower_edge < min_lower_edge) {
195 min_lower_edge = fleet_lower_edge;
196 }
197
198 if (fleet_upper_edge > max_upper_edge) {
199 max_upper_edge = fleet_upper_edge;
200 }
201 }
202 }
203
204 const double built_in_bin_width = 1.0;
205 double regular_upper_edge = min_lower_edge;
206 const double span = max_upper_edge - min_lower_edge;
207 const double tolerance = 1e-12 * (span > 1.0 ? span : 1.0);
208
209 while (regular_upper_edge < max_upper_edge - tolerance) {
210 regular_upper_edge += built_in_bin_width;
211 }
212
213 SizeGrid regular_grid = BuildRegularGrid(min_lower_edge, regular_upper_edge,
214 built_in_bin_width);
215
216 fims::Vector<double> default_edges = regular_grid.edges;
217 default_edges.emplace_back(regular_upper_edge + built_in_bin_width);
218
219 return BuildFromEdges(default_edges);
220 }
221};
222
223} // namespace fims_popdy
224
225#endif /* FIMS_POPULATION_DYNAMICS_SIZE_GRID_BUILDER_HPP */
Definition fims_vector.hpp:27
void emplace_back(Args &&...args)
Constructs an element in-place at the end.
Definition fims_vector.hpp:389
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
The population dynamics of FIMS.
Definition catch_at_age.hpp:45
Defines the SizeGrid container for population-level biological size support.
Helper for constructing internally consistent population size grids.
Definition size_grid_builder.hpp:24
static fims::Vector< double > BuildObservationEdgesFromLowerEdges(const fims::Vector< double > &lower_edges)
Build one fleet observation-bin edge vector from stored bin lower edges.
Definition size_grid_builder.hpp:112
static SizeGrid BuildFromEdges(const fims::Vector< double > &edges)
Build a size grid from an explicit vector of bin edges.
Definition size_grid_builder.hpp:30
static SizeGrid BuildRegularGrid(double lower_edge, double upper_edge, double bin_width)
Build a regular size grid from lower edge, upper edge, and bin width.
Definition size_grid_builder.hpp:61
static SizeGrid BuildDefaultFromFleetEdges(const fims::Vector< fims::Vector< double > > &fleet_edges)
Build the default population biological size grid from resolved fleet observation-bin edges.
Definition size_grid_builder.hpp:155
Population-level biological size grid.
Definition size_grid.hpp:26
bool IsConsistent() const
Return whether the grid dimensions and geometry are internally consistent.
Definition size_grid.hpp:80
fims::Vector< double > centers
Definition size_grid.hpp:29
fims::Vector< double > edges
Definition size_grid.hpp:28
std::size_t n_bins
Definition size_grid.hpp:27