【问题标题】:lsqlin optimized calculation (matlab)lsqlin优化计算(matlab)
【发布时间】:2017-02-15 00:11:02
【问题描述】:

我正在计算约束线性最小二乘问题的解,如下所示:

lb = zeros(7,1);
ub = ones(7,1);
for i = 1:size(b,2)
   x(:,i) = lsqlin(C,b(:,i),[],[],[],[],lb,ub);
end

其中Cm x 7bm x nn 非常大,导致计算时间变慢。有什么方法可以加快这个过程并摆脱缓慢的for 循环。我使用lsqlin 而不是pinv\,因为我需要将我的解决方案限制在0-1 的边界(lbub)。

【问题讨论】:

  • 您可以随时尝试切换默认求解器。试试'interior-point。不确定该循环的用途以及您希望我们如何处理它。
  • 我尝试了不同的求解器,但问题是一样的。我正在使用 for 循环,因为如果我尝试给 x = lsqlin(C,b,[],[],[],[],lb,ub); 我收到 Inner matrix dimensions must agree. 错误。另一方面,如果我使用pinv(C)*bC \ b 它就像一个魅力但对于lsqlin 我需要通过for 循环来完成它,因为我需要约束我需要使用@987654340 @。因此,我只是想问是否有可能优化或丢弃for 循环。

标签: matlab optimization least-squares


【解决方案1】:

for 循环不一定是任何缓慢的原因 - 您没有预先分配,lsqlin 可能在每次迭代时打印出很多东西。但是,您可以通过将 C 矩阵转换为稀疏块对角矩阵 C2n 相同块 (see here) 来加快此过程。这一口气解决了所有n 问题。如果新的C2 不是稀疏的,您可能会使用更多的内存,并且计算时间可能比for 循环长得多。

n = size(b,2);
C2 = kron(speye(n),C);
b2 = b(:);
lb2 = repmat(lb,n,1); % or zeros(7*n,1);
ub2 = repmat(ub,n,1); % or ones(7*n,1);
opts = optimoptions(@lsqlin,'Algorithm','interior-point','Display','off');
x = lsqlin(C2,b2,[],[],[],[],lb2,ub2,[],opts);

使用optimoptions,我已经specified the algorithm 并将'Display' 设置为'off',以确保任何输出和警告都不会减慢计算速度。

在我的机器上,这比使用 for 循环(使用适当的预分配和设置选项)快 6-10 倍。这种方法假设具有m*n*7 元素的稀疏C2 矩阵可以放入内存。如果没有,基于for 循环的方法将是唯一的选择(除了编写您自己的lsqlin 专用版本或利用问题中的任何其他空闲)。

【讨论】:

  • 非常感谢您的回答。您的解决方案似乎成功了;-)。在使用稀疏块对角矩阵时,我也关闭了消息但没有预先分配(我打算尝试的下一件事)是一个我不知道的技巧,它似乎有很大帮助。再次感谢您的帮助。
  • 只是另一个问题。在内存方面,稀疏块对角矩阵的使用有多优化。因为例如,在我的情况下,我必须处理大小为 C (193200x7) b (193200x16450) 或更大的矩阵,这很糟糕,我之前没有提到这一点。正如您在实践中尝试解决方案所理解的那样,现在我遇到了内存问题(250Gb 不足以用于 C2 预分配)。有什么提示吗?
  • 我假设m 小于n,因为您指出n 在您的问题中很大。您的稀疏 C2 将需要与 193200x7x16450 数组大致相同的内存(而不是比这大 16450 倍的完整数组!)。您的 b 已经大于我的 Matlab 版本中的默认最大数组大小(您可能不得不进入偏好更改限制)。 for 循环是内存受限的最佳选择,除非系统的其他部分是稀疏的。
  • 我明白了。再次感谢您的宝贵时间 ;-)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-08-05
  • 2014-07-17
  • 2015-03-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多