diff --git a/base/linalg/triangular.jl b/base/linalg/triangular.jl index b7dd6639d7205..30110711cd6d7 100644 --- a/base/linalg/triangular.jl +++ b/base/linalg/triangular.jl @@ -1291,40 +1291,6 @@ function A_rdiv_Bt!(A::StridedMatrix, B::UnitLowerTriangular) A end -for f in (:A_mul_B!, :A_ldiv_B!) - @eval begin - # Upper - $f(A::UpperTriangular, B::UpperTriangular) = - UpperTriangular($f(A, triu!(B.data))) - $f(A::UnitUpperTriangular, B::UpperTriangular) = - UpperTriangular($f(A, triu!(B.data))) - $f(A::UpperTriangular, B::UnitUpperTriangular) = - UpperTriangular($f(triu!(A.data), B)) - function $f(A::UnitUpperTriangular, B::UnitUpperTriangular) - BB = triu!(B.data) - for i = 1:size(BB, 1) - BB[i,i] = 1 - end - return UnitUpperTriangular($f(A, BB)) - end - - # Lower - $f(A::LowerTriangular, B::LowerTriangular) = - LowerTriangular($f(A, tril!(B.data))) - $f(A::UnitLowerTriangular, B::LowerTriangular) = - LowerTriangular($f(A, tril!(B.data))) - $f(A::LowerTriangular, B::UnitLowerTriangular) = - LowerTriangular($f(tril!(A), B)) - function $f(A::UnitLowerTriangular, B::UnitLowerTriangular) - BB = tril!(B.data) - for i = 1:size(BB, 1) - BB[i,i] = 1 - end - UnitLowerTriangular($f(A, BB)) - end - end -end - for f in (:Ac_mul_B!, :At_mul_B!, :Ac_ldiv_B!, :At_ldiv_B!) @eval begin $f(A::Union{LowerTriangular,UnitLowerTriangular}, B::UpperTriangular) = @@ -1363,25 +1329,33 @@ for (f1, f2) in ((:*, :A_mul_B!), (:\, :A_ldiv_B!)) function ($f1)(A::LowerTriangular, B::LowerTriangular) TAB = typeof(($f1)(zero(eltype(A)), zero(eltype(B))) + ($f1)(zero(eltype(A)), zero(eltype(B)))) - return LowerTriangular($f2(convert(AbstractMatrix{TAB}, A), copy_oftype(B, TAB))) + BB = similar(B, TAB, size(B)) + copy!(BB, B) + return LowerTriangular($f2(convert(AbstractMatrix{TAB}, A), BB)) end function $(f1)(A::UnitLowerTriangular, B::LowerTriangular) TAB = typeof((*)(zero(eltype(A)), zero(eltype(B))) + (*)(zero(eltype(A)), zero(eltype(B)))) - return LowerTriangular($f2(convert(AbstractMatrix{TAB}, A), copy_oftype(B, TAB))) + BB = similar(B, TAB, size(B)) + copy!(BB, B) + return LowerTriangular($f2(convert(AbstractMatrix{TAB}, A), BB)) end function ($f1)(A::UpperTriangular, B::UpperTriangular) TAB = typeof(($f1)(zero(eltype(A)), zero(eltype(B))) + ($f1)(zero(eltype(A)), zero(eltype(B)))) - return UpperTriangular($f2(convert(AbstractMatrix{TAB}, A), copy_oftype(B, TAB))) + BB = similar(B, TAB, size(B)) + copy!(BB, B) + return UpperTriangular($f2(convert(AbstractMatrix{TAB}, A), BB)) end function ($f1)(A::UnitUpperTriangular, B::UpperTriangular) TAB = typeof((*)(zero(eltype(A)), zero(eltype(B))) + (*)(zero(eltype(A)), zero(eltype(B)))) - return UpperTriangular($f2(convert(AbstractMatrix{TAB}, A), copy_oftype(B, TAB))) + BB = similar(B, TAB, size(B)) + copy!(BB, B) + return UpperTriangular($f2(convert(AbstractMatrix{TAB}, A), BB)) end end end @@ -1392,25 +1366,33 @@ for (f1, f2) in ((:Ac_mul_B, :Ac_mul_B!), (:At_mul_B, :At_mul_B!), function ($f1)(A::UpperTriangular, B::LowerTriangular) TAB = typeof(($f1)(zero(eltype(A)), zero(eltype(B))) + ($f1)(zero(eltype(A)), zero(eltype(B)))) - return LowerTriangular($f2(convert(AbstractMatrix{TAB}, A), copy_oftype(B, TAB))) + BB = similar(B, TAB, size(B)) + copy!(BB, B) + return LowerTriangular($f2(convert(AbstractMatrix{TAB}, A), BB)) end function ($f1)(A::UnitUpperTriangular, B::LowerTriangular) TAB = typeof((*)(zero(eltype(A)), zero(eltype(B))) + (*)(zero(eltype(A)), zero(eltype(B)))) - return LowerTriangular($f2(convert(AbstractMatrix{TAB}, A), copy_oftype(B, TAB))) + BB = similar(B, TAB, size(B)) + copy!(BB, B) + return LowerTriangular($f2(convert(AbstractMatrix{TAB}, A), BB)) end function ($f1)(A::LowerTriangular, B::UpperTriangular) TAB = typeof(($f1)(zero(eltype(A)), zero(eltype(B))) + ($f1)(zero(eltype(A)), zero(eltype(B)))) - return UpperTriangular($f2(convert(AbstractMatrix{TAB}, A), copy_oftype(B, TAB))) + BB = similar(B, TAB, size(B)) + copy!(BB, B) + return UpperTriangular($f2(convert(AbstractMatrix{TAB}, A), BB)) end function ($f1)(A::UnitLowerTriangular, B::UpperTriangular) TAB = typeof((*)(zero(eltype(A)), zero(eltype(B))) + (*)(zero(eltype(A)), zero(eltype(B)))) - return UpperTriangular($f2(convert(AbstractMatrix{TAB}, A), copy_oftype(B, TAB))) + BB = similar(B, TAB, size(B)) + copy!(BB, B) + return UpperTriangular($f2(convert(AbstractMatrix{TAB}, A), BB)) end end end @@ -1418,22 +1400,30 @@ end function (/)(A::LowerTriangular, B::LowerTriangular) TAB = typeof((/)(zero(eltype(A)), zero(eltype(B))) + (/)(zero(eltype(A)), zero(eltype(B)))) - return LowerTriangular(A_rdiv_B!(copy_oftype(A, TAB), convert(AbstractMatrix{TAB}, B))) + AA = similar(A, TAB, size(A)) + copy!(AA, A) + return LowerTriangular(A_rdiv_B!(AA, convert(AbstractMatrix{TAB}, B))) end function (/)(A::LowerTriangular, B::UnitLowerTriangular) TAB = typeof((*)(zero(eltype(A)), zero(eltype(B))) + (*)(zero(eltype(A)), zero(eltype(B)))) - return LowerTriangular(A_rdiv_B!(copy_oftype(A, TAB), convert(AbstractMatrix{TAB}, B))) + AA = similar(A, TAB, size(A)) + copy!(AA, A) + return LowerTriangular(A_rdiv_B!(AA, convert(AbstractMatrix{TAB}, B))) end function (/)(A::UpperTriangular, B::UpperTriangular) TAB = typeof((/)(zero(eltype(A)), zero(eltype(B))) + (/)(zero(eltype(A)), zero(eltype(B)))) - return UpperTriangular(A_rdiv_B!(copy_oftype(A, TAB), convert(AbstractMatrix{TAB}, B))) + AA = similar(A, TAB, size(A)) + copy!(AA, A) + return UpperTriangular(A_rdiv_B!(AA, convert(AbstractMatrix{TAB}, B))) end function (/)(A::UpperTriangular, B::UnitUpperTriangular) TAB = typeof((*)(zero(eltype(A)), zero(eltype(B))) + (*)(zero(eltype(A)), zero(eltype(B)))) - return UpperTriangular(A_rdiv_B!(copy_oftype(A, TAB), convert(AbstractMatrix{TAB}, B))) + AA = similar(A, TAB, size(A)) + copy!(AA, A) + return UpperTriangular(A_rdiv_B!(AA, convert(AbstractMatrix{TAB}, B))) end for (f1, f2) in ((:A_mul_Bc, :A_mul_Bc!), (:A_mul_Bt, :A_mul_Bt!), @@ -1442,25 +1432,33 @@ for (f1, f2) in ((:A_mul_Bc, :A_mul_Bc!), (:A_mul_Bt, :A_mul_Bt!), function $f1(A::LowerTriangular, B::UpperTriangular) TAB = typeof(($f1)(zero(eltype(A)), zero(eltype(B))) + ($f1)(zero(eltype(A)), zero(eltype(B)))) - return LowerTriangular($f2(copy_oftype(A, TAB), convert(AbstractMatrix{TAB}, B))) + AA = similar(A, TAB, size(A)) + copy!(AA, A) + return LowerTriangular($f2(AA, convert(AbstractMatrix{TAB}, B))) end function $f1(A::LowerTriangular, B::UnitUpperTriangular) TAB = typeof((*)(zero(eltype(A)), zero(eltype(B))) + (*)(zero(eltype(A)), zero(eltype(B)))) - return LowerTriangular($f2(copy_oftype(A, TAB), convert(AbstractMatrix{TAB}, B))) + AA = similar(A, TAB, size(A)) + copy!(AA, A) + return LowerTriangular($f2(AA, convert(AbstractMatrix{TAB}, B))) end function $f1(A::UpperTriangular, B::LowerTriangular) TAB = typeof(($f1)(zero(eltype(A)), zero(eltype(B))) + ($f1)(zero(eltype(A)), zero(eltype(B)))) - return UpperTriangular($f2(copy_oftype(A, TAB), convert(AbstractMatrix{TAB}, B))) + AA = similar(A, TAB, size(A)) + copy!(AA, A) + return UpperTriangular($f2(AA, convert(AbstractMatrix{TAB}, B))) end function $f1(A::UpperTriangular, B::UnitLowerTriangular) TAB = typeof((*)(zero(eltype(A)), zero(eltype(B))) + (*)(zero(eltype(A)), zero(eltype(B)))) - return UpperTriangular($f2(copy_oftype(A, TAB), convert(AbstractMatrix{TAB}, B))) + AA = similar(A, TAB, size(A)) + copy!(AA, A) + return UpperTriangular($f2(AA, convert(AbstractMatrix{TAB}, B))) end end end diff --git a/test/linalg/triangular.jl b/test/linalg/triangular.jl index 5218ff2074616..6f01fb1eff2d6 100644 --- a/test/linalg/triangular.jl +++ b/test/linalg/triangular.jl @@ -227,7 +227,7 @@ for elty1 in (Float32, Float64, BigFloat, Complex64, Complex128, Complex{BigFloa @test_approx_eq_eps det(A1) det(lufact(full(A1))) sqrt(eps(real(float(one(elty1)))))*n*n # Matrix square root - @test sqrtm(A1) |> t->t*t ≈ A1 + @test sqrtm(A1) |> t -> t*t ≈ A1 # naivesub errors @test_throws DimensionMismatch naivesub!(A1,ones(elty1,n+1))