ProvSQL C/C++ API
Adding support for provenance and uncertainty management to PostgreSQL databases
Loading...
Searching...
No Matches
Distribution.h File Reference

Per-family polymorphic view over a continuous gate_rv distribution (§F.1 class hierarchy). More...

#include <cstddef>
#include <memory>
#include <optional>
#include <random>
#include <string>
#include <utility>
#include <vector>
#include "../RandomVariable.h"
Include dependency graph for Distribution.h:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Classes

struct  provsql::DistSupport
 A closed support interval [lo, hi] (±infinity for unbounded). More...
class  provsql::Distribution
 Abstract per-family continuous distribution. More...
struct  provsql::DistributionFamily
 A registered family's descriptor: its complete identity. More...
struct  provsql::DistributionFamilyRegistrar
 Static-initialisation helper: one per family implementation. More...
struct  provsql::ComparatorRuleRegistrar
 Static-initialisation helper: one per registered family pair. More...
struct  provsql::ClosureTerm
 One wire of a PLUS under closure: a·Z + b for a base RV Z (dist non-null), or a pure additive constant b (dist null, a == 0). More...
struct  provsql::ClosureRuleRegistrar
 Static-initialisation helper: one per registered family pair. More...
struct  provsql::ProductRuleRegistrar
 Static-initialisation helper: one per registered family pair. More...
struct  provsql::TransformRuleRegistrar
 Static-initialisation helper: one per registered transform. More...
struct  provsql::ConjugateRule
 The conjugate update for one observation of a given likelihood family against the running posterior (= prior) family. More...
struct  provsql::ConjugateRuleRegistrar
 Static-initialisation helper: one per registered pair. More...

Namespaces

namespace  provsql

Functions

std::unique_ptr< Distributionprovsql::makeDistribution (const DistributionSpec &spec)
 Construct the per-family Distribution for a parsed spec.
double provsql::numericQuantile (const Distribution &d, double p)
 Numeric inverse CDF: monotone bisection of cdf() over the family's integration window.
ConjugateRuleRegistry – exact conjugate-prior posterior updates

One-observation Bayesian updates for conjugate prior/likelihood pairs: the exact posterior of a latent, wired into one parameter slot of an observed leaf, stays in the prior's family with updated parameters.

The conjugate-posterior recogniser (ConjugatePosterior.cpp) folds these rules over an and_agg evidence conjunction of gate_observe atoms, replacing likelihood-weighting importance sampling with the closed form where a rule chain covers every observation.

Like the comparator / closure registries, the rules stay out of the Distribution interface: the likelihood family's implementation file self-registers its rule(s) at static initialisation, keyed by name tokens (no cross-file static-init order dependence), and a registry miss is a silent decline – the caller falls back to importance sampling unchanged.

void provsql::registerConjugateRule (const char *likelihood_family, int wired_param, const char *prior_family, const ConjugateRule &rule)
 Register the conjugate update for observations of likelihood_family whose parameter wired_param (0 = p1, 1 = p2) is the latent, against a prior of prior_family.
const ConjugateRuleprovsql::lookupConjugateRule (const std::string &likelihood_family, int wired_param, const std::string &prior_family)
 Look up the conjugate rule for (likelihood family, wired parameter position, prior family); nullptr on a miss.

DistributionRegistry – family descriptor table

Family implementations self-register their descriptor at static initialisation: the on-disk name token (the part before the colon in a gate_rv extra), the parameter count, the display metadata, and the constructor.

makeDistribution and parse_distribution_spec dispatch through this table, so adding a family means one new implementation file with one registrar – no existing factory, parser, or header is touched.

using provsql::DistributionFactory
 Construct a family instance from its (up to) two parameters.
void provsql::registerDistributionFamily (const DistributionFamily &descriptor)
 Register a family; called by the registrar at static init.
const DistributionFamilyprovsql::lookupDistributionFamily (const std::string &name)
 Look up a family by its on-disk name token.
