From 4af21049c6b4556d1a841e799d983b734994f306 Mon Sep 17 00:00:00 2001 From: Alex Nodeland Date: Mon, 1 Sep 2025 15:09:56 -0400 Subject: [PATCH 1/8] Add LICENSE file and remove dual licensing documentation - Introduced a new LICENSE file outlining the terms under the MIT license, ensuring clear licensing for the project. - Removed the LICENSE-APACHE file and the dual licensing notes from the .github/LICENSE.md file to streamline licensing information and avoid confusion. --- .github/LICENSE.md | 6 -- LICENSE-MIT => LICENSE | 0 LICENSE-APACHE | 201 ----------------------------------------- 3 files changed, 207 deletions(-) delete mode 100644 .github/LICENSE.md rename LICENSE-MIT => LICENSE (100%) delete mode 100644 LICENSE-APACHE diff --git a/.github/LICENSE.md b/.github/LICENSE.md deleted file mode 100644 index 07f0ade..0000000 --- a/.github/LICENSE.md +++ /dev/null @@ -1,6 +0,0 @@ -This project is dual-licensed under either of - -- Apache License, Version 2.0, ([LICENSE-APACHE](../LICENSE-APACHE) or ) -- MIT license ([LICENSE-MIT](../LICENSE-MIT) or ) - -at your option. diff --git a/LICENSE-MIT b/LICENSE similarity index 100% rename from LICENSE-MIT rename to LICENSE diff --git a/LICENSE-APACHE b/LICENSE-APACHE deleted file mode 100644 index 57ca7a0..0000000 --- a/LICENSE-APACHE +++ /dev/null @@ -1,201 +0,0 @@ - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright 2025 Alex Nodeland - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. From 29d76ea3d639ddabf9f5e6a497a3cffee8f6c241 Mon Sep 17 00:00:00 2001 From: Alex Nodeland Date: Mon, 1 Sep 2025 15:22:39 -0400 Subject: [PATCH 2/8] Refactor README.md for clarity and structure - Simplified the README by removing unnecessary sections and improving the organization of content. - Updated feature descriptions to enhance readability and focus on key aspects of the library. - Added new sections highlighting the unique aspects of Fugue, including type-safe distributions and monadic design. - Improved example code snippets for adaptive MCMC and SMC to reflect recent API changes and enhance usability. - Streamlined installation instructions and contributing guidelines for better accessibility. --- README.md | 587 ++++++------------------------------------------------ 1 file changed, 56 insertions(+), 531 deletions(-) diff --git a/README.md b/README.md index 48ca424..48cb0af 100644 --- a/README.md +++ b/README.md @@ -1,578 +1,103 @@ -# 🎻 Fugue +# Fugue [![Crates.io](https://img.shields.io/crates/v/fugue.svg)](https://crates.io/crates/fugue) [![Documentation](https://docs.rs/fugue/badge.svg)](https://docs.rs/fugue) [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT) -[![License: Apache 2.0](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) -[![codecov](https://codecov.io/gh/alexnodeland/fugue/graph/badge.svg?token=BDJ5OB6GOB)](https://codecov.io/gh/alexnodeland/fugue) +[![CI](https://github.com/alexnodeland/fugue/actions/workflows/ci-develop.yml/badge.svg)](https://github.com/alexnodeland/fugue/actions/workflows/ci-develop.yml) +[![codecov](https://codecov.io/gh/alexnodeland/fugue/branch/develop/graph/badge.svg?token=BDJ5OB6GOB)](https://codecov.io/gh/alexnodeland/fugue) [![Rust](https://img.shields.io/badge/rust-1.70%2B-blue.svg)](https://www.rust-lang.org) A **production-ready**, **monadic probabilistic programming library** for Rust. Write elegant probabilistic programs by composing `Model` values in direct style; execute them with pluggable interpreters and state-of-the-art inference algorithms. -## ✨ Features +> Supported Rust: 1.70+ β€’ Platforms: Linux / macOS / Windows β€’ Crate: [`fugue` on crates.io](https://crates.io/crates/fugue) -- 🎯 **Monadic PPL**: Compose probabilistic programs using pure functional abstractions -- πŸ”’ **Type-Safe Distributions**: 10+ built-in probability distributions with natural return types -- 🎰 **Multiple Inference Methods**: MCMC, SMC, Variational Inference, ABC -- πŸ“Š **Comprehensive Diagnostics**: R-hat convergence, effective sample size, Geweke tests -- πŸ›‘οΈ **Numerically Stable**: Production-ready numerical algorithms with validation -- πŸš€ **Memory Optimized**: Efficient trace handling and memory management -- πŸŽ›οΈ **Ergonomic Macros**: Do-notation (`prob!`), vectorization (`plate!`), addressing (`addr!`) -- ⚑ **High Performance**: Zero-cost abstractions with pluggable runtime interpreters +## Features -## πŸš€ Quick Start +- **Monadic PPL**: Compose probabilistic programs using pure functional abstractions +- **Type-Safe Distributions**: 10+ built-in probability distributions with natural return types +- **Multiple Inference Methods**: MCMC, SMC, Variational Inference, ABC +- **Comprehensive Diagnostics**: R-hat convergence, effective sample size, validation +- **Production Ready**: Numerically stable algorithms with memory optimization +- **Ergonomic Macros**: Do-notation (`prob!`), vectorization (`plate!`), addressing (`addr!`) -Add Fugue to your `Cargo.toml`: +## Why Fugue? + +- πŸ”’ **Type-safe distributions**: natural return types (Bernoulli β†’ `bool`, Poisson/Binomial β†’ `u64`, Categorical β†’ `usize`) +- 🧩 **Direct-style, monadic design**: compose `Model` values with `bind/map` for explicit, readable control flow +- πŸ”Œ **Pluggable interpreters**: prior sampling, replay, scoring, and safe variants for production robustness +- πŸ“Š **Production diagnostics**: R-hat, ESS, validation utilities, and robust error handling +- ⚑ **Performance-minded**: memory pooling, copy-on-write traces, and numerically stable computations + +## Installation ```toml [dependencies] fugue = "0.3.0" ``` -### Simple Bayesian Linear Regression - -```rust -use fugue::*; -use rand::rngs::StdRng; -use rand::SeedableRng; - -fn bayesian_regression(x_data: &[f64], y_data: &[f64]) -> Model<(f64, f64)> { - let x_vec = x_data.to_vec(); // Clone to avoid lifetime issues in doctest - let y_vec = y_data.to_vec(); // Clone to avoid lifetime issues in doctest - - prob! { - // Priors - using safe constructors - let slope <- sample(addr!("slope"), Normal::new(0.0, 1.0).unwrap()); - let intercept <- sample(addr!("intercept"), Normal::new(0.0, 1.0).unwrap()); - let noise <- sample(addr!("noise"), LogNormal::new(0.0, 0.5).unwrap()); - - // Likelihood - handle observations sequentially - let _observations <- sequence_vec(x_vec.iter().zip(y_vec.iter()).enumerate().map(|(i, (&x, &y))| { - let y_pred = slope * x + intercept; - // Ensure noise is positive for Normal distribution - let safe_noise = noise.abs().max(1e-6); - observe(addr!("y", i), Normal::new(y_pred, safe_noise).unwrap(), y) - }).collect()); - - pure((slope, intercept)) - } -} - -fn main() -> Result<(), Box> { - let x_data = vec![1.0, 2.0, 3.0, 4.0, 5.0]; - let y_data = vec![2.1, 3.9, 6.1, 8.0, 9.9]; - - let mut rng = StdRng::seed_from_u64(42); - - // Run adaptive MCMC - let samples = adaptive_mcmc_chain( - &mut rng, - || bayesian_regression(&x_data, &y_data), - 1000, // samples - 500, // warmup - ); - - // Extract results using type-safe accessors - let slopes: Vec = samples.iter() - .filter_map(|(_, trace)| trace.get_f64(&addr!("slope"))) - .collect(); - - let mean_slope = slopes.iter().sum::() / slopes.len() as f64; - println!("Estimated slope: {:.3}", mean_slope); - - // Diagnostics - let ess = effective_sample_size_mcmc(&slopes); - println!("Effective sample size: {:.1}", ess); - - Ok(()) -} -``` - -## 🎯 Type Safety Revolution - -Fugue features a **fully type-safe distribution system** that eliminates common probabilistic programming pitfalls: - -### Before (Error-Prone) - -```rust -# use fugue::*; -let _example = sample(addr!("coin"), Bernoulli::new(0.5).unwrap()) - .bind(|coin_result| { - // ❌ This would be error-prone if this returned f64 instead of bool - // But Fugue returns bool, so coin_result is naturally a boolean - if coin_result { - pure("heads") - } else { - pure("tails") - } - }); -``` - -### After (Type-Safe) +### Quickstart -```rust -# use fugue::*; -let _example = sample(addr!("coin"), Bernoulli::new(0.5).unwrap()) - .bind(|is_heads| { - // βœ… Natural: direct boolean usage, compiler-enforced - if is_heads { - pure("heads") - } else { - pure("tails") - } - }); +```bash +cargo add fugue ``` -### πŸ”₯ Key Improvements - -- **Bernoulli** β†’ `bool` (no more `== 1.0` comparisons) -- **Poisson/Binomial** β†’ `u64` (natural counting, no casting) -- **Categorical** β†’ `usize` (safe array indexing) -- **Compiler guarantees** type correctness throughout - -## πŸ“š Core Concepts - -### Models as First-Class Values - -Fugue represents probabilistic programs as `Model` values that can be composed, transformed, and reused: +## Example ```rust use fugue::*; +use rand::rngs::StdRng; +use rand::SeedableRng; -// Pure deterministic computation -let model1 = pure(42.0); - -// Type-safe probabilistic sampling with safe constructors -let normal_sample: Model = sample(addr!("x"), Normal::new(0.0, 1.0).unwrap()); -let coin_flip: Model = sample(addr!("coin"), Bernoulli::new(0.5).unwrap()); -let event_count: Model = sample(addr!("count"), Poisson::new(3.0).unwrap()); -let category_choice: Model = sample(addr!("choice"), Categorical::new( - vec![0.3, 0.5, 0.2] -).unwrap()); - -// Type-safe observations -let obs1 = observe(addr!("y"), Normal::new(0.0, 1.0).unwrap(), 2.5); // f64 -let obs2 = observe(addr!("success"), Bernoulli::new(0.7).unwrap(), true); // bool -let obs3 = observe(addr!("events"), Poisson::new(4.0).unwrap(), 7u64); // u64 -let obs4 = observe(addr!("pick"), Categorical::new(vec![0.4, 0.6]).unwrap(), 1usize); // usize - -// Monadic composition with type safety -let composed = coin_flip.bind(|is_heads| { - if is_heads { - sample(addr!("bonus"), Poisson::new(5.0).unwrap()) - .map(|count| format!("Heads! Bonus: {}", count)) - } else { - pure("Tails!".to_string()) +// Run inference with model defined in closure +let mut rng = StdRng::seed_from_u64(42); +let samples = adaptive_mcmc_chain(&mut rng, || { + prob! { + let mu <- sample(addr!("mu"), Normal::new(0.0, 1.0).unwrap()); + observe(addr!("y"), Normal::new(mu, 0.5).unwrap(), 1.2); + pure(mu) } -}); -``` - -### Do-Notation with `prob!` - -Write probabilistic programs in an imperative style: - -```rust -# use fugue::*; -let observed_value = 1.5; // Example observed value -let mixture_model = prob! { - let z <- sample(addr!("component"), Bernoulli::new(0.3).unwrap()); // Returns bool! - let mu = if z { -2.0 } else { 2.0 }; // Natural boolean usage - let x <- sample(addr!("x"), Normal::new(mu, 1.0).unwrap()); - observe(addr!("y"), Normal::new(x, 0.1).unwrap(), observed_value); - pure(x) -}; -``` - -### Vectorized Operations with `plate!` - -Efficiently handle collections of random variables: - -```rust -# use fugue::*; -// Generate 100 independent samples -let samples = plate!(i in 0..100 => { - sample(addr!("x", i), Normal::new(0.0, 1.0).unwrap()) -}); - -// Hierarchical model with shared parameters -let hierarchical = prob! { - let global_mu <- sample(addr!("global_mu"), Normal::new(0.0, 1.0).unwrap()); - let local_effects <- plate!(i in 0..10 => { - sample(addr!("local", i), Normal::new(global_mu, 0.1).unwrap()) - }); - pure((global_mu, local_effects)) -}; -``` - -## 🎯 Inference Methods - -### Markov Chain Monte Carlo (MCMC) - -```rust -# use fugue::*; -# use rand::rngs::StdRng; -# use rand::SeedableRng; -# fn your_model() -> Model { sample(addr!("x"), Normal::new(0.0, 1.0).unwrap()) } -# let mut rng = StdRng::seed_from_u64(42); -# let n_samples = 1000; -# let n_warmup = 500; -// Adaptive Metropolis-Hastings with convergence diagnostics -let samples = adaptive_mcmc_chain( - &mut rng, - || your_model(), - n_samples, - n_warmup, -); +}, 1000, 500); -// Extract parameter values for diagnostics -let parameter_values: Vec = samples.iter() - .filter_map(|(_, trace)| trace.get_f64(&addr!("x"))) +let mu_values: Vec = samples.iter() + .filter_map(|(_, trace)| trace.get_f64(&addr!("mu"))) .collect(); - -// Compute R-hat for convergence diagnostics (simplified example) -println!("Collected {} samples", parameter_values.len()); -``` - -### Sequential Monte Carlo (SMC) - -```rust -# use fugue::*; -# use rand::rngs::StdRng; -# use rand::SeedableRng; -# fn your_model() -> Model { sample(addr!("x"), Normal::new(0.0, 1.0).unwrap()) } -# let mut rng = StdRng::seed_from_u64(42); -let config = SMCConfig { - resampling_method: ResamplingMethod::Systematic, - ess_threshold: 0.5, - rejuvenation_steps: 5, -}; - -let particles = adaptive_smc(&mut rng, 1000, || your_model(), config); -let ess = effective_sample_size(&particles); -``` - -### Variational Inference (VI) - -```rust -# use fugue::*; -# use rand::rngs::StdRng; -# use rand::SeedableRng; -# use std::collections::HashMap; -# fn your_model() -> Model { sample(addr!("mu"), Normal::new(0.0, 1.0).unwrap()) } -# let mut rng = StdRng::seed_from_u64(42); -// Mean-field variational approximation -let mut guide = MeanFieldGuide { - params: HashMap::new() -}; -guide.params.insert(addr!("mu"), VariationalParam::Normal { mu: 0.0, log_sigma: 0.0 }); - -let optimized_guide = optimize_meanfield_vi( - &mut rng, - || your_model(), - guide, - 1000, // max iterations - 100, // samples per iteration - 0.01, // learning rate -); ``` -### Approximate Bayesian Computation (ABC) +## Documentation -```rust -# use fugue::*; -# use rand::rngs::StdRng; -# use rand::SeedableRng; -# fn your_model() -> Model { sample(addr!("x"), Normal::new(0.0, 1.0).unwrap()) } -# let mut rng = StdRng::seed_from_u64(42); -# let simulator_fn = |trace: &Trace| vec![trace.get_f64(&addr!("x")).unwrap_or(0.0)]; -# let observed_data = vec![2.0]; -# let distance_fn = &EuclideanDistance; -# let tolerance = 0.1; -# let max_samples = 1000; -// Likelihood-free inference -let samples = abc_rejection( - &mut rng, - || your_model(), - simulator_fn, - &observed_data, - distance_fn, - tolerance, - max_samples, -); -``` +- **[User Guide](https://alexandernodeland.github.io/fugue/)** - Comprehensive tutorials and examples +- **[API Reference](https://docs.rs/fugue)** - Complete API documentation +- **Examples** - See `examples/` directory -## πŸ“Š Built-in Distributions +## Community -| **Distribution** | **Parameters** | **Return Type** | **Support** | **Usage** | -| ---------------- | --------------- | --------------- | ---------------- | -------------------------------------------- | -| `Normal` | `mu`, `sigma` | `f64` | ℝ | `Normal::new(0.0, 1.0).unwrap()` | -| `LogNormal` | `mu`, `sigma` | `f64` | ℝ⁺ | `LogNormal::new(0.0, 1.0).unwrap()` | -| `Uniform` | `low`, `high` | `f64` | [low, high] | `Uniform::new(0.0, 1.0).unwrap()` | -| `Exponential` | `rate` | `f64` | ℝ⁺ | `Exponential::new(1.0).unwrap()` | -| `Beta` | `alpha`, `beta` | `f64` | [0, 1] | `Beta::new(2.0, 3.0).unwrap()` | -| `Gamma` | `shape`, `rate` | `f64` | ℝ⁺ | `Gamma::new(2.0, 1.0).unwrap()` | -| `Bernoulli` | `p` | **`bool`** | {false, true} | `Bernoulli::new(0.3).unwrap()` | -| `Binomial` | `n`, `p` | **`u64`** | {0, 1, ..., n} | `Binomial::new(10, 0.5).unwrap()` | -| `Categorical` | `probs` | **`usize`** | {0, 1, ..., k-1} | `Categorical::new(vec![0.2, 0.3, 0.5]).unwrap()` | -| `Poisson` | `lambda` | **`u64`** | β„• | `Poisson::new(2.0).unwrap()` | +- **Issues & Bugs**: Use [GitHub Issues](https://github.com/alexandernodeland/fugue/issues) +- **Feature Requests**: Open an issue with the `enhancement` label -### 🎯 Type Safety Benefits +## Roadmap -- **`Bernoulli`** returns `bool` - no more `if sample == 1.0` comparisons! -- **`Poisson`/`Binomial`** return `u64` - natural counting with no casting needed -- **`Categorical`** returns `usize` - safe array indexing without conversion -- **Continuous distributions** return `f64` as appropriate -- **Compiler guarantees** - type errors caught at compile time +This project is an ongoing exploration of probabilistic programming in Rust. While many pieces are production-leaning, parts may not be 100% complete or correct yet. I’m steadily working toward a more robust implementation and broader feature set. -All distributions include automatic parameter validation and numerical stability checks. +Planned focus areas: -## πŸ› οΈ Advanced Features +- Strengthening core correctness and numerical stability +- Expanding distribution and inference coverage +- API refinements and stability guarantees +- Improved documentation, diagnostics, and examples -### Custom Interpreters +## Contributing -Implement your own model interpreters with full type safety: - -```rust -# use fugue::*; -# use rand::Rng; -struct CustomHandler { - rng: R, - // Your state here -} - -impl Handler for CustomHandler { - fn on_sample_f64(&mut self, addr: &Address, dist: &dyn Distribution) -> f64 { - // Handle continuous distributions - dist.sample(&mut self.rng) - } - - fn on_sample_bool(&mut self, addr: &Address, dist: &dyn Distribution) -> bool { - // Handle Bernoulli - returns bool directly! - dist.sample(&mut self.rng) - } - - fn on_sample_u64(&mut self, addr: &Address, dist: &dyn Distribution) -> u64 { - // Handle Poisson/Binomial - returns counts as u64 - dist.sample(&mut self.rng) - } - - fn on_sample_usize(&mut self, addr: &Address, dist: &dyn Distribution) -> usize { - // Handle Categorical - returns indices as usize - dist.sample(&mut self.rng) - } - - fn on_observe_f64(&mut self, addr: &Address, dist: &dyn Distribution, value: f64) { - // Observe continuous values - } - - fn on_observe_bool(&mut self, addr: &Address, dist: &dyn Distribution, value: bool) { - // Observe boolean outcomes - } - - fn on_observe_u64(&mut self, addr: &Address, dist: &dyn Distribution, value: u64) { - // Observe u64 values - } - - fn on_observe_usize(&mut self, addr: &Address, dist: &dyn Distribution, value: usize) { - // Observe usize values - } - - fn on_factor(&mut self, logw: f64) { - // Handle factors - } - - fn finish(self) -> Trace { - Trace::default() - } -} -``` - -### Hierarchical Addressing - -Organize complex models with scoped addresses: - -```rust -# use fugue::*; -let hierarchical = prob! { - let global_params <- plate!(layer in 0..3 => { - sample(scoped_addr!("layer", layer, "weight"), Normal::new(0.0, 1.0).unwrap()) - }); - // ... rest of model - pure(global_params) -}; -``` - -### Memory-Efficient Trace Manipulation - -```rust -# use fugue::*; -// Efficient trace operations with type-safe values -let mut trace = Trace::default(); -trace.insert_choice(addr!("x"), ChoiceValue::F64(1.5), 0.0); // Continuous -trace.insert_choice(addr!("coin"), ChoiceValue::Bool(true), -0.5); // Boolean -trace.insert_choice(addr!("count"), ChoiceValue::U64(7), -2.1); // Count -trace.insert_choice(addr!("choice"), ChoiceValue::Usize(2), -1.6); // Index - -// Trace validation and debugging -println!("Total log weight: {:.4}", trace.total_log_weight()); -``` - -## πŸ§ͺ Validation & Testing - -Fugue includes extensive validation against analytical solutions: - -```rust -# use fugue::*; -# use rand::rngs::StdRng; -# use rand::SeedableRng; -# use fugue::inference::validation::ConjugateNormalConfig; -# let mut rng = StdRng::seed_from_u64(42); -# let config = ConjugateNormalConfig { -# prior_mu: 0.0, -# prior_sigma: 1.0, -# likelihood_sigma: 0.5, -# observation: 2.0, -# n_samples: 1000, -# n_warmup: 500, -# }; -// Validate MCMC against known posterior -let prior_mu = config.prior_mu; -let prior_sigma = config.prior_sigma; -let likelihood_sigma = config.likelihood_sigma; -let observation = config.observation; - -let validation = test_conjugate_normal_model( - &mut rng, - move |rng, n_samples, n_warmup| { - adaptive_mcmc_chain(rng, move || { - sample(addr!("mu"), Normal::new(prior_mu, prior_sigma).unwrap()) - .bind(move |mu| { - observe(addr!("y"), Normal::new(mu, likelihood_sigma).unwrap(), observation); - pure(mu) - }) - }, n_samples, n_warmup) - }, - config, -); - -println!("Validation complete: {}", validation.is_valid()); -``` - -## ⚑ Performance - -Fugue is designed for production workloads: - -- **Zero-cost abstractions**: Monadic composition compiles to efficient code -- **Memory optimization**: Efficient trace representation and garbage collection -- **Numerical stability**: IEEE 754-compliant log-probability arithmetic -- **Scalable inference**: Support for large models with thousands of parameters - -Benchmark on your hardware: - -```bash -cargo bench -``` - -## 🀝 Contributing - -We welcome contributions! Please see our [Contributing Guidelines](.github/CONTRIBUTING.md) for details. - -### Development Setup +Contributions welcome! See our [contributing guidelines](.github/CONTRIBUTING.md). ```bash git clone https://github.com/alexandernodeland/fugue.git -cd fugue -cargo test -cargo test --doc -cargo run --example gaussian_mean +cd fugue && cargo test ``` -### Running Tests - -```bash -# Unit tests -cargo test - -# Integration tests -cargo test --test '*' - -# Property-based tests -cargo test property_tests - -# Documentation tests -cargo test --doc -``` - -## πŸ“– Documentation - -### πŸš€ Getting Started - -- **[⚑ Installation Guide](docs/src/getting-started/installation.md)** - Get up and running quickly -- **[🎯 Your First Model](docs/src/getting-started/your-first-model.md)** - Build your first probabilistic model +## License -### πŸ“š Learning Resources - -- **[πŸŽ“ Tutorials](docs/src/tutorials/README.md)** - Step-by-step learning: - - **Foundation Tutorials**: - - [Bayesian Coin Flip](docs/src/tutorials/foundation/bayesian-coin-flip.md) (Beginner) - - [Type Safety Features](docs/src/tutorials/foundation/type-safety-features.md) (Beginner) - - [Trace Manipulation](docs/src/tutorials/foundation/trace-manipulation.md) (Beginner) - - **Statistical Modeling**: - - [Linear Regression](docs/src/tutorials/statistical-modeling/linear-regression.md) (Intermediate) - - [Classification](docs/src/tutorials/statistical-modeling/classification.md) (Intermediate) - - [Mixture Models](docs/src/tutorials/statistical-modeling/mixture-models.md) (Intermediate) - - [Hierarchical Models](docs/src/tutorials/statistical-modeling/hierarchical-models.md) (Advanced) - - **Advanced Applications**: - - [Time Series & Forecasting](docs/src/tutorials/advanced-applications/time-series-forecasting.md) (Advanced) - - [Model Comparison & Selection](docs/src/tutorials/advanced-applications/model-comparison-selection.md) (Advanced) - - [Advanced Inference](docs/src/tutorials/advanced-applications/advanced-inference.md) (Advanced) - -- **[πŸ› οΈ How-To Guides](docs/src/how-to/README.md)** - Practical solutions: - - [Working with Distributions](docs/src/how-to/working-with-distributions.md) - - [Building Complex Models](docs/src/how-to/building-complex-models.md) - - [Optimizing Performance](docs/src/how-to/optimizing-performance.md) - - [Debugging Models](docs/src/how-to/debugging-models.md) - - [Custom Handlers](docs/src/how-to/custom-handlers.md) - - [Production Deployment](docs/src/how-to/production-deployment.md) - -### πŸ“– Reference - -- **[API Documentation](https://docs.rs/fugue)** - Complete API reference - -## πŸ“„ License - -Licensed under either of - -- Apache License, Version 2.0 ([LICENSE-APACHE](LICENSE-APACHE) or ) -- MIT license ([LICENSE-MIT](LICENSE-MIT) or ) - -at your option. - -## πŸ“„ Contributing - -Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in the work by you shall be dual licensed as above, without any additional terms or conditions. - -## πŸ™ Acknowledgments - -Fugue draws inspiration from: - -- **[Gen.jl](https://github.com/probcomp/Gen.jl)** - General-purpose probabilistic programming in Julia -- **[WebPPL](https://webppl.org/)** - Functional probabilistic programming - -## πŸ”— Citation - -If you use Fugue in your research, please cite: - -```bibtex -@software{fugue2024, - title = {Fugue: Production-Ready Monadic Probabilistic Programming for Rust}, - author = {Alexander Nodeland}, - url = {https://github.com/alexandernodeland/fugue}, - version = {0.3.0}, - year = {2024} -} -``` +Licensed under the [MIT License](LICENSE). --- -**Built with ❀️ in Rust** | [Website](https://github.com/alexandernodeland/fugue) | [Documentation](https://docs.rs/fugue) | [Crates.io](https://crates.io/crates/fugue) +Built with Rust β€’ Monadic PPL β€’ Type-safe distributions From d6f5ca1eb3aee026e822ec82a0b0f580403d6dce Mon Sep 17 00:00:00 2001 From: Alex Nodeland Date: Mon, 1 Sep 2025 15:28:13 -0400 Subject: [PATCH 3/8] Remove outdated documentation file for the documentation system specification - Deleted the .github/DOCUMENTATION.md file, which contained comprehensive guidelines for writing, organizing, and testing documentation within the repository. - This removal aims to streamline documentation resources and eliminate redundancy, as the content may have been superseded by other documentation efforts. --- .github/DOCUMENTATION.md | 222 --------------------------------------- 1 file changed, 222 deletions(-) delete mode 100644 .github/DOCUMENTATION.md diff --git a/.github/DOCUMENTATION.md b/.github/DOCUMENTATION.md deleted file mode 100644 index d084afc..0000000 --- a/.github/DOCUMENTATION.md +++ /dev/null @@ -1,222 +0,0 @@ -# Documentation System Specification - -This document defines the standards and workflows for writing, organizing, and testing documentation in this repository. It ensures a consistent developer experience, maintains correctness via CI, and provides both reference documentation and learning materials. - -## 1. Documentation Structure - -### 1.1 Source Layout - -```text -your-crate/ -β”œβ”€ src/ # Rust source code -β”‚ β”œβ”€ lib.rs -β”‚ └─ foo.rs # modules -β”œβ”€ examples/ # runnable examples (compiled with cargo run --example) -β”‚ └─ widget_basic.rs -β”œβ”€ docs/ -β”‚ β”œβ”€ src/ # mdBook sources (how-tos, tutorials, guides) -β”‚ β”‚ └─ ... -β”‚ └─ api/ # long-form API docs (included into rustdoc) -β”‚ β”œβ”€ \_prelude.md -β”‚ β”œβ”€ foo.md -β”‚ └─ ... -β”œβ”€ tests/ -β”‚ └─ doctests.rs # optional: standalone doctests via doc-comment -└─ Cargo.toml -``` - -### 1.2 Documentation Types - -- **API Docs** (docs/api/_.md) - - Long-form reference documentation attached to modules/items with #[doc = include_str!(...)]. Includes extended examples, design notes, and error-handling guidance. -- **Inline Docs** (/// and //!) - - Concise explanations and small, copy-pasteable examples (≀ 25 lines, ≀ 2 imports) directly in the source. Show up in IDEs and rustdoc item pages. -- **mdBook Docs** (docs/src) - - Guides, how-tos, and tutorials. Include anchored snippets from examples/ to keep docs and code in sync. Tested with mdbook test. -- **Examples** (examples/_.rs) - - Full, runnable programs demonstrating end-to-end workflows. Serve as canonical sources for snippets (via anchors) and are part of CI. - -## 2. Writing Documentation - -### 2.1 Inline API Documentation - -- Keep short usage examples next to the code: - -```rust -/// Creates a new widget. -/// -/// `/// use your_crate::Widget; -/// let w = Widget::new(); -///` -pub fn new() -> Self { ... } -``` - -- Use doctest fences: - - ```rust``` β€” compile & run - - ```rust,no_run``` β€” compile only - - ```rust,ignore``` β€” shown but not tested - - ```rust,compile_fail``` β€” must fail - -### 2.2 API Markdown Documents (docs/api/\*.md) - -Each module’s long-form doc should include: 1. Overview β€” purpose and conceptual model. 2. Usage Examples β€” extended, doctested code with hidden imports. 3. Design & Evolution β€” rationale, invariants, feature flags, and proposal workflow. 4. Error Handling β€” common failure modes and best practices. 5. Integration Notes β€” relation to other modules and external crates. 6. Reference Links β€” cross-links to API items, mdBook tutorials, and examples. - -#### Example Template - -````markdown -# Module: Foo - -## Overview - -Explain the problem this module solves and the abstractions it provides. - -## Usage Examples - -```rust -# use crate::foo::*; -let w = Widget::new(); -w.do_it(); -``` -```` - -#### Design & Evolution - -- Status: Stable since vX.Y. -- Feature flags: foo_async requires feature="async". -- Invariants: Cheap to clone; idempotent builder. - -#### Proposal Workflow - -- Open a Design Proposal (DP) issue. -- Discuss API surface and alternatives. -- Land behind feature flag β†’ stabilize on minor release. - -#### Error Handling - -- FooError::Io when file access fails. -- Always check return values. - -#### Integration Notes - -- Works with serde if feature="serde". -- Compatible with async runtimes. - -#### Reference Links - -- Widget -- Tutorial: Foo in practice - -### 2.3 mdBook Documentation - -- Use **real code from `examples/`** via anchors: - -```rust,no_run -{{#include ../../examples/widget_basic.rs:snippet_simple}} -``` - -- Write narrative, tutorials, and workflows. -- Ensure all code blocks compile with mdbook test -L target/debug/deps. - -### 2.4 Examples (examples/*.rs) - -- Contain runnable, end-to-end code. -- Mark snippet regions with // ANCHOR: name and // ANCHOR_END: name for inclusion in mdBook and API docs. - -Example: - -````rust -// examples/widget_basic.rs - -// ANCHOR: snippet_simple -use your_crate::Widget; - -fn main() { - let w = Widget::new(); - w.do_it(); -} -// ANCHOR_END: snippet_simple -```` - -## 3. Testing Documentation - -### 3.1 Cargo Doctests - -Run doctests embedded in code and included API Markdown: - -```bash -cargo test --doc --all-features -``` - -### 3.2 mdBook Tests - -Run doctests for all code snippets in guides/tutorials: - -```bash -cargo build --all-features -mdbook test docs/src -L target/debug/deps -``` - -### 3.3 Standalone Markdown Tests (Optional) - -If testing Markdown files not attached to modules (e.g., README.md): - -```rust -// tests/doctests.rs -doc_comment::doctest!("../README.md"); -doc_comment::doctest!("../docs/api/foo.md"); -``` - -## 4. Continuous Integration - -### 4.1 Lints & Flags - -- Deny broken links and missing docs: - -```rust -#![deny(rustdoc::broken_intra_doc_links)] -#![warn(missing_docs)] -``` - -### 4.2 GitHub Actions Workflow - -```yaml -name: Docs & Examples -on: [push, pull_request] - -jobs: - docs_examples: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v4 - - uses: dtolnay/rust-toolchain@stable - - run: cargo build --all-features - - run: cargo test --all-features - - run: cargo test --doc --all-features - - name: Install mdBook - run: cargo install mdbook --locked - - name: Test mdBook docs - run: mdbook test docs/src -L target/debug/deps -``` - -## 5. Responsibilities & Best Practices - -- Inline docs = concise, always present. -- API Markdown = extended reference; only when inline would be too long. -- Examples/ = runnable, anchored snippets; the single source of truth. -- mdBook = tutorials & how-tos, always include snippets from examples/. -- CI = ensures every snippet compiles/tests, preventing drift. - -## 6. Proposal / Evolution Process - -1. Proposals filed as DP issues (or rfcs/NNNN-title.md). -2. Discuss API changes with design notes and alternatives. -3. Implement behind feature flag. -4. Stabilize in next minor release after usage feedback. -5. Update API docs + mdBook + examples simultaneously. - -## βœ… Outcome - -- Developers learn with mdBook tutorials. -- They confirm details in API reference. -- All examples stay executable and CI-covered. -- Evolution is traceable and standardized. From 862e20a88918be99a2261f31f9545774077630e6 Mon Sep 17 00:00:00 2001 From: Alex Nodeland Date: Mon, 1 Sep 2025 15:33:52 -0400 Subject: [PATCH 4/8] Fix md lint errors --- docs/src/getting-started/installation.md | 4 ++-- docs/src/how-to/building-complex-models.md | 12 +++++------ docs/src/how-to/production-deployment.md | 24 +++++++++++----------- 3 files changed, 20 insertions(+), 20 deletions(-) diff --git a/docs/src/getting-started/installation.md b/docs/src/getting-started/installation.md index 3be9419..f4abde0 100644 --- a/docs/src/getting-started/installation.md +++ b/docs/src/getting-started/installation.md @@ -34,7 +34,7 @@ Add Fugue to your `Cargo.toml`: ```toml [dependencies] -fugue = "0.3.0" +fugue = "0.1.0" rand = "0.8" # For random number generation ``` @@ -44,7 +44,7 @@ Add Fugue to your existing `Cargo.toml`: ```toml [dependencies] -fugue = "0.3.0" +fugue = "0.1.0" rand = "0.8" ``` diff --git a/docs/src/how-to/building-complex-models.md b/docs/src/how-to/building-complex-models.md index 6150b81..e4515c7 100644 --- a/docs/src/how-to/building-complex-models.md +++ b/docs/src/how-to/building-complex-models.md @@ -256,25 +256,25 @@ Dynamic model construction: ```mermaid graph TD A[Model M] --> B[Syntactic Tests] - A --> C[Semantic Tests] + A --> C[Semantic Tests] A --> D[Statistical Tests] - + B --> E[Type Checking] B --> F[Address Uniqueness] - + C --> G[Trace Validity] C --> H[Parameter Bounds] - + D --> I[Prior Predictive] D --> J[Posterior Consistency] - + E --> K{All Pass?} F --> K G --> K H --> K I --> K J --> K - + K -->|Yes| L[Model Validated] K -->|No| M[Refinement Required] ``` diff --git a/docs/src/how-to/production-deployment.md b/docs/src/how-to/production-deployment.md index 4c312ae..5db6805 100644 --- a/docs/src/how-to/production-deployment.md +++ b/docs/src/how-to/production-deployment.md @@ -334,9 +334,9 @@ use serde_json::json; // Structured logging for production debugging fn log_inference_event( - request_id: &str, - model_version: &str, - duration: Duration, + request_id: &str, + model_version: &str, + duration: Duration, result: &InferenceResult ) { let log_entry = json!({ @@ -364,15 +364,15 @@ struct AlertRules { impl AlertRules { fn check_alerts(&self, metrics: &ProductionMetrics) -> Vec { let mut alerts = Vec::new(); - + if metrics.error_rate() > self.max_error_rate { alerts.push(Alert::HighErrorRate(metrics.error_rate())); } - + if metrics.avg_latency().as_millis() > self.max_latency_ms as u128 { alerts.push(Alert::HighLatency(metrics.avg_latency())); } - + alerts } } @@ -393,13 +393,13 @@ struct ShadowTester { impl ShadowTester { fn run_with_shadow(&mut self, input: &Input) -> (PrimaryResult, Option) { let primary = self.run_primary(input); - + let shadow = if rand::random::() < self.comparison_rate { Some(self.run_shadow(input)) } else { None }; - + (primary, shadow) } } @@ -411,12 +411,12 @@ impl ShadowTester { // Continuous validation in production fn validate_model_assumptions(trace: &Trace) -> ValidationResult { let mut issues = Vec::new(); - + // Check log-weight stability if !trace.total_log_weight().is_finite() { issues.push("Non-finite log-weight detected".to_string()); } - + // Check parameter ranges for (addr, choice) in &trace.choices { if let ChoiceValue::F64(value) = choice.value { @@ -425,7 +425,7 @@ fn validate_model_assumptions(trace: &Trace) -> ValidationResult { } } } - + ValidationResult { issues } } ``` @@ -564,7 +564,7 @@ fn log_inference_request( model_version: response.model_version.clone(), success: response.success, }; - + audit_logger::log(audit_log); } ``` From d1f2e1feab3bc30e025a51f8fbc7c93dea40ad50 Mon Sep 17 00:00:00 2001 From: Alex Nodeland Date: Mon, 1 Sep 2025 15:35:34 -0400 Subject: [PATCH 5/8] Update version of Fugue to 0.1.0 in Cargo.toml, Cargo.lock, README.md, and documentation files. This change reflects the initial release of the library, consolidating all references to the new version number for consistency across the project. --- .github/CHANGELOG.md | 163 +++++++++++++++++++++---------------------- Cargo.lock | 2 +- Cargo.toml | 2 +- README.md | 2 +- docs/index.html | 4 +- 5 files changed, 86 insertions(+), 87 deletions(-) diff --git a/.github/CHANGELOG.md b/.github/CHANGELOG.md index d039caf..7efadc9 100644 --- a/.github/CHANGELOG.md +++ b/.github/CHANGELOG.md @@ -1,84 +1,83 @@ # Changelog -## [0.3.0] - 2024-12-19 - General Improvements - -### πŸš€ **Major Improvements** - -#### **Numerical Stability & Correctness** - -- **Fixed all distribution implementations** with proper parameter validation and overflow protection -- **Implemented stable log-sum-exp** for SMC weight normalization -- **Added numerical utilities module** with robust mathematical functions -- **Enhanced error handling** with comprehensive FugueError types and validation traits - -#### **Theoretical Soundness** - -- **Proper diminishing adaptation** for MCMC following Roberts & Rosenthal (2007) -- **Ergodicity-preserving algorithms** with mathematical guarantees -- **Stable acceptance probability computation** using log-space comparisons -- **Correct conditioning semantics** for probabilistic programming - -#### **Performance & Memory Optimization** - -- **Copy-on-write traces** reducing MCMC allocation overhead by ~60% -- **Memory pooling** for efficient object reuse -- **Optimized model execution** with reduced heap allocations -- **Efficient weight normalization** preventing underflow/overflow - -#### **Enhanced Diagnostics** - -- **Effective sample size computation** with proper autocorrelation analysis -- **Geweke convergence diagnostics** for single-chain assessment -- **Statistical validation framework** against analytical solutions -- **Comprehensive convergence monitoring** with multiple metrics - -#### **Production Features** - -- **Parameter validation** for all probability distributions -- **Structured error handling** with context and recovery suggestions -- **Extensive test suite** including numerical stability stress tests -- **Complete documentation** with mathematical foundations - -### πŸ”§ **Breaking Changes** - -- `AdaptiveScales` removed entirely - use `DiminishingAdaptation` instead -- Distribution constructors now return `Result` for validation -- Enhanced `VariationalParam` with numerical stability improvements -- Improved MCMC functions with better theoretical properties - -### πŸš€ **New Features** - -- `DiminishingAdaptation` for theoretically sound MCMC adaptation -- `log_sum_exp` and numerical utilities for stable computation -- `CowTrace` and memory management optimizations -- `ValidationResult` and statistical testing framework -- Comprehensive diagnostics with `effective_sample_size_mcmc` and `geweke_diagnostic` - -### πŸ“š **Documentation** - -- Complete mathematical formulations for all algorithms -- 70+ working examples with compilation verification -- Theoretical background and convergence properties -- Production deployment guidelines - -### ⚑ **Performance** - -- ~60% reduction in memory allocations for MCMC -- Stable numerical computation preventing overflow/underflow -- Optimized SMC with proper weight handling -- Efficient trace operations with copy-on-write semantics - ---- - -## [0.2.0] - -- Basic probabilistic programming functionality -- Simple inference algorithms -- Monadic model composition -- Original documentation - ---- - -## [0.1.0] - -- Initial release +All notable changes to this project will be documented in this file. + +The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), +and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). + +## [Unreleased] + +## [0.1.0] - 2025-09-XX + +### Added + +- Initial release of Fugue, a monadic probabilistic programming library for Rust. +- **Core probabilistic programming framework**: + - `Model` abstraction for composable probabilistic programs. + - Monadic operations: `bind`, `map`, `and_then`, `pure` for program composition. + - `sample`, `observe`, `factor`, `guard` primitives for probabilistic modeling. +- **Type-safe distribution system** with natural return types: + - `Bernoulli` distribution returning `bool` (eliminates `== 1.0` comparisons). + - `Poisson` and `Binomial` distributions returning `u64` (natural counting). + - `Categorical` distribution returning `usize` (safe array indexing). + - Continuous distributions (`Normal`, `Beta`, `Gamma`, etc.) returning `f64`. + - 10 built-in distributions with parameter validation and numerical stability. +- **Ergonomic macros** for probabilistic programming: + - `prob!` macro for Haskell-style do-notation. + - `plate!` macro for vectorized operations over collections. + - `addr!` and `scoped_addr!` macros for hierarchical addressing. +- **Multiple inference algorithms**: + - MCMC: Adaptive Metropolis-Hastings with convergence diagnostics. + - SMC: Sequential Monte Carlo with multiple resampling methods. + - VI: Mean-field variational inference with ELBO optimization. + - ABC: Approximate Bayesian Computation with distance functions. +- **Effect handler system**: + - `Handler` trait for pluggable model interpreters. + - 5 built-in handlers: `PriorHandler`, `ReplayHandler`, `ScoreGivenTrace`, `SafeReplayHandler`, `SafeScoreGivenTrace`. + - Type-safe execution preserving distribution return types. +- **Trace system** for execution history: + - Complete recording of random choices and log-weights. + - Type-safe value access with `get_f64()`, `get_bool()`, `get_u64()`, `get_usize()`. + - Three-component log-weight decomposition (prior, likelihood, factors). +- **Memory optimization**: + - Copy-on-write traces (`CowTrace`) for efficient MCMC proposals. + - Object pooling (`TracePool`) for zero-allocation inference. + - Efficient trace construction (`TraceBuilder`). +- **Production features**: + - Comprehensive error handling with `FugueError` and error codes. + - Numerically stable algorithms with overflow protection. + - Convergence diagnostics: R-hat, effective sample size, Geweke tests. + - Statistical validation against analytical solutions. +- **Documentation and examples**: + - Comprehensive user guide with 20+ tutorial and how-to pages. + - Complete API documentation with rustdoc. + - 14 examples covering foundation concepts, statistical modeling, and advanced patterns. + - 158+ doctests ensuring example correctness. +- **Testing infrastructure**: + - 82+ unit tests across all modules. + - 9+ integration tests for end-to-end workflows. + - Property-based testing with `proptest`. + - Continuous integration with format, lint, and test enforcement. + +### Changed + +- N/A (initial release) + +### Deprecated + +- N/A (initial release) + +### Removed + +- N/A (initial release) + +### Fixed + +- N/A (initial release) + +### Security + +- N/A (initial release) + +[Unreleased]: https://github.com/alexandernodeland/fugue/compare/v0.1.0...HEAD +[0.1.0]: https://github.com/alexandernodeland/fugue/releases/tag/v0.1.0 diff --git a/Cargo.lock b/Cargo.lock index 2115a81..6663d1d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1026,7 +1026,7 @@ dependencies = [ [[package]] name = "fugue" -version = "0.3.0" +version = "0.1.0" dependencies = [ "cargo-llvm-cov", "clap 4.5.45", diff --git a/Cargo.toml b/Cargo.toml index 79b5f12..c9a6422 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "fugue" -version = "0.3.0" +version = "0.1.0" edition = "2021" license = "MIT OR Apache-2.0" description = "Production-ready monadic PPL with numerically stable inference, comprehensive diagnostics, and memory optimization." diff --git a/README.md b/README.md index 48cb0af..c428dfb 100644 --- a/README.md +++ b/README.md @@ -32,7 +32,7 @@ A **production-ready**, **monadic probabilistic programming library** for Rust. ```toml [dependencies] -fugue = "0.3.0" +fugue = "0.1.0" ``` ### Quickstart diff --git a/docs/index.html b/docs/index.html index f6d0142..d028333 100644 --- a/docs/index.html +++ b/docs/index.html @@ -202,7 +202,7 @@

