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]));