feat(python): implement python bindings for all components and solvers

This commit is contained in:
Sepehr
2026-02-21 20:34:56 +01:00
parent 8ef8cd2eba
commit 4440132b0a
310 changed files with 11577 additions and 397 deletions

View File

@@ -7,8 +7,8 @@
//! - AC #4: Error handling for empty/invalid systems
//! - AC #5: Pre-allocated buffers (no panic)
use entropyk_solver::{NewtonConfig, Solver, SolverError, System};
use approx::assert_relative_eq;
use entropyk_solver::{NewtonConfig, Solver, SolverError, System};
use std::time::Duration;
// ─────────────────────────────────────────────────────────────────────────────
@@ -18,7 +18,7 @@ use std::time::Duration;
#[test]
fn test_newton_config_default() {
let cfg = NewtonConfig::default();
assert_eq!(cfg.max_iterations, 100);
assert_relative_eq!(cfg.tolerance, 1e-6);
assert!(!cfg.line_search);
@@ -33,7 +33,7 @@ fn test_newton_config_default() {
fn test_newton_config_with_timeout() {
let timeout = Duration::from_millis(500);
let cfg = NewtonConfig::default().with_timeout(timeout);
assert_eq!(cfg.timeout, Some(timeout));
}
@@ -50,7 +50,7 @@ fn test_newton_config_custom_values() {
divergence_threshold: 1e8,
..Default::default()
};
assert_eq!(cfg.max_iterations, 50);
assert_relative_eq!(cfg.tolerance, 1e-8);
assert!(cfg.line_search);
@@ -72,7 +72,7 @@ fn test_empty_system_returns_invalid() {
let mut solver = NewtonConfig::default();
let result = solver.solve(&mut sys);
assert!(result.is_err());
match result {
Err(SolverError::InvalidSystem { message }) => {
@@ -110,7 +110,7 @@ fn test_timeout_value_in_error() {
};
let result = solver.solve(&mut sys);
// Empty system returns InvalidSystem immediately (before timeout check)
assert!(result.is_err());
}
@@ -166,7 +166,7 @@ fn test_error_equality() {
final_residual: 1e-3,
};
assert_eq!(e1, e2);
let e3 = SolverError::Timeout { timeout_ms: 100 };
assert_ne!(e1, e3);
}
@@ -181,7 +181,7 @@ fn test_solver_does_not_panic_on_empty_system() {
sys.finalize().unwrap();
let mut solver = NewtonConfig::default();
// Should complete without panic
let result = solver.solve(&mut sys);
assert!(result.is_err());
@@ -196,7 +196,7 @@ fn test_solver_does_not_panic_with_line_search() {
line_search: true,
..Default::default()
};
// Should complete without panic
let result = solver.solve(&mut sys);
assert!(result.is_err());
@@ -211,7 +211,7 @@ fn test_solver_does_not_panic_with_numerical_jacobian() {
use_numerical_jacobian: true,
..Default::default()
};
// Should complete without panic
let result = solver.solve(&mut sys);
assert!(result.is_err());
@@ -223,16 +223,11 @@ fn test_solver_does_not_panic_with_numerical_jacobian() {
#[test]
fn test_converged_state_is_converged() {
use entropyk_solver::ConvergenceStatus;
use entropyk_solver::ConvergedState;
let state = ConvergedState::new(
vec![1.0, 2.0, 3.0],
10,
1e-8,
ConvergenceStatus::Converged,
);
use entropyk_solver::ConvergenceStatus;
let state = ConvergedState::new(vec![1.0, 2.0, 3.0], 10, 1e-8, ConvergenceStatus::Converged);
assert!(state.is_converged());
assert_eq!(state.iterations, 10);
assert_eq!(state.state, vec![1.0, 2.0, 3.0]);
@@ -240,15 +235,15 @@ fn test_converged_state_is_converged() {
#[test]
fn test_converged_state_timed_out() {
use entropyk_solver::ConvergenceStatus;
use entropyk_solver::ConvergedState;
use entropyk_solver::ConvergenceStatus;
let state = ConvergedState::new(
vec![1.0],
50,
1e-3,
ConvergenceStatus::TimedOutWithBestState,
);
assert!(!state.is_converged());
}
}