ripped/lib.rs
1//! A pure-Rust Interior Point solver for linear programs with equality and inequality constraints.
2//!
3//! # Linear programs
4//!
5//! A linear program is a mathematical optimization problem defined as:
6//!
7//! ```text
8//! min_x c'x
9//! st A_eq'x == b_eq
10//! A_ub'x <= b_ub
11//! x >= 0
12//! ```
13//!
14//!
15//!
16//! # Example
17//! ```
18//! use approx::assert_abs_diff_eq;
19//! use ndarray::array;
20//!
21//! use ripped::prelude::*;
22//!
23//! let A_ub = array![[-3f64, 1.], [1., 2.]];
24//! let b_ub = array![6., 4.];
25//! let A_eq = array![[1., 1.]];
26//! let b_eq = array![1.];
27//! let c = array![-1., 4.];
28//!
29//! let problem = Problem::target(&c)
30//! // If you define neither equality nor inequality constraints,
31//! // the problem returns as unconstrained.
32//! .ub(&A_ub, &b_ub)
33//! .eq(&A_eq, &b_eq)
34//! .build()
35//! .unwrap();
36//!
37//! // These are the default values you can overwrite.
38//! // You may omit any option for which the default is good enough for you
39//! let solver = InteriorPoint::custom()
40//! .solver_type(EquationSolverType::Cholesky)
41//! .tol(1e-8)
42//! .disp(false)
43//! .ip(true)
44//! .alpha0(0.99995)
45//! .max_iter(1000)
46//! .build()
47//! .unwrap();
48//!
49//! let res = solver.solve(&problem).unwrap();
50//!
51//! assert_abs_diff_eq!(res.x(), &array![1., 0.], epsilon = 1e-6);
52//! ```
53//!
54//! # Feature flags
55//! ### `[linfa-linalg]` backend for pure-rust linear algebra:
56//! This feature is enabled by default. Disable this if you opt for one of the LAPACK options below.
57//! For details on this backend, see the documentation of [`linfa-linalg`](https://docs.rs/linfa-linalg/).
58//!
59//! ### LAPACK backend for linear algebra (and BLAS for matrix operations):
60//! * `[netlib-system]`
61//! * `[netlib-system]`
62//! * `[openblas-static]`
63//! * `[openblas-system]`
64//! * `[intel-mkl-static]`
65//! * `[intel-mkl-system]`
66//!
67//! If you don't mind compiling and/or linking one of the reference LAPACK implementations, then one of these options
68//! is for you. These features are forwarded to [`ndarray-linalg`](https://github.com/rust-ndarray/ndarray-linalg),
69//! see their documentation for details on how to compile/link each backend.
70
71pub mod error;
72pub(crate) mod float;
73pub mod linear_program;
74pub mod prelude;
75pub mod solvers;
76
77#[allow(non_snake_case)]
78#[cfg(test)]
79mod tests {
80 use crate::prelude::*;
81 use approx::assert_abs_diff_eq;
82 use ndarray::array;
83
84 fn make_problem() -> Problem<f64> {
85 let A_ub = array![[-3f64, 1.], [1., 2.]];
86 let b_ub = array![6., 4.];
87 let A_eq = array![[1., 1.]];
88 let b_eq = array![1.];
89 let c = array![-1., 4.];
90 let problem = Problem::target(&c)
91 .ub(&A_ub, &b_ub)
92 .eq(&A_eq, &b_eq)
93 .build()
94 .unwrap();
95 problem
96 }
97 #[test]
98 fn test_problem_interface() {
99 let problem = make_problem();
100 problem.A();
101 problem.b();
102 problem.c();
103 problem.c0();
104 }
105
106 #[test]
107 fn test_interior_point_interface() {
108 let problem = make_problem();
109 let solver = InteriorPoint::custom().build().unwrap();
110 let res = solver.solve(&problem).unwrap();
111
112 assert_abs_diff_eq!(*res.x(), array![1., 0.], epsilon = 1e-6);
113 }
114}