From c6d0759285820d9e2c21a9b87aa9c0f5cf0548da Mon Sep 17 00:00:00 2001 From: Andreas Noack Date: Wed, 13 May 2015 09:11:40 -0400 Subject: [PATCH] Fix #11256 and fix the tests that should have caught this. Dividing unit triangular matrix gave wrong result. --- base/linalg/triangular.jl | 110 +++++++++++++++----------------------- test/linalg/triangular.jl | 8 +-- 2 files changed, 48 insertions(+), 70 deletions(-) diff --git a/base/linalg/triangular.jl b/base/linalg/triangular.jl index a03815b2d32ab..81a97c01dbdbc 100644 --- a/base/linalg/triangular.jl +++ b/base/linalg/triangular.jl @@ -265,73 +265,51 @@ eigvecs{T<:BlasFloat,S<:StridedMatrix}(A::UnitLowerTriangular{T,S}) = (for i = 1 # Generic routines # #################### -(*)(A::UpperTriangular, x::Number) = UpperTriangular(A.data*x) -(*)(A::LowerTriangular, x::Number) = LowerTriangular(A.data*x) -function (*)(A::UnitUpperTriangular, x::Number) - B = A.data*x - for i = 1:size(A, 1) - B[i,i] = x - end - UpperTriangular(B) -end -function (*)(A::UnitLowerTriangular, x::Number) - B = A.data*x - for i = 1:size(A, 1) - B[i,i] = x - end - LowerTriangular(B) -end -(*)(x::Number, A::UpperTriangular) = UpperTriangular(x*A.data) -(*)(x::Number, A::LowerTriangular) = LowerTriangular(x*A.data) -function (*)(x::Number, A::UnitUpperTriangular) - B = x*A.data - for i = 1:size(A, 1) - B[i,i] = x - end - UpperTriangular(B) -end -function (*)(x::Number, A::UnitLowerTriangular) - B = x*A.data - for i = 1:size(A, 1) - B[i,i] = x - end - LowerTriangular(B) -end -(/)(A::UpperTriangular, x::Number) = UpperTriangular(A.data/x) -(/)(A::LowerTriangular, x::Number) = LowerTriangular(A.data/x) -function (/)(A::UnitUpperTriangular, x::Number) - B = A.data*x - invx = inv(x) - for i = 1:size(A, 1) - B[i,i] = x - end - UpperTriangular(B) -end -function (/)(A::UnitLowerTriangular, x::Number) - B = A.data*x - invx = inv(x) - for i = 1:size(A, 1) - B[i,i] = x - end - LowerTriangular(B) -end -(\)(x::Number, A::UpperTriangular) = UpperTriangular(x\A.data) -(\)(x::Number, A::LowerTriangular) = LowerTriangular(x\A.data) -function (\)(x::Number, A::UnitUpperTriangular) - B = x\A.data - invx = inv(x) - for i = 1:size(A, 1) - B[i,i] = invx - end - UpperTriangular(B) -end -function (\)(x::Number, A::UnitLowerTriangular) - B = x\A.data - invx = inv(x) - for i = 1:size(A, 1) - B[i,i] = invx +for (t, unitt) in ((UpperTriangular, UnitUpperTriangular), + (LowerTriangular, UnitLowerTriangular)) + @eval begin + (*)(A::$t, x::Number) = $t(A.data*x) + + function (*)(A::$unitt, x::Number) + B = A.data*x + for i = 1:size(A, 1) + B[i,i] = x + end + $t(B) + end + + (*)(x::Number, A::$t) = $t(x*A.data) + + function (*)(x::Number, A::$unitt) + B = x*A.data + for i = 1:size(A, 1) + B[i,i] = x + end + $t(B) + end + + (/)(A::$t, x::Number) = $t(A.data/x) + + function (/)(A::$unitt, x::Number) + B = A.data/x + invx = inv(x) + for i = 1:size(A, 1) + B[i,i] = invx + end + $t(B) + end + + (\)(x::Number, A::$t) = $t(x\A.data) + + function (\)(x::Number, A::$unitt) + B = x\A.data + invx = inv(x) + for i = 1:size(A, 1) + B[i,i] = invx + end + $t(B) + end end - LowerTriangular(B) end ## Generic triangular multiplication diff --git a/test/linalg/triangular.jl b/test/linalg/triangular.jl index 6ebcd17094741..6570ec80e5f1c 100644 --- a/test/linalg/triangular.jl +++ b/test/linalg/triangular.jl @@ -98,10 +98,10 @@ for elty1 in (Float32, Float64, Complex64, Complex128, BigFloat, Int) @test full(-A1) == -full(A1) # Binary operations - @test A1*0.5 == full(A1*0.5) - @test 0.5*A1 == full(0.5*A1) - @test A1/0.5 == full(A1/0.5) - @test 0.5\A1 == full(0.5\A1) + @test A1*0.5 == full(A1)*0.5 + @test 0.5*A1 == 0.5*full(A1) + @test A1/0.5 == full(A1)/0.5 + @test 0.5\A1 == 0.5\full(A1) # inversion @test_approx_eq inv(A1) inv(lufact(full(A1)))