From 464bb63ca35d6714f593b3d333f55a81ab44470d Mon Sep 17 00:00:00 2001 From: Sacha Verweij Date: Sun, 17 Dec 2017 14:48:01 -0800 Subject: [PATCH] Make A' lower to postfixapostrophize(A) with default def = Adjoint(A) and clean up fallout. --- base/exports.jl | 1 + base/linalg/generic.jl | 9 ++++++--- base/operators.jl | 3 ++- src/julia-syntax.scm | 2 +- test/arrayops.jl | 2 +- test/show.jl | 2 +- 6 files changed, 12 insertions(+), 7 deletions(-) diff --git a/base/exports.jl b/base/exports.jl index f9b2d14c11db3..b0c84d0d0046b 100644 --- a/base/exports.jl +++ b/base/exports.jl @@ -248,6 +248,7 @@ export At_mul_Bt!, At_rdiv_B, At_rdiv_Bt, + postfixapostrophize, # scalar math @evalpoly, diff --git a/base/linalg/generic.jl b/base/linalg/generic.jl index 744dc0885a5cc..a14f2981146d8 100644 --- a/base/linalg/generic.jl +++ b/base/linalg/generic.jl @@ -816,15 +816,18 @@ function inv(A::AbstractMatrix{T}) where T ldiv!(factorize(convert(AbstractMatrix{S}, A)), dest) end -function pinv(v::AbstractVector{T}, tol::Real=real(zero(T))) where T - res = similar(v, typeof(zero(T) / (abs2(one(T)) + abs2(one(T)))))' +pinv(v::AbstractVector{T}, tol::Real = real(zero(T))) where {T<:Real} = _vectorpinv(Transpose, v, tol) +pinv(v::AbstractVector{T}, tol::Real = real(zero(T))) where {T<:Complex} = _vectorpinv(Adjoint, v, tol) +pinv(v::AbstractVector{T}, tol::Real = real(zero(T))) where {T} = _vectorpinv(Adjoint, v, tol) +function _vectorpinv(dualfn::Tf, v::AbstractVector{Tv}, tol) where {Tv,Tf} + res = dualfn(similar(v, typeof(zero(Tv) / (abs2(one(Tv)) + abs2(one(Tv)))))) den = sum(abs2, v) # as tol is the threshold relative to the maximum singular value, for a vector with # single singular value σ=√den, σ ≦ tol*σ is equivalent to den=0 ∨ tol≥1 if iszero(den) || tol >= one(tol) fill!(res, zero(eltype(res))) else - res .= v' ./ den + res .= dualfn(v) ./ den end return res end diff --git a/base/operators.jl b/base/operators.jl index 0d0f70e410eee..5967f45f2d9a2 100644 --- a/base/operators.jl +++ b/base/operators.jl @@ -739,7 +739,8 @@ fldmod1(x::T, y::T) where {T<:Real} = (fld1(x,y), mod1(x,y)) # efficient version for integers fldmod1(x::T, y::T) where {T<:Integer} = (fld1(x,y), mod1(x,y)) -# transpose +# postfix apostophre +postfixapostrophize(x) = Adjoint(x) """ adjoint(A) diff --git a/src/julia-syntax.scm b/src/julia-syntax.scm index ba58b7915dcee..bf1aa50dc83f8 100644 --- a/src/julia-syntax.scm +++ b/src/julia-syntax.scm @@ -2396,7 +2396,7 @@ ,.(apply append rows))) `(call (top typed_vcat) ,t ,@a))))) - '|'| (lambda (e) (expand-forms `(call adjoint ,(cadr e)))) + '|'| (lambda (e) (expand-forms `(call postfixapostrophize ,(cadr e)))) '|.'| (lambda (e) (begin (deprecation-message (string "The syntax `.'` for transposition is deprecated, " "and the special lowering of `.'` in multiplication " "(`*`), left-division (`\\`), and right-division (`/`) " diff --git a/test/arrayops.jl b/test/arrayops.jl index 6a90094e6894f..3d2edc4127869 100644 --- a/test/arrayops.jl +++ b/test/arrayops.jl @@ -2048,7 +2048,7 @@ end # module AutoRetType @test isa(cat((1,2), densearray, densearray), Array) end @test isa([[1,2,3]'; [1,2,3]'], Matrix{Int}) - @test isa([[1,2,3]' [1,2,3]'], Transpose{Int, Vector{Int}}) + @test isa([[1,2,3]' [1,2,3]'], Adjoint{Int, Vector{Int}}) @test isa([Any[1.0, 2]'; Any[2.0, 2]'], Matrix{Any}) @test isa([Any[1.0, 2]' Any[2.0, 2]'], Adjoint{Any, Vector{Any}}) # Test that concatenations of heterogeneous Matrix-Vector pairs yield dense matrices diff --git a/test/show.jl b/test/show.jl index 228e7e0c5bf05..3219e6c919e5e 100644 --- a/test/show.jl +++ b/test/show.jl @@ -557,7 +557,7 @@ end @test replstr(Matrix(1.0I, 10, 10)) == "10×10 Array{Float64,2}:\n 1.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0\n 0.0 1.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0\n 0.0 0.0 1.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0\n 0.0 0.0 0.0 1.0 0.0 0.0 0.0 0.0 0.0 0.0\n 0.0 0.0 0.0 0.0 1.0 0.0 0.0 0.0 0.0 0.0\n 0.0 0.0 0.0 0.0 0.0 1.0 0.0 0.0 0.0 0.0\n 0.0 0.0 0.0 0.0 0.0 0.0 1.0 0.0 0.0 0.0\n 0.0 0.0 0.0 0.0 0.0 0.0 0.0 1.0 0.0 0.0\n 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 1.0 0.0\n 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 1.0" # an array too long vertically to fit on screen, and too long horizontally: @test replstr(collect(1.:100.)) == "100-element Array{Float64,1}:\n 1.0\n 2.0\n 3.0\n 4.0\n 5.0\n 6.0\n 7.0\n 8.0\n 9.0\n 10.0\n ⋮ \n 92.0\n 93.0\n 94.0\n 95.0\n 96.0\n 97.0\n 98.0\n 99.0\n 100.0" -@test replstr(collect(1.:100.)') == "1×100 Transpose{Float64,Array{Float64,1}}:\n 1.0 2.0 3.0 4.0 5.0 6.0 7.0 … 95.0 96.0 97.0 98.0 99.0 100.0" +@test replstr(collect(1.:100.)') == "1×100 Adjoint{Float64,Array{Float64,1}}:\n 1.0 2.0 3.0 4.0 5.0 6.0 7.0 … 95.0 96.0 97.0 98.0 99.0 100.0" # too big in both directions to fit on screen: @test replstr((1.:100.)*(1:100)') == "100×100 Array{Float64,2}:\n 1.0 2.0 3.0 4.0 5.0 6.0 … 97.0 98.0 99.0 100.0\n 2.0 4.0 6.0 8.0 10.0 12.0 194.0 196.0 198.0 200.0\n 3.0 6.0 9.0 12.0 15.0 18.0 291.0 294.0 297.0 300.0\n 4.0 8.0 12.0 16.0 20.0 24.0 388.0 392.0 396.0 400.0\n 5.0 10.0 15.0 20.0 25.0 30.0 485.0 490.0 495.0 500.0\n 6.0 12.0 18.0 24.0 30.0 36.0 … 582.0 588.0 594.0 600.0\n 7.0 14.0 21.0 28.0 35.0 42.0 679.0 686.0 693.0 700.0\n 8.0 16.0 24.0 32.0 40.0 48.0 776.0 784.0 792.0 800.0\n 9.0 18.0 27.0 36.0 45.0 54.0 873.0 882.0 891.0 900.0\n 10.0 20.0 30.0 40.0 50.0 60.0 970.0 980.0 990.0 1000.0\n ⋮ ⋮ ⋱ \n 92.0 184.0 276.0 368.0 460.0 552.0 8924.0 9016.0 9108.0 9200.0\n 93.0 186.0 279.0 372.0 465.0 558.0 9021.0 9114.0 9207.0 9300.0\n 94.0 188.0 282.0 376.0 470.0 564.0 9118.0 9212.0 9306.0 9400.0\n 95.0 190.0 285.0 380.0 475.0 570.0 9215.0 9310.0 9405.0 9500.0\n 96.0 192.0 288.0 384.0 480.0 576.0 … 9312.0 9408.0 9504.0 9600.0\n 97.0 194.0 291.0 388.0 485.0 582.0 9409.0 9506.0 9603.0 9700.0\n 98.0 196.0 294.0 392.0 490.0 588.0 9506.0 9604.0 9702.0 9800.0\n 99.0 198.0 297.0 396.0 495.0 594.0 9603.0 9702.0 9801.0 9900.0\n 100.0 200.0 300.0 400.0 500.0 600.0 9700.0 9800.0 9900.0 10000.0"