From: redick.metaperl.com
Subject: joining homogenous inner arrays into a single array
Date: 
Message-ID: <ecaa25c6-2ef2-43b2-aac9-9652109aa4a9@q3g2000hsg.googlegroups.com>
If you have a vector of length m  and each vector element contains an
array of dimension '(n p), how would you form this into an array
of dimension '(m n p)

Here is some code to build a vector of length vecsize where each
vector contains an array of dimension '(2 4). The next step is to
write the array-join and I cant figure it out.

; Jørn Inge
; http://groups.google.com/group/comp.lang.lisp/browse_thread/thread/d44a7c5c6b3276d8/b0a5f72e4a061991#b0a5f72e4a061991

(defun set-array! (a f)
  (let ((result (make-array (array-total-size a) :displaced-to a)))
        (map-into result f result)
     a))

(defconstant vecsize 3)
(setf inners (loop for i from 0 below vecsize collect (make-array '(2
4))))
(loop for a in inners do (set-array! a (lambda (x) (random 50.0))))
(setf outer (make-array (list vecsize) :initial-contents inners))

From: David Golden
Subject: Re: joining homogenous inner arrays into a single array
Date: 
Message-ID: <oyA9j.23790$j7.445536@news.indigo.ie>
redick.metaperl.com wrote:

> If you have a vector of length m  and each vector element contains an
> array of dimension '(n p), how would you form this into an array
> of dimension '(m n p)
> 
> Here is some code to build a vector of length vecsize where each
> vector contains an array of dimension '(2 4). The next step is to
> write the array-join and I cant figure it out.


Have to cons a new (m n p) array and copy elements of items into it
I fear. You *could* then just explicitly loop over indices and
repeatedly (setf (aref...) ...)...  But far more fun to do it without
doing that though... ;-)

; (Note I assume first item in vector is representative below...)
; 1. Simple displacement, fill-pointer and vector-push

(defun merged-array-from-vec-of-arrays1 (vector)
  (loop 
     with element-type = (array-element-type (aref vector 0))
     with merged-array =
       (make-array (cons (length vector)
                         (array-dimensions (aref vector 0)))
                   :element-type element-type)
     with flattened-merged-array =
       (make-array (array-total-size merged-array)
                   :displaced-to merged-array
                   :element-type element-type
                   :fill-pointer 0)
     for item across vector 
     do (loop for element across 
             (make-array (array-total-size item)
                         :displaced-to item
                         :element-type element-type)
           do (vector-push element flattened-merged-array))
     finally (return merged-array)))

; 2. Offset displacement making a (1D) "stencil", map-into,
; otherwise similar to 1.

(defun merged-array-from-vec-of-arrays (vector)
  (loop 
     with element-type = (array-element-type (aref vector 0))
     with merged-array = 
       (make-array (cons (length vector)
                         (array-dimensions (aref vector 0)))
                   :element-type element-type)
     with item-size = (array-total-size (aref vector 0))
     with rmidx = 0
     for item across vector
     do (let ((stencil (make-array item-size 
                                   :displaced-to merged-array
                                   :displaced-index-offset rmidx
                                   :element-type element-type)))
          (map-into stencil #'identity 
                    (make-array item-size 
                                :displaced-to item
                                :element-type element-type))
          (incf rmidx item-size))
     finally (return merged-array)))
From: livingcosmos.org
Subject: Re: joining homogenous inner arrays into a single array
Date: 
Message-ID: <16a82c67-a023-4b02-8aa8-adca6e69aa1d@s19g2000prg.googlegroups.com>
On Dec 17, 2:59 pm, David Golden <············@oceanfree.net> wrote:
> redick.metaperl.com wrote:
> > If you have a vector of length m  and each vector element contains an
> > array of dimension '(n p), how would you form this into an array
> > of dimension '(m n p)
>
> > Here is some code to build a vector of length vecsize where each
> > vector contains an array of dimension '(2 4). The next step is to
> > write the array-join and I cant figure it out.
>
> Have to cons a new (m n p) array and copy elements of items into it
> I fear. You *could* then just explicitly loop over indices and
> repeatedly (setf (aref...) ...)...  But far more fun to do it without
> doing that though... ;-)

Here is the implementation of that approach. It depends on a few
functions in the redick distro - http://hg.metaperl.com/redick?cmd=summary;style=gitweb

(defun array-join (a)
  "Input: ARRAY a - an array whose innermost dimension contains
arrays
(instead of the usual case of containing elements)
Output: ARRAY target-array with that innermost dimension spread out
over
more dimesions so that the innermost dimension now only has atoms."

  (let* ((current-dimensions (array-dimensions a))
	 (inner-dimensions (array-dimensions (aref a 0)))
	 (target-dimensions (append current-dimensions inner-dimensions))
	 (target-array (make-array target-dimensions))
	 (target-array-indices (x-prod (mapcar #'iota target-dimensions)))
	 (split-point (length current-dimensions))
	 )
    (progn
      (loop for tai in target-array-indices
	 for (outer-i inner-i) =
	   (multiple-value-list (sequence-partition tai split-point))
	   do (let* ((outer-val  (aref a (car outer-i))) ;;; HACKISH
		     (inner-val  (apply #'aref outer-val inner-i)))
		(setf (apply #'aref target-array tai) inner-val)
		))
      target-array))

)