Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Proposal for AbstractWrappedArray in order to mitigate "AbstractArray-fallback" #31563

Closed
wants to merge 5 commits into from
Closed
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Next Next commit
introduce AbstractWrappedArray
  • Loading branch information
KlausC committed Apr 5, 2019
commit 391c7b000cc68cf031cd7810799da374039b403f
21 changes: 21 additions & 0 deletions base/abstractarray.jl
Original file line number Diff line number Diff line change
Expand Up @@ -2226,3 +2226,24 @@ function hash(A::AbstractArray, h::UInt)

return h
end

"""
AbstractWrappedArray{T,N,P,B}

Supertype for `N`-dimensional array-like types with elements of type `T` which are
'wrapping' another [`AbstractArray`](@ref) of type `P`. The ultimate unwrapped base
type is `B`.
[`Adjoint`](@ref), [`Symmetric`](@ref), [`SubArray`](@ref) and other types are subtypes
of this. Main purpose of this type is to allow for dispatching on `B`, which is
appropriate for sparse arrays. Typically `B == basetype(P)`.
"""
abstract type AbstractWrappedArray{T,N,P,S} <: AbstractArray{T,N}; end

"""
basetype(::Type)

Return the base type of an `AbstractWrappedArray`, the type itself otherwise.
"""

basetype(::Type{<:AbstractWrappedArray{T,N,X,S}}) where {T,N,X,S} = S
basetype(::Type{P}) where P = P
9 changes: 6 additions & 3 deletions base/subarray.jl
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,18 @@ const ViewIndex = Union{Real, AbstractArray}
const ScalarIndex = Real

# L is true if the view itself supports fast linear indexing
struct SubArray{T,N,P,I,L} <: AbstractArray{T,N}
struct SubArray{T,N,P,I,L,B} <: AbstractWrappedArray{T,N,P,B}
parent::P
indices::I
offset1::Int # for linear indexing and pointer, only valid when L==true
stride1::Int # used only for linear indexing
function SubArray{T,N,P,I,L}(parent, indices, offset1, stride1) where {T,N,P,I,L}
function SubArray{T,N,P,I,L,B}(parent, indices, offset1, stride1) where {T,N,P,I,L,B}
@_inline_meta
check_parent_index_match(parent, indices)
new(parent, indices, offset1, stride1)
new{T,N,P,I,L,B}(parent, indices, offset1, stride1)
end
function SubArray{T,N,P,I,L}(parent, indices, offset1, stride1) where {T,N,P,I,L}
SubArray{T,N,P,I,L,basetype(P)}(parent, indices, offset1, stride1)
end
end
# Compute the linear indexability of the indices, and combine it with the linear indexing of the parent
Expand Down
1 change: 1 addition & 0 deletions stdlib/LinearAlgebra/src/LinearAlgebra.jl
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import Base: USE_BLAS64, abs, acos, acosh, acot, acoth, acsc, acsch, adjoint, as
using Base: hvcat_fill, IndexLinear, promote_op, promote_typeof,
@propagate_inbounds, @pure, reduce, typed_vcat, require_one_based_indexing
using Base.Broadcast: Broadcasted
using Base: AbstractWrappedArray, basetype

