Implementing array broadcasting Bradley Lucier (10 Sep 2024 15:45 UTC)
Re: Implementing array broadcasting Alex Shinn (11 Sep 2024 00:50 UTC)
Re: Implementing array broadcasting Bradley Lucier (15 Sep 2024 18:37 UTC)
Re: Implementing array broadcasting Alex Shinn (15 Sep 2024 21:53 UTC)

Re: Implementing array broadcasting Bradley Lucier 15 Sep 2024 18:37 UTC

On 9/10/24 8:49 PM, Alex Shinn wrote:
> The Chibi implementation actually translates any axis with
> the same (non-1) width to the lower bound of the destination
> domain for free:
>
> https://github.com/ashinn/alschemist/blob/master/chibi/math/
> linalg.scm#L391

Some questions about chibi's array-broadcast:

1. If chibi is given a generalized array as an argument, it copies it to
a specialized array before broadcasting.  It then passes a multi-index
transform to specialized-array-share to implement the broadcasting.
This transform is not 1-to-1.

This means that it broadcasts a mutable array if the array argument is
already a mutable specialized array; if a generalized array is copied,
it doesn't seem that the copied array is specified as immutable.

Is this intentional?  My inclination is to say that non-1-to-1 index
transforms are allowed only for immutable arrays.  (And I'd get rid of
array-freeze!, so one cannot mutate the immutability of arrays.)

2.  Python broadcasts arrays implicitly, and it seems that it takes two
arrays A and B and returns new arrays A' and B', both of whose axes are
broadcast to make them compatible.

Chibi takes as arguments an array and a new domain, and returns a single
array.  So to achieve what Python does will take two calls to
array-broadcast.

And with the implicit translation when the lower bounds don't line up,
it's not clear to me whether the final arrays will depend on the order
that array-broadcasts are called, i.e.,

(let* ((B' (array-broadcast B (array-domain A)))
        (A' (array-broadcast A (array-domain B')));; or (array-domain B)?

or vice versa

So my inclination would be to have (array-broadcast A B) require

(a)  A and B be immutable arrays;
(b)  the domains of A and B have zero lower bounds (so basically be
Python arrays);

and

(c) return A' and B' that satisfy the "broadcast rules", or error if
that isn't possible.

If we do that, then there will be two routines that require their array
arguments to have zero lower bounds, array-scale and array-broadcast, so
it would be useful to have a routine array-rebase, say, that computes

(array-translate A (vector-map - (interval-lower-bounds->vector
(array-domain A))

You may already have something like that in chibi.

Brad