Skip to content

Commit 566acb1

Browse files
committed
Allow setindex! in zero part of Triangular matrices...
as long as the value is zero
1 parent 83eac1e commit 566acb1

File tree

2 files changed

+33
-17
lines changed

2 files changed

+33
-17
lines changed

base/linalg/triangular.jl

Lines changed: 21 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -23,12 +23,12 @@ for t in (:LowerTriangular, :UnitLowerTriangular, :UpperTriangular, :UnitUpperTr
2323
convert{T,S}(::Type{Matrix}, A::$t{T,S}) = convert(Matrix{T}, A)
2424

2525
function similar{T,S,Tnew}(A::$t{T,S}, ::Type{Tnew}, dims::Dims)
26-
if dims[1] != dims[2]
27-
throw(ArgumentError("Triangular matrix must be square"))
28-
end
2926
if length(dims) != 2
3027
throw(ArgumentError("Triangular matrix must have two dimensions"))
3128
end
29+
if dims[1] != dims[2]
30+
throw(ArgumentError("Triangular matrix must be square"))
31+
end
3232
B = similar(A.data, Tnew, dims)
3333
return $t(B)
3434
end
@@ -119,33 +119,41 @@ getindex{T,S}(A::UpperTriangular{T,S}, i::Integer, j::Integer) = i <= j ? A.data
119119

120120
function setindex!(A::UpperTriangular, x, i::Integer, j::Integer)
121121
if i > j
122-
throw(BoundsError(A,(i,j)))
122+
x == 0 || throw(ArgumentError("cannot set index in the lower triangular part ($i, $j) of an UpperTriangular matrix to a nonzero value ($x)"))
123+
else
124+
A.data[i,j] = x
123125
end
124-
A.data[i,j] = x
125126
return A
126127
end
127128

128129
function setindex!(A::UnitUpperTriangular, x, i::Integer, j::Integer)
129-
if i >= j
130-
throw(BoundsError(A,(i,j)))
130+
if i > j
131+
x == 0 || throw(ArgumentError("cannot set index in the lower triangular part ($i, $j) of a UnitUpperTriangular matrix to a nonzero value ($x)"))
132+
elseif i == j
133+
x == 1 || throw(ArgumentError("cannot set index on the diagonal ($i, $j) of a UnitUpperTriangular matrix to a non-unit value ($x)"))
134+
else
135+
A.data[i,j] = x
131136
end
132-
A.data[i,j] = x
133137
return A
134138
end
135139

136140
function setindex!(A::LowerTriangular, x, i::Integer, j::Integer)
137141
if i < j
138-
throw(BoundsError(A,(i,j)))
142+
x == 0 || throw(ArgumentError("cannot set index in the upper triangular part ($i, $j) of a LowerTriangular matrix to a nonzero value ($x)"))
143+
else
144+
A.data[i,j] = x
139145
end
140-
A.data[i,j] = x
141146
return A
142147
end
143148

144149
function setindex!(A::UnitLowerTriangular, x, i::Integer, j::Integer)
145-
if i <= j
146-
throw(BoundsError(A,(i,j)))
150+
if i < j
151+
x == 0 || throw(ArgumentError("cannot set index in the upper triangular part ($i, $j) of a UnitLowerTriangular matrix to a nonzero value ($x)"))
152+
elseif i == j
153+
x == 1 || throw(ArgumentError("cannot set diagonal index ($i, $j) of a UnitLowerTriangular matrix to a non-unit value ($x)"))
154+
else
155+
A.data[i,j] = x
147156
end
148-
A.data[i,j] = x
149157
return A
150158
end
151159

test/linalg/triangular.jl

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -59,15 +59,23 @@ for elty1 in (Float32, Float64, Complex64, Complex128, BigFloat, Int)
5959
for i = 1:size(A1, 1)
6060
for j = 1:size(A1, 2)
6161
if uplo1 == :U
62-
if i > j || (i == j && t1 == UnitUpperTriangular)
63-
@test_throws BoundsError A1c[i,j] = 0
62+
if i > j
63+
A1c[i,j] = 0
64+
@test_throws ArgumentError A1c[i,j] = 1
65+
elseif i == j && t1 == UnitUpperTriangular
66+
A1c[i,j] = 1
67+
@test_throws ArgumentError A1c[i,j] = 0
6468
else
6569
A1c[i,j] = 0
6670
@test A1c[i,j] == 0
6771
end
6872
else
69-
if i < j || (i == j && t1 == UnitLowerTriangular)
70-
@test_throws BoundsError A1c[i,j] = 0
73+
if i < j
74+
A1c[i,j] = 0
75+
@test_throws ArgumentError A1c[i,j] = 1
76+
elseif i == j && t1 == UnitLowerTriangular
77+
A1c[i,j] = 1
78+
@test_throws ArgumentError A1c[i,j] = 0
7179
else
7280
A1c[i,j] = 0
7381
@test A1c[i,j] == 0

0 commit comments

Comments
 (0)