19 #if !defined(__NORI_DISCRETE_PDF_H)
20 #define __NORI_DISCRETE_PDF_H
22 #include <nori/common.h>
45 m_cdf.push_back(0.0f);
51 m_cdf.reserve(nEntries+1);
56 m_cdf.push_back(m_cdf[m_cdf.size()-1] + pdfValue);
61 return m_cdf.size()-1;
66 return m_cdf[entry+1] - m_cdf[entry];
89 return m_normalization;
98 m_sum = m_cdf[m_cdf.size()-1];
100 m_normalization = 1.0f / m_sum;
101 for (
size_t i=1; i<m_cdf.size(); ++i)
102 m_cdf[i] *= m_normalization;
103 m_cdf[m_cdf.size()-1] = 1.0f;
106 m_normalization = 0.0f;
120 std::vector<float>::const_iterator entry =
121 std::lower_bound(m_cdf.begin(), m_cdf.end(), sampleValue);
122 size_t index = (size_t) std::max((ptrdiff_t) 0, entry - m_cdf.begin() - 1);
123 return std::min(index, m_cdf.size()-2);
136 size_t sample(
float sampleValue,
float &pdf)
const {
137 size_t index =
sample(sampleValue);
153 size_t index =
sample(sampleValue);
154 sampleValue = (sampleValue - m_cdf[index])
155 / (m_cdf[index + 1] - m_cdf[index]);
172 size_t index =
sample(sampleValue, pdf);
173 sampleValue = (sampleValue - m_cdf[index])
174 / (m_cdf[index + 1] - m_cdf[index]);
183 std::string result = tfm::format(
"DiscretePDF[sum=%f, "
184 "normalized=%f, pdf = {", m_sum, m_normalized);
186 for (
size_t i=0; i<m_cdf.size(); ++i) {
187 result += std::to_string(
operator[](i));
188 if (i != m_cdf.size()-1)
191 return result +
"}]";
194 std::vector<float> m_cdf;
195 float m_sum, m_normalization;
Discrete probability distribution.
float getSum() const
Return the original (unnormalized) sum of all PDF entries.
float getNormalization() const
Return the normalization factor (i.e. the inverse of getSum())
size_t sampleReuse(float &sampleValue) const
Transform a uniformly distributed sample to the stored distribution
size_t size() const
Return the number of entries so far.
void clear()
Clear all entries.
void append(float pdfValue)
Append an entry with the specified discrete probability.
std::string toString() const
Turn the underlying distribution into a human-readable string format.
size_t sampleReuse(float &sampleValue, float &pdf) const
Transform a uniformly distributed sample.
void reserve(size_t nEntries)
Reserve memory for a certain number of entries.
bool isNormalized() const
Have the probability densities been normalized?
float normalize()
Normalize the distribution.
size_t sample(float sampleValue) const
Transform a uniformly distributed sample to the stored distribution
size_t sample(float sampleValue, float &pdf) const
Transform a uniformly distributed sample to the stored distribution
float operator[](size_t entry) const
Access an entry by its index.
DiscretePDF(size_t nEntries=0)
Allocate memory for a distribution with the given number of entries.