From: Richard Harrington
Subject: creating a sub-array
Date: 
Message-ID: <d1b16522.0108011416.28cb42dc@posting.google.com>
Hi, I'm a newbie to lisp and was wondering if there is a function to
create a sub-array from a larger array, similar to the subseq
function. I've read that subseq works for different types of
sequences, creating sublists from lists and subvectors from vectors,
but is there one for a 2D array - specifically I'm trying to get a
subarray of n complete rows, specifying the start and finish.  Thanks
in advance

From: Barry Margolin
Subject: Re: creating a sub-array
Date: 
Message-ID: <QG1a7.41$TO3.478@burlma1-snr2>
In article <····························@posting.google.com>,
Richard Harrington <······@chip.org> wrote:
>Hi, I'm a newbie to lisp and was wondering if there is a function to
>create a sub-array from a larger array, similar to the subseq
>function. I've read that subseq works for different types of
>sequences, creating sublists from lists and subvectors from vectors,
>but is there one for a 2D array - specifically I'm trying to get a
>subarray of n complete rows, specifying the start and finish.  Thanks
>in advance

You can do this with displaced arrays:

(make-array (list (- finish start) (array-dimension old-array 1))
            :displaced-to old-array
            :displaced-index-offset (array-row-major-index start 0))

This array shares space with the original array.  If you want a copy, like
subseq makes, you can do something like:

(let* ((n (- finish start))
       (displaced-vector
         (make-array (* n (array-dimension old-array 1))
                     :displaced-to old-array
                     :displaced-index-offset (array-row-major-index start 0)))
       (new-vector (copy-seq displaced-vector)))
  (make-array (list n (array-dimension old-array 1))
              :displaced-to new-vector))

-- 
Barry Margolin, ······@genuity.net
Genuity, Woburn, MA
*** DON'T SEND TECHNICAL QUESTIONS DIRECTLY TO ME, post them to newsgroups.
Please DON'T copy followups to me -- I'll assume it wasn't posted to the group.
From: Kent M Pitman
Subject: Re: creating a sub-array
Date: 
Message-ID: <sfwy9p344ut.fsf@world.std.com>
Barry Margolin <······@genuity.net> writes:

> 
> In article <····························@posting.google.com>,
> Richard Harrington <······@chip.org> wrote:
> >Hi, I'm a newbie to lisp and was wondering if there is a function to
> >create a sub-array from a larger array, similar to the subseq
> >function. I've read that subseq works for different types of
> >sequences, creating sublists from lists and subvectors from vectors,
> >but is there one for a 2D array - specifically I'm trying to get a
> >subarray of n complete rows, specifying the start and finish.  Thanks
> >in advance
> 
> You can do this with displaced arrays:
> 
> (make-array (list (- finish start) (array-dimension old-array 1))
>             :displaced-to old-array
>             :displaced-index-offset (array-row-major-index start 0))
> 
> This array shares space with the original array.  If you want a copy, like
> subseq makes, you can do something like:
> 
> (let* ((n (- finish start))
>        (displaced-vector
>          (make-array (* n (array-dimension old-array 1))
>                      :displaced-to old-array
>                      :displaced-index-offset (array-row-major-index start 0)))
>        (new-vector (copy-seq displaced-vector)))
>   (make-array (list n (array-dimension old-array 1))
>               :displaced-to new-vector))

But this works because the storage layout is known to be row-major and 
because he specifically wants rows, right?  It can't work this way 
for arbitrary subrectangles, I think.
From: Marco Antoniotti
Subject: Re: creating a sub-array
Date: 
Message-ID: <y6ck80mpmqp.fsf@octagon.mrl.nyu.edu>
Kent M Pitman <······@world.std.com> writes:

