Skip to main content

so_linalg/
lib.rs

1//! Linear algebra middleware providing unified interface to multiple backends
2//!
3//! This crate provides a common interface for linear algebra operations,
4//! with support for multiple backends (faer, ndarray-linalg, etc.).
5#![allow(missing_docs)]
6//!
7//! # Usage
8//!
9//! ```rust
10//! use so_linalg::{solve, inv, matmul};
11//! use ndarray::{arr1, arr2};
12//!
13//! // Solve linear system
14//! let A = arr2(&[[1.0, 2.0], [3.0, 4.0]]);
15//! let b = arr1(&[5.0, 6.0]);
16//! let x = solve(&A, &b).unwrap();
17//!
18//! // Matrix inverse
19//! let inv_A = inv(&A).unwrap();
20//!
21//! // Matrix multiplication
22//! let B = arr2(&[[2.0, 0.0], [1.0, 2.0]]);
23//! let C = matmul(&A, &B).unwrap();
24//! ```
25//!
26//! # Backends
27//!
28//! The crate supports multiple backends selectable via Cargo features:
29//! - `faer` (default): Uses the faer library for high-performance linear algebra
30//! - `ndarray-linalg`: Uses ndarray-linalg with OpenBLAS/LAPACK
31//! - `pure-rust`: Pure Rust implementation (slower but no external dependencies)
32
33#![allow(non_snake_case)] // Allow mathematical notation (A, B, D, etc.)
34//!
35//! # Advanced Usage
36//!
37//! For more control, you can use backends directly:
38//! ```rust
39//! use so_linalg::backend::{LinalgBackend, FaerBackend};
40//! use ndarray::{arr1, arr2};
41//!
42//! // Create example matrices
43//! let A = arr2(&[[1.0, 2.0], [3.0, 4.0]]);
44//! let b = arr1(&[5.0, 6.0]);
45//!
46//! let backend = FaerBackend::default();
47//! let result = backend.solve(&A, &b);
48//! ```
49
50#![warn(missing_docs)]
51#![allow(non_snake_case)] // Allow mathematical notation (A, B, etc.)
52
53pub mod backend;
54pub mod error;
55
56// Re-exports for convenience
57pub use backend::{FaerBackend, LinalgBackend};
58pub use error::{LinalgError, Result};
59
60// ============================================================================
61// Global Backend Selection
62// ============================================================================
63
64/// Get the default linear algebra backend
65///
66/// The backend is selected based on enabled Cargo features:
67/// - `faer` (default): FaerBackend
68/// - `ndarray-linalg`: NdarrayLinalgBackend
69/// - `pure-rust`: PureRustBackend
70pub fn default_backend() -> impl LinalgBackend {
71    // Feature-based backend selection
72    #[cfg(feature = "faer")]
73    {
74        backend::FaerBackend::default()
75    }
76
77    #[cfg(all(not(feature = "faer"), feature = "ndarray-linalg"))]
78    {
79        backend::NdarrayLinalgBackend::default()
80    }
81
82    #[cfg(all(
83        not(feature = "faer"),
84        not(feature = "ndarray-linalg"),
85        feature = "pure-rust"
86    ))]
87    {
88        backend::PureRustBackend::default()
89    }
90
91    #[cfg(not(any(feature = "faer", feature = "ndarray-linalg", feature = "pure-rust")))]
92    {
93        // Default to faer if no features specified
94        backend::FaerBackend::default()
95    }
96}
97
98// ============================================================================
99// Convenience Functions (using default backend)
100// ============================================================================
101
102/// Solve linear system A * x = b using the default backend
103pub fn solve(A: &ndarray::Array2<f64>, b: &ndarray::Array1<f64>) -> Result<ndarray::Array1<f64>> {
104    default_backend().solve(A, b)
105}
106
107/// Compute matrix inverse using the default backend
108pub fn inv(A: &ndarray::Array2<f64>) -> Result<ndarray::Array2<f64>> {
109    default_backend().inv(A)
110}
111
112/// Compute matrix multiplication: C = A * B using the default backend
113pub fn matmul(A: &ndarray::Array2<f64>, B: &ndarray::Array2<f64>) -> Result<ndarray::Array2<f64>> {
114    default_backend().matmul(A, B)
115}
116
117// ============================================================================
118// Optional Backend Implementations (feature-gated)
119// ============================================================================
120
121// TODO: Implement these backends
122// #[cfg(feature = "ndarray-linalg")]
123// mod ndarray_linalg_backend;
124//
125// #[cfg(feature = "pure-rust")]
126// mod pure_rust_backend;