Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Migrating from 0.11 to 0.12

0.12 redesigns the representation of distributions in symplex::stats; the query API on RandomVariable is unchanged. Every break has a one-line fix.

Distribution is a struct, not an enum

Distribution::Continuous(ContinuousFamily::Normal { mean, std }) and Distribution::Discrete(DiscreteFamily::Binomial { n, p }) are gone. A Distribution is an opaque handle to a Family (a trait); the families are structs.

0.110.12
match d { Distribution::Continuous(ContinuousFamily::Normal { mean, std }) => … }if let Some(n) = d.downcast_ref::<Normal>() { n.mean, n.std }
Distribution::Continuous(f) => f.entropy(&ctx)d.family().entropy() (closed form) or d.entropy() (always an answer)
d.mean(&ctx), d.variance(&ctx), d.raw_moment(n, &ctx)Option<Ex>d.family().mean(), .variance(), .raw_moment(n)Option<Ex>; d.mean(), d.variance(), d.moment(n)Ex (closed form or generic route)
d.cdf(&x), d.mgf(&t), d.quantile(&p)Option<Ex>d.family().cdf(&x) … → Option<Ex> (closed form on the support); d.cdf(&x), d.mgf(&t)Ex
d.is_continuous()unchanged (d.kind() == Kind::Continuous)

Support is a typed region

Support::Continuous { lo: Option<Ex>, hi: Option<Ex> }, Support::Discrete { … } and Support::Finite(Vec<Ex>) are replaced by a struct with a Kind and Pieces.

0.110.12
Support::Continuous { lo: Some(a), hi: Some(b) }Support::interval(a, b); unbounded ends are ctx.neg_infinity() / ctx.infinity()
Support::Discrete { lo: Some(a), hi: None }Support::integers(&ctx, Some(a), None)
Support::Finite(values)Support::points(values)
match support { Support::Continuous { lo, hi } => … }let iv = support.as_interval()?; then iv.lower, iv.upper, iv.kind (an Interval<Ex>)
matches!(s, Support::Discrete { .. })s.kind() == Kind::Discrete

Distribution::finite takes the context

Distribution::try_finite(table)Distribution::try_finite(&ctx, table) (likewise finite): an empty table has no parameter to take a context from.

cdf is clamped to the support

RandomVariable::cdf(&x) / Distribution::cdf(&x) return the whole-line distribution function — 0 below the support, the closed form on it, 1 above it — as SymPy’s cdf(X)(x) does (Uniform(0, 1).cdf(3) is 1, not 3; Geometric(p).cdf(k) is a Piecewise that is 0 for k < 1). A test that pinned the unclamped formula should compare d.family().cdf(&x) instead.

Events that used to be NotImplemented now have answers

P(X² < 1), P(X < −1 ∨ X > 1), E[X | X² > 1] go through the inequality solver when the bounds are numeric. P(X = 3 ∧ X > 5) is 0 (it was P(X = 3)), P(X > 1 ∧ X ≥ 2) is P(X ≥ 2) (the strict bound no longer wins), and P(X = ½) for an integer-valued variable is 0.