> Barry Margolin <······@genuity.net> writes:
> 
> > 
> > In article <····························@posting.google.com>,
> > Richard Harrington <······@chip.org> wrote:
> > >Hi, I'm a newbie to lisp and was wondering if there is a function to
> > >create a sub-array from a larger array, similar to the subseq
> > >function. I've read that subseq works for different types of
> > >sequences, creating sublists from lists and subvectors from vectors,
> > >but is there one for a 2D array - specifically I'm trying to get a
> > >subarray of n complete rows, specifying the start and finish.  Thanks
> > >in advance
> > 
> > You can do this with displaced arrays:
> > 
> > (make-array (list (- finish start) (array-dimension old-array 1))
> >             :displaced-to old-array
> >             :displaced-index-offset (array-row-major-index start 0))
> > 
> > This array shares space with the original array.  If you want a copy, like
> > subseq makes, you can do something like:
> > 
> > (let* ((n (- finish start))
> >        (displaced-vector
> >          (make-array (* n (array-dimension old-array 1))
> >                      :displaced-to old-array
> >                      :displaced-index-offset (array-row-major-index start 0)))
> >        (new-vector (copy-seq displaced-vector)))
> >   (make-array (list n (array-dimension old-array 1))
> >               :displaced-to new-vector))
> 
> But this works because the storage layout is known to be row-major and 
> because he specifically wants rows, right?  It can't work this way 
> for arbitrary subrectangles, I think.

Yep.  It ain't the APL "reshape" operator.

BTW.  I have some code laying around that may be of interest to
somebody.  Write me if you want it.  Here is the interface.

;;; displaced-arrays.lisp -- An extension to quickly define in a
;;; single place arrays with slices. I.e. how to simulate the C idiom
;;;
;;; typedef union _packet_ {
;;;   struct {
;;;     int a[3];
;;;     int b[3];
;;;   } slices;
;;;   int raw[6];
;;; } packet;
;;;
;;; Author:  Marco Antoniotti
;;; Date:    19990115
;;; Version: 0.99 alfa.
;;;
;;; Commentary:
;;;
;;; We use displaced arrays and the automatic definition of several
;;; accessors in order to achieve the same effect in a more controlled
;;; way.
;;;
;;; (define-array-with-views (packet 6 :initial-element 0
;;;                                    :element-type '(unsigned-byte 8))
;;;    (:view slice-a 3)
;;;    (:view slice-b 3 :displaced-index-offset 3))
;;;
;;; This form defines a constructor for the whole array and accessors
;;; for each 'view'. In the above example you would get
;;;
;;; MAKE-PACKET to create an 'array' of length 6 with two displaced
;;;             arrays.
;;; PACKET-P to check whether an object is a packet.
;;; PACKET to access the whole array.
;;; SLICE-A to access the first view (or slice).
;;; SLICE-B to access the second view.
;;;

Cheers

-- 
Marco Antoniotti ========================================================
NYU Courant Bioinformatics Group        tel. +1 - 212 - 998 3488
719 Broadway 12th Floor                 fax  +1 - 212 - 995 4122
New York, NY 10003, USA                 http://bioinformatics.cat.nyu.edu
                    "Hello New York! We'll do what we can!"
                           Bill Murray in `Ghostbusters'.
From: Barry Margolin
Subject: Re: creating a sub-array
Date: 
Message-ID: <z7ha7.7$885.296@burlma1-snr2>
In article <···············@world.std.com>,
Kent M Pitman  <······@world.std.com> wrote:
>But this works because the storage layout is known to be row-major and 
>because he specifically wants rows, right?  It can't work this way 
>for arbitrary subrectangles, I think.

Correct.  For that, you'd need something like the Lisp Machine's
"conformant array" facility.  AFAIK, the Lisp Machine was the only system
with this feature, and I suspect the only reason it was included was
because the window system needed it (I think a fully-visible window would
be displaced to the appropriate subrectangle of the frame buffer memory).

-- 
Barry Margolin, ······@genuity.net
Genuity, Woburn, MA
*** DON'T SEND TECHNICAL QUESTIONS DIRECTLY TO ME, post them to newsgroups.
Please DON'T copy followups to me -- I'll assume it wasn't posted to the group.