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
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.
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.
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'.
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.