From: Antonio, Fabio Di Narzo
Subject: applying functions to array margins
Date: 
Message-ID: <1188384940.642950.301810@57g2000hsv.googlegroups.com>
Hi all.
I'm really new to Common Lisp. I'm writing some numerical code, and I
would find really useful a function for computing aggregating
functions of array margins. I.e., something like:

(array-margin my-matrix 1 #'mean)

for computing the vector of column means or, better:

(array-margin my-array '(0 1) #'total)

for computing the 2-dim array of totals over first 2 margins of the 3-
dim array "my-array". This utility is built-in in R (www.r-
project.org, function 'apply').
By now, I can easily write ugly specialized code for 2-dim and 3-dim
arrays. However, a generic (efficient?) solution for n-dim arrays
would be great. Someone already done this?

Bests,
Antonio, Fabio Di Narzo.
From: Tamas Papp
Subject: Re: applying functions to array margins
Date: 
Message-ID: <87wsveefm7.fsf@pu100877.student.princeton.edu>
"Antonio, Fabio Di Narzo" <················@gmail.com> writes:

> Hi all.
> I'm really new to Common Lisp. I'm writing some numerical code, and I
> would find really useful a function for computing aggregating
> functions of array margins. I.e., something like:
>
> (array-margin my-matrix 1 #'mean)
>
> for computing the vector of column means or, better:
>
> (array-margin my-array '(0 1) #'total)
>
> for computing the 2-dim array of totals over first 2 margins of the 3-
> dim array "my-array". This utility is built-in in R (www.r-
> project.org, function 'apply').
> By now, I can easily write ugly specialized code for 2-dim and 3-dim
> arrays. However, a generic (efficient?) solution for n-dim arrays
> would be great. Someone already done this?

Hi Antonio,

I have worked in R for years before switching to CL, so I know how it
feels to miss handy functions.  However, when using R, sometimes there
is a pressure to "vectorize" operations, meaning that they would be
slow otherwise if implemented with loops.  I had to work a lot on my
thinking to stop avoiding loops in CL.

That said, for your first case (the function takes vectors, like mean)
you only need to write the 3-dim case, then use displaced arrays (see
the CLHS) and call this function.  Eg a 5 x 4 x 7 x 2 x 3 array would
be displaced to a 20 x 7 x 6 array if calling apply on the 3rd rank of
the original aray, etc.

The second case is trickier, and the solution depends on how general
you want to make it.  For operations like total, sum etc, it works if
you traverse the array elements in a particular order and apply a
bivariate function repeatedly (consider reduce in CL).  For more
general things which need the slices as a whole (eg taking an inverse
of 2d slices of a 3d matrix), I would implement aperm and then use a
displaced array as above.

I know of no implementation of aperm, I have been meaning to do it but
could always avoid it so far.

HTH,

Tamas