Skip to content

Commit 21673e5

Browse files
fix LU factorization when lead != k
1 parent 1cf4415 commit 21673e5

File tree

2 files changed

+18
-21
lines changed

2 files changed

+18
-21
lines changed

src/linear_algebra.jl

Lines changed: 16 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -17,14 +17,14 @@ function _sym_lu(A)
1717
lead = 1
1818
leads = zeros(Int, minmn)
1919
rank = 0
20-
for k = 1:m
20+
for k = 1:minmn
2121
kp = k # pivot index
2222

2323
# search for the expression different from zero with the least terms
2424
amin = SINGULAR
2525
for j = lead:n
2626
for i = k:m # search first by columns
27-
absi = Symbolics._iszero(F[i, j]) ? SINGULAR : Symbolics.nterms(F[i, j])
27+
absi = _iszero(F[i, j]) ? SINGULAR : nterms(F[i, j])
2828
if absi < amin
2929
kp = i
3030
amin = absi
@@ -42,8 +42,8 @@ function _sym_lu(A)
4242

4343
# break from function as the reduced echelon form has been
4444
# reached, but fill `p`
45-
if amin == SINGULAR && !(amin isa Symbolics.Symbolic) && (amin isa Number) && iszero(rank)
46-
for i = k+1:m
45+
if amin == SINGULAR && !(amin isa Symbolic) && (amin isa Number)
46+
for i = k+1:minmn
4747
p[i] = i
4848
end
4949
break
@@ -57,21 +57,24 @@ function _sym_lu(A)
5757
end
5858
end
5959

60-
# normalize the lead column
60+
# set values for L matrix
6161
c = F[k, lead]
62-
for i = lead+1:m
63-
F[i, k] = F[i, k] / c
62+
for i = k+1:m
63+
F[i, k] = F[i, lead] / c
64+
if lead != k
65+
F[i, lead] = zero(Num)
66+
end
6467
end
6568

66-
# substract the row form every other, traverse first by colums
69+
# substract the row from every other, traverse first by colums
6770
# we start from lead+1 to avoid chaing the leading value on the column
6871
for j = lead+1:n
69-
for i = lead+1:m
72+
for i = k+1:m
7073
# this line occupies most of the time, distributed in the
7174
# following methods
7275
# - `*(::Num, ::Num)` dynamic dispatch
7376
# - `-(::Num, ::Num)` dynamic dispatch
74-
F[i, j] = F[i, j] - F[i, lead] * F[k, j]
77+
F[i, j] = F[i, j] - F[i, k] * F[k, j]
7578
end
7679
end
7780

@@ -98,18 +101,13 @@ function sym_rref(A, b)
98101
leads = zeros(Int, minmn)
99102
rank = 0
100103
for k = 1:m
101-
# if there is no more reduction to do
102-
if lead > n
103-
break
104-
end
105-
106104
kp = k # pivot index
107105

108106
# search for the expression different from zero with the least terms
109107
amin = SINGULAR
110108
for j = lead:n
111109
for i = k:m # search first by columns
112-
absi = Symbolics._iszero(F[i, j]) ? SINGULAR : Symbolics.nterms(F[i, j])
110+
absi = _iszero(F[i, j]) ? SINGULAR : nterms(F[i, j])
113111
if absi < amin
114112
kp = i
115113
amin = absi
@@ -126,9 +124,8 @@ function sym_rref(A, b)
126124
# normally, here we would save the permutation in an array
127125
# but this is not needed as we have the extended matrix
128126

129-
# save to check for consistency
130127
# break from function as the reduced echelon form has been reached
131-
if amin == SINGULAR && !(amin isa Symbolics.Symbolic) && (amin isa Number) && iszero(rank)
128+
if amin == SINGULAR && !(amin isa Symbolic) && (amin isa Number)
132129
break
133130
end
134131
rank = k
@@ -168,7 +165,7 @@ function sym_rref(A, b)
168165
# zero the lead column
169166
for i = 1:m
170167
if i != k
171-
F[i, lead] = zero(eltype(F))
168+
F[i, lead] = zero(Num)
172169
end
173170
end
174171

test/overloads.jl

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ qr(X)
5555
X2 = [0 b c; 0 0 0; 0 h 0]
5656
@test_throws SingularException lu(X2)
5757
F2 = lu(X2, check=false)
58-
@test F2.info == 1
58+
@test F2.info == 2 # F2.info == rank(X2)
5959

6060
# test operations with sparse arrays
6161
# note `isequal` instead of `==` because `==` would give another symbolic type
@@ -167,7 +167,7 @@ z2 = c + d * im
167167
@test sign(Num(1)) isa Num
168168
@test isequal(sign(Num(1)), Num(1))
169169
@test isequal(sign(Num(-1)), Num(-1))
170-
170+
171171
@test isequal(ℯ^a, exp(a))
172172

173173
using IfElse: ifelse

0 commit comments

Comments
 (0)