43#ifndef LASS_GUARDIAN_OF_INCLUSION_NUM_INVERSE_TRANSFORM_SAMPLING_H
44#define LASS_GUARDIAN_OF_INCLUSION_NUM_INVERSE_TRANSFORM_SAMPLING_H
65template <
typename RandomIterator,
typename T>
66T
sampleCdf1D(RandomIterator first, RandomIterator last, T sample, T& pdf,
size_t& index)
68 LASS_ASSERT(first != last);
69 const T n =
static_cast<T
>(last - first);
70 const RandomIterator it = std::lower_bound(first, last, sample);
79 pdf = n * (*(last - 1) - *(last - 2));
80 index =
static_cast<size_t>(last - first) - 1;
83 const RandomIterator prev = it - 1;
84 index =
static_cast<size_t>(it - first);
85 pdf = n * (*it - *prev);
86 const T x0 =
static_cast<T
>(index) / n;
87 return x0 + (sample - *prev) / pdf;
93class InverseTransformSampling2D
97 typedef prim::Point2D<T> TSample;
98 typedef prim::Point2D<size_t> TIndex;
100 InverseTransformSampling2D(): uSize_(0), vSize_(0) {}
102 template <
typename InputIterator>
103 InverseTransformSampling2D(InputIterator first, InputIterator last,
size_t uSize,
size_t vSize)
105 reset(first, last, uSize, vSize);
108 template <
typename InputIterator>
109 void reset(InputIterator first, InputIterator last,
size_t uSize,
size_t vSize)
111 LASS_ENFORCE(uSize > 0 && vSize > 0);
112 uSize_ =
static_cast<std::ptrdiff_t
>(uSize);
113 vSize_ =
static_cast<std::ptrdiff_t
>(vSize);
114 condCdfV_.resize(uSize * vSize);
115 margCdfU_.resize(uSize);
116 std::copy(first, last, condCdfV_.begin());
120 TSample operator()(
const TSample& in, TValue& pdf, TIndex& index)
const
122 LASS_ASSERT(!margCdfU_.empty());
124 const TValue u = impl::sampleCdf1D(margCdfU_.begin(), margCdfU_.end(),
in.x, pdfU, index.x);
125 const typename TValues::const_iterator cdfV = condCdfV_.begin() +
static_cast<std::ptrdiff_t
>(index.x) * vSize_;
126 const TValue v = impl::sampleCdf1D(cdfV, cdfV + vSize_,
in.y, pdfV, index.y);
128 return TSample(u, v);
132 typedef std::vector<TValue> TValues;
136 LASS_ASSERT(condCdfV_.size() ==
static_cast<size_t>(uSize_ * vSize_));
137 const typename TValues::iterator margCdfU = margCdfU_.begin();
138 for (std::ptrdiff_t i = 0; i < uSize_; ++i)
140 const typename TValues::iterator firstCdfV = condCdfV_.begin() + i * vSize_;
141 const typename TValues::iterator lastCdfV = firstCdfV + vSize_;
142 std::partial_sum(firstCdfV, lastCdfV, firstCdfV);
143 const TValue maxCdfV = *(lastCdfV - 1);
144 *(margCdfU + i) = maxCdfV;
145 std::transform(firstCdfV, lastCdfV, firstCdfV, [maxCdfV](TValue cdf) {
return cdf / maxCdfV; });
147 std::partial_sum(margCdfU_.begin(), margCdfU_.end(), margCdfU_.begin());
148 const TValue maxCdfU = margCdfU_.back();
149 std::transform(margCdfU_.begin(), margCdfU_.end(), margCdfU_.begin(), [maxCdfU](TValue cdf) { return cdf / maxCdfU; });
154 std::ptrdiff_t uSize_;
155 std::ptrdiff_t vSize_;
numeric types and traits.
ColorRGBA in(const ColorRGBA &a, const ColorRGBA &b)
part of a inside b.
Library for Assembled Shared Sources.