export
# Modules
Expand Down
14 changes: 8 additions & 6 deletions stdlib/LinearAlgebra/src/adjtrans.jl
Original file line number Diff line number Diff line change
Expand Up @@ -32,12 +32,13 @@ julia> adjoint(A)
9-2im 4-6im
```
"""
struct Adjoint{T,S} <: AbstractMatrix{T}
struct Adjoint{T,S,B} <: AbstractWrappedArray{T,2,S,B}
parent::S
function Adjoint{T,S}(A::S) where {T,S}
function Adjoint{T,S,B}(A::S) where {T,S,B}
checkeltype_adjoint(T, eltype(A))
new(A)
end
Adjoint{T,S}(A::S) where {T,S} = Adjoint{T,S,basetype(S)}(A)
end
"""
Transpose
Expand All @@ -63,17 +64,18 @@ julia> transpose(A)
9+2im 4+6im
```
"""
struct Transpose{T,S} <: AbstractMatrix{T}
struct Transpose{T,S,B} <: AbstractWrappedArray{T,2,S,B}
parent::S
function Transpose{T,S}(A::S) where {T,S}
function Transpose{T,S,B}(A::S) where {T,S,B}
checkeltype_transpose(T, eltype(A))
new(A)
end
Transpose{T,S}(A::S) where {T,S} = Transpose{T,S,basetype(S)}(A)
end

function checkeltype_adjoint(::Type{ResultEltype}, ::Type{ParentEltype}) where {ResultEltype,ParentEltype}
Expected = Base.promote_op(adjoint, ParentEltype)
ResultEltype === Expected || error(string(
ResultEltype >: Expected || error(string(
"Element type mismatch. Tried to create an `Adjoint{", ResultEltype, "}` ",
"from an object with eltype `", ParentEltype, "`, but the element type of ",
"the adjoint of an object with eltype `", ParentEltype, "` must be ",
Expand All @@ -83,7 +85,7 @@ end

function checkeltype_transpose(::Type{ResultEltype}, ::Type{ParentEltype}) where {ResultEltype, ParentEltype}
Expected = Base.promote_op(transpose, ParentEltype)
ResultEltype === Expected || error(string(
ResultEltype >: Expected || error(string(
"Element type mismatch. Tried to create a `Transpose{", ResultEltype, "}` ",
"from an object with eltype `", ParentEltype, "`, but the element type of ",
"the transpose of an object with eltype `", ParentEltype, "` must be ",
Expand Down
18 changes: 12 additions & 6 deletions stdlib/LinearAlgebra/src/symmetric.jl
Original file line number Diff line number Diff line change
@@ -1,13 +1,16 @@
# This file is a part of Julia. License is MIT: https://julialang.org/license

# Symmetric and Hermitian matrices
struct Symmetric{T,S<:AbstractMatrix{<:T}} <: AbstractMatrix{T}
struct Symmetric{T,S<:AbstractMatrix{<:T},B} <: AbstractWrappedArray{T,2,S,B}
data::S
uplo::Char

function Symmetric{T,S}(data, uplo) where {T,S<:AbstractMatrix{<:T}}
function Symmetric{T,S,B}(data, uplo) where {T,S<:AbstractMatrix{<:T},B}
require_one_based_indexing(data)
new{T,S}(data, uplo)
new(data, uplo)
end
function Symmetric{T,S}(data, uplo) where {T,S<:AbstractMatrix{<:T}}
Symmetric{T,S,basetype(S)}(data, uplo)
end
end
"""
Expand Down Expand Up @@ -76,13 +79,16 @@ function symmetric_type(::Type{T}) where {S, T<:AbstractMatrix{S}}
end
symmetric_type(::Type{T}) where {T<:Number} = T

struct Hermitian{T,S<:AbstractMatrix{<:T}} <: AbstractMatrix{T}
struct Hermitian{T,S<:AbstractMatrix{<:T},B} <: AbstractWrappedArray{T,2,S,B}
data::S
uplo::Char

