Skip to content

Commit 0ef8a91

Browse files
authored
Preserve structure in scaling triangular matrices by NaN (#55310)
Addresses the `Matrix` cases from https://github.com/JuliaLang/julia/issues/55296. This restores the behavior to match that on v1.10, and preserves the structure of the matrix on scaling by `NaN`. This behavior is consistent with the strong-zero behavior for other structured matrix types, and the scaling may be seen to be occurring in the vector space corresponding to the filled elements. After this, ```julia julia> UpperTriangular(rand(2,2)) * NaN 2×2 UpperTriangular{Float64, Matrix{Float64}}: NaN NaN ⋅ NaN ``` cc. @mikmoore
1 parent 7c6a1a2 commit 0ef8a91

File tree

2 files changed

+71
-4
lines changed

2 files changed

+71
-4
lines changed

stdlib/LinearAlgebra/src/triangular.jl

+57-4
Original file line numberDiff line numberDiff line change
@@ -702,6 +702,43 @@ function _triscale!(A::LowerOrUnitLowerTriangular, c::Number, B::UnitLowerTriang
702702
return A
703703
end
704704

705+
function _trirdiv!(A::UpperTriangular, B::UpperOrUnitUpperTriangular, c::Number)
706+
n = checksize1(A, B)
707+
for j in 1:n
708+
for i in 1:j
709+
@inbounds A[i, j] = B[i, j] / c
710+
end
711+
end
712+
return A
713+
end
714+
function _trirdiv!(A::LowerTriangular, B::LowerOrUnitLowerTriangular, c::Number)
715+
n = checksize1(A, B)
716+
for j in 1:n
717+
for i in j:n
718+
@inbounds A[i, j] = B[i, j] / c
719+
end
720+
end
721+
return A
722+
end
723+
function _trildiv!(A::UpperTriangular, c::Number, B::UpperOrUnitUpperTriangular)
724+
n = checksize1(A, B)
725+
for j in 1:n
726+
for i in 1:j
727+
@inbounds A[i, j] = c \ B[i, j]
728+
end
729+
end
730+
return A
731+
end
732+
function _trildiv!(A::LowerTriangular, c::Number, B::LowerOrUnitLowerTriangular)
733+
n = checksize1(A, B)
734+
for j in 1:n
735+
for i in j:n
736+
@inbounds A[i, j] = c \ B[i, j]
737+
end
738+
end
739+
return A
740+
end
741+
705742
rmul!(A::UpperOrLowerTriangular, c::Number) = @inline _triscale!(A, A, c, MulAddMul())
706743
lmul!(c::Number, A::UpperOrLowerTriangular) = @inline _triscale!(A, c, A, MulAddMul())
707744

@@ -1095,7 +1132,11 @@ for (t, unitt) in ((UpperTriangular, UnitUpperTriangular),
10951132
tstrided = t{<:Any, <:StridedMaybeAdjOrTransMat}
10961133
@eval begin
10971134
(*)(A::$t, x::Number) = $t(A.data*x)
1098-
(*)(A::$tstrided, x::Number) = A .* x
1135+
function (*)(A::$tstrided, x::Number)
1136+
eltype_dest = promote_op(*, eltype(A), typeof(x))
1137+
dest = $t(similar(parent(A), eltype_dest))
1138+
_triscale!(dest, x, A, MulAddMul())
1139+
end
10991140

11001141
function (*)(A::$unitt, x::Number)
11011142
B = $t(A.data)*x
@@ -1106,7 +1147,11 @@ for (t, unitt) in ((UpperTriangular, UnitUpperTriangular),
11061147
end
11071148

11081149
(*)(x::Number, A::$t) = $t(x*A.data)
1109-
(*)(x::Number, A::$tstrided) = x .* A
1150+
function (*)(x::Number, A::$tstrided)
1151+
eltype_dest = promote_op(*, typeof(x), eltype(A))
1152+
dest = $t(similar(parent(A), eltype_dest))
1153+
_triscale!(dest, x, A, MulAddMul())
1154+
end
11101155

11111156
function (*)(x::Number, A::$unitt)
11121157
B = x*$t(A.data)
@@ -1117,7 +1162,11 @@ for (t, unitt) in ((UpperTriangular, UnitUpperTriangular),
11171162
end
11181163

11191164
(/)(A::$t, x::Number) = $t(A.data/x)
1120-
(/)(A::$tstrided, x::Number) = A ./ x
1165+
function (/)(A::$tstrided, x::Number)
1166+
eltype_dest = promote_op(/, eltype(A), typeof(x))
1167+
dest = $t(similar(parent(A), eltype_dest))
1168+
_trirdiv!(dest, A, x)
1169+
end
11211170

11221171
function (/)(A::$unitt, x::Number)
11231172
B = $t(A.data)/x
@@ -1129,7 +1178,11 @@ for (t, unitt) in ((UpperTriangular, UnitUpperTriangular),
11291178
end
11301179

11311180
(\)(x::Number, A::$t) = $t(x\A.data)
1132-
(\)(x::Number, A::$tstrided) = x .\ A
1181+
function (\)(x::Number, A::$tstrided)
1182+
eltype_dest = promote_op(\, typeof(x), eltype(A))
1183+
dest = $t(similar(parent(A), eltype_dest))
1184+
_trildiv!(dest, x, A)
1185+
end
11331186

11341187
function (\)(x::Number, A::$unitt)
11351188
B = x\$t(A.data)

stdlib/LinearAlgebra/test/triangular.jl

+14
Original file line numberDiff line numberDiff line change
@@ -1180,4 +1180,18 @@ end
11801180
@test V == Diagonal([1, 1])
11811181
end
11821182

1183+
@testset "preserve structure in scaling by NaN" begin
1184+
M = rand(Int8,2,2)
1185+
for (Ts, TD) in (((UpperTriangular, UnitUpperTriangular), UpperTriangular),
1186+
((LowerTriangular, UnitLowerTriangular), LowerTriangular))
1187+
for T in Ts
1188+
U = T(M)
1189+
for V in (U * NaN, NaN * U, U / NaN, NaN \ U)
1190+
@test V isa TD{Float64, Matrix{Float64}}
1191+
@test all(isnan, diag(V))
1192+
end
1193+
end
1194+
end
1195+
end
1196+
11831197
end # module TestTriangular

0 commit comments

Comments
 (0)