lsqlin
求解约束线性最小二乘问题
语法
说明
求 x
= lsqlin(problem
)problem
的最小值,它是 problem
中所述的一个结构体。使用圆点表示法或 struct
函数创建 problem
结构体。您也可以使用 prob2struct
从 OptimizationProblem
对象创建一个 problem
结构体。
示例
具有线性不等式约束的最小二乘
对于具有线性不等式约束的超定问题,求使 C*x - d
的范数最小的 x
。
指定问题和约束。
C = [0.9501 0.7620 0.6153 0.4057 0.2311 0.4564 0.7919 0.9354 0.6068 0.0185 0.9218 0.9169 0.4859 0.8214 0.7382 0.4102 0.8912 0.4447 0.1762 0.8936]; d = [0.0578 0.3528 0.8131 0.0098 0.1388]; A = [0.2027 0.2721 0.7467 0.4659 0.1987 0.1988 0.4450 0.4186 0.6037 0.0152 0.9318 0.8462]; b = [0.5251 0.2026 0.6721];
调用 lsqlin
以求解问题。
x = lsqlin(C,d,A,b)
Minimum found that satisfies the constraints. Optimization completed because the objective function is non-decreasing in feasible directions, to within the value of the optimality tolerance, and constraints are satisfied to within the value of the constraint tolerance.
x = 4×1
0.1299
-0.5757
0.4251
0.2438
具有线性约束和边界的最小二乘
对于具有线性等式和不等式约束和边界的超定问题,求使 C*x - d
的范数最小的 x
。
指定问题和约束。
C = [0.9501 0.7620 0.6153 0.4057 0.2311 0.4564 0.7919 0.9354 0.6068 0.0185 0.9218 0.9169 0.4859 0.8214 0.7382 0.4102 0.8912 0.4447 0.1762 0.8936]; d = [0.0578 0.3528 0.8131 0.0098 0.1388]; A =[0.2027 0.2721 0.7467 0.4659 0.1987 0.1988 0.4450 0.4186 0.6037 0.0152 0.9318 0.8462]; b =[0.5251 0.2026 0.6721]; Aeq = [3 5 7 9]; beq = 4; lb = -0.1*ones(4,1); ub = 2*ones(4,1);
调用 lsqlin
以求解问题。
x = lsqlin(C,d,A,b,Aeq,beq,lb,ub)
Minimum found that satisfies the constraints. Optimization completed because the objective function is non-decreasing in feasible directions, to within the value of the optimality tolerance, and constraints are satisfied to within the value of the constraint tolerance.
x = 4×1
-0.1000
-0.1000
0.1599
0.4090
使用非默认选项的线性最小二乘
此示例说明如何使用非默认选项执行线性最小二乘运算。
设置选项以使用 'interior-point'
算法并提供迭代输出。
options = optimoptions('lsqlin','Algorithm','interior-point','Display','iter');
建立线性最小二乘问题。
C = [0.9501 0.7620 0.6153 0.4057 0.2311 0.4564 0.7919 0.9354 0.6068 0.0185 0.9218 0.9169 0.4859 0.8214 0.7382 0.4102 0.8912 0.4447 0.1762 0.8936]; d = [0.0578 0.3528 0.8131 0.0098 0.1388]; A = [0.2027 0.2721 0.7467 0.4659 0.1987 0.1988 0.4450 0.4186 0.6037 0.0152 0.9318 0.8462]; b = [0.5251 0.2026 0.6721];
运行问题。
x = lsqlin(C,d,A,b,[],[],[],[],[],options)
Iter Resnorm Primal Infeas Dual Infeas Complementarity 0 6.545534e-01 1.600492e+00 6.150431e-01 1.000000e+00 1 6.545534e-01 8.002458e-04 3.075216e-04 2.430833e-01 2 1.757343e-01 4.001229e-07 1.537608e-07 5.945636e-02 3 5.619277e-02 2.000615e-10 2.036997e-08 1.370933e-02 4 2.587604e-02 1.000589e-13 1.006816e-08 2.548273e-03 5 1.868939e-02 2.775558e-17 2.955102e-09 4.295807e-04 6 1.764630e-02 0.000000e+00 1.237758e-09 3.102850e-05 7 1.758561e-02 2.775558e-17 1.645863e-10 1.138719e-07 8 1.758538e-02 0.000000e+00 2.400302e-13 5.693290e-11 Minimum found that satisfies the constraints. Optimization completed because the objective function is non-decreasing in feasible directions, to within the value of the optimality tolerance, and constraints are satisfied to within the value of the constraint tolerance.
x = 4×1
0.1299
-0.5757
0.4251
0.2438
返回所有输出
获取并解释所有 lsqlin
输出。
定义具有线性不等式约束和边界的问题。问题是超定的,因为 C
矩阵中有四列,但有五行。这意味着问题有四个未知数和五个条件,而这还不包括线性约束和边界。
C = [0.9501 0.7620 0.6153 0.4057 0.2311 0.4564 0.7919 0.9354 0.6068 0.0185 0.9218 0.9169 0.4859 0.8214 0.7382 0.4102 0.8912 0.4447 0.1762 0.8936]; d = [0.0578 0.3528 0.8131 0.0098 0.1388]; A = [0.2027 0.2721 0.7467 0.4659 0.1987 0.1988 0.4450 0.4186 0.6037 0.0152 0.9318 0.8462]; b = [0.5251 0.2026 0.6721]; lb = -0.1*ones(4,1); ub = 2*ones(4,1);
设置选项以使用 'interior-point'
算法。
options = optimoptions('lsqlin','Algorithm','interior-point');
'interior-point'
算法不使用初始点,因此将 x0
设置为 []
。
x0 = [];
带所有输出调用 lsqlin
。
[x,resnorm,residual,exitflag,output,lambda] = ...
lsqlin(C,d,A,b,[],[],lb,ub,x0,options)
Minimum found that satisfies the constraints. Optimization completed because the objective function is non-decreasing in feasible directions, to within the value of the optimality tolerance, and constraints are satisfied to within the value of the constraint tolerance.
x = 4×1
-0.1000
-0.1000
0.2152
0.3502
resnorm = 0.1672
residual = 5×1
0.0455
0.0764
-0.3562
0.1620
0.0784
exitflag = 1
output = struct with fields:
message: 'Minimum found that satisfies the constraints....'
algorithm: 'interior-point'
firstorderopt: 4.3374e-11
constrviolation: 0
iterations: 6
linearsolver: 'dense'
cgiterations: []
lambda = struct with fields:
ineqlin: [3x1 double]
eqlin: [0x1 double]
lower: [4x1 double]
upper: [4x1 double]
更详细地检查非零拉格朗日乘数字段。首先检查线性不等式约束的拉格朗日乘数。
lambda.ineqlin
ans = 3×1
0.0000
0.2392
0.0000
当解位于对应的约束边界上时,拉格朗日乘数为非零值。换句话说,当对应的约束处于活动状态时,拉格朗日乘数为非零值。lambda.ineqlin(2)
为非零值。这意味着 A*x
中的第二个元素应等于 b
中的第二个元素,因为约束处于活动状态。
[A(2,:)*x,b(2)]
ans = 1×2
0.2026 0.2026
现在检查下界和上界约束的拉格朗日乘数。
lambda.lower
ans = 4×1
0.0409
0.2784
0.0000
0.0000
lambda.upper
ans = 4×1
0
0
0
0
lambda.lower
的前两个元素为非零值。您会看到 x(1)
和 x(2)
位于其下界 -0.1
上。lambda.upper
的所有元素实质上为零,您会看到 x
的所有分量都小于其上界 2
。
返回热启动对象
创建一个热启动对象,以便您可以快速求解修改后的问题。设置选项以关闭迭代输出来支持热启动。
rng default % For reproducibility options = optimoptions('lsqlin','Algorithm','active-set','Display','off'); n = 15; x0 = 5*rand(n,1); ws = optimwarmstart(x0,options);
创建并求解第一个问题。找出求解时间。
r = 1:n-1; % Index for making vectors v(n) = (-1)^(n+1)/n; % Allocating the vector v v(r) =( -1).^(r+1)./r; C = gallery('circul',v); C = [C;C]; r = 1:2*n; d(r) = n-r; lb = -5*ones(1,n); ub = 5*ones(1,n); tic [ws,fval,~,exitflag,output] = lsqlin(C,d,[],[],[],[],lb,ub,ws) toc
Elapsed time is 0.005117 seconds.
添加一个线性约束并再次求解。
A = ones(1,n); b = -10; tic [ws,fval,~,exitflag,output] = lsqlin(C,d,A,b,[],[],lb,ub,ws) toc
Elapsed time is 0.001491 seconds.
输入参数
C
— 乘数矩阵
实矩阵
乘数矩阵,指定为由双精度值组成的矩阵。C
表示 C*x - d
表达式中解 x
的乘数。C
的大小为 M
×N
,其中 M
是方程的数目,N
是 x
的元素数。
示例: C = [1,4;2,5;7,8]
数据类型: double
d
— 常向量
实数向量
常向量,指定为由双精度值组成的向量。d
表示表达式 C*x - d
中的附加常数项。d
的大小为 M
×1
,其中 M
是方程的数目。
示例: d = [5;0;-12]
数据类型: double
A
— 线性不等式约束
实矩阵
线性不等式约束,指定为实矩阵。A
是 M
×N
矩阵,其中 M
是不等式的数目,而 N
是变量的数目(x0
中的元素数)。对于大型问题,将 A
作为稀疏矩阵传递。
A
以如下形式编写 M
个线性不等式
A*x <= b
,
其中,x
是由 N
个变量组成的列向量 x(:)
,b
是具有 M
个元素的列向量。
例如,假设有以下不等式:
x1 +2x2 ≤10
3x1 +4x2 ≤20
5x1 +6x2 ≤30,
通过输入以下约束来指定不等式。
A = [1,2;3,4;5,6]; b = [10;20;30];
示例: 要指定 x 分量总和等于或小于 1,请使用 A = ones(1,N)
和 b = 1
。
数据类型: double
b
— 线性不等式约束
实数向量
线性不等式约束,指定为实数向量。b
是与 A
矩阵相关的包含 M
个元素的向量。如果将 b
作为行向量传递,求解器会在内部将 b
转换为列向量 b(:)
。对于大型问题,将 b
作为稀疏向量传递。
b
以如下形式编写 M
个线性不等式
A*x <= b
,
其中,x
是由 N
个变量组成的列向量 x(:)
,A
是大小为 M
×N
的矩阵。
例如,假设有以下不等式:
x1 + 2x2 ≤ 10
3x1 + 4x2 ≤ 20
5x1 + 6x2 ≤ 30。
通过输入以下约束来指定不等式。
A = [1,2;3,4;5,6]; b = [10;20;30];
示例: 要指定 x 分量总和等于或小于 1,请使用 A = ones(1,N)
和 b = 1
。
数据类型: double
Aeq
— 线性等式约束
实矩阵
线性等式约束,指定为实矩阵。Aeq
是 Me
×N
矩阵,其中 Me
是等式的数目,而 N
是变量的数目(x0
中的元素数)。对于大型问题,将 Aeq
作为稀疏矩阵传递。
Aeq
以如下形式编写 Me
个线性等式
Aeq*x = beq
,
其中,x
是由 N
个变量组成的列向量 x(:)
,beq
是具有 Me
个元素的列向量。
例如,假设有以下不等式:
x1 +2x2 +3x3 =10
2x1 +4x2 + x3 =20,
通过输入以下约束来指定不等式。
Aeq = [1,2,3;2,4,1]; beq = [10;20];
示例: 要指定 x 分量总和为 1,请使用 Aeq = ones(1,N)
和 beq = 1
。
数据类型: double
beq
— 线性等式约束
实数向量
线性等式约束,指定为实数向量。beq
是与 Aeq
矩阵相关的包含 Me
个元素的向量。如果将 beq
作为行向量传递,求解器会在内部将 beq
转换为列向量 beq(:)
。对于大型问题,将 beq
作为稀疏向量传递。
beq
以如下形式编写 Me
个线性等式
Aeq*x = beq
,
其中,x
是由 N
个变量组成的列向量 x(:)
,Aeq
是大小为 Me
×N
的矩阵。
例如,请参考以下等式:
x1 + 2x2 + 3x3 = 10
2x1 + 4x2 + x3 = 20。
通过输入以下约束来指定等式。
Aeq = [1,2,3;2,4,1]; beq = [10;20];
示例: 要指定 x 分量总和为 1,请使用 Aeq = ones(1,N)
和 beq = 1
。
数据类型: double
lb
— 下界
[]
(默认) | 实数向量或数组
下界,指定为双精度值组成的向量或数组。lb
按元素表示下界,形如 lb
≤ x
≤ ub
。
lsqlin
在内部将数组 lb
转换为向量 lb(:)
。
示例: lb = [0;-Inf;4]
表示 x(1) ≥ 0
,x(3) ≥ 4
。
数据类型: double
ub
— 上界
[]
(默认) | 实数向量或数组
上界,指定为双精度值组成的向量或数组。ub
按元素表示上界,形如 lb
≤ x
≤ ub
。
lsqlin
在内部将数组 ub
转换为向量 ub(:)
。
示例: ub = [Inf;4;10]
表示 x(2) ≤ 4
,x(3) ≤ 10
。
数据类型: double
x0
— 初始点
zeros(M,1)
,其中 M
是方程的个数 (默认) | 实数向量或数组
求解过程的初始点,指定为实数向量或数组。
'interior-point'
算法不使用x0
。x0
是'trust-region-reflective'
算法的可选参量。默认情况下,此算法将x0
设置为全零向量。如果这些分量中任何一个违反了边界约束,lsqlin
会将整个默认值x0
重置为满足边界的向量。如果非默认x0
的任何分量违反了边界,lsqlin
会设置这些分量以满足边界。非空
x0
是'active-set'
算法的必需参量。如果x0
的任何分量违反了边界,lsqlin
会设置这些分量以满足边界。
示例: x0 = [4;-3]
数据类型: double
options
— lsqlin
的选项
使用 optimoptions
创建的选项 | 诸如由 optimset
创建的结构体
lsqlin
的选项,指定为 optimoptions
函数的输出或诸如由 optimset
创建的结构体。
optimoptions
显示中缺少某些选项。这些选项在下表中以斜体显示。有关详细信息,请参阅查看优化选项。
所有算法
| 选择算法:
当问题没有约束时, 如果您有大量的线性约束而没有大量的变量,请尝试 有关选择算法的详细信息,请参阅选择算法。 |
Diagnostics | 显示关于要最小化或求解的函数的诊断信息。选择项是 |
Display | 返回到命令行的输出显示级别。
|
MaxIterations | 允许的最大迭代次数,非负整数。 对于 |
trust-region-reflective
算法选项
FunctionTolerance | 函数值的终止容差,非负标量。默认值为 对于 |
JacobianMultiplyFcn | 雅可比矩阵乘法函数,指定为函数句柄。对于大规模结构问题,此函数应计算雅可比矩阵乘积 W = jmfun(Jinfo,Y,flag) 其中
有关示例,请参阅雅可比乘法函数与线性最小二乘法。 对于 |
MaxPCGIter | PCG(预条件共轭梯度)迭代的最大次数,正标量。默认值为 |
OptimalityTolerance | 一阶最优性的终止容差(非负标量)。默认值为 对于 |
PrecondBandWidth | PCG(预条件共轭梯度)的预条件子上带宽。默认情况下,使用对角预条件(上带宽为 0)。对于某些问题,增加带宽会减少 PCG 迭代次数。将 |
SubproblemAlgorithm | 确定迭代步的计算方式。与 |
TolPCG | PCG(预条件共轭梯度)迭代的终止容差,正标量。默认值为 |
TypicalX | 典型的 |
interior-point
算法选项
ConstraintTolerance | 约束违反值的容差,非负标量。默认值为 对于 |
LinearSolver | 算法内部线性求解器的类型: |
OptimalityTolerance | 一阶最优性的终止容差(非负标量)。默认值为 对于 |
StepTolerance |
对于 |
'active-set'
算法选项
ConstraintTolerance | 约束违反值容差;正标量。默认值为 对于 |
ObjectiveLimit | 容差(停止条件),标量。如果目标函数值低于 |
OptimalityTolerance | 一阶最优性的终止容差,正标量。默认值为 对于 |
StepTolerance | 关于正标量 对于 |
problem
— 优化问题
结构体
优化问题,指定为具有以下字段的结构体。
| 项 C*x - d 中的矩阵乘数 |
| 项 C*x - d 中的加法常数 |
| 线性不等式约束的矩阵 |
| 线性不等式约束的向量 |
| 线性等式约束的矩阵 |
| 线性等式约束的向量 |
lb | 由下界组成的向量 |
ub | 由上界组成的向量 |
| x 的初始点 |
| 'lsqlin' |
| 用 optimoptions 创建的选项 |
注意
您不能将热启动与 problem
参量结合使用。
数据类型: struct
ws
— 热启动对象
使用 optimwarmstart
创建的对象
热启动对象,指定为使用 optimwarmstart
创建的对象。热启动对象包含起点和选项,以及代码生成中的内存大小数据(可选)。请参阅热启动最佳实践。
示例: ws = optimwarmstart(x0,options)
输出参量
x
— 解
实数向量
解,以向量形式返回,它在满足所有边界和线性约束的情况下最小化 C*x-d
的范数。
wsout
— 热启动对象求解
LsqlinWarmStart
对象
热启动对象求解,以 LsqlinWarmStart
对象形式返回。解点是 wsout.X
。
您可以在后续的 lsqlin
调用中使用 wsout
作为输入热启动对象。
resnorm
— 目标值
实数标量
目标值,以标量值 norm(C*x-d)^2
形式返回。
residual
— 解残差
实数向量
解残差,以向量 C*x-d
形式返回。
exitflag
— 算法停止条件
整数
算法停止条件,以整数形式返回,标识算法停止的原因。下面列出 exitflag
的值以及相应的 lsqlin
停止原因。
| 残差的变化小于指定容差 |
| 步长小于 |
| 函数收敛于解 |
| 迭代次数超出 |
| 此问题不可行。或者,对于 |
-3 | 此问题无界。 |
| 病态会妨碍进一步优化。 |
| 无法计算步的方向。 |
interior-point
算法的退出消息可以提供关于 lsqlin
停止原因的详细信息,例如超出容差。请参阅退出标志和退出消息。
output
— 求解过程摘要
结构体
求解过程摘要,以包含优化过程信息的结构体形式返回。
| 求解器已进行的迭代次数。 |
| 下列算法之一:
对于无约束问题, |
| 约束违反值,在违反约束时为正值(
|
| 退出消息。 |
| 解处的一阶最优性。请参阅一阶最优性测度。 |
linearsolver | 内部线性求解器的类型, |
| 求解器执行的共轭梯度迭代的次数。仅对 |
请参阅输出结构体。
lambda
— 拉格朗日乘数
结构体
提示
对于没有约束的问题,考虑使用
mldivide
(矩阵左除)或lsqminnorm
。当没有约束时,lsqlin
返回x = C\d
。由于要求解的问题始终为凸,因此
lsqlin
寻找一个全局解,尽管它不一定唯一。如果您的问题有很多线性约束和很少的变量,请尝试使用
'active-set'
算法。请参阅具有多个线性约束的二次规划。如果您使用
Aeq
和beq
显式指定(而不是使用lb
和ub
隐式指定)等式,可能会得到更好的数值结果。trust-region-reflective
算法不允许相等的上界和下界。在这种情况下,请换一种算法。如果问题的指定输入边界不一致,则输出
x
为x0
,输出resnorm
和residual
为[]
。您可以使用
trust-region-reflective
算法和雅可比矩阵乘法函数来求解一些大规模结构问题,包括那些因C
矩阵太大而无法放入内存的问题。有关信息,请参阅trust-region-reflective 算法选项。
算法
信赖域反射算法
内点算法
'interior-point'
算法基于 quadprog
'interior-point-convex'
算法。请参阅线性最小二乘:内点或活动集。
活动集算法
'active-set'
算法基于 quadprog
'active-set'
算法。有关详细信息,请参阅线性最小二乘:内点或活动集和active-set quadprog 算法。
无约束问题
对于无约束问题,lsqlin
使用 decomposition
对 C
系数矩阵执行分解。当 lsqlin
检测到 C
矩阵为病态时,lsqlin
使用 QR 分解来求解问题。
参考
[1] Coleman, T. F. and Y. Li. “A Reflective Newton Method for Minimizing a Quadratic Function Subject to Bounds on Some of the Variables,” SIAM Journal on Optimization, Vol. 6, Number 4, pp. 1040–1058, 1996.
[2] Gill, P. E., W. Murray, and M. H. Wright. Practical Optimization, Academic Press, London, UK, 1981.
热启动
热启动对象维护先前已求解问题的活动约束列表。求解器将尽可能多地携带活动约束信息来求解当前问题。如果前一个问题与当前问题差异太大,则不会重用任何活动约束集信息。在这种情况下,求解器实际上执行冷启动,以重新构建活动约束列表。
替代功能
App
优化实时编辑器任务为 lsqlin
提供可视化界面。
扩展功能
C/C++ 代码生成
使用 MATLAB® Coder™ 生成 C 代码和 C++ 代码。
用法说明和限制:
lsqlin
支持使用codegen
(MATLAB Coder) 函数或 MATLAB® Coder™ 生成代码。您必须拥有 MATLAB Coder 许可证才能生成代码。目标硬件必须支持标准双精度浮点计算。您不能为单精度或定点计算生成代码。
代码生成目标与 MATLAB 求解器不使用相同的数学核心函数库。因此,代码生成解可能不同于求解器解,尤其是对于病态问题。
在 MATLAB 中求解无约束和欠定问题时,
lsqlin
调用mldivide
,后者返回一个基解。在代码生成中,返回的解具有最小范数,最小范数通常是不同的。在生成代码时,
lsqlin
不支持problem
参量。[x,fval] = lsqlin(problem) % Not supported
所有
lsqlin
输入矩阵(如A
、Aeq
、lb
和ub
)都必须是满矩阵,而不能是稀疏矩阵。您可以使用full
函数将稀疏矩阵转换为满矩阵。lb
和ub
参量的条目数必须与C
中的列数相同,或必须为空[]
。如果您的目标硬件不支持无限边界,请使用
optim.coder.infbound
。对于涉及嵌入式处理器的高级代码优化,您还需要 Embedded Coder® 许可证。
您必须包括适用于
lsqlin
的选项,并使用optimoptions
指定这些选项。选项中必须包括Algorithm
并将其设置为'active-set'
。options = optimoptions('lsqlin','Algorithm','active-set'); [x,fval,exitflag] = lsqlin(C,d,A,b,Aeq,beq,lb,ub,x0,options);
代码生成支持以下选项:
Algorithm
- 必须为'active-set'
ConstraintTolerance
MaxIterations
ObjectiveLimit
OptimalityTolerance
StepTolerance
生成的代码只会对选项进行有限的错误检查。更新选项的推荐方法是使用
optimoptions
,而不是圆点表示法。opts = optimoptions('lsqlin','Algorithm','active-set'); opts = optimoptions(opts,'MaxIterations',1e4); % Recommended opts.MaxIterations = 1e4; % Not recommended
不要从文件中加载选项。否则会导致代码生成失败。请在代码中创建选项。
如果您指定了不受支持的选项,在代码生成过程中通常会忽略该选项。为了获得可靠的结果,请仅指定支持的选项。
版本历史记录
在 R2006a 之前推出R2024a: 处理无约束问题更加稳健
现在,当求解具有方形输入矩阵 C
(行数等于列数)的病态无约束问题时,求解器会采取额外的步骤。结果可以有更高的准确度,并且得到 Inf
或 NaN
结果的可能性降低了。
对于无约束问题,output.algorithm
字段现在是 'direct'
,而不是以前的 'mldivide'
。
MATLAB 命令
您点击的链接对应于以下 MATLAB 命令:
请在 MATLAB 命令行窗口中直接输入以执行命令。Web 浏览器不支持 MATLAB 命令。
Select a Web Site
Choose a web site to get translated content where available and see local events and offers. Based on your location, we recommend that you select: .
You can also select a web site from the following list:
How to Get Best Site Performance
Select the China site (in Chinese or English) for best site performance. Other MathWorks country sites are not optimized for visits from your location.
Americas
- América Latina (Español)
- Canada (English)
- United States (English)
Europe
- Belgium (English)
- Denmark (English)
- Deutschland (Deutsch)
- España (Español)
- Finland (English)
- France (Français)
- Ireland (English)
- Italia (Italiano)
- Luxembourg (English)
- Netherlands (English)
- Norway (English)
- Österreich (Deutsch)
- Portugal (English)
- Sweden (English)
- Switzerland
- United Kingdom (English)