Totsu (凸 in Japanese) means convex.
This crate for Rust provides a first-order conic linear program solver.
A common target problem is continuous scalar convex optimization such as LP, QP, QCQP, SOCP and SDP. Each of those problems can be represented as a conic linear program.
The author combines the two papers [1] [2] so that the homogeneous self-dual embedding matrix in [2] is formed as a linear operator in [1].
A core method solver::Solver::solve
takes the following arguments:
* objective and constraint linear operators that implement operator::Operator
trait and
* a projection onto a cone that implements cone::Cone
trait.
Therefore solving a specific problem requires an implementation of those traits.
You can use pre-defined implementations (see problem
),
as well as construct a user-defined tailored version for the reason of functionality and efficiency.
Modules operator
and cone
include several basic structs
that implement operator::Operator
and cone::Cone
trait.
Core linear algebra operations that solver::Solver
requires
are abstracted by linalg::LinAlg
trait,
while subtrait linalg::LinAlgEx
is used for operator
,
cone
and problem
modules.
This crate includes two linalg::LinAlgEx
implementors:
* linalg::FloatGeneric
-
num::Float
-generic implementation (pure Rust but slow)
* linalg::F64LAPACK
-
f64
-specific implementation using cblas-sys
and lapacke-sys
(you need a BLAS/LAPACK source to link).
```rust use floateq::assertfloat_eq; use totsu::prelude::*; use totsu::operator::MatBuild; use totsu::problem::ProbQP;
type LA = FloatGeneric
let n = 2; // x0, x1 let m = 1; let p = 0;
// (1/2)(x - a)^2 + const let mut symp = AMatBuild::new(MatType::SymPack(n)); symp[(0, 0)] = 1.; sym_p[(1, 1)] = 1.;
let mut vecq = AMatBuild::new(MatType::General(n, 1)); vecq[(0, 0)] = -(-1.); // -a0 vec_q[(1, 0)] = -(-2.); // -a1
// 1 - x0/b0 - x1/b1 <= 0 let mut matg = AMatBuild::new(MatType::General(m, n)); matg[(0, 0)] = -1. / 2.; // -1/b0 mat_g[(0, 1)] = -1. / 3.; // -1/b1
let mut vech = AMatBuild::new(MatType::General(m, 1)); vech[(0, 0)] = -1.;
let mat_a = AMatBuild::new(MatType::General(p, n));
let vec_b = AMatBuild::new(MatType::General(p, 1));
let s = ASolver::new().par(|p| { p.maxiter = Some(100000); }); let mut qp = AProbQP::new(symp, vecq, matg, vech, mata, vecb, s.par.eps_zero); let rslt = s.solve(qp.problem(), NullLogger).unwrap();
assertfloateq!(rslt.0[0..2], [2., 0.].asref(), absall <= 1e-3); ```
You can find other tests of pre-defined solvers. More practical examples are also available.