Refactor: Modularize code structure for better maintainability

- Split HMM module into separate files (emission.rs, config.rs, model.rs, viterbi.rs, python_bindings.rs)
- Split MCMC module into separate files (proposal.rs, config.rs, likelihood.rs, sampler.rs, python_bindings.rs)
- Create organized src/hmm/ and src/mcmc/ directory structure
- Rename legacy files to hmm_legacy.rs and mcmc_legacy.rs for backward compatibility
- Update lib.rs to use new modular structure
- Reduce file sizes: largest file now 171 lines (previously 583 lines)
- Improve code reusability and maintainability
- All Python bindings remain backward compatible
This commit is contained in:
Melvin Avarez
2025-12-04 23:08:06 +01:00
parent a62ceaa64b
commit b87fe2eeec
16 changed files with 1319 additions and 26 deletions
+53
View File
@@ -0,0 +1,53 @@
//! Log-likelihood interface for MCMC
//!
//! Defines the LogLikelihood trait for target distributions.
use pyo3::prelude::*;
/// Generic log-likelihood function trait
pub trait LogLikelihood: Send + Sync {
fn evaluate(&self, state: &[f64]) -> f64;
}
/// Wrapper for Python callable log-likelihood
pub struct PyLogLikelihood {
func: Py<PyAny>,
}
impl PyLogLikelihood {
pub fn new(func: Py<PyAny>) -> Self {
Self { func }
}
}
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]));
}
}