Skip to content

Commit aa3ee45

Browse files
committed
parametrize Bidiagonal on wrapped vector type
1 parent 80667ea commit aa3ee45

File tree

6 files changed

+74
-53
lines changed

6 files changed

+74
-53
lines changed

NEWS.md

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -73,8 +73,9 @@ This section lists changes that do not have deprecation warnings.
7373
longer present. Use `first(R)` and `last(R)` to obtain
7474
start/stop. ([#20974])
7575

76-
* The `Diagonal` type definition has changed from `Diagonal{T}` to
77-
`Diagonal{T,V<:AbstractVector{T}}` ([#22718]).
76+
* The `Diagonal` and `Bidiagonal` type definitions have changed from `Diagonal{T}` and
77+
`Bidiagonal{T}` to `Diagonal{T,V<:AbstractVector{T}}` and
78+
`Bidiagonal{T,V<:AbstractVector{T}}` respectively ([#22718], [#22925]).
7879

7980
* Spaces are no longer allowed between `@` and the name of a macro in a macro call ([#22868]).
8081

@@ -142,8 +143,9 @@ Library improvements
142143

143144
* `Char`s can now be concatenated with `String`s and/or other `Char`s using `*` ([#22532]).
144145

145-
* `Diagonal` is now parameterized on the type of the wrapped vector. This allows
146-
for `Diagonal` matrices with arbitrary `AbstractVector`s ([#22718]).
146+
* `Diagonal` and `Bidiagonal` are now parameterized on the type of the wrapped vectors,
147+
allowing `Diagonal` and `Bidiagonal` matrices with arbitrary
148+
`AbstractVector`s ([#22718], [#22925]).
147149

148150
* Mutating versions of `randperm` and `randcycle` have been added:
149151
`randperm!` and `randcycle!` ([#22723]).

base/deprecated.jl

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1601,6 +1601,15 @@ end
16011601
# issue #6466
16021602
# `write` on non-isbits arrays is deprecated in io.jl.
16031603

1604+
# PR #22925
1605+
# also uncomment constructor tests in test/linalg/bidiag.jl
1606+
function Bidiagonal(dv::AbstractVector{T}, ev::AbstractVector{S}, uplo::Symbol) where {T,S}
1607+
depwarn(string("Bidiagonal(dv::AbstractVector{T}, ev::AbstractVector{S}, uplo::Symbol) ",
1608+
"where {T,S} is deprecated; convert both vectors to the same type instead."), :Bidiagonal)
1609+
R = promote_type(T, S)
1610+
Bidiagonal(convert(Vector{R}, dv), convert(Vector{R}, ev), uplo)
1611+
end
1612+
16041613
# END 0.7 deprecations
16051614

16061615
# BEGIN 1.0 deprecations

base/linalg/bidiag.jl

Lines changed: 20 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,17 @@
11
# This file is a part of Julia. License is MIT: https://julialang.org/license
22

33
# Bidiagonal matrices
4-
struct Bidiagonal{T} <: AbstractMatrix{T}
5-
dv::Vector{T} # diagonal
6-
ev::Vector{T} # sub/super diagonal
7-
uplo::Char # upper bidiagonal ('U') or lower ('L')
8-
function Bidiagonal{T}(dv::Vector{T}, ev::Vector{T}, uplo::Char) where T
4+
struct Bidiagonal{T,V<:AbstractVector{T}} <: AbstractMatrix{T}
5+
dv::V # diagonal
6+
ev::V # sub/super diagonal
7+
uplo::Char # upper bidiagonal ('U') or lower ('L')
8+
function Bidiagonal{T}(dv::V, ev::V, uplo::Char) where {T,V<:AbstractVector{T}}
99
if length(ev) != length(dv)-1
1010
throw(DimensionMismatch("length of diagonal vector is $(length(dv)), length of off-diagonal vector is $(length(ev))"))
1111
end
12-
new(dv, ev, uplo)
12+
new{T,V}(dv, ev, uplo)
1313
end
14-
function Bidiagonal(dv::Vector{T}, ev::Vector{T}, uplo::Char) where T
14+
function Bidiagonal(dv::V, ev::V, uplo::Char) where {T,V<:AbstractVector{T}}
1515
Bidiagonal{T}(dv, ev, uplo)
1616
end
1717
end
@@ -41,27 +41,22 @@ julia> ev = [7, 8, 9]
4141
9
4242
4343
julia> Bu = Bidiagonal(dv, ev, :U) # ev is on the first superdiagonal
44-
4×4 Bidiagonal{Int64}:
44+
4×4 Bidiagonal{Int64,Array{Int64,1}}:
4545
1 7 ⋅ ⋅
4646
⋅ 2 8 ⋅
4747
⋅ ⋅ 3 9
4848
⋅ ⋅ ⋅ 4
4949
5050
julia> Bl = Bidiagonal(dv, ev, :L) # ev is on the first subdiagonal
51-
4×4 Bidiagonal{Int64}:
51+
4×4 Bidiagonal{Int64,Array{Int64,1}}:
5252
1 ⋅ ⋅ ⋅
5353
7 2 ⋅ ⋅
5454
⋅ 8 3 ⋅
5555
⋅ ⋅ 9 4
5656
```
5757
"""
58-
function Bidiagonal(dv::AbstractVector{T}, ev::AbstractVector{T}, uplo::Symbol) where T
59-
Bidiagonal{T}(collect(dv), collect(ev), char_uplo(uplo))
60-
end
61-
62-
function Bidiagonal(dv::AbstractVector{Td}, ev::AbstractVector{Te}, uplo::Symbol) where {Td,Te}
63-
T = promote_type(Td,Te)
64-
Bidiagonal(convert(Vector{T}, dv), convert(Vector{T}, ev), uplo)
58+
function Bidiagonal(dv::V, ev::V, uplo::Symbol) where {T,V<:AbstractVector{T}}
59+
Bidiagonal{T}(dv, ev, char_uplo(uplo))
6560
end
6661

6762
"""
@@ -79,22 +74,24 @@ julia> A = [1 1 1 1; 2 2 2 2; 3 3 3 3; 4 4 4 4]
7974
3 3 3 3
8075
4 4 4 4
8176
82-
julia> Bidiagonal(A, :U) #contains the main diagonal and first superdiagonal of A
83-
4×4 Bidiagonal{Int64}:
77+
julia> Bidiagonal(A, :U) # contains the main diagonal and first superdiagonal of A
78+
4×4 Bidiagonal{Int64,Array{Int64,1}}:
8479
1 1 ⋅ ⋅
8580
⋅ 2 2 ⋅
8681
⋅ ⋅ 3 3
8782
⋅ ⋅ ⋅ 4
8883
89-
julia> Bidiagonal(A, :L) #contains the main diagonal and first subdiagonal of A
90-
4×4 Bidiagonal{Int64}:
84+
julia> Bidiagonal(A, :L) # contains the main diagonal and first subdiagonal of A
85+
4×4 Bidiagonal{Int64,Array{Int64,1}}:
9186
1 ⋅ ⋅ ⋅
9287
2 2 ⋅ ⋅
9388
⋅ 3 3 ⋅
9489
⋅ ⋅ 4 4
9590
```
9691
"""
97-
Bidiagonal(A::AbstractMatrix, uplo::Symbol) = Bidiagonal(diag(A), diag(A, uplo == :U ? 1 : -1), uplo)
92+
function Bidiagonal(A::AbstractMatrix, uplo::Symbol)
93+
Bidiagonal(diag(A, 0), diag(A, uplo == :U ? 1 : -1), uplo)
94+
end
9895

9996
function getindex(A::Bidiagonal{T}, i::Integer, j::Integer) where T
10097
if !((1 <= i <= size(A,2)) && (1 <= j <= size(A,2)))
@@ -164,7 +161,8 @@ promote_rule(::Type{Tridiagonal{T}}, ::Type{Bidiagonal{S}}) where {T,S} = Tridia
164161
# No-op for trivial conversion Bidiagonal{T} -> Bidiagonal{T}
165162
convert(::Type{Bidiagonal{T}}, A::Bidiagonal{T}) where {T} = A
166163
# Convert Bidiagonal to Bidiagonal{T} by constructing a new instance with converted elements
167-
convert(::Type{Bidiagonal{T}}, A::Bidiagonal) where {T} = Bidiagonal(convert(Vector{T}, A.dv), convert(Vector{T}, A.ev), A.uplo)
164+
convert(::Type{Bidiagonal{T}}, A::Bidiagonal) where {T} =
165+
Bidiagonal(convert(AbstractVector{T}, A.dv), convert(AbstractVector{T}, A.ev), A.uplo)
168166
# When asked to convert Bidiagonal to AbstractMatrix{T}, preserve structure by converting to Bidiagonal{T} <: AbstractMatrix{T}
169167
convert(::Type{AbstractMatrix{T}}, A::Bidiagonal) where {T} = convert(Bidiagonal{T}, A)
170168

test/linalg/bidiag.jl

Lines changed: 36 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -24,10 +24,23 @@ srand(1)
2424
end
2525

2626
@testset "Constructors" begin
27-
@test Bidiagonal(dv,ev,:U) != Bidiagonal(dv,ev,:L)
28-
@test_throws ArgumentError Bidiagonal(dv,ev,:R)
29-
@test_throws DimensionMismatch Bidiagonal(dv,ones(elty,n),:U)
30-
@test_throws MethodError Bidiagonal(dv,ev)
27+
for (x, y) in ((dv, ev), (GenericArray(dv), GenericArray(ev)))
28+
# from vectors
29+
ubd = Bidiagonal(x, y, :U)
30+
lbd = Bidiagonal(x, y, :L)
31+
@test ubd != lbd
32+
@test ubd.dv === x
33+
@test lbd.ev === y
34+
@test_throws ArgumentError Bidiagonal(x, y, :R)
35+
@test_throws DimensionMismatch Bidiagonal(x, x, :U)
36+
@test_throws MethodError Bidiagonal(x, y)
37+
# from matrix
38+
@test Bidiagonal(ubd, :U) == Bidiagonal(Matrix(ubd), :U) == ubd
39+
@test Bidiagonal(lbd, :L) == Bidiagonal(Matrix(lbd), :L) == lbd
40+
end
41+
# enable when deprecations for 0.7 are dropped
42+
# @test_throws MethodError Bidiagonal(dv, GenericArray(ev), :U)
43+
# @test_throws MethodError Bidiagonal(GenericArray(dv), ev, :U)
3144
end
3245

3346
@testset "getindex, setindex!, size, and similar" begin
@@ -97,29 +110,30 @@ srand(1)
97110
end
98111

99112
@testset "triu and tril" begin
113+
bidiagcopy(dv, ev, uplo) = Bidiagonal(copy(dv), copy(ev), uplo)
100114
@test istril(Bidiagonal(dv,ev,:L))
101115
@test !istril(Bidiagonal(dv,ev,:U))
102-
@test tril!(Bidiagonal(dv,ev,:U),-1) == Bidiagonal(zeros(dv),zeros(ev),:U)
103-
@test tril!(Bidiagonal(dv,ev,:L),-1) == Bidiagonal(zeros(dv),ev,:L)
104-
@test tril!(Bidiagonal(dv,ev,:U),-2) == Bidiagonal(zeros(dv),zeros(ev),:U)
105-
@test tril!(Bidiagonal(dv,ev,:L),-2) == Bidiagonal(zeros(dv),zeros(ev),:L)
106-
@test tril!(Bidiagonal(dv,ev,:U),1) == Bidiagonal(dv,ev,:U)
107-
@test tril!(Bidiagonal(dv,ev,:L),1) == Bidiagonal(dv,ev,:L)
108-
@test tril!(Bidiagonal(dv,ev,:U)) == Bidiagonal(dv,zeros(ev),:U)
109-
@test tril!(Bidiagonal(dv,ev,:L)) == Bidiagonal(dv,ev,:L)
110-
@test_throws ArgumentError tril!(Bidiagonal(dv,ev,:U),n+1)
116+
@test tril!(bidiagcopy(dv,ev,:U),-1) == Bidiagonal(zeros(dv),zeros(ev),:U)
117+
@test tril!(bidiagcopy(dv,ev,:L),-1) == Bidiagonal(zeros(dv),ev,:L)
118+
@test tril!(bidiagcopy(dv,ev,:U),-2) == Bidiagonal(zeros(dv),zeros(ev),:U)
119+
@test tril!(bidiagcopy(dv,ev,:L),-2) == Bidiagonal(zeros(dv),zeros(ev),:L)
120+
@test tril!(bidiagcopy(dv,ev,:U),1) == Bidiagonal(dv,ev,:U)
121+
@test tril!(bidiagcopy(dv,ev,:L),1) == Bidiagonal(dv,ev,:L)
122+
@test tril!(bidiagcopy(dv,ev,:U)) == Bidiagonal(dv,zeros(ev),:U)
123+
@test tril!(bidiagcopy(dv,ev,:L)) == Bidiagonal(dv,ev,:L)
124+
@test_throws ArgumentError tril!(bidiagcopy(dv,ev,:U),n+1)
111125

112126
@test istriu(Bidiagonal(dv,ev,:U))
113127
@test !istriu(Bidiagonal(dv,ev,:L))
114-
@test triu!(Bidiagonal(dv,ev,:L),1) == Bidiagonal(zeros(dv),zeros(ev),:L)
115-
@test triu!(Bidiagonal(dv,ev,:U),1) == Bidiagonal(zeros(dv),ev,:U)
116-
@test triu!(Bidiagonal(dv,ev,:U),2) == Bidiagonal(zeros(dv),zeros(ev),:U)
117-
@test triu!(Bidiagonal(dv,ev,:L),2) == Bidiagonal(zeros(dv),zeros(ev),:L)
118-
@test triu!(Bidiagonal(dv,ev,:U),-1) == Bidiagonal(dv,ev,:U)
119-
@test triu!(Bidiagonal(dv,ev,:L),-1) == Bidiagonal(dv,ev,:L)
120-
@test triu!(Bidiagonal(dv,ev,:L)) == Bidiagonal(dv,zeros(ev),:L)
121-
@test triu!(Bidiagonal(dv,ev,:U)) == Bidiagonal(dv,ev,:U)
122-
@test_throws ArgumentError triu!(Bidiagonal(dv,ev,:U),n+1)
128+
@test triu!(bidiagcopy(dv,ev,:L),1) == Bidiagonal(zeros(dv),zeros(ev),:L)
129+
@test triu!(bidiagcopy(dv,ev,:U),1) == Bidiagonal(zeros(dv),ev,:U)
130+
@test triu!(bidiagcopy(dv,ev,:U),2) == Bidiagonal(zeros(dv),zeros(ev),:U)
131+
@test triu!(bidiagcopy(dv,ev,:L),2) == Bidiagonal(zeros(dv),zeros(ev),:L)
132+
@test triu!(bidiagcopy(dv,ev,:U),-1) == Bidiagonal(dv,ev,:U)
133+
@test triu!(bidiagcopy(dv,ev,:L),-1) == Bidiagonal(dv,ev,:L)
134+
@test triu!(bidiagcopy(dv,ev,:L)) == Bidiagonal(dv,zeros(ev),:L)
135+
@test triu!(bidiagcopy(dv,ev,:U)) == Bidiagonal(dv,ev,:U)
136+
@test_throws ArgumentError triu!(bidiagcopy(dv,ev,:U),n+1)
123137
end
124138

125139
Tfull = Array(T)
@@ -255,7 +269,6 @@ srand(1)
255269
end
256270
BD = Bidiagonal(dv, ev, :U)
257271
@test Matrix{Complex{Float64}}(BD) == BD
258-
259272
end
260273

261274
# Issue 10742 and similar

test/linalg/cholesky.jl

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -101,8 +101,7 @@ using Base.LinAlg: BlasComplex, BlasFloat, BlasReal, QRPivoted, PosDefException
101101

102102
# test chol of 2x2 Strang matrix
103103
S = convert(AbstractMatrix{eltya},full(SymTridiagonal([2,2],[-1])))
104-
U = Bidiagonal([2,sqrt(eltya(3))],[-1],:U) / sqrt(eltya(2))
105-
@test full(chol(S)) full(U)
104+
@test full(chol(S)) [2 -1; 0 sqrt(eltya(3))] / sqrt(eltya(2))
106105

107106
# test extraction of factor and re-creating original matrix
108107
if eltya <: Real

test/show.jl

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -556,8 +556,8 @@ end
556556
# test structured zero matrix printing for select structured types
557557
A = reshape(1:16,4,4)
558558
@test replstr(Diagonal(A)) == "4×4 Diagonal{$(Int),Array{$(Int),1}}:\n 1 ⋅ ⋅ ⋅\n ⋅ 6 ⋅ ⋅\n ⋅ ⋅ 11 ⋅\n ⋅ ⋅ ⋅ 16"
559-
@test replstr(Bidiagonal(A,:U)) == "4×4 Bidiagonal{$Int}:\n 1 5 ⋅ ⋅\n ⋅ 6 10 ⋅\n ⋅ ⋅ 11 15\n ⋅ ⋅ ⋅ 16"
560-
@test replstr(Bidiagonal(A,:L)) == "4×4 Bidiagonal{$Int}:\n 1 ⋅ ⋅ ⋅\n 2 6 ⋅ ⋅\n ⋅ 7 11 ⋅\n ⋅ ⋅ 12 16"
559+
@test replstr(Bidiagonal(A,:U)) == "4×4 Bidiagonal{$(Int),Array{$(Int),1}}:\n 1 5 ⋅ ⋅\n ⋅ 6 10 ⋅\n ⋅ ⋅ 11 15\n ⋅ ⋅ ⋅ 16"
560+
@test replstr(Bidiagonal(A,:L)) == "4×4 Bidiagonal{$(Int),Array{$(Int),1}}:\n 1 ⋅ ⋅ ⋅\n 2 6 ⋅ ⋅\n ⋅ 7 11 ⋅\n ⋅ ⋅ 12 16"
561561
@test replstr(SymTridiagonal(A+A')) == "4×4 SymTridiagonal{$Int}:\n 2 7 ⋅ ⋅\n 7 12 17 ⋅\n ⋅ 17 22 27\n ⋅ ⋅ 27 32"
562562
@test replstr(Tridiagonal(diag(A,-1),diag(A),diag(A,+1))) == "4×4 Tridiagonal{$Int}:\n 1 5 ⋅ ⋅\n 2 6 10 ⋅\n ⋅ 7 11 15\n ⋅ ⋅ 12 16"
563563
@test replstr(UpperTriangular(copy(A))) == "4×4 UpperTriangular{$Int,Array{$Int,2}}:\n 1 5 9 13\n ⋅ 6 10 14\n ⋅ ⋅ 11 15\n ⋅ ⋅ ⋅ 16"

0 commit comments

Comments
 (0)