deep_causality_uncertain
A Rust library for first-order uncertain data types, enabling robust computation and decision-making under uncertainty.
Introduction
In many modern applications, from sensor data processing and machine learning to probabilistic modeling, estimates are often treated as precise facts. This can lead to "uncertainty bugs" where random errors are ignored, computations compound these errors, and probabilistic data leads to misleading boolean decisions (false positives/negatives).
deep_causality_uncertain introduces Uncertain<T>, a programming language abstraction for explicitly modeling and propagating uncertainty. Inspired by the research presented in "Uncertain: A First-Order Type for Uncertain Data" by Bornholt et al., this crate provides a powerful yet intuitive way to work with probabilistic data. By treating uncertainty as a first-class citizen, Uncertain<T> improves the expressiveness, accuracy, and correctness of applications dealing with inherent data variability.
Key Features
- First-Order Uncertainty:
Uncertain<T>is a generic type that encapsulates a value along with its inherent uncertainty, modeled as a probability distribution. - Probabilistic Presence (
MaybeUncertain<T>): IntroducesMaybeUncertain<T>, a specialized type for modeling values whose very presence is uncertain. This is crucial for scenarios with sparse or intermittently available data, allowing explicit reasoning about the probability of a value existing, in addition to its inherent uncertainty if present. - Rich Distribution Support: Create uncertain values from various probability distributions, including:
Point(T): For precise, known values.Normal(mean, std_dev): Gaussian distribution for continuous data with noise.Uniform(low, high): For values within a defined range.Bernoulli(p): For uncertain boolean outcomes.
- Intuitive Operator Overloading: Perform standard arithmetic (
+,-,*,/), unary negation (-), comparison (>,<,==), and logical (&,|,!,^) operations directly onUncertaintypes. The uncertainty is automatically propagated through these operations. - Implicit Computation Graph: Operations on
Uncertaintypes implicitly build a computation graph (similar to a Bayesian network), allowing for lazy and efficient evaluation. - Sampling-Based Evaluation: The runtime uses intelligent sampling and statistical hypothesis tests (like SPRT) to evaluate computations and conditionals lazily and efficiently, drawing only as many samples as necessary.
- Comprehensive Statistical Analysis: Extract meaningful insights from uncertain results:
expected_value(): Estimate the mean of an uncertainf64value.standard_deviation(): Estimate the spread of an uncertainf64value.estimate_probability(): Estimate the probability of an uncertainboolcondition being true.
- Robust Decision Making: Make informed decisions under uncertainty:
to_bool(): Convert anUncertain<bool>to a concrete boolean with a specified confidence.probability_exceeds(): Test if the probability of a condition being true exceeds a threshold.implicit_conditional(): A convenient method for "more likely than not" decisions.conditional(): Implementif-then-elselogic where the condition itself is uncertain.
- Global Sample Cache: An efficient, thread-local caching mechanism memoizes sampled values, preventing redundant computations and improving performance.
Installation
Add deep_causality_uncertain to your Cargo.toml file:
[]
= "0.1.0" # Or the latest version
Usage
Here are some basic examples to get started with deep_causality_uncertain.
Creating Uncertain Values
use Uncertain;
// A precise, known value
let precise_value = point;
// A value with normal distribution (e.g., sensor reading with noise)
let noisy_sensor_reading = normal; // mean 50.0, std_dev 2.5
// A value uniformly distributed within a range
let uncertain_range = uniform;
// An uncertain boolean (e.g., outcome of a coin flip)
let coin_flip = bernoulli;
Arithmetic Operations
Uncertain values can be combined using standard arithmetic operators. The uncertainty is automatically propagated.
use Uncertain;
let a = normal;
let b = normal;
// Addition: (10.0 +/- 1.0) + (5.0 +/- 0.5)
let sum = a + b;
println!; // e.g., 15.00
// Subtraction
let diff = a - b;
println!; // e.g., 5.00
// Multiplication
let product = a * b;
println!; // e.g., 50.00
// Division
let quotient = a / b;
println!; // e.g., 2.00
// Unary Negation
let neg_a = -a;
println!; // e.g., -10.00
Mapping and Transformations
Apply custom functions to uncertain values.
use Uncertain;
let temperature_celsius = normal;
// Map to Fahrenheit: F = C * 1.8 + 32
let temperature_fahrenheit = temperature_celsius.map;
println!;
// Map to a boolean condition: Is it hot? (> 30 Celsius)
let is_hot = temperature_celsius.map_to_bool;
println!;
Comparison Operations
Compare uncertain values or an uncertain value against a threshold. These operations return Uncertain<bool>.
use Uncertain;
let sensor_reading = normal;
let threshold = 105.0;
// Is sensor reading greater than threshold?
let is_greater = sensor_reading.greater_than;
println!;
let target_value = normal;
// Is sensor reading greater than another uncertain value?
let sensor_gt_target = sensor_reading.gt_uncertain;
println!;
// Check approximate equality within a tolerance
let is_approx_100 = sensor_reading.approx_eq; // within +/- 1.0
println!;
Conditional Logic
Implement if-then-else logic where the condition itself is uncertain.
use Uncertain;
let traffic_heavy = bernoulli; // 70% chance of heavy traffic
let time_via_main_road = normal; // 30 +/- 5 min
let time_via_back_road = normal; // 45 +/- 2 min
// If traffic is heavy, take back road, else take main road
let estimated_travel_time = conditional;
println!;
Statistical Properties
Calculate statistical measures of uncertain values.
use Uncertain;
let stock_price = normal; // Current stock price
println!;
println!;
Decision Making
Convert uncertain boolean conditions into concrete decisions.
use Uncertain;
let system_healthy = bernoulli; // 90% chance system is healthy
// Make a decision with 95% confidence
let decision_healthy = system_healthy.to_bool.unwrap;
if decision_healthy else
// Implicit conditional (equivalent to probability_exceeds(0.5, 0.95, 1000))
if system_healthy.implicit_conditional.unwrap
Probabilistic Presence (MaybeUncertain<T>)
Model values that might be present or absent with a certain probability.
use ;
// A value that is certainly present, but its value is uncertain
let certain_but_uncertain = from_uncertain;
println!;
// A value that is certainly absent
let certainly_absent = always_none;
println!;
// A value that is probabilistically present (e.g., 70% chance)
let probabilistically_present = from_bernoulli_and_uncertain;
println!;
// Check probability of presence
println!;
// Arithmetic operations propagate None
let sum_with_absent = certain_but_uncertain.clone + certainly_absent.clone;
println!;
// Lift to Uncertain<T> if evidence of presence is sufficient
match probabilistically_present.lift_to_uncertain
More Examples
For more complex and real-world scenarios, refer to the examples directory:
-
GPS Navigation (
example_gps_navigation.rs): Simulates GPS readings, propagates uncertainty through distance and time calculations, and makes route decisions. -
Sensor Data Processing (
example_sensor_processing.rs): Demonstrates robust sensor data processing with error handling, sensor fusion, and anomaly detection under uncertainty. -
Aspirin Headache Trial Analysis (
example_clinical_trial.rs): Demonstrates usingMaybeUncertain<T>to model clinical trial data with probabilistic presence, analyzing drug effectiveness under uncertainty.
To run an example:
Acknowledgements
This crate is inspired by the Blog post "Uncertain⟨T⟩" by @Mattt and his Implementation of Uncertain for Swift. Furthermore, prior art in the uncertain crate and uncertain-rs crate inspired some of the implementation and examples.
The Uncertain⟨T⟩ type is based by the foundational research presented in:
- Bornholt, J., Mytkowicz, T., & McKinley, K. S. (2014). Uncertain: A First-Order Type for Uncertain Data. Proceedings of the 19th International Conference on Architectural Support for Programming Languages and Operating Systems (ASPLOS '14). ACM, New York, NY, USA, 123-136. (Download Paper)
Contributing
Contributions are welcome! Please refer to the CONTRIBUTING.md for guidelines.
License
This project is licensed under the MIT License. See the LICENSE file for details.
💻 Author
- Marvin Hansen.
- Github GPG key ID: 369D5A0B210D39BC
- GPG Fingerprint: 4B18 F7B2 04B9 7A72 967E 663E 369D 5A0B 210D 39BC