Closed gambiteer closed 6 months ago
Thanks, but your fix results in a lazily evaluated array-reduce
on an empty array, so for instance calling array->list*
on the result gives the error:
ERROR: (array->list* (array-inner-product (make-array (make-interval '...
Exception: assertion failed
(not (interval-empty? domain))
(domain #<Interval 134075314546304>)
on line 3589 of file "./lib/srfi/231/test.sld"
(array->list* (array-inner-product (make-array (make-interval '#(4 0)) list) list list (make-array (make-interval '#(0 4)) list)))
What is the correct semantics here?
That's a good question. You're making something from nothing, basically.
It appears that APL does not allow empty arrays (intrinsically).
NumPy seems to suffer from the same problem: https://stackoverflow.com/questions/45282176/numpy-dot-product-with-inner-dimension-zero-gives-unexpected-result
In Matlab, matrix products are the only type of inner product, it appears, so there are multiplicative and additive identities, so reduce gives a reasonable answer: https://www.mathworks.com/help/matlab/math/empty-arrays.html See also: https://www.mathworks.com/help/matlab/matlab_prog/compatible-array-sizes-for-basic-operations.html
So I would say "It is an error if the width of the last axis of A (the same as the first axis of B) is zero".
Then it would just be a question of where to catch that error.
I'd be inclined to add (not (zero? (interval-width B-dom 0)))
to the second (and ...)
in the assert
.
It seems that the sample implementation recognized that this situation could happen; accessing an entry of the result of array-inner-product
threw an error with a message beginning array-inner-product: Attempting to reduce over an empty array:
I.e., the name of the caller (array-inner-product
) was passed to the internal procedure %%array-reduce
for the error message.
So the sample implementation delayed the error until there was an attempt to access an entry of the result of array-inner-product
.
I'm not sure I agree with that point of view now.
In Matlab, matrix products are the only type of inner product, it appears, so there are multiplicative and additive identities, so reduce gives a reasonable answer: https://www.mathworks.com/help/matlab/math/empty-arrays.html See also: https://www.mathworks.com/help/matlab/matlab_prog/compatible-array-sizes-for-basic-operations.html
So I would say "It is an error if the width of the last axis of A (the same as the first axis of B) is zero".
Unless you have a neutral element for the addition (which you don't supply array-inner-product
with), it has to be an error.
In most natural applications, however, there is a neutral element, so array-inner-product
does not catch the common situations quite right. A better version would take a ring (e.g., modelled by a record) that encodes addition, multiplication, and neutral elements.
Then it would just be a question of where to catch that error.
I'd be inclined to add
(not (zero? (interval-width B-dom 0)))
to the second(and ...)
in theassert
.
Dimensions are never lazily calculated, are they? If so, the check should be performed eagerly.
Rather than introducing a ring concept, taking a neutral element as an optional parameter is easier, but the SRFI is finalized. Changed to fail fast.
A better version would take a ring (e.g., modelled by a record) that encodes addition, multiplication, and neutral elements.
I want to push back on this a bit.
The data in arrays have no intrinsic algebraic or mathematical structure. I haven't wanted to complicate this SRFI (it's complicated enough!) by building in the possibility of specifying algebraic structures for some of the operations.
You have
Fixed with:
(along with some error checking).