如何在 MATLAB 中求解只有一个分量的线性系统
How to solve a linear system for only one component in MATLAB
我需要求解线性系统
A x = b
可以通过
有效地完成
x = A \ b
但现在 A
非常大,我实际上只需要一个组件,比如 x(1)
。有没有比计算 x
的所有组件更有效地解决这个问题的方法?
A
不疏。在这里,效率实际上是一个问题,因为这是为许多 b
.
完成的
此外,存储 K
的倒数并仅将其第一行乘以 b
是不可能的,因为 K
的条件很差。在这种情况下,使用 \
运算符会使用 LDL 求解器,并且在显式使用逆函数时会失去准确性。
我不认为你在技术上会比非常优化的 Matlab 例程得到加速,但是如果你了解它是如何求解的,那么你可以只求解 x 的一部分。例如,传统求解器中的 following. 您使用 backsub 进行 QR 求解。在 LU solve 中,您同时使用 back sub 和 front sub。我可以得到LU。不幸的是,由于它的解决方式,它实际上是从最后开始的。对于将同时使用两者的 LDL 也是如此。这并不排除可能有更有效的方法来解决您所拥有的问题。
function [Q,R] = qrcgs(A)
%Classical Gram Schmidt for an m x n matrix
[m,n] = size(A);
% Generates the Q, R matrices
Q = zeros(m,n);
R = zeros(n,n);
for k = 1:n
% Assign the vector for normalization
w = A(:,k);
for j=1:k-1
% Gets R entries
R(j,k) = Q(:,j)'*w;
end
for j = 1:k-1
% Subtracts off orthogonal projections
w = w-R(j,k)*Q(:,j);
end
% Normalize
R(k,k) = norm(w);
Q(:,k) = w./R(k,k);
end
end
function x = backsub(R,b)
% Backsub for upper triangular matrix.
[m,n] = size(R);
p = min(m,n);
x = zeros(n,1);
for i=p:-1:1
% Look from bottom, assign to vector
r = b(i);
for j=(i+1):p
% Subtract off the difference
r = r-R(i,j)*x(j);
end
x(i) = r/R(i,i);
end
end
方法mldivide
,通常表示为\
,接受一次解决许多具有相同A
的系统。
x = A\[b1 b2 b3 b4] # where bi are vectors with n rows
求解每个 b
的系统,并将 return 一个 nx4 矩阵,其中每一列是每个 b
的解。像这样调用 mldivide 应该会提高效率,因为分解只进行一次。
在许多分解中,如 LU od LDL'(以及您特别感兴趣的分解),矩阵乘法 x
是上对角线,要求解的第一个值是 x(n)
。但是,必须进行 LDL 分解,简单的向后替换算法不会成为代码的瓶颈。因此,可以省去分解,避免每bi
重复计算一次。因此,代码看起来类似于:
[LA,DA] = ldl(A);
DA = sparse(DA);
% LA = sparse(LA); %LA can also be converted to sparse matrix
% loop over bi
xi = LA'\(DA\(LA\bi));
% end loop
正如您在 mldivide (Algorithms section) 的文档中看到的那样,它对输入矩阵执行一些检查,并将 LA
定义为满矩阵,将 DA
定义为稀疏矩阵,它应该直接用于三角求解器和三对角求解器。如果 LA
转换为稀疏,它也会使用三角求解器,我不知道转换为稀疏是否代表任何改进。
我需要求解线性系统
A x = b
可以通过
有效地完成x = A \ b
但现在 A
非常大,我实际上只需要一个组件,比如 x(1)
。有没有比计算 x
的所有组件更有效地解决这个问题的方法?
A
不疏。在这里,效率实际上是一个问题,因为这是为许多 b
.
此外,存储 K
的倒数并仅将其第一行乘以 b
是不可能的,因为 K
的条件很差。在这种情况下,使用 \
运算符会使用 LDL 求解器,并且在显式使用逆函数时会失去准确性。
我不认为你在技术上会比非常优化的 Matlab 例程得到加速,但是如果你了解它是如何求解的,那么你可以只求解 x 的一部分。例如,传统求解器中的 following. 您使用 backsub 进行 QR 求解。在 LU solve 中,您同时使用 back sub 和 front sub。我可以得到LU。不幸的是,由于它的解决方式,它实际上是从最后开始的。对于将同时使用两者的 LDL 也是如此。这并不排除可能有更有效的方法来解决您所拥有的问题。
function [Q,R] = qrcgs(A)
%Classical Gram Schmidt for an m x n matrix
[m,n] = size(A);
% Generates the Q, R matrices
Q = zeros(m,n);
R = zeros(n,n);
for k = 1:n
% Assign the vector for normalization
w = A(:,k);
for j=1:k-1
% Gets R entries
R(j,k) = Q(:,j)'*w;
end
for j = 1:k-1
% Subtracts off orthogonal projections
w = w-R(j,k)*Q(:,j);
end
% Normalize
R(k,k) = norm(w);
Q(:,k) = w./R(k,k);
end
end
function x = backsub(R,b)
% Backsub for upper triangular matrix.
[m,n] = size(R);
p = min(m,n);
x = zeros(n,1);
for i=p:-1:1
% Look from bottom, assign to vector
r = b(i);
for j=(i+1):p
% Subtract off the difference
r = r-R(i,j)*x(j);
end
x(i) = r/R(i,i);
end
end
方法mldivide
,通常表示为\
,接受一次解决许多具有相同A
的系统。
x = A\[b1 b2 b3 b4] # where bi are vectors with n rows
求解每个 b
的系统,并将 return 一个 nx4 矩阵,其中每一列是每个 b
的解。像这样调用 mldivide 应该会提高效率,因为分解只进行一次。
在许多分解中,如 LU od LDL'(以及您特别感兴趣的分解),矩阵乘法 x
是上对角线,要求解的第一个值是 x(n)
。但是,必须进行 LDL 分解,简单的向后替换算法不会成为代码的瓶颈。因此,可以省去分解,避免每bi
重复计算一次。因此,代码看起来类似于:
[LA,DA] = ldl(A);
DA = sparse(DA);
% LA = sparse(LA); %LA can also be converted to sparse matrix
% loop over bi
xi = LA'\(DA\(LA\bi));
% end loop
正如您在 mldivide (Algorithms section) 的文档中看到的那样,它对输入矩阵执行一些检查,并将 LA
定义为满矩阵,将 DA
定义为稀疏矩阵,它应该直接用于三角求解器和三对角求解器。如果 LA
转换为稀疏,它也会使用三角求解器,我不知道转换为稀疏是否代表任何改进。