Skip to content

Commit 3ed7386

Browse files
committed
Deprecate ConjRowVector/RowVector in favor of Adjoint/Transpose.
1 parent 7c8068f commit 3ed7386

File tree

8 files changed

+283
-573
lines changed

8 files changed

+283
-573
lines changed

base/deprecated.jl

+276-6
Original file line numberDiff line numberDiff line change
@@ -2219,12 +2219,6 @@ end
22192219
@deprecate chol!(x::Number, uplo) chol(x) false
22202220
end
22212221

2222-
# deprecate RowVector{T}(shape...) constructors to RowVector{T}(uninitialized, shape...) equivalents
2223-
@deprecate RowVector{T}(n::Int) where {T} RowVector{T}(uninitialized, n)
2224-
@deprecate RowVector{T}(n1::Int, n2::Int) where {T} RowVector{T}(uninitialized, n1, n2)
2225-
@deprecate RowVector{T}(n::Tuple{Int}) where {T} RowVector{T}(uninitialized, n)
2226-
@deprecate RowVector{T}(n::Tuple{Int,Int}) where {T} RowVector{T}(uninitialized, n)
2227-
22282222
@deprecate cumsum(A::AbstractArray) cumsum(A, 1)
22292223
@deprecate cumprod(A::AbstractArray) cumprod(A, 1)
22302224

@@ -2309,6 +2303,282 @@ end
23092303
export ConjArray
23102304
end
23112305

