You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
137 lines
4.7 KiB
137 lines
4.7 KiB
3 years ago
|
function [L,U,Q] = luq(A,do_pivot,tol)
|
||
|
% PURPOSE: calculates the following decomposition
|
||
|
%
|
||
|
% A = L |Ubar 0 | Q
|
||
|
% |0 0 |
|
||
|
%
|
||
|
% where Ubar is a square invertible matrix
|
||
|
% and matrices L, Q are invertible.
|
||
|
%
|
||
|
% ---------------------------------------------------
|
||
|
% USAGE: [L,U,Q] = luq(A,do_pivot,tol)
|
||
|
% INPUT:
|
||
|
% A a sparse matrix
|
||
|
% do_pivot = 1 with column pivoting
|
||
|
% = 0 without column pivoting
|
||
|
% tol uses the tolerance tol in separating zero and
|
||
|
% nonzero values
|
||
|
%
|
||
|
% OUTPUT:
|
||
|
% L,U,Q matrices
|
||
|
%
|
||
|
% COMMENTS:
|
||
|
% based on lu decomposition
|
||
|
%
|
||
|
% Copyright (c) Pawel Kowal (2006)
|
||
|
% All rights reserved
|
||
|
% LREM_SOLVE toolbox is available free for noncommercial academic use only.
|
||
|
% pkowal3@sgh.waw.pl
|
||
|
|
||
|
[n,m] = size(A);
|
||
|
|
||
|
if ~issparse(A)
|
||
|
A = sparse(A);
|
||
|
end
|
||
|
|
||
|
%--------------------------------------------------------------------------
|
||
|
% SPECIAL CASES
|
||
|
%--------------------------------------------------------------------------
|
||
|
if size(A,1)==0
|
||
|
L = speye(n);
|
||
|
U = A;
|
||
|
Q = speye(m);
|
||
|
return;
|
||
|
end
|
||
|
if size(A,2)==0
|
||
|
L = speye(n);
|
||
|
U = A;
|
||
|
Q = speye(m);
|
||
|
return;
|
||
|
end
|
||
|
|
||
|
%--------------------------------------------------------------------------
|
||
|
% LU DECOMPOSITION
|
||
|
%--------------------------------------------------------------------------
|
||
|
if do_pivot
|
||
|
[L,U,P,Q] = lu(A);
|
||
|
Q = Q';
|
||
|
else
|
||
|
[L,U,P] = lu(A);
|
||
|
Q = speye(m);
|
||
|
end
|
||
|
p = size(A,1)-size(L,2);
|
||
|
LL = [sparse(n-p,p);speye(p)];
|
||
|
L = [P'*L P(n-p+1:n,:)'];
|
||
|
U = [U;sparse(p,m)];
|
||
|
|
||
|
%--------------------------------------------------------------------------
|
||
|
% FINDS ROWS WITH ZERO AND NONZERO ELEMENTS ON THE DIAGONAL
|
||
|
%--------------------------------------------------------------------------
|
||
|
if size(U,1)==1 || size(U,2)==1
|
||
|
S = U(1,1);
|
||
|
else
|
||
|
S = diag(U);
|
||
|
end
|
||
|
I = find(abs(S)>tol);
|
||
|
Jl = (1:n)';
|
||
|
Jl(I) = [];
|
||
|
Jq = (1:m)';
|
||
|
Jq(I) = [];
|
||
|
|
||
|
Ubar1 = U(I,I);
|
||
|
Ubar2 = U(Jl,Jq);
|
||
|
Qbar1 = Q(I,:);
|
||
|
Lbar1 = L(:,I);
|
||
|
|
||
|
%--------------------------------------------------------------------------
|
||
|
% ELININATES NONZEZO ELEMENTS BELOW AND ON THE RIGHT OF THE
|
||
|
% INVERTIBLE BLOCK OF THE MATRIX U
|
||
|
%
|
||
|
% UPDATES MATRICES L, Q
|
||
|
%--------------------------------------------------------------------------
|
||
|
if ~isempty(I)
|
||
|
Utmp = U(I,Jq);
|
||
|
X = Ubar1'\U(Jl,I)';
|
||
|
Ubar2 = Ubar2-X'*Utmp;
|
||
|
Lbar1 = Lbar1+L(:,Jl)*X';
|
||
|
|
||
|
X = Ubar1\Utmp;
|
||
|
Qbar1 = Qbar1+X*Q(Jq,:);
|
||
|
Utmp = [];
|
||
|
X = [];
|
||
|
end
|
||
|
|
||
|
%--------------------------------------------------------------------------
|
||
|
% FINDS ROWS AND COLUMNS WITH ONLY ZERO ELEMENTS
|
||
|
%--------------------------------------------------------------------------
|
||
|
I2 = find(max(abs(Ubar2),[],2)>tol);
|
||
|
I5 = find(max(abs(Ubar2),[],1)>tol);
|
||
|
|
||
|
I3 = Jl(I2);
|
||
|
I4 = Jq(I5);
|
||
|
Jq(I5) = [];
|
||
|
Jl(I2) = [];
|
||
|
U = [];
|
||
|
|
||
|
%--------------------------------------------------------------------------
|
||
|
% FINDS A PART OF THE MATRIX U WHICH IS NOT IN THE REQIRED FORM
|
||
|
%--------------------------------------------------------------------------
|
||
|
A = Ubar2(I2,I5);
|
||
|
|
||
|
%--------------------------------------------------------------------------
|
||
|
% PERFORMS LUQ DECOMPOSITION OF THE MATRIX A
|
||
|
%--------------------------------------------------------------------------
|
||
|
[L1,U1,Q1] = luq(A,do_pivot,tol);
|
||
|
|
||
|
%--------------------------------------------------------------------------
|
||
|
% UPDATES MATRICES L, U, Q
|
||
|
%--------------------------------------------------------------------------
|
||
|
Lbar2 = L(:,I3)*L1;
|
||
|
Qbar2 = Q1*Q(I4,:);
|
||
|
L = [Lbar1 Lbar2 L(:,Jl)];
|
||
|
Q = [Qbar1; Qbar2; Q(Jq,:)];
|
||
|
|
||
|
n1 = length(I);
|
||
|
n2 = length(I3);
|
||
|
m2 = length(I4);
|
||
|
U = [Ubar1 sparse(n1,m-n1);sparse(n2,n1) U1 sparse(n2,m-n1-m2);sparse(n-n1-n2,m)];
|