Report a bug
Quickly fork, edit online, and submit a pull request for this page. Requires a signed-in GitHub account. This works well for small changes. If you'd like to make larger changes you may want to consider using a local clone.

# Bound Constrained Convex Quadratic Problem Solver

Authors:
Ilya Yaroshenko
enum `BoxQPStatus`: int;
BOXCQP Exit Status
`solved`
`numericError`
`maxIterations`
pure nothrow @nogc @safe size_t `mir_box_qp_work_length`(size_t `n`);
pure nothrow @nogc @safe size_t `mir_box_qp_iwork_length`(size_t `n`);
struct `BoxQPSettings`(T) if (is(T == float) || is(T == double));
BOXCQP Algorithm Settings
T `relTolerance`;
Relative active constraints tolerance.
T `absTolerance`;
Absolute active constraints tolerance.
uint `maxIterations`;
Maximal iterations allowed. 0 is used for default value equals to 10 * N + 100.
pure nothrow @nogc @safe BoxQPStatus `solveBoxQP`(T)(Slice!(T*, 2, Canonical) `P`, Slice!(const(T)*) `q`, Slice!(const(T)*) `l`, Slice!(const(T)*) `u`, Slice!(T*) `x`, BoxQPSettings!T `settings` = BoxQPSettings!T.init)
if (is(T == float) || is(T == double));

Solves argmin_x(xPx + qx) : `l` <= `x` <= `u`

Parameters:
 Slice!(T*, 2, Canonical) `P` Positive-definite Matrix, NxN Slice!(const(T)*) `q` Linear component, N Slice!(const(T)*) `l` Lower bounds in [-inf, +inf), N Slice!(const(T)*) `u` Upper bounds in (-inf, +inf], N Slice!(T*) `x` solutoin, N BoxQPSettings!T `settings` Iteration settings (optional)
pure nothrow @nogc @safe BoxQPStatus `solveBoxQP`(T)(ref const BoxQPSettings!T `settings`, Slice!(T*, 2, Canonical) `P`, Slice!(const(T)*) `q`, Slice!(const(T)*) `l`, Slice!(const(T)*) `u`, Slice!(T*) `x`, bool `unconstrainedSolution`, Slice!(T*) `work`, Slice!(lapackint*) `iwork`, bool `restoreUpperP` = true)
if (is(T == float) || is(T == double));

Solves argmin_x(xPx + qx) : `l` <= `x` <= `u`

Parameters:
 BoxQPSettings!T `settings` Iteration settings Slice!(T*, 2, Canonical) `P` Positive-definite Matrix (in lower triangular part is store), NxN. The upper triangular part (and diagonal) of the matrix is used for temporary data and then can be resotored. Matrix diagonal is always restored. Slice!(const(T)*) `q` Linear component, N Slice!(const(T)*) `l` Lower bounds in [-inf, +inf), N Slice!(const(T)*) `u` Upper bounds in (-inf, +inf], N Slice!(T*) `x` solutoin, N bool `unconstrainedSolution` Slice!(T*) `work` workspace, mir_box_qp_work_length(N) Slice!(lapackint*) `iwork` integer workspace, mir_box_qp_iwork_length(N) bool `restoreUpperP` (optional) restore upper triangular part of P
Examples:
```import mir.ndslice;
import mir.algorithm.iteration;
import mir.math.common;

auto P = [
[ 2.0, -1, 0],
[-1.0, 2, -1],
[ 0.0, -1, 2],
].fuse.canonical;

auto q = [3.0, -7, 5].sliced;
auto l = [-100.0, -2, 1].sliced;
auto u = [100.0, 2, 1].sliced;
auto x = slice!double(q.length);

solveBoxQP(P, q, l, u, x);
assert(x.equal!approxEqual([-0.5, 2, 1]));
```