Skip to content

Commit

Permalink
Reorganize hvcat methods, so more specialized ones are used
Browse files Browse the repository at this point in the history
  • Loading branch information
pabloferz committed Jun 6, 2016
1 parent f4cb80b commit d1843c7
Showing 1 changed file with 47 additions and 46 deletions.
93 changes: 47 additions & 46 deletions base/abstractarray.jl
Original file line number Diff line number Diff line change
Expand Up @@ -796,50 +796,8 @@ function hvcat(nbc::Integer, as...)
hvcat(ntuple(i->nbc, nbr), as...)
end

function hvcat{T}(rows::Tuple{Vararg{Int}}, as::AbstractMatrix{T}...)
nbr = length(rows) # number of block rows

nc = 0
for i=1:rows[1]
nc += size(as[i],2)
end

nr = 0
a = 1
for i = 1:nbr
nr += size(as[a],1)
a += rows[i]
end

out = similar(full(as[1]), T, nr, nc)

a = 1
r = 1
for i = 1:nbr
c = 1
szi = size(as[a],1)
for j = 1:rows[i]
Aj = as[a+j-1]
szj = size(Aj,2)
if size(Aj,1) != szi
throw(ArgumentError("mismatched height in block row $(i) (expected $szi, got $(size(Aj,1)))"))
end
if c-1+szj > nc
throw(ArgumentError("block row $(i) has mismatched number of columns (expected $nc, got $(c-1+szj))"))
end
out[r:r-1+szi, c:c-1+szj] = Aj
c += szj
end
if c != nc+1
throw(ArgumentError("block row $(i) has mismatched number of columns (expected $nc, got $(c-1))"))
end
r += szi
a += rows[i]
end
out
end

hvcat(rows::Tuple{Vararg{Int}}) = []
typed_hvcat(T::Type, rows::Tuple{Vararg{Int}}) = []

function hvcat{T<:Number}(rows::Tuple{Vararg{Int}}, xs::T...)
nr = length(rows)
Expand Down Expand Up @@ -874,6 +832,8 @@ function hvcat_fill(a::Array, xs::Tuple)
a
end

hvcat(rows::Tuple{Vararg{Int}}, xs::Number...) = typed_hvcat(promote_typeof(xs...), rows, xs...)

function typed_hvcat(T::Type, rows::Tuple{Vararg{Int}}, xs::Number...)
nr = length(rows)
nc = rows[1]
Expand All @@ -889,9 +849,50 @@ function typed_hvcat(T::Type, rows::Tuple{Vararg{Int}}, xs::Number...)
hvcat_fill(Array{T}(nr, nc), xs)
end

function hvcat(rows::Tuple{Vararg{Int}}, xs::Number...)
T = promote_typeof(xs...)
typed_hvcat(T, rows, xs...)
hvcat(rows::Tuple{Vararg{Int}}, xs::AbstractMatrix...) = typed_hvcat(promote_eltype(xs...), rows, xs...)
hvcat{T}(rows::Tuple{Vararg{Int}}, xs::AbstractMatrix{T}...) = typed_hvcat(T, rows, xs...)

function typed_hvcat{T}(TT::Type{T}, rows::Tuple{Vararg{Int}}, as::AbstractMatrix{T}...)
nbr = length(rows) # number of block rows

nc = 0
for i=1:rows[1]
nc += size(as[i],2)
end

nr = 0
a = 1
for i = 1:nbr
nr += size(as[a],1)
a += rows[i]
end

out = similar(full(as[1]), T, nr, nc)

a = 1
r = 1
for i = 1:nbr
c = 1
szi = size(as[a],1)
for j = 1:rows[i]
Aj = as[a+j-1]
szj = size(Aj,2)
if size(Aj,1) != szi
throw(ArgumentError("mismatched height in block row $(i) (expected $szi, got $(size(Aj,1)))"))
end
if c-1+szj > nc
throw(ArgumentError("block row $(i) has mismatched number of columns (expected $nc, got $(c-1+szj))"))
end
out[r:r-1+szi, c:c-1+szj] = Aj
c += szj
end
if c != nc+1
throw(ArgumentError("block row $(i) has mismatched number of columns (expected $nc, got $(c-1))"))
end
r += szi
a += rows[i]
end
out
end

# fallback definition of hvcat in terms of hcat and vcat
Expand Down

0 comments on commit d1843c7

Please sign in to comment.