function Hermitian{T,S}(data, uplo) where {T,S<:AbstractMatrix{<:T}}
function Hermitian{T,S,B}(data, uplo) where {T,S<:AbstractMatrix{<:T},B}
require_one_based_indexing(data)
new{T,S}(data, uplo)
new(data, uplo)
end
function Hermitian{T,S}(data, uplo) where {T,S<:AbstractMatrix{<:T}}
Hermitian{T,S,basetype(S)}(data, uplo)
end
end
"""
Expand Down
11 changes: 7 additions & 4 deletions stdlib/LinearAlgebra/src/triangular.jl
Original file line number Diff line number Diff line change
Expand Up @@ -3,19 +3,22 @@
## Triangular

# could be renamed to Triangular when that name has been fully deprecated
abstract type AbstractTriangular{T,S<:AbstractMatrix} <: AbstractMatrix{T} end
abstract type AbstractTriangular{T,S<:AbstractMatrix,B} <: AbstractWrappedArray{T,2,S,B} end

# First loop through all methods that don't need special care for upper/lower and unit diagonal
for t in (:LowerTriangular, :UnitLowerTriangular, :UpperTriangular,
:UnitUpperTriangular)
@eval begin
struct $t{T,S<:AbstractMatrix{T}} <: AbstractTriangular{T,S}
struct $t{T,S<:AbstractMatrix{T},B} <: AbstractTriangular{T,S,B}
data::S

function $t{T,S}(data) where {T,S<:AbstractMatrix{T}}
function $t{T,S,B}(data) where {T,S<:AbstractMatrix{T},B}
require_one_based_indexing(data)
checksquare(data)
new{T,S}(data)
new(data)
end
function $t{T,S}(data) where {T,S<:AbstractMatrix{T}}
($t){T,S,basetype(S)}(data)
end
end
$t(A::$t) = A
Expand Down
30 changes: 15 additions & 15 deletions stdlib/LinearAlgebra/test/adjtrans.jl
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ using Test, LinearAlgebra, SparseArrays
intvecvec = [[1, 2], [3, 4]]
intmatmat = [[[1 2]] [[3 4]] [[5 6]]; [[7 8]] [[9 10]] [[11 12]]]
@test (X = Adjoint{Adjoint{Int,Vector{Int}},Vector{Vector{Int}}}(intvecvec);
isa(X, Adjoint{Adjoint{Int,Vector{Int}},Vector{Vector{Int}}}) && X.parent === intvecvec)
isa(X, Adjoint{Adjoint{Int,Vector{Int}}}) && X.parent === intvecvec)
@test (X = Adjoint{Adjoint{Int,Matrix{Int}},Matrix{Matrix{Int}}}(intmatmat);
isa(X, Adjoint{Adjoint{Int,Matrix{Int}},Matrix{Matrix{Int}}}) && X.parent === intmatmat)
@test (X = Transpose{Transpose{Int,Vector{Int}},Vector{Vector{Int}}}(intvecvec);
Expand Down Expand Up @@ -63,10 +63,10 @@ end

@testset "Adjoint and Transpose add additional layers to already-wrapped objects" begin
intvec, intmat = [1, 2], [1 2; 3 4]
@test (A = Adjoint(Adjoint(intvec))::Adjoint{Int,Adjoint{Int,Vector{Int}}}; A.parent.parent === intvec)
@test (A = Adjoint(Adjoint(intmat))::Adjoint{Int,Adjoint{Int,Matrix{Int}}}; A.parent.parent === intmat)
@test (A = Transpose(Transpose(intvec))::Transpose{Int,Transpose{Int,Vector{Int}}}; A.parent.parent === intvec)
@test (A = Transpose(Transpose(intmat))::Transpose{Int,Transpose{Int,Matrix{Int}}}; A.parent.parent === intmat)
@test (A = Adjoint(Adjoint(intvec))::Adjoint{Int,<:Adjoint{Int,Vector{Int}}}; A.parent.parent === intvec)
@test (A = Adjoint(Adjoint(intmat))::Adjoint{Int,<:Adjoint{Int,Matrix{Int}}}; A.parent.parent === intmat)
@test (A = Transpose(Transpose(intvec))::Transpose{Int,<:Transpose{Int,Vector{Int}}}; A.parent.parent === intvec)
@test (A = Transpose(Transpose(intmat))::Transpose{Int,<:Transpose{Int,Matrix{Int}}}; A.parent.parent === intmat)
end

@testset "Adjoint and Transpose basic AbstractArray functionality" begin
Expand Down Expand Up @@ -290,8 +290,8 @@ end
@test hcat(Transpose(vec), Transpose(vec))::Transpose{Complex{Int},Vector{Complex{Int}}} == hcat(tvec, tvec)
@test hcat(Transpose(vec), 1, Transpose(vec))::Transpose{Complex{Int},Vector{Complex{Int}}} == hcat(tvec, 1, tvec)
# for arrays with concrete array eltype
@test hcat(Adjoint(vecvec), Adjoint(vecvec))::Adjoint{Adjoint{Complex{Int},Vector{Complex{Int}}},Vector{Vector{Complex{Int}}}} == hcat(avecvec, avecvec)
@test hcat(Transpose(vecvec), Transpose(vecvec))::Transpose{Transpose{Complex{Int},Vector{Complex{Int}}},Vector{Vector{Complex{Int}}}} == hcat(tvecvec, tvecvec)
@test hcat(Adjoint(vecvec), Adjoint(vecvec))::Adjoint{<:Adjoint{Complex{Int},Vector{Complex{Int}}},Vector{Vector{Complex{Int}}}} == hcat(avecvec, avecvec)
@test hcat(Transpose(vecvec), Transpose(vecvec))::Transpose{<:Transpose{Complex{Int},Vector{Complex{Int}}},Vector{Vector{Complex{Int}}}} == hcat(tvecvec, tvecvec)
end

@testset "map/broadcast over Adjoint/Transpose-wrapped vectors and Numbers" begin
Expand All @@ -305,26 +305,26 @@ end
@test map(-, Adjoint(vec))::Adjoint{Complex{Int},Vector{Complex{Int}}} == -avec
@test map(-, Transpose(vec))::Transpose{Complex{Int},Vector{Complex{Int}}} == -tvec
# unary map over wrapped vectors with concrete array eltype
@test map(-, Adjoint(vecvec))::Adjoint{Adjoint{Complex{Int},Vector{Complex{Int}}},Vector{Vector{Complex{Int}}}} == -avecvec
@test map(-, Transpose(vecvec))::Transpose{Transpose{Complex{Int},Vector{Complex{Int}}},Vector{Vector{Complex{Int}}}} == -tvecvec
@test map(-, Adjoint(vecvec))::Adjoint{<:Adjoint{Complex{Int},Vector{Complex{Int}}},Vector{Vector{Complex{Int}}}} == -avecvec
@test map(-, Transpose(vecvec))::Transpose{<:Transpose{Complex{Int},Vector{Complex{Int}}},Vector{Vector{Complex{Int}}}} == -tvecvec
# binary map over wrapped vectors with concrete scalar eltype
@test map(+, Adjoint(vec), Adjoint(vec))::Adjoint{Complex{Int},Vector{Complex{Int}}} == avec + avec
@test map(+, Transpose(vec), Transpose(vec))::Transpose{Complex{Int},Vector{Complex{Int}}} == tvec + tvec
# binary map over wrapped vectors with concrete array eltype
@test map(+, Adjoint(vecvec), Adjoint(vecvec))::Adjoint{Adjoint{Complex{Int},Vector{Complex{Int}}},Vector{Vector{Complex{Int}}}} == avecvec + avecvec
@test map(+, Transpose(vecvec), Transpose(vecvec))::Transpose{Transpose{Complex{Int},Vector{Complex{Int}}},Vector{Vector{Complex{Int}}}} == tvecvec + tvecvec
@test map(+, Adjoint(vecvec), Adjoint(vecvec))::Adjoint{<:Adjoint{Complex{Int},Vector{Complex{Int}}},Vector{Vector{Complex{Int}}}} == avecvec + avecvec
@test map(+, Transpose(vecvec), Transpose(vecvec))::Transpose{<:Transpose{Complex{Int},Vector{Complex{Int}}},Vector{Vector{Complex{Int}}}} == tvecvec + tvecvec
# unary broadcast over wrapped vectors with concrete scalar eltype
@test broadcast(-, Adjoint(vec))::Adjoint{Complex{Int},Vector{Complex{Int}}} == -avec
@test broadcast(-, Transpose(vec))::Transpose{Complex{Int},Vector{Complex{Int}}} == -tvec
# unary broadcast over wrapped vectors with concrete array eltype
@test broadcast(-, Adjoint(vecvec))::Adjoint{Adjoint{Complex{Int},Vector{Complex{Int}}},Vector{Vector{Complex{Int}}}} == -avecvec
@test broadcast(-, Transpose(vecvec))::Transpose{Transpose{Complex{Int},Vector{Complex{Int}}},Vector{Vector{Complex{Int}}}} == -tvecvec
@test broadcast(-, Adjoint(vecvec))::Adjoint{<:Adjoint{Complex{Int},Vector{Complex{Int}}},Vector{Vector{Complex{Int}}}} == -avecvec
@test broadcast(-, Transpose(vecvec))::Transpose{<:Transpose{Complex{Int},Vector{Complex{Int}}},Vector{Vector{Complex{Int}}}} == -tvecvec
# binary broadcast over wrapped vectors with concrete scalar eltype
@test broadcast(+, Adjoint(vec), Adjoint(vec))::Adjoint{Complex{Int},Vector{Complex{Int}}} == avec + avec
@test broadcast(+, Transpose(vec), Transpose(vec))::Transpose{Complex{Int},Vector{Complex{Int}}} == tvec + tvec
# binary broadcast over wrapped vectors with concrete array eltype
@test broadcast(+, Adjoint(vecvec), Adjoint(vecvec))::Adjoint{Adjoint{Complex{Int},Vector{Complex{Int}}},Vector{Vector{Complex{Int}}}} == avecvec + avecvec
@test broadcast(+, Transpose(vecvec), Transpose(vecvec))::Transpose{Transpose{Complex{Int},Vector{Complex{Int}}},Vector{Vector{Complex{Int}}}} == tvecvec + tvecvec
@test broadcast(+, Adjoint(vecvec), Adjoint(vecvec))::Adjoint{<:Adjoint{Complex{Int},Vector{Complex{Int}}},Vector{Vector{Complex{Int}}}} == avecvec + avecvec
@test broadcast(+, Transpose(vecvec), Transpose(vecvec))::Transpose{<:Transpose{Complex{Int},Vector{Complex{Int}}},Vector{Vector{Complex{Int}}}} == tvecvec + tvecvec
# trinary broadcast over wrapped vectors with concrete scalar eltype and numbers
@test broadcast(+, Adjoint(vec), 1, Adjoint(vec))::Adjoint{Complex{Int},Vector{Complex{Int}}} == avec + avec .+ 1
@test broadcast(+, Transpose(vec), 1, Transpose(vec))::Transpose{Complex{Int},Vector{Complex{Int}}} == tvec + tvec .+ 1
Expand Down
2 changes: 1 addition & 1 deletion stdlib/LinearAlgebra/test/dense.jl
Original file line number Diff line number Diff line change
Expand Up @@ -665,7 +665,7 @@ end
@test typeof(log(A13)) == Array{elty, 2}

T = elty == Float64 ? Symmetric : Hermitian
@test typeof(log(T(A13))) == T{elty, Array{elty, 2}}
@test typeof(log(T(A13))) == T{elty, Array{elty, 2}, Array{elty, 2}}

A1 = convert(Matrix{elty}, [4 2 0; 1 4 1; 1 1 4])
logA1 = convert(Matrix{elty}, [1.329661349 0.5302876358 -0.06818951543;
Expand Down
8 changes: 4 additions & 4 deletions stdlib/LinearAlgebra/test/triangular.jl
Original file line number Diff line number Diff line change
Expand Up @@ -548,13 +548,13 @@ end
end

@testset "special printing of Lower/UpperTriangular" begin
@test occursin(r"3×3 (LinearAlgebra\.)?LowerTriangular{Int64,Array{Int64,2}}:\n 2 ⋅ ⋅\n 2 2 ⋅\n 2 2 2",
@test occursin(r"3×3 (LinearAlgebra\.)?LowerTriangular{Int64,Array{Int64,2},Array{Int64,2}}:\n 2 ⋅ ⋅\n 2 2 ⋅\n 2 2 2",
sprint(show, MIME"text/plain"(), LowerTriangular(2ones(Int64,3,3))))
@test occursin(r"3×3 (LinearAlgebra\.)?UnitLowerTriangular{Int64,Array{Int64,2}}:\n 1 ⋅ ⋅\n 2 1 ⋅\n 2 2 1",
@test occursin(r"3×3 (LinearAlgebra\.)?UnitLowerTriangular{Int64,Array{Int64,2},Array{Int64,2}}:\n 1 ⋅ ⋅\n 2 1 ⋅\n 2 2 1",
sprint(show, MIME"text/plain"(), UnitLowerTriangular(2ones(Int64,3,3))))
@test occursin(r"3×3 (LinearAlgebra\.)?UpperTriangular{Int64,Array{Int64,2}}:\n 2 2 2\n ⋅ 2 2\n ⋅ ⋅ 2",
@test occursin(r"3×3 (LinearAlgebra\.)?UpperTriangular{Int64,Array{Int64,2},Array{Int64,2}}:\n 2 2 2\n ⋅ 2 2\n ⋅ ⋅ 2",
sprint(show, MIME"text/plain"(), UpperTriangular(2ones(Int64,3,3))))
@test occursin(r"3×3 (LinearAlgebra\.)?UnitUpperTriangular{Int64,Array{Int64,2}}:\n 1 2 2\n ⋅ 1 2\n ⋅ ⋅ 1",
@test occursin(r"3×3 (LinearAlgebra\.)?UnitUpperTriangular{Int64,Array{Int64,2},Array{Int64,2}}:\n 1 2 2\n ⋅ 1 2\n ⋅ ⋅ 1",
sprint(show, MIME"text/plain"(), UnitUpperTriangular(2ones(Int64,3,3))))
end

Expand Down
6 changes: 3 additions & 3 deletions test/show.jl
Original file line number Diff line number Diff line change
Expand Up @@ -636,7 +636,7 @@ Base.methodloc_callback[] = methloc
@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(Vector(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 occursin(r"1×100 (LinearAlgebra\.)?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", replstr(Vector(1.:100.)'))
@test occursin(r"1×100 (LinearAlgebra\.)?Adjoint{Float64,Array{Float64,1},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", replstr(Vector(1.:100.)'))
# 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"

Expand Down Expand Up @@ -689,8 +689,8 @@ let A = reshape(1:16, 4, 4)
@test occursin(r"4×4 (LinearAlgebra\.)?Bidiagonal{Int(32|64),Array{Int(32|64),1}}:\n 1 ⋅ ⋅ ⋅\n 2 6 ⋅ ⋅\n ⋅ 7 11 ⋅\n ⋅ ⋅ 12 16", replstr(Bidiagonal(A, :L)))
@test occursin(r"4×4 (LinearAlgebra\.)?SymTridiagonal{Int(32|64),Array{Int(32|64),1}}:\n 2 7 ⋅ ⋅\n 7 12 17 ⋅\n ⋅ 17 22 27\n ⋅ ⋅ 27 32", replstr(SymTridiagonal(A + A')))
@test occursin(r"4×4 (LinearAlgebra\.)?Tridiagonal{Int(32|64),Array{Int(32|64),1}}:\n 1 5 ⋅ ⋅\n 2 6 10 ⋅\n ⋅ 7 11 15\n ⋅ ⋅ 12 16", replstr(Tridiagonal(diag(A, -1), diag(A), diag(A, +1))))
@test occursin(r"4×4 (LinearAlgebra\.)?UpperTriangular{Int(32|64),Array{Int(32|64),2}}:\n 1 5 9 13\n ⋅ 6 10 14\n ⋅ ⋅ 11 15\n ⋅ ⋅ ⋅ 16", replstr(UpperTriangular(copy(A))))
@test occursin(r"4×4 (LinearAlgebra\.)?LowerTriangular{Int(32|64),Array{Int(32|64),2}}:\n 1 ⋅ ⋅ ⋅\n 2 6 ⋅ ⋅\n 3 7 11 ⋅\n 4 8 12 16", replstr(LowerTriangular(copy(A))))
@test occursin(r"4×4 (LinearAlgebra\.)?UpperTriangular{Int(32|64),Array{Int(32|64),2},Array{Int(32|64),2}}:\n 1 5 9 13\n ⋅ 6 10 14\n ⋅ ⋅ 11 15\n ⋅ ⋅ ⋅ 16", replstr(UpperTriangular(copy(A))))
@test occursin(r"4×4 (LinearAlgebra\.)?LowerTriangular{Int(32|64),Array{Int(32|64),2},Array{Int(32|64),2}}:\n 1 ⋅ ⋅ ⋅\n 2 6 ⋅ ⋅\n 3 7 11 ⋅\n 4 8 12 16", replstr(LowerTriangular(copy(A))))
end

# Vararg methods in method tables
Expand Down