Hi,
I have a couple of questions concerning arrays.
* Is there a "shorter" (i.e. less consy) way of getting the number of
axes an array has than (length (array-dimensions arr))?
* Suppose I have a three dimensional array, and an array of length
three that encodes the position of an entry in the first array. The
following function picks the right entry from the array, but i find
it rather consy. Is there an easy way of improving it?
(defun access (arr idx)
(let ((ax)
(l (length idx)))
(do ((i (- l 1) (1- i)))
((< i 0) (apply #'aref (cons arr ax)))
(push (aref idx i) ax))))
...
(access #2a((1 2) (3 4)) #(1 0)) ===> 3
Regards,
Mario.
Mario S. Mommer wrote:
> * Is there a "shorter" (i.e. less consy) way of getting the number of
> axes an array has than (length (array-dimensions arr))?
(array-rank arr)
>
> * Suppose I have a three dimensional array, and an array of length
> three that encodes the position of an entry in the first array. The
> following function picks the right entry from the array, but i find
> it rather consy. Is there an easy way of improving it?
>
> (defun access (arr idx)
> (let ((ax)
> (l (length idx)))
> (do ((i (- l 1) (1- i)))
> ((< i 0) (apply #'aref (cons arr ax)))
> (push (aref idx i) ax))))
>
> ...
>
> (access #2a((1 2) (3 4)) #(1 0)) ===> 3
If this is a performance bottleneck (and measure first) you can
specialize the common cases. I doubt you're going to be having
very many 17 dimensional arrays, for example.
Paul
Mario S. Mommer <········@yahoo.com> writes:
> * Is there a "shorter" (i.e. less consy) way of getting the number
> of axes an array has than (length (array-dimensions arr))?
ARRAY-RANK
> * Suppose I have a three dimensional array, and an array of length
> three that encodes the position of an entry in the first array. The
> following function picks the right entry from the array, but i find
> it rather consy. Is there an easy way of improving it?
>
> (defun access (arr idx)
> (let ((ax)
> (l (length idx)))
> (do ((i (- l 1) (1- i)))
> ((< i 0) (apply #'aref (cons arr ax)))
> (push (aref idx i) ax))))
>
> ...
>
> (access #2a((1 2) (3 4)) #(1 0)) ===> 3
Maybe use ARRAY-DIMENSION and ROW-MAJOR-AREF?
Regards,
--
Nils G�sche
"Don't ask for whom the <CTRL-G> tolls."
PGP key ID 0x0655CFA0
Nils Goesche <······@cartan.de> writes:
> Mario S. Mommer <········@yahoo.com> writes:
> > * Is there a "shorter" (i.e. less consy) way of getting the number
> > of axes an array has than (length (array-dimensions arr))?
>
> ARRAY-RANK
Indeed. I somehow overlooked that one in the hyperspec. Thanks.
> > (access #2a((1 2) (3 4)) #(1 0)) ===> 3
>
> Maybe use ARRAY-DIMENSION and ROW-MAJOR-AREF?
Like this?
(defun access (arr idx)
(let ((l (length idx)))
(do ((i 1 (1+ i))
(ax (aref idx 0)
(+ (aref idx i)
(* ax (array-dimension arr i)))))
((>= i l) (row-major-aref arr ax)))))
Fair enough. I hoped for an easier version ;-)
Thanks again.
Regards,
Mario.
Mario S. Mommer <········@yahoo.com> writes:
> Nils Goesche <······@cartan.de> writes:
> > Maybe use ARRAY-DIMENSION and ROW-MAJOR-AREF?
>
> Like this?
>
> (defun access (arr idx)
> (let ((l (length idx)))
> (do ((i 1 (1+ i))
> (ax (aref idx 0)
> (+ (aref idx i)
> (* ax (array-dimension arr i)))))
> ((>= i l) (row-major-aref arr ax)))))
>
> Fair enough. I hoped for an easier version ;-)
The easier version is consy.
(defun access (arr idx)
(declare (type vector idx) (type array arr)) ; Just to be more precise.
(apply #'aref arr (coerce idx 'list)))
This is screaming for Common Lisp Extension #42:
APPLY may take a sequence as its last argument.
Of course this will slow down APPLY.
Cheers
--
Marco Antoniotti ========================================================
NYU Courant Bioinformatics Group tel. +1 - 212 - 998 3488
715 Broadway 10th 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 <···············@octagon.valis.nyu.edu>,
Marco Antoniotti <·······@cs.nyu.edu> wrote:
>The easier version is consy.
>
>(defun access (arr idx)
> (declare (type vector idx) (type array arr)) ; Just to be more precise.
> (apply #'aref arr (coerce idx 'list)))
>
>This is screaming for Common Lisp Extension #42:
>APPLY may take a sequence as its last argument.
The simple solution to the OP's problem is for him to use a list instead of
an array for the IDX parameter. Then it's not necessary to coerce it.
An SSC could recognize tghat the result of COERCE is being used only by
APPLY, so it could simply copy the array elements directly into the stack,
rather than consing a list.
But even most other implementations should not have too much trouble with
this code. The list becomes garbage very quickly, so an ephemeral GC
should clean it up efficiently. Outside of environments with very strict
limits on GC, Lisp programmers generally don't get too concerned about
consing lots of small, short-live objects like this.
--
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.