imsl.linalg.lin_lsq_lin_constraints¶
-
lin_lsq_lin_constraints
(a, b, c, bl, bu, con_type, xlb=None, xub=None, abs_tol=None, rel_tol=None, max_iter=None)¶ Solve a linear least-squares problem with linear constraints.
Parameters: - a ((M, N) array_like) – Array containing the coefficients of the M least-squares equations.
- b ((M,) array_like) – Array containing the right-hand sides of the least-squares equations.
- c ((K, N) array_like) – Array containing the coefficients of the K general constraints. If
the problem contains no general constraints, set
c = None
. - bl ((K,) array_like) – Array containing the lower limits of the general constraints. If
there is no lower limit on the i-th constraint, then
bl[i]
will not be referenced. - bu ((K,) array_like) – Array containing the upper limits of the general constraints. If
there is no upper limit on the i-th constraint, then
bl[i]
will not be referenced. - con_type ((K,) array_like) – Array indicating the type of the general constraints, where
con_type[i] = 0, 1, 2, 3
indicates =, <=, >= and range constraints, respectively. - xlb ((N,) array_like, optional) –
Array containing the lower bounds on the variables. If there is no lower bound on the i-th variable, then
xlb[i]
should be set to constantUNBOUNDED_ABOVE
in moduleimsl.constants
.Default: The variables have no lower bounds.
- xub ((N,) array_like, optional) –
Array containing the upper bounds on the variables. If there is no upper bound on the i-th variable, then
xlb[i]
should be set to constantUNBOUNDED_BELOW
in moduleimsl.constants
.Default: The variables have no upper bounds.
- abs_tol (float, optional) –
Absolute rank determination tolerance to be used.
Default: abs_tol = math.sqrt(numpy.finfo(numpy.float64).eps).
- rel_tol (float, optional) –
Relative rank determination tolerance to be used.
Default: rel_tol = math.sqrt(numpy.finfo(numpy.float64).eps).
- max_iter (int, optional) –
The maximum number of add/drop iterations.
Default: max_iter = 5 * max(M,N).
Returns: - A named tuple with the following fields
- solution ((N,) ndarray) – The approximate solution of the least-squares problem.
- residual ((M,) ndarray) – The residuals b-Ax of the least-squares equations at the approximate solution.
Notes
Function lin_lsq_lin_constraints solves linear least-squares problems with linear constraints. These are systems of least-squares equations of the form
\[Ax \cong b\]subject to
\[\begin{split}b_l \le Cx \le b_u \\ x_l \le x \le x_u\end{split}\]Here A is the coefficient matrix of the least-squares equations, b is the right-hand side, and C is the coefficient matrix of the constraints. The vectors \(b_l, b_u, x_l\) and \(x_u\) are the lower and upper bounds on the constraints and the variables, respectively. The system is solved by defining dependent variables \(y \equiv Cx\) and then solving the least-squares system with the lower and upper bounds on x and y. The equation \(Cx-y=0\) is a set of equality constraints. These constraints are realized by heavy weighting, i.e., a penalty method ([1]).
References
[1] Hanson, Richard J. (1986), Linear Least Squares with Bounds and Linear Constraints, SIAM J. Sci. and Stat. Computing, 7(3), 826-834. Examples
The following problem is solved in the least-squares sense:
\[\begin{split}3x_1+2x_2+x_3=3.3 \\ 4x_1+2x_2+x_3=2.3 \\ 2x_1+2x_2+x_3=1.3 \\ x_1+x_2+x_3=1.0\end{split}\]subject to
\[\begin{split}x_1=x_2+x_3 \le 1 \\ 0 \le x_1 \le 0.5 \\ 0 \le x_2 \le 0.5 \\ 0 \le x_3 \le 0.5\end{split}\]The approximate solution of the least-squares problem, the residuals of the least-squares equations at the solution and the norm of the residual vector are printed.
>>> import imsl.linalg as la >>> import numpy as np >>> a = [[3.0, 2.0, 1.0], [4.0, 2.0, 1.0], [2.0, 2.0, 1.0], ... [1.0, 1.0, 1.0]] >>> b = [3.3, 2.3, 1.3, 1.0] >>> c = [[1.0, 1.0, 1.0]] >>> xlb = [0.0, 0.0, 0.0] >>> xub = [0.5, 0.5, 0.5] >>> con_type = [1] >>> bc = [1.0] >>> x = la.lin_lsq_lin_constraints(a, b, c, bc, bc, con_type, xlb=xlb, ... xub=xub) >>> print(x.solution) [0.5 0.3 0.2] >>> print(x.residual) [-1. 0.5 0.5 0. ] >>> print("{0:8.6f}".format(np.linalg.norm(x.residual))) 1.224745