67template <Space Space_, RealScalar Scalar_ =
double>
92 internal::hasEqualSizes<Space_>,
93 "a uniform box needs a space whose values and differences have the same coordinates"
99 : m_space{std::move(
space)}
105 internal::forEachLeaf(m_space, [&](
Index offset,
auto const & leaf) {
106 using Leaf = std::remove_cvref_t<
decltype(leaf)>;
107 static_assert(hasDefaultInterval<Leaf>(),
"a coordinate has no default interval; give the box explicitly");
108 constexpr auto found = internal::leafSupport<Leaf>();
109 constexpr internal::LeafSupport support = *found;
110 constexpr double width = support.upper - support.lower;
111 auto const rows = Eigen::seqN(offset, leaf.valueDimension());
112 m_lower(rows).setConstant(
Scalar(support.lower));
115 static_assert(support.periodic);
118 m_logVolume = m_width.array().log().sum();
126 template <MatrixExpression Lower,
typename UpperDerived>
127 [[nodiscard]]
static std::expected<Uniform, UniformError>
131 EMRYS_FILTER_ASSERT(
upper.size() == start.size() &&
"give one upper bound per lower bound");
133 internal::fitValueDimension(
space, start.size());
142 auto period =
VectorType{VectorType::Zero(start.size())};
144 internal::forEachLeaf(
space, [&](
Index offset,
auto const & leaf) {
145 constexpr auto support = internal::leafSupport<std::remove_cvref_t<
decltype(leaf)>>();
146 if constexpr (support.has_value() && support->periodic)
148 constexpr double leafPeriod = support->upper - support->lower;
149 for (
Index i = offset; i < offset + leaf.valueDimension(); ++i)
152 period(i) =
Scalar(leafPeriod);
160 return Uniform{std::move(
space), std::move(start), std::move(
width), std::move(period)};
164 template <MatrixExpression Lower,
typename UpperDerived>
165 requires internal::SizedByLength<Space_>
166 [[nodiscard]]
static std::expected<Uniform, UniformError>
176 return m_lower.size();
183 return m_lower.size();
187 [[nodiscard]] Space_
const &
206 return m_lower + m_width;
224 template <
typename Derived>
226 contains(Eigen::MatrixBase<Derived>
const & x)
const
228 static_assert(Derived::IsVectorAtCompileTime,
"contains() expects a vector");
233 if (m_period(i) >
Scalar(0))
237 if (!(offset >=
Scalar(0) && offset <= m_width(i)))
248 template <
typename Derived>
252 return contains(x) ? -m_logVolume : -std::numeric_limits<Scalar>::infinity();
256 template <
typename Derived>
258 density(Eigen::MatrixBase<Derived>
const & x)
const
274 result.
mean() = m_lower +
Scalar(0.5) * m_width;
276 result.covarianceLower() = (m_width.array().square() /
Scalar(12)).matrix().asDiagonal();
281 template <
typename Path>
285 return internal::marginalOverPath<Path>(m_space, [&](
auto const & target,
auto space) {
286 return restricted(target.values, std::move(
space));
291 template <
typename Path>
295 return internal::marginalOverElement<Path>(m_space, element, [&](
auto const & target,
auto space) {
296 return restricted(target.values, std::move(
space));
306 template <
typename GivenPath,
typename Derived>
310 return internal::tagConditional<GivenPath>(
312 [&](
auto const & t,
auto const & g,
auto space,
auto const &) {
313 EMRYS_FILTER_ASSERT(values.size() == g.values.size());
314 return restricted(t.values, std::move(
space));
322 template <Space, RealScalar>
328 template <
typename Leaf>
329 static consteval bool
332 constexpr auto support = internal::leafSupport<Leaf>();
333 return support && support->lower > -std::numeric_limits<double>::infinity()
334 && support->upper < std::numeric_limits<double>::infinity();
341 : m_space{std::move(
space)}
342 , m_lower{std::move(
lower)}
343 , m_width{std::move(
width)}
344 , m_period{std::move(period)}
345 , m_logVolume{m_width.array().log().sum()}
349 template <
typename Target,
typename SubSpace>
351 restricted(Target
const & target, SubSpace
space)
const
354 using ResultVector =
typename Result::VectorType;
357 ResultVector{m_lower(target)},
358 ResultVector{m_width(target)},
359 ResultVector{m_period(target)}
376template <
typename Scalar,
typename Space, std::uniform_random_bit_generator G>
380 EMRYS_FILTER_ASSERT(n >= 0);
382 SampleSetType samples =
383 uniform.
width().asDiagonal() * internal::standardUniform<SampleSetType>(uniform.
valueDimension(), n, rng);
384 samples.colwise() += uniform.
lower();
394template <
typename Scalar,
typename Space, std::uniform_random_bit_generator G>
395[[nodiscard]]
typename Moments<Space, Scalar>::VectorType
398 static_assert(std::floating_point<Scalar>,
"sampling requires a standard floating-point scalar");
400 auto draw = std::uniform_real_distribution<Scalar>{};
403 for (Eigen::Index i = 0; i <
sample.size(); ++i)
417template <
typename Scalar,
typename Space, std::uniform_random_bit_generator G>
418[[nodiscard]] SamplesWithLogDensity<Space, Scalar>
421 return {
drawSamples(uniform, n, rng), Eigen::Array<Scalar, Eigen::Dynamic, 1>::Constant(n, -uniform.
logVolume())};
429template <
typename Scalar,
typename Space, std::uniform_random_bit_generator G>
430[[nodiscard]] SampleWithLogDensity<Space, Scalar>
438#ifndef EMRYS_FILTER_NO_IO
448describe(std::ostream & stream,
UniformError error, Indent indent)
454 stream <<
"an upper bound is not above its lower bound";
457 stream <<
"a bound is not finite";
460 stream <<
"an interval is wider than its coordinate's period";
Spaces built from other spaces (decisions.md [sizes-and-dimensions], [several-resizable-blocks]): Com...
How a function that stores a matrix argument takes it (decisions.md [forwarded-matrices]): the concep...
What marginals and conditionals are built from: resolving Eigen index sets against a space; the share...
The macros every header includes first.
Mathematical constants and scalar functions that work in every scalar type the library accepts,...
Moments: the mean and covariance that a Gaussian carries and that a mixture or a sample set is moment...
Printing: operator<< and std::formatter for every distribution, every filter (which prints its name a...
SampleSet: a matrix whose columns are samples in a space, which the samplers return and the unscented...
Drawing samples: SamplesWithLogDensity and SampleWithLogDensity, the Gaussian draws drawSamples(),...
The Space concept and what every continuous space shares (decisions.md [sizes-and-dimensions]): the t...
First and second moments (mean and covariance) of a distribution.
Definition Moments.h:55
DifferenceMatrix< Space_, Space_, Scalar > MatrixType
Definition Moments.h:76
ValueVector< Space_, Scalar > VectorType
Definition Moments.h:74
static constexpr int MaxDifferenceDimensionAtCompileTime
Definition Moments.h:72
VectorType const & mean() const
Definition Moments.h:141
static constexpr int DifferenceDimensionAtCompileTime
Definition Moments.h:69
static constexpr int MaxValueDimensionAtCompileTime
Definition Moments.h:66
static constexpr int ValueDimensionAtCompileTime
Definition Moments.h:63
bool allFinite(Eigen::DenseBase< Derived > const &x)
Definition Math.h:354
#define EMRYS_FILTER_NO_UNIQUE_ADDRESS
Assertion used for programmer errors (misuse of the API).
Definition Macros.h:38
Scalar floorOf(std::type_identity_t< Scalar > const &x)
Definition Math.h:277
@ NonFinite
a matrix, a factor, or a log-weight holds NaN or infinity (+inf, for a log-weight)
Definition NumericError.h:33
@ Empty
there are no weights
Definition NumericError.h:34
SampleWithLogDensity< Space, Scalar > drawSampleWithLogDensity(Gamma< Space, Scalar > const &gamma, G &rng)
Definition Gamma.h:546
Eigen::Matrix< Scalar, valueDimensionAtCompileTime< Space >, Eigen::Dynamic,(maxValueDimensionAtCompileTime< Space >==1 ? Eigen::RowMajor :Eigen::ColMajor), maxValueDimensionAtCompileTime< Space >, Eigen::Dynamic > SampleSet
A matrix whose columns are samples in Space (see Spaces), with the space's size and storage bound.
Definition SampleSet.h:33
Eigen::Index drawSample(Categorical< Space, Scalar > const &distribution, G &rng)
Definition Categorical.h:1111
UniformError
Reasons bounds fail to define a Uniform.
Definition Uniform.h:35
std::vector< Eigen::Index > drawSamples(Categorical< Space, Scalar > const &distribution, Eigen::Index n, G &rng)
Definition Categorical.h:1087
SamplesWithLogDensity< Space, Scalar > drawSamplesWithLogDensity(Gamma< Space, Scalar > const &gamma, Eigen::Index n, G &rng)
Definition Gamma.h:529
@ NonFinite
a bound is NaN or infinite
Definition Uniform.h:37
@ Empty
an upper bound is not above its lower bound
Definition Uniform.h:36
@ WiderThanPeriod
an interval on a Periodic coordinate spans more than one period
Definition Uniform.h:38
Sample< std::remove_cvref_t< G > > sample(G &&function)
Definition Policies.h:665
Eigen::Index valueDimension(S const &space)
Definition Space.h:272
constexpr bool isLinear
Whether S is linear: its values and its differences are both plain vectors.
Definition Space.h:321
void normalizeValues(S const &space, Eigen::MatrixBase< Derived > const &block)
Brings the values in block (rows are space's coordinates, columns samples) into canonical form,...
Definition Space.h:331