6#include <Common/assertion.h>
16 const T min,
const T max,
17 const std::vector<T>& weights) :
21 weights.data(), weights.size())
28 const T*
const weights,
29 const std::size_t numWeights) :
31 m_min(min), m_max(max),
35 m_firstNonZeroPdfColumn(0),
38 m_cdf(numWeights + 1, 0)
40 PH_ASSERT(max > min && weights && numWeights > 0);
41 m_delta = (max - min) /
static_cast<T
>(numWeights);
45 for(std::size_t i = 1; i <= numWeights; ++i)
47 const T wi = weights[i - 1];
50 m_cdf[i] = m_cdf[i - 1] + wi * m_delta;
53 const T rcpSum =
static_cast<T
>(1) / m_cdf.back();
59 if(std::isfinite(rcpSum))
62 for(std::size_t i = 1; i < numWeights; ++i)
70 for(std::size_t i = 1; i < numWeights; ++i)
72 m_cdf[i] =
static_cast<T
>(i) /
static_cast<T
>(numWeights);
77 for(std::size_t i = 0; i < numColumns(); ++i)
79 if(pdfContinuous(i) > 0)
81 m_firstNonZeroPdfColumn = i;
86 PH_ASSERT_EQ(m_cdf.front(), 0);
87 PH_ASSERT_EQ(m_cdf.back(), 1);
101 const auto& result = std::lower_bound(m_cdf.begin(), m_cdf.end(), sample);
102 PH_ASSERT_MSG(result != m_cdf.end(),
103 "sample = " + std::to_string(sample) +
", "
104 "last CDF value = " + (m_cdf.empty() ?
"(empty CDF)" : std::to_string(m_cdf.back())));
106 return result != m_cdf.begin() ? result - m_cdf.begin() - 1 : m_firstNonZeroPdfColumn;
112 const std::size_t sampledColumn = sampleDiscrete(sample);
113 return continuouslySampleValue(sample, sampledColumn);
121 const std::size_t sampledColumn = sampleDiscrete(sample);
123 *out_pdf = pdfContinuous(sampledColumn);
124 return continuouslySampleValue(sample, sampledColumn);
131 std::size_t*
const out_straddledColumn)
const
134 PH_ASSERT(out_straddledColumn);
136 *out_straddledColumn = sampleDiscrete(sample);
137 *out_pdf = pdfContinuous(*out_straddledColumn);
138 return continuouslySampleValue(sample, *out_straddledColumn);
144 PH_ASSERT(m_cdf.size() >= 2);
146 return m_cdf.size() - 1;
152 return pdfContinuous(continuousToDiscrete(sample));
158 PH_ASSERT(!m_cdf.empty() &&
159 0 <= columnIndex && columnIndex < numColumns());
161 return (m_cdf[columnIndex + 1] - m_cdf[columnIndex]) / m_delta;
167 PH_ASSERT(!m_cdf.empty() &&
168 0 <= columnIndex && columnIndex < numColumns());
170 return m_cdf[columnIndex + 1] - m_cdf[columnIndex];
176 PH_ASSERT_MSG(m_min <= sample && sample <= m_max,
177 "m_min = " + std::to_string(m_min) +
", "
178 "m_max = " + std::to_string(m_max) +
", "
179 "sample = " + std::to_string(sample));
181 const T continuousColumn = (sample - m_min) / m_delta;
182 return math::clamp(
static_cast<std::size_t
>(continuousColumn),
183 static_cast<std::size_t
>(0), numColumns() - 1);
189 PH_ASSERT(straddledColumn < numColumns());
191 const T cdfDelta = m_cdf[straddledColumn + 1] - m_cdf[straddledColumn];
192 T overshoot = sample - m_cdf[straddledColumn];
195 overshoot /= cdfDelta;
197 PH_ASSERT(0 <= overshoot && overshoot <= 1);
202 const T sampledValue = m_delta * (overshoot +
static_cast<T
>(straddledColumn));
A 1-D piecewise constant distribution of floating-point type T. The sample weights can be seen as a h...
Definition TPwcDistribution1D.h:16
std::size_t sampleDiscrete(T sample) const
Generate an index. Given a uniform unit random sample, generate a column index according to the sampl...
Definition TPwcDistribution1D.ipp:99
T sampleContinuous(T sample) const
Generate a continuous sample. Given a uniform unit random sample, generate a continuous sample accord...
Definition TPwcDistribution1D.ipp:110
T pdfDiscrete(std::size_t columnIndex) const
Definition TPwcDistribution1D.ipp:165
T pdfContinuous(T value) const
Definition TPwcDistribution1D.ipp:150
std::size_t numColumns() const
Definition TPwcDistribution1D.ipp:142
std::size_t continuousToDiscrete(T value) const
Calculates the sampled column index given a continuously sampled value.
Definition TPwcDistribution1D.ipp:174
Miscellaneous math utilities.
Math functions and utilities.
Definition TransformInfo.h:10
T clamp(const T value, const T lowerBound, const T upperBound)
Clamps a value to [lowerBound, upperBound]. None of value, lowerBound and upperBound can be NaN,...
Definition math.h:77