Skip to content

Commit f7524e3

Browse files
jishnublazarusA
authored andcommitted
Avoid concatenating LazyString in setindex! for triangular matrices (JuliaLang#54631)
1 parent 94aec64 commit f7524e3

File tree

1 file changed

+37
-23
lines changed

1 file changed

+37
-23
lines changed

stdlib/LinearAlgebra/src/triangular.jl

+37-23
Original file line numberDiff line numberDiff line change
@@ -246,14 +246,23 @@ Base.isstored(A::UpperTriangular, i::Int, j::Int) =
246246
@propagate_inbounds getindex(A::UpperTriangular, i::Int, j::Int) =
247247
i <= j ? A.data[i,j] : _zero(A.data,j,i)
248248

249-
Base._reverse(A::UpperOrUnitUpperTriangular, dims::Integer) = reverse!(Matrix(A); dims)
250-
Base._reverse(A::UpperTriangular, ::Colon) = LowerTriangular(reverse(A.data))
251-
Base._reverse(A::UnitUpperTriangular, ::Colon) = UnitLowerTriangular(reverse(A.data))
249+
@noinline function throw_nonzeroerror(T, @nospecialize(x), i, j)
250+
_upper_lower_str(::Type{<:UpperOrUnitUpperTriangular}) = "upper"
251+
_upper_lower_str(::Type{<:LowerOrUnitLowerTriangular}) = "lower"
252+
Ts = _upper_lower_str(T)
253+
Tn = nameof(T)
254+
throw(ArgumentError(
255+
lazy"cannot set index in the $Ts triangular part ($i, $j) of an $Tn matrix to a nonzero value ($x)"))
256+
end
257+
@noinline function throw_nononeerror(T, @nospecialize(x), i, j)
258+
Tn = nameof(T)
259+
throw(ArgumentError(
260+
lazy"cannot set index on the diagonal ($i, $j) of an $Tn matrix to a non-unit value ($x)"))
261+
end
252262

253263
@propagate_inbounds function setindex!(A::UpperTriangular, x, i::Integer, j::Integer)
254264
if i > j
255-
iszero(x) || throw(ArgumentError("cannot set index in the lower triangular part " *
256-
lazy"($i, $j) of an UpperTriangular matrix to a nonzero value ($x)"))
265+
iszero(x) || throw_nonzeroerror(typeof(A), x, i, j)
257266
else
258267
A.data[i,j] = x
259268
end
@@ -262,25 +271,18 @@ end
262271

263272
@propagate_inbounds function setindex!(A::UnitUpperTriangular, x, i::Integer, j::Integer)
264273
if i > j
265-
iszero(x) || throw(ArgumentError("cannot set index in the lower triangular part " *
266-
lazy"($i, $j) of a UnitUpperTriangular matrix to a nonzero value ($x)"))
274+
iszero(x) || throw_nonzeroerror(typeof(A), x, i, j)
267275
elseif i == j
268-
x == oneunit(x) || throw(ArgumentError(lazy"cannot set index on the diagonal ($i, $j) " *
269-
lazy"of a UnitUpperTriangular matrix to a non-unit value ($x)"))
276+
x == oneunit(x) || throw_nononeerror(typeof(A), x, i, j)
270277
else
271278
A.data[i,j] = x
272279
end
273280
return A
274281
end
275282

276-
Base._reverse(A::LowerOrUnitLowerTriangular, dims) = reverse!(Matrix(A); dims)
277-
Base._reverse(A::LowerTriangular, ::Colon) = UpperTriangular(reverse(A.data))
278-
Base._reverse(A::UnitLowerTriangular, ::Colon) = UnitUpperTriangular(reverse(A.data))
279-
280283
@propagate_inbounds function setindex!(A::LowerTriangular, x, i::Integer, j::Integer)
281284
if i < j
282-
iszero(x) || throw(ArgumentError("cannot set index in the upper triangular part " *
283-
lazy"($i, $j) of a LowerTriangular matrix to a nonzero value ($x)"))
285+
iszero(x) || throw_nonzeroerror(typeof(A), x, i, j)
284286
else
285287
A.data[i,j] = x
286288
end
@@ -289,34 +291,46 @@ end
289291

290292
@propagate_inbounds function setindex!(A::UnitLowerTriangular, x, i::Integer, j::Integer)
291293
if i < j
292-
iszero(x) || throw(ArgumentError("cannot set index in the upper triangular part " *
293-
lazy"($i, $j) of a UnitLowerTriangular matrix to a nonzero value ($x)"))
294+
iszero(x) || throw_nonzeroerror(typeof(A), x, i, j)
294295
elseif i == j
295-
x == oneunit(x) || throw(ArgumentError(lazy"cannot set index on the diagonal ($i, $j) " *
296-
lazy"of a UnitLowerTriangular matrix to a non-unit value ($x)"))
296+
x == oneunit(x) || throw_nononeerror(typeof(A), x, i, j)
297297
else
298298
A.data[i,j] = x
299299
end
300300
return A
301301
end
302302

303+
@noinline function throw_setindex_structuralzero_error(T, @nospecialize(x))
304+
_struct_zero_half_str(::Type{<:UpperTriangular}) = "lower"
305+
_struct_zero_half_str(::Type{<:LowerTriangular}) = "upper"
306+
Ts = _struct_zero_half_str(T)
307+
Tn = nameof(T)
308+
throw(ArgumentError(
309+
lazy"cannot set indices in the $Ts triangular part of an $Tn matrix to a nonzero value ($x)"))
310+
end
311+
303312
@inline function fill!(A::UpperTriangular, x)
304-
iszero(x) || throw(ArgumentError("cannot set indices in the lower triangular part " *
305-
lazy"of an UpperTriangular matrix to a nonzero value ($x)"))
313+
iszero(x) || throw_setindex_structuralzero_error(typeof(A), x)
306314
for col in axes(A,2), row in firstindex(A,1):col
307315
@inbounds A.data[row, col] = x
308316
end
309317
A
310318
end
311319
@inline function fill!(A::LowerTriangular, x)
312-
iszero(x) || throw(ArgumentError("cannot set indices in the upper triangular part " *
313-
lazy"of a LowerTriangular matrix to a nonzero value ($x)"))
320+
iszero(x) || throw_setindex_structuralzero_error(typeof(A), x)
314321
for col in axes(A,2), row in col:lastindex(A,1)
315322
@inbounds A.data[row, col] = x
316323
end
317324
A
318325
end
319326

327+
Base._reverse(A::UpperOrUnitUpperTriangular, dims::Integer) = reverse!(Matrix(A); dims)
328+
Base._reverse(A::UpperTriangular, ::Colon) = LowerTriangular(reverse(A.data))
329+
Base._reverse(A::UnitUpperTriangular, ::Colon) = UnitLowerTriangular(reverse(A.data))
330+
Base._reverse(A::LowerOrUnitLowerTriangular, dims) = reverse!(Matrix(A); dims)
331+
Base._reverse(A::LowerTriangular, ::Colon) = UpperTriangular(reverse(A.data))
332+
Base._reverse(A::UnitLowerTriangular, ::Colon) = UnitUpperTriangular(reverse(A.data))
333+
320334
## structured matrix methods ##
321335
function Base.replace_in_print_matrix(A::Union{UpperTriangular,UnitUpperTriangular},
322336
i::Integer, j::Integer, s::AbstractString)

0 commit comments

Comments
 (0)