Major Features: • Comprehensive Differential Evolution with 5 strategies (rand1, best1, currenttobest1, rand2, best2) • Adaptive jDE algorithm for self-tuning F and CR parameters • Convergence tracking with history records and early stopping • Mathematical toolkit module (780 lines): gradient, hessian, jacobian, statistics, linear algebra • Optimal control framework: HJB solvers, regime switching, jump diffusion, MRSJD • Sparse optimization: Sparse PCA, Box-Tao decomposition, ADMM, Elastic Net • Rayon parallelization infrastructure (ready for pure Rust objectives) Performance: • 74-88× speedup for DE vs SciPy • 50-100× speedup overall vs pure Python Refactoring & Cleanup: • Removed 5 legacy files (de_refactored.rs, hmm_legacy.rs, hmm_refactored.rs, mcmc_legacy.rs, mcmc_refactored.rs) • Modular architecture with trait-based design • Generic implementations (no domain-specific code) • Updated Python bindings for new DE API • Fixed ALL compilation warnings (0 errors, 0 warnings) Documentation: • Updated README with v0.2.0 features and benchmarks • Created RELEASE_NOTES_v0.2.0.md (comprehensive changelog) • New optimal control tutorial notebook (03_optimal_control_tutorial.ipynb) • Updated API examples in README • Created test_release.py for release validation Version Bumps: • Cargo.toml: 0.1.0 → 0.2.0 • pyproject.toml: 0.1.0 → 0.2.0 • python/__init__.py: 0.1.0 → 0.2.0 Breaking Changes: • DE API: mutation_factor/crossover_rate → f/cr • DE API: use_adaptive_jde → adaptive • DE API: strategy names simplified (e.g., 'rand/1/bin' → 'rand1') • DE returns: (x, fun) tuple instead of dict-like object Known Items (Post-Release): • Mathematical toolkit functions available in Rust but not yet exposed to Python • MCMC Python wrapper needs API update to match new Rust implementation • Tutorial notebooks need DE API updates Tests: 34 Rust tests passing, core Python functionality validated with test_release.py
58 lines
1.4 KiB
Rust
58 lines
1.4 KiB
Rust
//! Log-likelihood interface for MCMC
|
|
//!
|
|
//! Defines the LogLikelihood trait for target distributions.
|
|
|
|
/// Generic log-likelihood function trait
|
|
pub trait LogLikelihood: Send + Sync {
|
|
fn evaluate(&self, state: &[f64]) -> f64;
|
|
}
|
|
|
|
#[cfg(feature = "python-bindings")]
|
|
use pyo3::prelude::*;
|
|
|
|
/// Wrapper for Python callable log-likelihood
|
|
#[cfg(feature = "python-bindings")]
|
|
pub struct PyLogLikelihood {
|
|
func: Py<PyAny>,
|
|
}
|
|
|
|
#[cfg(feature = "python-bindings")]
|
|
impl PyLogLikelihood {
|
|
pub fn new(func: Py<PyAny>) -> Self {
|
|
Self { func }
|
|
}
|
|
}
|
|
|
|
#[cfg(feature = "python-bindings")]
|
|
impl LogLikelihood for PyLogLikelihood {
|
|
fn evaluate(&self, state: &[f64]) -> f64 {
|
|
Python::with_gil(|py| {
|
|
let args = (state.to_vec(),);
|
|
self.func
|
|
.call1(py, args)
|
|
.and_then(|res| res.extract::<f64>(py))
|
|
.unwrap_or(f64::NEG_INFINITY)
|
|
})
|
|
}
|
|
}
|
|
|
|
#[cfg(test)]
|
|
mod tests {
|
|
use super::*;
|
|
|
|
struct TestLogLikelihood;
|
|
|
|
impl LogLikelihood for TestLogLikelihood {
|
|
fn evaluate(&self, state: &[f64]) -> f64 {
|
|
// Standard normal log-likelihood
|
|
-0.5 * state.iter().map(|x| x.powi(2)).sum::<f64>()
|
|
}
|
|
}
|
|
|
|
#[test]
|
|
fn test_log_likelihood() {
|
|
let ll = TestLogLikelihood;
|
|
assert!(ll.evaluate(&[0.0]) > ll.evaluate(&[1.0]));
|
|
}
|
|
}
|