distribution/piecewise_power_law.h
| Line | Branch | Exec | Source |
|---|---|---|---|
| 1 | /// @file | ||
| 2 | /// @brief Size-frequency distributions made of power-law segments. | ||
| 3 | #pragma once | ||
| 4 | |||
| 5 | #include "terraingen/distribution/power_law.h" | ||
| 6 | #include "terraingen/distribution/size_frequency.h" | ||
| 7 | |||
| 8 | #include <vector> | ||
| 9 | |||
| 10 | namespace terraingen { | ||
| 11 | |||
| 12 | /// A cumulative distribution made of power-law segments in increasing diameter order, each | ||
| 13 | /// applying from its `start` up to the next segment's start. | ||
| 14 | /// | ||
| 15 | /// Segments must meet at their joins within a relative tolerance unless `allowDiscontinuities` is | ||
| 16 | /// set (for legacy specifications). A downward jump at a join gives a finite fraction of the | ||
| 17 | /// population exactly the join diameter, which `SampleDiameter` returns for that fraction. | ||
| 18 | class PiecewisePowerLawSfd final : public SizeFrequencyDistribution { | ||
| 19 | public: | ||
| 20 | /// The distribution made of `segments`. | ||
| 21 | /// @param segments At least one segment, with strictly increasing `start` and the first `start` | ||
| 22 | /// equal to `range.min`. | ||
| 23 | /// @param range The valid range, in metres. | ||
| 24 | /// @param tolerance Relative mismatch allowed at a join. | ||
| 25 | /// @throws std::invalid_argument for no segments, a coefficient or exponent that is not | ||
| 26 | /// positive and finite, starts that do not increase within the range, a join that rises, or a | ||
| 27 | /// discontinuity larger than `tolerance` without `allowDiscontinuities`. | ||
| 28 | PiecewisePowerLawSfd(std::vector<PowerLawSegment> segments, SfdKind kind = SfdKind::Density, | ||
| 29 | DiameterRange range = {}, bool allowDiscontinuities = false, | ||
| 30 | double tolerance = 1e-3); | ||
| 31 | |||
| 32 | /// The segments in increasing `start` order. | ||
| 33 | 2 | const std::vector<PowerLawSegment>& Segments() const { | |
| 34 | 2 | return segments_; | |
| 35 | } | ||
| 36 | |||
| 37 | protected: | ||
| 38 | double CumulativeAt(double diameter) const override; | ||
| 39 | double IncrementalAt(double diameter) const override; | ||
| 40 | double InvertCumulative(double target, double dMin, double dMax) const override; | ||
| 41 | |||
| 42 | private: | ||
| 43 | const PowerLawSegment& SegmentAt(double diameter) const; | ||
| 44 | |||
| 45 | std::vector<PowerLawSegment> segments_; | ||
| 46 | }; | ||
| 47 | |||
| 48 | } // namespace terraingen | ||
| 49 |