-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmy_splu.m
71 lines (67 loc) · 1.66 KB
/
my_splu.m
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
function [P, L, U, sign] = my_splu(A)
% Square PA=LU factorization *with row exchanges*.
%
% Usage: [P, L, U] = splu(A)
% INPUT:
% A - square invertible m-by-my matrix
% OUTPUT:
% L - square m-by-m unit lower-triangular matrix;
% U - square m-by-m upper-triangular matrix;
% P - square m-by-m permutation matrix;
% sign - sign = det(P); it is 1 or -1.
% ALGORITHM:
% L and U are computed by Gaussian elimination, with pivoting,
% i.e., row exchange, so that L*U=P*A.
%
% Examples:
% A = randn(5); [P,L,U,sign] = splu(A);
%
% See also: slu, backSub, forSub.
% Defaults:
[m, n] = size(A);
if m ~= n
error('Matrix must be square.')
end
P = eye(n, n);
L = eye(n, n);
U = zeros(n, n);
tol = sqrt(eps);
sign = 1;
for k = 1:n
[max_ak, r] = max(abs(A([k:n], k)));
r = r+k-1;
if r ~= k
if max_ak < tol
if nargout == 4
sign = 0;
return
else
disp('A is singular within tolerance.')
error(['No pivot in column ' int2str(k) '.'])
end
end
A([r k], 1:n) = A([k r], 1:n);
if k > 1, L([r k], 1:k-1) = L([k r], 1:k-1); end
P([r k], 1:n) = P([k r], 1:n);
sign = -sign;
end
for i = k+1:n
L(i, k) = A(i, k) / A(k, k);
for j = k+1:n
A(i, j) = A(i, j) - L(i, k)*A(k, j);
end
end
for j = k:n
U(k, j) = A(k, j) * (abs(A(k, j)) >= tol);
end
if n <= 10
figure(k); clf;
dispMEq('P*A=L*U',P,A,L,U);
title(['Step ' num2str(k)], 'FontSize', 15);
pause
end
end
if nargout < 4
roworder = P*(1:n)';
disp('Pivots in rows:'), disp(roworder'); end
end