distribution/tabulated.h
| Line | Branch | Exec | Source |
|---|---|---|---|
| 1 | /// @file | ||
| 2 | /// @brief Size-frequency distributions given as tables, interpolated in log-log space. | ||
| 3 | #pragma once | ||
| 4 | |||
| 5 | #include "terraingen/distribution/size_frequency.h" | ||
| 6 | |||
| 7 | #include <cstddef> | ||
| 8 | #include <vector> | ||
| 9 | |||
| 10 | namespace terraingen { | ||
| 11 | |||
| 12 | /// A cumulative distribution given as a table of (D, N(>=D)) points, interpolated linearly | ||
| 13 | /// in log D and log N, so each interval is a power law. Extrapolation continues the end intervals' | ||
| 14 | /// slopes. | ||
| 15 | class TabulatedSfd final : public SizeFrequencyDistribution { | ||
| 16 | public: | ||
| 17 | /// The distribution through the table's points. | ||
| 18 | /// @param diameters At least two strictly increasing positive diameters, in `diameterUnit` | ||
| 19 | /// metres. | ||
| 20 | /// @param cumulative N(>=D) at each diameter, positive, finite and not increasing, per | ||
| 21 | /// `areaUnit` m^2. | ||
| 22 | /// @param diameterUnit Metres per table diameter unit. | ||
| 23 | /// @param areaUnit m^2 per table area unit. | ||
| 24 | /// @throws std::invalid_argument for fewer than two points, mismatched lengths, units or values | ||
| 25 | /// that are not positive and finite, diameters that do not strictly increase, or values that | ||
| 26 | /// increase. | ||
| 27 | TabulatedSfd(std::vector<double> diameters, std::vector<double> cumulative, | ||
| 28 | SfdKind kind = SfdKind::Density, double diameterUnit = 1.0, double areaUnit = 1.0); | ||
| 29 | |||
| 30 | /// The table's diameters in metres. | ||
| 31 | 2 | const std::vector<double>& Diameters() const { | |
| 32 | 2 | return diameters_; | |
| 33 | } | ||
| 34 | |||
| 35 | /// The table's N(>=D) values per m^2 (or per m^2 per Gyr). | ||
| 36 | 2 | const std::vector<double>& CumulativeValues() const { | |
| 37 | 2 | return cumulative_; | |
| 38 | } | ||
| 39 | |||
| 40 | protected: | ||
| 41 | double CumulativeAt(double diameter) const override; | ||
| 42 | double IncrementalAt(double diameter) const override; | ||
| 43 | /// The power-law inverse within the interval holding `target`, ignoring `dMin` and `dMax`; a | ||
| 44 | /// flat interval, where N(>=D) never reaches `target`, gives its start diameter. | ||
| 45 | double InvertCumulative(double target, double dMin, double dMax) const override; | ||
| 46 | |||
| 47 | private: | ||
| 48 | std::size_t IntervalAt(double diameter) const; | ||
| 49 | |||
| 50 | std::vector<double> diameters_; | ||
| 51 | std::vector<double> cumulative_; | ||
| 52 | std::vector<double> slopes_; | ||
| 53 | }; | ||
| 54 | |||
| 55 | } // namespace terraingen | ||
| 56 |