2306+
# deprecate ConjRowVector/RowVector
2307+
# TODO: between 0.7 and 1.0 remove
2308+
# 1) the type definitions in base/linalg/rowvector.jl
2309+
# 2) the include("base/linalg/rowvector.jl") from base/linalg/linalg.jl
2310+
# 3) the file base/linalg/rowvector.jl itself
2311+
# 4) the RowVectors in the Unions in base/sparse/sparsevector.jl around lines 995, 1010, 1011, and 1012
2312+
@eval Base.LinAlg begin
2313+
export RowVector
2314+
2315+
_RowVector_depstring() = string("`ConjRowVector` and `RowVector` have been deprecated in favor ",
2316+
"of `Adjoint` and `Transpose`. Please see 0.7's NEWS.md for a more detailed explanation ",
2317+
"of the associated changes.")
2318+
2319+
@inline check_types(::Type{T1}, ::AbstractVector{T2}) where {T1,T2} = check_types(T1, T2)
2320+
@pure check_types(::Type{T1}, ::Type{T2}) where {T1,T2} = T1 === transpose_type(T2) ? nothing :
2321+
error("Element type mismatch. Tried to create a `RowVector{$T1}` from an `AbstractVector{$T2}`")
2322+
2323+
# The element type may be transformed as transpose is recursive
2324+
@inline transpose_type(::Type{T}) where {T} = promote_op(transpose, T)
2325+
2326+
# Constructors that take a vector
2327+
function RowVector(vec::AbstractVector{T}) where {T}
2328+
Base.depwarn(_RowVector_depstring(), :RowVector)
2329+
return RowVector{transpose_type(T),typeof(vec)}(vec)
2330+
end
2331+
function RowVector{T}(vec::AbstractVector{T}) where {T}
2332+
Base.depwarn(_RowVector_depstring(), :RowVector)
2333+
return RowVector{T,typeof(vec)}(vec)
2334+
end
2335+
2336+
# Constructors that take a size and default to Array
2337+
function RowVector{T}(::Uninitialized, n::Int) where {T}
2338+
Base.depwarn(_RowVector_depstring(), :RowVector)
2339+
return RowVector{T}(Vector{transpose_type(T)}(uninitialized, n))
2340+
end
2341+
function RowVector{T}(::Uninitialized, n1::Int, n2::Int) where {T}
2342+
Base.depwarn(_RowVector_depstring(), :RowVector)
2343+
return n1 == 1 ? RowVector{T}(Vector{transpose_type(T)}(uninitialized, n2)) :
2344+
error("RowVector expects 1×N size, got ($n1,$n2)")
2345+
end
2346+
function RowVector{T}(::Uninitialized, n::Tuple{Int}) where {T}
2347+
Base.depwarn(_RowVector_depstring(), :RowVector)
2348+
return RowVector{T}(Vector{transpose_type(T)}(uninitialized, n[1]))
2349+
end
2350+
function RowVector{T}(::Uninitialized, n::Tuple{Int,Int}) where {T}
2351+
Base.depwarn(_RowVector_depstring(), :RowVector)
2352+
return n[1] == 1 ? RowVector{T}(Vector{transpose_type(T)}(uninitialized, n[2])) :
2353+
error("RowVector expects 1×N size, got $n")
2354+
end
2355+
2356+
# Conversion of underlying storage
2357+
convert(::Type{RowVector{T,V}}, rowvec::RowVector) where {T,V<:AbstractVector} =
2358+
RowVector{T,V}(convert(V,rowvec.vec))
2359+
2360+
# similar tries to maintain the RowVector wrapper and the parent type
2361+
@inline similar(rowvec::RowVector) = RowVector(similar(parent(rowvec)))
2362+
@inline similar(rowvec::RowVector, ::Type{T}) where {T} = RowVector(similar(parent(rowvec), transpose_type(T)))
2363+
2364+
# Resizing similar currently loses its RowVector property.
2365+
@inline similar(rowvec::RowVector, ::Type{T}, dims::Dims{N}) where {T,N} = similar(parent(rowvec), T, dims)
2366+
2367+
# Basic methods
2368+
2369+
# replaced in the Adjoint/Transpose transition
2370+
# """
2371+
# transpose(v::AbstractVector)
2372+
#
2373+
# The transposition operator (`.'`).
2374+
#
2375+
# # Examples
2376+
# ```jldoctest
2377+
# julia> v = [1,2,3]
2378+
# 3-element Array{Int64,1}:
2379+
# 1
2380+
# 2
2381+
# 3
2382+
#
2383+
# julia> transpose(v)
2384+
# 1×3 RowVector{Int64,Array{Int64,1}}:
2385+
# 1 2 3
2386+
# ```
2387+
# """
2388+
# @inline transpose(vec::AbstractVector) = RowVector(vec)
2389+
# @inline adjoint(vec::AbstractVector) = RowVector(_conj(vec))
2390+
2391+
# methods necessary to preserve RowVector's behavior through the Adjoint/Transpose transition
2392+
rvadjoint(v::AbstractVector) = RowVector(_conj(v))
2393+
rvtranspose(v::AbstractVector) = RowVector(v)
2394+
rvadjoint(v::RowVector) = conj(v.vec)
2395+
rvadjoint(v::RowVector{<:Real}) = v.vec
2396+
rvtranspose(v::RowVector) = v.vec
2397+
rvtranspose(v::ConjRowVector) = copy(v.vec)
2398+
rvadjoint(x) = adjoint(x)
2399+
rvtranspose(x) = transpose(x)
2400+
2401+
@inline transpose(rowvec::RowVector) = rowvec.vec
2402+
@inline transpose(rowvec::ConjRowVector) = copy(rowvec.vec) # remove the ConjArray wrapper from any raw vector
2403+
@inline adjoint(rowvec::RowVector) = conj(rowvec.vec)
2404+
@inline adjoint(rowvec::RowVector{<:Real}) = rowvec.vec
2405+
2406+
parent(rowvec::RowVector) = rowvec.vec
2407+
vec(rowvec::RowVector) = rowvec.vec
2408+
2409+
"""
2410+
conj(v::RowVector)
2411+
2412+
Return a [`ConjArray`](@ref) lazy view of the input, where each element is conjugated.
2413+
2414+
# Examples
2415+
```jldoctest
2416+
julia> v = RowVector([1+im, 1-im])
2417+
1×2 RowVector{Complex{Int64},Array{Complex{Int64},1}}:
2418+
1+1im 1-1im
2419+
2420+
julia> conj(v)
2421+
1×2 RowVector{Complex{Int64},ConjArray{Complex{Int64},1,Array{Complex{Int64},1}}}:
2422+
1-1im 1+1im
2423+
```
2424+
"""
2425+
@inline conj(rowvec::RowVector) = RowVector(_conj(rowvec.vec))
2426+
@inline conj(rowvec::RowVector{<:Real}) = rowvec
2427+
2428+
# AbstractArray interface
2429+
@inline length(rowvec::RowVector) = length(rowvec.vec)
2430+
@inline size(rowvec::RowVector) = (1, length(rowvec.vec))
2431+
@inline size(rowvec::RowVector, d) = ifelse(d==2, length(rowvec.vec), 1)
2432+
@inline axes(rowvec::RowVector) = (Base.OneTo(1), axes(rowvec.vec)[1])
2433+
@inline axes(rowvec::RowVector, d) = ifelse(d == 2, axes(rowvec.vec)[1], Base.OneTo(1))
2434+
IndexStyle(::RowVector) = IndexLinear()
2435+
IndexStyle(::Type{<:RowVector}) = IndexLinear()
2436+
2437+
@propagate_inbounds getindex(rowvec::RowVector, i::Int) = rvtranspose(rowvec.vec[i])
2438+
@propagate_inbounds setindex!(rowvec::RowVector, v, i::Int) = (setindex!(rowvec.vec, rvtranspose(v), i); rowvec)
2439+
2440+
# Keep a RowVector where appropriate
2441+
@propagate_inbounds getindex(rowvec::RowVector, ::Colon, i::Int) = rvtranspose.(rowvec.vec[i:i])
2442+
@propagate_inbounds getindex(rowvec::RowVector, ::Colon, inds::AbstractArray{Int}) = RowVector(rowvec.vec[inds])
2443+
@propagate_inbounds getindex(rowvec::RowVector, ::Colon, ::Colon) = RowVector(rowvec.vec[:])
2444+
2445+
# helper function for below
2446+
@inline to_vec(rowvec::RowVector) = map(rvtranspose, rvtranspose(rowvec))
2447+
@inline to_vec(x::Number) = x
2448+
@inline to_vecs(rowvecs...) = (map(to_vec, rowvecs)...,)
2449+
2450+
# map: Preserve the RowVector by un-wrapping and re-wrapping, but note that `f`
2451+
# expects to operate within the transposed domain, so to_vec transposes the elements
2452+
@inline map(f, rowvecs::RowVector...) = RowVector(map(rvtransposef, to_vecs(rowvecs...)...))
2453+
2454+
# broacast (other combinations default to higher-dimensional array)
2455+
@inline broadcast(f, rowvecs::Union{Number,RowVector}...) =
2456+
RowVector(broadcast(transposef, to_vecs(rowvecs...)...))
2457+
2458+
# Horizontal concatenation #
2459+
2460+
@inline hcat(X::RowVector...) = rvtranspose(vcat(map(rvtranspose, X)...))
2461+
@inline hcat(X::Union{RowVector,Number}...) = rvtranspose(vcat(map(rvtranspose, X)...))
2462+
2463+
@inline typed_hcat(::Type{T}, X::RowVector...) where {T} =
2464+
rvtranspose(typed_vcat(T, map(rvtranspose, X)...))
2465+
@inline typed_hcat(::Type{T}, X::Union{RowVector,Number}...) where {T} =
2466+
rvtranspose(typed_vcat(T, map(rvtranspose, X)...))
2467+
2468+
# Multiplication #
2469+
2470+
# inner product -> dot product specializations
2471+
@inline *(rowvec::RowVector{T}, vec::AbstractVector{T}) where {T<:Real} = dot(parent(rowvec), vec)
2472+
@inline *(rowvec::ConjRowVector{T}, vec::AbstractVector{T}) where {T<:Real} = dot(rvadjoint(rowvec), vec)
2473+
@inline *(rowvec::ConjRowVector, vec::AbstractVector) = dot(rvadjoint(rowvec), vec)
2474+
2475+
# Generic behavior
2476+
@inline function *(rowvec::RowVector, vec::AbstractVector)
2477+
if length(rowvec) != length(vec)
2478+
throw(DimensionMismatch("A has dimensions $(size(rowvec)) but B has dimensions $(size(vec))"))
2479+
end
2480+
sum(@inbounds(return rowvec[i]*vec[i]) for i = 1:length(vec))
2481+
end
2482+
@inline *(rowvec::RowVector, mat::AbstractMatrix) = rvtranspose(Transpose(mat) * rvtranspose(rowvec))
2483+
*(::RowVector, ::RowVector) = throw(DimensionMismatch("Cannot multiply two transposed vectors"))
2484+
@inline *(vec::AbstractVector, rowvec::RowVector) = vec .* rowvec
2485+
*(vec::AbstractVector, rowvec::AbstractVector) = throw(DimensionMismatch("Cannot multiply two vectors"))
2486+
2487+
# Transposed forms
2488+
*(::RowVector, ::Transpose{<:Any,<:AbstractVector}) =
2489+
throw(DimensionMismatch("Cannot multiply two transposed vectors"))
2490+
*(rowvec::RowVector, transmat::Transpose{<:Any,<:AbstractMatrix}) =
2491+
(mat = transmat.parent; rvtranspose(mat * rvtranspose(rowvec)))
2492+
*(rowvec1::RowVector, transrowvec2::Transpose{<:Any,<:RowVector}) =
2493+
(rowvec2 = transrowvec2.parent; rowvec1*rvtranspose(rowvec2))
2494+
*(::AbstractVector, ::Transpose{<:Any,<:RowVector}) =
2495+
throw(DimensionMismatch("Cannot multiply two vectors"))
2496+
*(mat::AbstractMatrix, transrowvec::Transpose{<:Any,<:RowVector}) =
2497+
(rowvec = transrowvec.parent; mat * rvtranspose(rowvec))
2498+
2499+
*(transrowvec::Transpose{<:Any,<:RowVector}, transvec::Transpose{<:Any,<:AbstractVector}) =
2500+
rvtranspose(transrowvec.parent) * transpose(transvec.parent)
2501+
*(transrowvec1::Transpose{<:Any,<:RowVector}, transrowvec2::Transpose{<:Any,<:RowVector}) =
2502+
throw(DimensionMismatch("Cannot multiply two vectors"))
2503+
*(transvec::Transpose{<:Any,<:AbstractVector}, transrowvec::Transpose{<:Any,<:RowVector}) =
2504+
transpose(transvec.parent)*rvtranspose(transrowvec.parent)
2505+
*(transmat::Transpose{<:Any,<:AbstractMatrix}, transrowvec::Transpose{<:Any,<:RowVector}) =
2506+
transmat * rvtranspose(transrowvec.parent)
2507+
2508+
*(::Transpose{<:Any,<:RowVector}, ::AbstractVector) =
2509+
throw(DimensionMismatch("Cannot multiply two vectors"))
2510+
*(transrowvec1::Transpose{<:Any,<:RowVector}, rowvec2::RowVector) =
2511+
rvtranspose(transrowvec1.parent) * rowvec2
2512+
*(transvec::Transpose{<:Any,<:AbstractVector}, rowvec::RowVector) =
2513+
throw(DimensionMismatch("Cannot multiply two transposed vectors"))
2514+
2515+
# Conjugated forms
2516+
*(::RowVector, ::Adjoint{<:Any,<:AbstractVector}) =
2517+
throw(DimensionMismatch("Cannot multiply two transposed vectors"))
2518+
*(rowvec::RowVector, adjmat::Adjoint{<:Any,<:AbstractMatrix}) =
2519+
rvadjoint(adjmat.parent * rvadjoint(rowvec))
2520+
*(rowvec1::RowVector, adjrowvec2::Adjoint{<:Any,<:RowVector}) =
2521+
rowvec1 * rvadjoint(adjrowvec2.parent)
2522+
*(vec::AbstractVector, adjrowvec::Adjoint{<:Any,<:RowVector}) =
2523+
throw(DimensionMismatch("Cannot multiply two vectors"))
2524+
*(mat::AbstractMatrix, adjrowvec::Adjoint{<:Any,<:RowVector}) =
2525+
mat * rvadjoint(adjrowvec.parent)
2526+
2527+
*(adjrowvec::Adjoint{<:Any,<:RowVector}, adjvec::Adjoint{<:Any,<:AbstractVector}) =
2528+
rvadjoint(adjrowvec.parent) * adjoint(adjvec.parent)
2529+
*(adjrowvec1::Adjoint{<:Any,<:RowVector}, adjrowvec2::Adjoint{<:Any,<:RowVector}) =
2530+
throw(DimensionMismatch("Cannot multiply two vectors"))
2531+
*(adjvec::Adjoint{<:Any,<:AbstractVector}, adjrowvec::Adjoint{<:Any,<:RowVector}) =
2532+
adjoint(adjvec.parent)*rvadjoint(adjrowvec.parent)
2533+
*(adjmat::Adjoint{<:Any,<:AbstractMatrix}, adjrowvec::Adjoint{<:Any,<:RowVector}) =
2534+
adjoint(adjmat.parent) * rvadjoint(adjrowvec.parent)
2535+
2536+
*(::Adjoint{<:Any,<:RowVector}, ::AbstractVector) = throw(DimensionMismatch("Cannot multiply two vectors"))
2537+
*(adjrowvec1::Adjoint{<:Any,<:RowVector}, rowvec2::RowVector) = rvadjoint(adjrowvec1.parent) * rowvec2
2538+
*(adjvec::Adjoint{<:Any,<:AbstractVector}, rowvec::RowVector) = throw(DimensionMismatch("Cannot multiply two transposed vectors"))
2539+
2540+
# Pseudo-inverse
2541+
pinv(v::RowVector, tol::Real=0) = rvadjoint(pinv(rvadjoint(v), tol))
2542+
2543+
# Left Division #
2544+
2545+
\(rowvec1::RowVector, rowvec2::RowVector) = pinv(rowvec1) * rowvec2
2546+
\(mat::AbstractMatrix, rowvec::RowVector) = throw(DimensionMismatch("Cannot left-divide transposed vector by matrix"))
2547+
\(transmat::Transpose{<:Any,<:AbstractMatrix}, rowvec::RowVector) =
2548+
throw(DimensionMismatch("Cannot left-divide transposed vector by matrix"))
2549+
\(adjmat::Adjoint{<:Any,<:AbstractMatrix}, rowvec::RowVector) =
2550+
throw(DimensionMismatch("Cannot left-divide transposed vector by matrix"))
2551+
2552+
# Right Division #
2553+
2554+
@inline /(rowvec::RowVector, mat::AbstractMatrix) = rvtranspose(transpose(mat) \ rvtranspose(rowvec))
2555+
/(rowvec::RowVector, transmat::Transpose{<:Any,<:AbstractMatrix}) = rvtranspose(transmat.parent \ rvtranspose(rowvec))
2556+
/(rowvec::RowVector, adjmat::Adjoint{<:Any,<:AbstractMatrix}) = rvadjoint(adjmat.parent \ rvadjoint(rowvec))
2557+
2558+
2559+
# definitions necessary for test/linalg/dense.jl to pass
2560+
# should be cleaned up / revised as necessary in the future
2561+
/(A::Number, B::Adjoint{<:Any,<:RowVector}) = /(A, rvadjoint(B.parent))
2562+
/(A::Matrix, B::RowVector) = rvadjoint(rvadjoint(B) \ adjoint(A))
2563+
2564+
2565+
# dismabiguation methods
2566+
*(A::Adjoint{<:Any,<:AbstractVector}, B::Transpose{<:Any,<:RowVector}) = adjoint(A.parent) * B
2567+
*(A::Adjoint{<:Any,<:AbstractMatrix}, B::Transpose{<:Any,<:RowVector}) = A * rvtranspose(B.parent)
2568+
*(A::Transpose{<:Any,<:AbstractVector}, B::Adjoint{<:Any,<:RowVector}) = transpose(A.parent) * B
2569+
*(A::Transpose{<:Any,<:AbstractMatrix}, B::Adjoint{<:Any,<:RowVector}) = A * rvadjoint(B.parent)
2570+
end
2571+
@eval Base begin
2572+
export RowVector
2573+
end
2574+
@eval Base.LinAlg begin
2575+
# deprecate RowVector{T}(shape...) constructors to RowVector{T}(uninitialized, shape...) equivalents
2576+
@deprecate RowVector{T}(n::Int) where {T} RowVector{T}(uninitialized, n)
2577+
@deprecate RowVector{T}(n1::Int, n2::Int) where {T} RowVector{T}(uninitialized, n1, n2)
2578+
@deprecate RowVector{T}(n::Tuple{Int}) where {T} RowVector{T}(uninitialized, n)
2579+
@deprecate RowVector{T}(n::Tuple{Int,Int}) where {T} RowVector{T}(uninitialized, n)
2580+
end
2581+
23122582
# A[ct]_(mul|ldiv|rdiv)_B[ct][!] methods from base/operators.jl, to deprecate
23132583
@deprecate Ac_ldiv_Bt(a,b) (\)(Adjoint(a), Transpose(b))
23142584
@deprecate At_ldiv_Bt(a,b) (\)(Transpose(a), Transpose(b))

base/exports.jl

-1
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,6 @@ export
9797
RoundUp,
9898
Adjoint,
9999
Transpose,
100-
RowVector,
101100
AbstractSerializer,
102101
SerializationState,
103102
Set,

base/linalg/linalg.jl

-1
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,6 @@ export
2828
# Types
2929
Adjoint,
3030
Transpose,
31-
RowVector,
3231
SymTridiagonal,
3332
Tridiagonal,
3433
Bidiagonal,

0 commit comments

Comments
 (0)