std::vector< const DistributionFamily * > provsql::listDistributionFamilies ()
 Every registered family, sorted by name token.

ComparatorRuleRegistry – pairwise §B.2 closed forms

Closed-form \(P(X < Y)\) for an ordered pair of independent RV families.

On continuous distributions every ordered comparator reduces to \(P(X < Y)\) or its complement, so rules are keyed on the family pair alone (no operator in the key). Pairwise behaviour deliberately stays out of the Distribution interface: family files self-register their rules at static initialisation through provsql::ComparatorRuleRegistrar, so adding a family touches no existing file, and a missing rule is not an error – the driver falls back to a family-agnostic quadrature.

using provsql::ComparatorRule
 A pairwise closed form for \(P(X < Y)\), X and Y independent.
void provsql::registerComparatorRule (const char *x, const char *y, ComparatorRule rule)
 Register the \(P(X < Y)\) closed form for a family pair.
double provsql::comparatorPairLess (const Distribution &X, const Distribution &Y)
 \(P(X < Y)\) for two independent RVs.

ClosureRuleRegistry – pairwise family-closure folds on PLUS

Closed-form folds of a sum of independent scalar terms into a single distribution (Normal + Normal, same-rate Exponential / Erlang chains).

Like the comparator rules, pairwise behaviour stays out of the Distribution interface: family files self-register at static initialisation via provsql::ClosureRuleRegistrar, keyed on the (ordered) pair of families that may meet in the sum, and a registry miss simply means the sum stays unfolded (Monte Carlo handles it).

A rule receives the whole term list rather than reducing pairwise so its accumulation arithmetic (e.g. one variance sum with a single final square root) is not perturbed by intermediate re-serialisation.

using provsql::ClosureRule
 A family sum-closure fold.
using provsql::ProductRule
 A family product-closure fold: the distribution of the product of the (independent) factors, or nullptr when the shape is outside the closure.
using provsql::TransformRule
 A closed-form image of a monotone transform of one family (e.g.
void provsql::registerClosureRule (const char *x, const char *y, ClosureRule rule)
 Register the sum-closure rule for a family pair (name-token keyed, like the comparator rules).
void provsql::registerProductRule (const char *x, const char *y, ProductRule rule)
 Register the product-closure rule for a family pair (name-token keyed, like the sum-closure rules).
std::unique_ptr< Distributionprovsql::closeProductFactors (const std::vector< const Distribution * > &factors)
 Fold a product of independent factors into a single distribution when a registered closure covers every family present (same first-vs-each dispatch as closePlusTerms); nullptr on any miss.
void provsql::registerTransformRule (const char *transform, const char *family, TransformRule rule)
 Register the image rule for transform ("ln" / "exp" / ...; the evaluator maps its arith opcodes to these names, keeping this registry opcode-free) applied to family.
std::unique_ptr< Distributionprovsql::closeTransform (const char *transform, const Distribution &x)
 The image distribution of transform applied to x, when a registered rule covers x's family; nullptr otherwise.
std::unique_ptr< Distributionprovsql::closePlusTerms (const std::vector< ClosureTerm > &terms)
 Fold PLUS(terms) into a single distribution when a registered closure covers every family in the sum.

Detailed Description

Per-family polymorphic view over a continuous gate_rv distribution (§F.1 class hierarchy).

Every RV evaluator dispatches through this interface (one virtual call per family) and the registries below; family identity is the interned DistributionFamily descriptor each implementation file registers – there is no family enum anywhere. A Distribution is a transient view constructed from a parsed DistributionSpec via provsql::makeDistribution; the on-disk extra text encoding stores the family's name token.

Adding a family is one new self-registering implementation file under src/distributions/ (plus its SQL constructor). Methods a family cannot answer follow the NaN-as-undecided contract so the analytic paths fall back to Monte Carlo unchanged.

Definition in file Distribution.h.