Re: Implications of array broadcasting
Bradley Lucier 05 Nov 2024 03:07 UTC
On 11/3/24 17:20, Alex Shinn wrote:
>
> On Sat, Nov 2, 2024 at 1:24 PM Bradley Lucier <xxxxxx@purdue.edu
> <mailto:xxxxxx@purdue.edu>> wrote:
>
> On 10/31/24 09:15, Alex Shinn wrote:
> > So we
> > are left with the dilemma: array-broadcast is an efficient
> > way to broadcast without copying data, but we require the
> > input to it to be copied (or to have been immutable to begin
> > with which is not always practical).
>
> That's true.
>
> It seems that arrays are usually broadcast to expand a small array to
> match a larger array by repeating the elements of the small array. So
> the argument to array-broadcast usually has many fewer entries compared
> to the result, and to the domains of the other arrays in the operation.
>
>
> Actually, in many cases the broadcast just amounts to a reshape,
> without increasing the size, so copying the input loses 100% of the
> benefit. In other cases you may only replicate 2 or 3 times, so the
> copy is still a substantial fraction of the result size.
Thank you for this comment, it led to a great deal of thought.
Can you give an example where a broadcast just amounts to a reshape? I
can't think of one.
To get the TL;DR version of the rest of this email, skip to ****.
I kept coming up with situations where having
(define B (array-broadcast A new-compatible-domain))
without any copying could lead to problems---I wondered how trying to
reshape B would work (in all cases), for example.
Then I realized that you can't actually have a variable B with the
result of broadcasting A in NumPy. Broadcasting is implicit in NumPy:
An array argument is broadcast basically *inside an operation*, and then
the result of the broadcast is no longer available *outside* that operation.
Here is some NumPy documentation about broadcasting:
https://numpy.org/doc/stable/user/basics.broadcasting.html
(The outer-product example uses np.newaxis to add an axis to an
argument, we can do that in this SRFI by calling array-stack.)
The numerical operations that are used most often as examples using
array broadcasting in NumPy operate on at most two arrays at a time:
https://numpy.org/devdocs/reference/routines.math.html
In this SRFI we allow
(array-map f A_1 A_2 ...)
with an arbitrary number of array arguments, and an arbitrary function f
operating on array elements. (That can cause my head to hurt trying to
understand the consequences if f mutates the elements of any array
argument or captures a continuation or ...)
****
What I'm leading to is that I believe that we can achieve the effects of
array broadcasting in NumPy simply with
(array-map-with-broadcasting f A_1 A_2 ...)
which automatically broadcasts arguments when given a set of
"compatible" arrays, and not reifying broadcast arrays for further purposes.
Another alternative, which I don't prefer, is simply to modify array-map
to automatically broadcast arguments when given a set of "compatible"
arrays. But that is a possibility.
Brad