Skip to content

Commit 0699e8e

Browse files
jishnubKristofferC
authored and
KristofferC
committed
Avoid concatenating LazyString in setindex! for triangular matrices (#54631)
(cherry picked from commit aea4627)
1 parent 90acf2a commit 0699e8e

File tree

1 file changed

+38
-16
lines changed

1 file changed

+38
-16
lines changed

stdlib/LinearAlgebra/src/triangular.jl

Lines changed: 38 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -269,10 +269,23 @@ Base.isstored(A::UpperTriangular, i::Int, j::Int) =
269269
@propagate_inbounds getindex(A::UpperTriangular, i::Integer, j::Integer) =
270270
i <= j ? A.data[i,j] : _zero(A.data,j,i)
271271

272+
@noinline function throw_nonzeroerror(T, @nospecialize(x), i, j)
273+
_upper_lower_str(::Type{<:UpperOrUnitUpperTriangular}) = "upper"
274+
_upper_lower_str(::Type{<:LowerOrUnitLowerTriangular}) = "lower"
275+
Ts = _upper_lower_str(T)
276+
Tn = nameof(T)
277+
throw(ArgumentError(
278+
lazy"cannot set index in the $Ts triangular part ($i, $j) of an $Tn matrix to a nonzero value ($x)"))
279+
end
280+
@noinline function throw_nononeerror(T, @nospecialize(x), i, j)
281+
Tn = nameof(T)
282+
throw(ArgumentError(
283+
lazy"cannot set index on the diagonal ($i, $j) of an $Tn matrix to a non-unit value ($x)"))
284+
end
285+
272286
@propagate_inbounds function setindex!(A::UpperTriangular, x, i::Integer, j::Integer)
273287
if i > j
274-
iszero(x) || throw(ArgumentError("cannot set index in the lower triangular part " *
275-
lazy"($i, $j) of an UpperTriangular matrix to a nonzero value ($x)"))
288+
iszero(x) || throw_nonzeroerror(typeof(A), x, i, j)
276289
else
277290
A.data[i,j] = x
278291
end
@@ -281,11 +294,9 @@ end
281294

282295
@propagate_inbounds function setindex!(A::UnitUpperTriangular, x, i::Integer, j::Integer)
283296
if i > j
284-
iszero(x) || throw(ArgumentError("cannot set index in the lower triangular part " *
285-
lazy"($i, $j) of a UnitUpperTriangular matrix to a nonzero value ($x)"))
297+
iszero(x) || throw_nonzeroerror(typeof(A), x, i, j)
286298
elseif i == j
287-
x == oneunit(x) || throw(ArgumentError(lazy"cannot set index on the diagonal ($i, $j) " *
288-
lazy"of a UnitUpperTriangular matrix to a non-unit value ($x)"))
299+
x == oneunit(x) || throw_nononeerror(typeof(A), x, i, j)
289300
else
290301
A.data[i,j] = x
291302
end
@@ -294,8 +305,7 @@ end
294305

295306
@propagate_inbounds function setindex!(A::LowerTriangular, x, i::Integer, j::Integer)
296307
if i < j
297-
iszero(x) || throw(ArgumentError("cannot set index in the upper triangular part " *
298-
lazy"($i, $j) of a LowerTriangular matrix to a nonzero value ($x)"))
308+
iszero(x) || throw_nonzeroerror(typeof(A), x, i, j)
299309
else
300310
A.data[i,j] = x
301311
end
@@ -304,34 +314,46 @@ end
304314

305315
@propagate_inbounds function setindex!(A::UnitLowerTriangular, x, i::Integer, j::Integer)
306316
if i < j
307-
iszero(x) || throw(ArgumentError("cannot set index in the upper triangular part " *
308-
lazy"($i, $j) of a UnitLowerTriangular matrix to a nonzero value ($x)"))
317+
iszero(x) || throw_nonzeroerror(typeof(A), x, i, j)
309318
elseif i == j
310-
x == oneunit(x) || throw(ArgumentError(lazy"cannot set index on the diagonal ($i, $j) " *
311-
lazy"of a UnitLowerTriangular matrix to a non-unit value ($x)"))
319+
x == oneunit(x) || throw_nononeerror(typeof(A), x, i, j)
312320
else
313321
A.data[i,j] = x
314322
end
315323
return A
316324
end
317325

326+
@noinline function throw_setindex_structuralzero_error(T, @nospecialize(x))
327+
_struct_zero_half_str(::Type{<:UpperTriangular}) = "lower"
328+
_struct_zero_half_str(::Type{<:LowerTriangular}) = "upper"
329+
Ts = _struct_zero_half_str(T)
330+
Tn = nameof(T)
331+
throw(ArgumentError(
332+
lazy"cannot set indices in the $Ts triangular part of an $Tn matrix to a nonzero value ($x)"))
333+
end
334+
318335
@inline function fill!(A::UpperTriangular, x)
319-
iszero(x) || throw(ArgumentError("cannot set indices in the lower triangular part " *
320-
lazy"of an UpperTriangular matrix to a nonzero value ($x)"))
336+
iszero(x) || throw_setindex_structuralzero_error(typeof(A), x)
321337
for col in axes(A,2), row in firstindex(A,1):col
322338
@inbounds A.data[row, col] = x
323339
end
324340
A
325341
end
326342
@inline function fill!(A::LowerTriangular, x)
327-
iszero(x) || throw(ArgumentError("cannot set indices in the upper triangular part " *
328-
lazy"of a LowerTriangular matrix to a nonzero value ($x)"))
343+
iszero(x) || throw_setindex_structuralzero_error(typeof(A), x)
329344
for col in axes(A,2), row in col:lastindex(A,1)
330345
@inbounds A.data[row, col] = x
331346
end
332347
A
333348
end
334349

350+
Base._reverse(A::UpperOrUnitUpperTriangular, dims::Integer) = reverse!(Matrix(A); dims)
351+
Base._reverse(A::UpperTriangular, ::Colon) = LowerTriangular(reverse(A.data))
352+
Base._reverse(A::UnitUpperTriangular, ::Colon) = UnitLowerTriangular(reverse(A.data))
353+
Base._reverse(A::LowerOrUnitLowerTriangular, dims) = reverse!(Matrix(A); dims)
354+
Base._reverse(A::LowerTriangular, ::Colon) = UpperTriangular(reverse(A.data))
355+
Base._reverse(A::UnitLowerTriangular, ::Colon) = UnitUpperTriangular(reverse(A.data))
356+
335357
## structured matrix methods ##
336358
function Base.replace_in_print_matrix(A::Union{UpperTriangular,UnitUpperTriangular},
337359
i::Integer, j::Integer, s::AbstractString)

0 commit comments

Comments
 (0)