Class LinearConstraint

java.lang.Object
de.labathome.trustconstr.LinearConstraint
All Implemented Interfaces:
Constraint, Jacobian

public class LinearConstraint extends Object implements Constraint, Jacobian
Linear constraint of the form
     lb <= A x <= ub
 
Counterpart to scipy.optimize.LinearConstraint (scipy/optimize/_constraints.py:139). Stores the constraint matrix A, the bounds, and the per-row keepFeasible flag.

The Java port distinguishes equality and inequality at the constraint level -- this class implements both Constraint (constraint values) and Jacobian (analytic Jacobian, which for a linear constraint is just A).

Each row i of A is classified as one of four categories:

  • equal: lb[i] == ub[i] (finite). Contributes one row to constrEq / jacEq: A[i,:] x - lb[i].
  • less: lb[i] == -inf, ub[i] < inf (upper-only). Contributes one ineq row A[i,:] x - ub[i] (sign +1).
  • greater: ub[i] == +inf, lb[i] > -inf (lower-only). Contributes one ineq row lb[i] - A[i,:] x (sign -1, target lb).
  • interval: both finite, lb[i] < ub[i]. Contributes two ineq rows: an upper-side row and a lower-side row.

The constrIneq / jacIneq output is grouped scipy-style (mirrors canonical_constraint.py:_interval_to_canonical): all less rows first, then all greater rows, then all interval-upper rows, then all interval-lower rows. Within each block the original row order is preserved.

  • Constructor Details

    • LinearConstraint

      public LinearConstraint(Matrix a, double[] lb, double[] ub, boolean[] keepFeasible)
      Build a linear constraint lb &le; A x &le; ub.

      Rows where lb[i] == ub[i] (and both are finite) become equality rows; other rows become canonical inequality rows in scipy's 4-block order: less | greater | interval-upper | interval-lower.

      Parameters:
      a - constraint matrix (m x n)
      lb - lower bounds, length m (use -inf to disable per row)
      ub - upper bounds, length m (use +inf to disable per row)
      keepFeasible - per-row strict-feasibility flag, length m; null = all-false
    • LinearConstraint

      public LinearConstraint(Matrix a, double[] lb, double[] ub)
      Convenience overload: equivalent to LinearConstraint(Matrix, double[], double[], boolean[]) with keepFeasible = null.
      Parameters:
      a - constraint matrix (m x n)
      lb - lower bounds, length m
      ub - upper bounds, length m
  • Method Details

    • fromBounds

      public static LinearConstraint fromBounds(Bounds bounds)
      Build a LinearConstraint from variable Bounds, i.e. the trivial linear constraint lb <= x <= ub with A = I. Mirrors scipy's promotion of Bounds to a canonical constraint via PreparedConstraint(bounds, ...).
      Parameters:
      bounds - variable bounds -- lb and ub are n x 1 column matrices
      Returns:
      identity-Jacobian constraint that enforces bounds
    • getA

      public Matrix getA()
      Returns:
      the constraint matrix A
    • lb

      public double[] lb()
      Returns:
      a defensive copy of the lower bounds array
    • ub

      public double[] ub()
      Returns:
      a defensive copy of the upper bounds array
    • keepFeasible

      public boolean[] keepFeasible()
      Returns:
      a defensive copy of the per-row keep-feasible flags
    • bounds

      public Bounds bounds()
      Returns:
      the bounds repackaged as a Bounds record
    • nEq

      public int nEq()
      Returns:
      number of canonical equality rows
    • nIneq

      public int nIneq()
      Returns:
      number of canonical inequality rows
    • enforceFeasibilityIneq

      public boolean[] enforceFeasibilityIneq()
      Per-canonical-inequality-row enforceFeasibility flags derived from the user-supplied keep_feasible. Each canonical ineq row inherits the kf flag of the original row it came from. Length matches nIneq() and is suitable to pass directly to TrustRegionInteriorPoint's enforceFeasibility parameter.
      Returns:
      per-canonical-row strict-feasibility flags, length nIneq()
    • validateKeepFeasibleAtStart

      public void validateKeepFeasibleAtStart(Matrix x0)
      Throws IllegalArgumentException if any row marked keepFeasible[i] == true is violated at the supplied starting point. Mirrors scipy's strict-feasibility precondition for keep_feasible=True rows: the algorithm will not enforce intermediate-iterate feasibility for these rows if the start is already infeasible there.
      Parameters:
      x0 - starting iterate (n x 1)
    • residual

      public Residual residual(Matrix x)
      Lower and upper residuals at x: sl = A x - lb (positive iff lower bound satisfied), sb = ub - A x (positive iff upper bound satisfied). Mirrors scipy's LinearConstraint.residual(x).
      Parameters:
      x - current iterate (n x 1)
      Returns:
      (sl, sb) as a Residual
    • constrEq

      public Matrix constrEq(Matrix x)
      Specified by:
      constrEq in interface Constraint
      Parameters:
      x - current iterate (n &times; 1)
      Returns:
      equality-constraint residual (nEq &times; 1)
    • constrIneq

      public Matrix constrIneq(Matrix x)
      Specified by:
      constrIneq in interface Constraint
      Parameters:
      x - current iterate (n &times; 1)
      Returns:
      inequality-constraint residual (nIneq &times; 1); feasible iff every entry is &le; 0
    • jacEq

      public Matrix jacEq(Matrix x)
      Specified by:
      jacEq in interface Jacobian
      Parameters:
      x - current iterate (n &times; 1)
      Returns:
      Jacobian of constr_eq at x (nEq &times; n)
    • jacIneq

      public Matrix jacIneq(Matrix x)
      Specified by:
      jacIneq in interface Jacobian
      Parameters:
      x - current iterate (n &times; 1)
      Returns:
      Jacobian of constr_ineq at x (nIneq &times; n)
    • jacEqCSR

      public CSRMatrix jacEqCSR()
      Sparse Jacobian for equality rows: a CSRMatrix built directly from the row-selected non-zeros of A, without going through a dense intermediate.
      Returns:
      CSR representation of the equality-row Jacobian
    • jacIneqCSR

      public CSRMatrix jacIneqCSR()
      Sparse Jacobian for inequality rows: a CSRMatrix (with the appropriate per-row sign flips for one-sided lower-bound rows).
      Returns:
      CSR representation of the inequality-row Jacobian