Skip to content

Commit f02b76a

Browse files
committed
adding hvcat 2d concatenation function
called as hvcat((rows...), arguments...) where the first argument is a tuple giving the number of arguments in each block row addresses issue #122 also related to issue #38
1 parent 7559e4a commit f02b76a

File tree

3 files changed

+69
-5
lines changed

3 files changed

+69
-5
lines changed

j/abstractarray.j

+12
Original file line numberDiff line numberDiff line change
@@ -961,6 +961,18 @@ end
961961

962962
## Other array functions ##
963963

964+
# fallback definition of hvcat in terms of hcat and vcat
965+
function hvcat(rows::(Size...), as...)
966+
nbr = length(rows) # number of block rows
967+
rs = cell(nbr)
968+
a = 1
969+
for i = 1:nbr
970+
rs[i] = hcat(as[a:a-1+rows[i]]...)
971+
a += rows[i]
972+
end
973+
vcat(rs...)
974+
end
975+
964976
function repmat(a::AbstractMatrix, m::Size, n::Size)
965977
o,p = size(a)
966978
b = similar(a, o*m, p*n)

j/array.j

+34
Original file line numberDiff line numberDiff line change
@@ -261,6 +261,8 @@ function cat(catdim::Int, X...)
261261
dimsC = nargs
262262
elseif catdim == 2
263263
dimsC = (1, nargs)
264+
else
265+
# TODO
264266
end
265267
C = Array(typeC, dimsC)
266268

@@ -317,3 +319,35 @@ end
317319

318320
vcat(A::Array...) = cat(1, A...)
319321
hcat(A::Array...) = cat(2, A...)
322+
323+
# 2d concatenation
324+
325+
function hvcat{T}(rows::(Size...), as::Array{T,2}...)
326+
nbr = length(rows) # number of block rows
327+
328+
nc = mapreduce(+, a->size(a,2), as[1:rows[1]])
329+
nr = 0
330+
331+
a = 1
332+
for i = 1:nbr
333+
nr += size(as[a],1)
334+
a += rows[i]
335+
end
336+
337+
out = Array(T, nr, nc)
338+
339+
a = 1
340+
r = 1
341+
for i = 1:nbr
342+
c = 1
343+
szi = size(as[a],1)
344+
for j = 1:rows[i]
345+
szj = size(as[a+j-1],2)
346+
out[r:r-1+szi, c:c-1+szj] = as[a+j-1]
347+
c += szj
348+
end
349+
r += szi
350+
a += rows[i]
351+
end
352+
out
353+
end

src/julia-parser.scm

+23-5
Original file line numberDiff line numberDiff line change
@@ -769,6 +769,22 @@
769769
(else
770770
(error "missing separator in array expression")))))))
771771

772+
(define (cat-to-hvcat closer e)
773+
(if (and
774+
(eqv? closer #\])
775+
(eq? (car e) 'vcat)
776+
(any (lambda (x) (and (pair? x) (eq? (car x) 'hcat))) (cdr e)))
777+
;; convert nested hcat inside vcat to hvcat
778+
(let ((rows (map (lambda (x)
779+
(if (and (pair? x) (eq? (car x) 'hcat))
780+
(cdr x)
781+
(list x)))
782+
(cdr e))))
783+
`(call (top hvcat)
784+
(tuple ,@(map length rows))
785+
,@(apply nconc rows)))
786+
e))
787+
772788
(define (parse-matrix s first closer)
773789
(define (fix head v) (cons head (reverse v)))
774790
(define (update-outer v outer)
@@ -782,11 +798,13 @@
782798
(require-token s))))
783799
(if (eqv? t closer)
784800
(begin (take-token s)
785-
(if (pair? outer)
786-
(fix 'vcat (update-outer vec outer))
787-
(if (or (null? vec) (null? (cdr vec)))
788-
(fix 'vcat vec) ; [x] => (vcat x)
789-
(fix 'hcat vec)))) ; [x y] => (hcat x y)
801+
(cat-to-hvcat
802+
closer
803+
(if (pair? outer)
804+
(fix 'vcat (update-outer vec outer))
805+
(if (or (null? vec) (null? (cdr vec)))
806+
(fix 'vcat vec) ; [x] => (vcat x)
807+
(fix 'hcat vec))))) ; [x y] => (hcat x y)
790808
(case t
791809
((#\; #\newline)
792810
(take-token s) (loop '() (update-outer vec outer)))

0 commit comments

Comments
 (0)