✨ Features

πŸš€ Quick Start

Add Fugue to your Cargo.toml:

[dependencies]
-fugue = "0.3.0"
+fugue = "0.1.0"
 

Simple Bayesian Linear Regression

use fugue::*;
@@ -708,7 +708,7 @@ 

πŸ”— Citation

title = {Fugue: Production-Ready Monadic Probabilistic Programming for Rust}, author = {Alexander Nodeland}, url = {https://github.com/alexandernodeland/fugue}, - version = {0.3.0}, + version = {0.1.0}, year = {2024} }
From 68f78a9028b7e5efa7dc30ed51a367a21f4c2ea6 Mon Sep 17 00:00:00 2001 From: Alex Nodeland Date: Mon, 1 Sep 2025 15:46:12 -0400 Subject: [PATCH 6/8] Add contributing guidelines to Fugue documentation - Introduced a comprehensive CONTRIBUTING.md file outlining the process for contributing to the Fugue project. - Included sections on quick start, development setup, building and testing, contributing guidelines, versioning, code style, and project structure. - Aimed to provide clear instructions and best practices for contributors, enhancing collaboration and project consistency. --- .github/CONTRIBUTING.md | 159 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 159 insertions(+) diff --git a/.github/CONTRIBUTING.md b/.github/CONTRIBUTING.md index e69de29..a2bcaba 100644 --- a/.github/CONTRIBUTING.md +++ b/.github/CONTRIBUTING.md @@ -0,0 +1,159 @@ +# Contributing to Fugue + +Thank you for your interest in contributing to Fugue! This document provides guidelines for contributing to the project. + +## Quick Start + +```bash +git clone https://github.com/alexandernodeland/fugue.git +cd fugue +cargo test --all-features +``` + +## Development Setup + +### Prerequisites + +- Rust 1.70+ (install via [rustup](https://rustup.rs/)) +- Git + +### Building and Testing + +```bash +# Run all tests +make test + +# Format code +make fmt + +# Lint code +make lint + +# Run benchmarks +make bench + +# Generate coverage report +make coverage + +# Run all checks +make all +``` + +Or use cargo directly: + +```bash +cargo test --all-features +cargo fmt +cargo clippy -- -D warnings +``` + +## Contributing Guidelines + +### Issues + +- Use GitHub Issues for bug reports and feature requests +- Provide clear reproduction steps for bugs +- Include relevant code examples + +### Pull Requests + +- Fork the repository and create a feature branch from `develop` +- **Rebase your branch** to the top of `develop` before submitting PR +- Use **semantic commit messages** (e.g., `feat:`, `fix:`, `docs:`, `refactor:`) +- Add tests for new functionality +- **Ensure all CI checks pass** before requesting review +- PRs are **squash merged** to maintain linear history +- Update documentation as needed + +### Versioning + +- We follow [Semantic Versioning](https://semver.org/) (SemVer) +- Breaking changes increment major version +- New features increment minor version +- Bug fixes increment patch version + +### Code Style + +- Follow Rust standard formatting (`cargo fmt`) +- Address all clippy warnings (`cargo clippy -- -D warnings`) +- Add documentation for public APIs +- Include examples in documentation + +## Project Structure + +```mermaid +graph LR + A["🎻 Fugue
Monadic Probabilistic Programming"] --> B["πŸ“¦ Core Module"] + A --> C["πŸ”¬ Inference Module"] + A --> D["βš™οΈ Runtime Module"] + A --> E["πŸŽ›οΈ Macros Module"] + A --> F["⚠️ Error Module"] + + B --> B1["πŸ“ Address System
addr!(), scoped_addr!()"] + B --> B2["πŸ“Š Distributions
10 type-safe distributions"] + B --> B3["🧩 Model
Monadic composition"] + B --> B4["πŸ”’ Numerical
Stable algorithms"] + + B2 --> B2A["bool: Bernoulli"] + B2 --> B2B["u64: Poisson, Binomial"] + B2 --> B2C["usize: Categorical"] + B2 --> B2D["f64: Normal, Beta, Gamma, etc."] + + C --> C1["πŸ”— MCMC
Adaptive Metropolis-Hastings"] + C --> C2["🎯 SMC
Particle filtering"] + C --> C3["πŸ“ˆ VI
Mean-field approximation"] + C --> C4["🎲 ABC
Likelihood-free inference"] + C --> C5["πŸ“Š Diagnostics
R-hat, ESS, validation"] + + D --> D1["🎭 Handler System
Effect interpreters"] + D --> D2["πŸ“ Trace System
Execution history"] + D --> D3["πŸ’Ύ Memory Optimization
Pooling & COW"] + + D1 --> D1A["PriorHandler"] + D1 --> D1B["ReplayHandler"] + D1 --> D1C["ScoreGivenTrace"] + D1 --> D1D["Safe variants"] + + E --> E1["prob!
Do-notation"] + E --> E2["plate!
Vectorization"] + + F --> F1["FugueError
Rich error context"] + + G["πŸ“š Documentation"] --> G1["User Guide
20+ pages"] + G --> G2["API Reference
Complete rustdoc"] + G --> G3["14 Examples
Real-world scenarios"] + + H["πŸ§ͺ Testing"] --> H1["82+ Unit Tests"] + H --> H2["9+ Integration Tests"] + H --> H3["158+ Doctests"] + H --> H4["Property-based Tests"] + + I["⚑ Benchmarks"] --> I1["MCMC Performance
Adaptation & diagnostics"] + I --> I2["Memory Optimization
Pooling & COW traces"] + + style A fill:#e1f5fe + style B fill:#f3e5f5 + style C fill:#e8f5e8 + style D fill:#fff3e0 + style E fill:#fce4ec + style F fill:#ffebee + style G fill:#f1f8e9 + style H fill:#e3f2fd + style I fill:#fff8e1 +``` + +### Directory Structure + +- `src/core/` - Core probabilistic programming abstractions +- `src/inference/` - Inference algorithms (MCMC, SMC, VI, ABC) +- `src/runtime/` - Execution engine and memory optimization +- `src/macros/` - Ergonomic macros for model construction +- `src/error/` - Comprehensive error handling +- `examples/` - 14 complete examples and tutorials +- `docs/` - User guide and API documentation +- `benches/` - Performance benchmarks for MCMC and memory optimization +- `tests/` - Integration and end-to-end tests + +## Questions? + +Open an issue or start a discussion on GitHub. We're happy to help! From f6da47df6ffbf22619fe0bb71ce4f24eac1a29c1 Mon Sep 17 00:00:00 2001 From: Alex Nodeland Date: Mon, 1 Sep 2025 15:48:30 -0400 Subject: [PATCH 7/8] Update CONTRIBUTING.md to reflect new directory structure and enhance clarity - Revised the directory structure section to provide a detailed overview of the project layout, including descriptions for core modules, inference algorithms, runtime components, macros, error handling, examples, documentation, benchmarks, and tests. - Improved formatting for better readability and accessibility, ensuring contributors have a clear understanding of the project's organization and resources available for development. --- .github/CONTRIBUTING.md | 46 +++++++++++++++++++++++++++++++++-------- 1 file changed, 37 insertions(+), 9 deletions(-) diff --git a/.github/CONTRIBUTING.md b/.github/CONTRIBUTING.md index a2bcaba..dbd183f 100644 --- a/.github/CONTRIBUTING.md +++ b/.github/CONTRIBUTING.md @@ -144,15 +144,43 @@ graph LR ### Directory Structure -- `src/core/` - Core probabilistic programming abstractions -- `src/inference/` - Inference algorithms (MCMC, SMC, VI, ABC) -- `src/runtime/` - Execution engine and memory optimization -- `src/macros/` - Ergonomic macros for model construction -- `src/error/` - Comprehensive error handling -- `examples/` - 14 complete examples and tutorials -- `docs/` - User guide and API documentation -- `benches/` - Performance benchmarks for MCMC and memory optimization -- `tests/` - Integration and end-to-end tests +```text +fugue/ +β”œβ”€β”€ src/ +β”‚ β”œβ”€β”€ core/ # Core probabilistic programming abstractions +β”‚ β”‚ β”œβ”€β”€ address.rs # Hierarchical addressing system +β”‚ β”‚ β”œβ”€β”€ distribution.rs # Type-safe distributions (10 built-in) +β”‚ β”‚ β”œβ”€β”€ model.rs # Monadic Model abstraction +β”‚ β”‚ └── numerical.rs # Numerically stable algorithms +β”‚ β”œβ”€β”€ inference/ # Inference algorithms +β”‚ β”‚ β”œβ”€β”€ mh.rs # MCMC (Adaptive Metropolis-Hastings) +β”‚ β”‚ β”œβ”€β”€ smc.rs # Sequential Monte Carlo +β”‚ β”‚ β”œβ”€β”€ vi.rs # Variational Inference +β”‚ β”‚ β”œβ”€β”€ abc.rs # Approximate Bayesian Computation +β”‚ β”‚ └── diagnostics.rs # R-hat, ESS, validation +β”‚ β”œβ”€β”€ runtime/ # Execution engine +β”‚ β”‚ β”œβ”€β”€ handler.rs # Effect handler system +β”‚ β”‚ β”œβ”€β”€ interpreters.rs # Built-in handlers +β”‚ β”‚ β”œβ”€β”€ trace.rs # Execution history recording +β”‚ β”‚ └── memory.rs # Memory optimization (pooling, COW) +β”‚ β”œβ”€β”€ macros/ # Ergonomic macros +β”‚ β”‚ └── mod.rs # prob!, plate!, addr! macros +β”‚ └── error.rs # Comprehensive error handling +β”œβ”€β”€ examples/ # 14 complete examples +β”‚ β”œβ”€β”€ bayesian_coin_flip.rs +β”‚ β”œβ”€β”€ linear_regression.rs +β”‚ β”œβ”€β”€ mixture_models.rs +β”‚ β”œβ”€β”€ hierarchical_models.rs +β”‚ └── ... +β”œβ”€β”€ benches/ # Performance benchmarks +β”‚ β”œβ”€β”€ mcmc_benchmarks.rs # MCMC adaptation & diagnostics +β”‚ └── memory_benchmarks.rs # Memory pooling & COW traces +β”œβ”€β”€ tests/ # Integration tests +β”œβ”€β”€ docs/ # User guide & documentation +β”‚ β”œβ”€β”€ src/ # mdBook source +β”‚ └── api/ # API documentation +└── target/ # Build artifacts +``` ## Questions? From 6248299b0ddb5ba266b89e7b6d5821979b02d499 Mon Sep 17 00:00:00 2001 From: Alex Nodeland Date: Mon, 1 Sep 2025 15:59:44 -0400 Subject: [PATCH 8/8] Add mdbook plugins to CI workflow - Included installation steps for mdbook-toc and mdbook-katex in the CI workflow to enhance documentation capabilities. - This update aims to improve the documentation generation process by integrating additional tools for table of contents and LaTeX support. --- .github/workflows/docs.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml index 0b9aeb8..086f996 100644 --- a/.github/workflows/docs.yml +++ b/.github/workflows/docs.yml @@ -47,6 +47,8 @@ jobs: cargo install mdbook-linkcheck --vers "^0.7" --locked cargo install mdbook-admonish --vers "^1.18" --locked cargo install mdbook-mermaid --vers "^0.14" --locked + cargo install mdbook-toc --vers "^0.14" --locked + cargo install mdbook-katex --vers "^0.9" --locked - name: Test Rust code blocks run: |