Questions about what math/array does and how it works

I'm the author of SRFI 231 about arrays and I'm trying to figure out what Racket's math/array does and how it works internally. So I thought I'd ask my questions here.

It appears at first reading that there is no way to make a mutable-array that is not strict, is that correct?

If this is true, then, while there is this mention of sparse matrices in math-array.scrbl

math-array.scrbl:Some arrays are mutable, some are lazy, some are strict, some are sparse, and most

it would seem that there would be no way of creating a mutable sparse array.

Another question: list*->array appears to return an immutable array when the dimension of the array is zero, but returns a mutable array when the array is positive:

> (list*->array 'another symbol?)
(array 'another)
> (list*->array '(another symbol) symbol?)
(mutable-array #['another 'symbol])

while vector*->array appears to always return a mutable array:

> (vector*->array 'another symbol?)
(mutable-array 'another)
> (vector*->array '#(another symbol) symbol?)
(mutable-array #['another 'symbol])

Looking at the code in untyped-array-convert.rkt it appears that the behavior of list*->array on a singleton may have been unintended.

So to make a question: Is this behavior of list*->array intended?

Thanks.

Brad

1 Like

It appears that the math/array library does not "share" arrays in the sense of SRFI 231. Here's an example:

heine:~> /usr/local/racket/bin/racket 
Welcome to Racket v8.16.0.1 [cs].
> (require math/array)
> (array-strictness #f)
> (define arr (array #[#[0 1] #[2 3]]))
> (array-strict? arr)
#t
> (define b (array-axis-swap arr 0 1))
> (array-strict? b)
#f

The code in math-lib/math/private/array/typed-array-transform.rkt for array-axis-swap returns

         (array-default-strict
          (unsafe-build-array
           new-ds (λ: ([js : Indexes])
                    (define j0 (unsafe-vector-ref js i0))
                    (define j1 (unsafe-vector-ref js i1))
                    (unsafe-vector-set! js i0 j1)
                    (unsafe-vector-set! js i1 j0)
                    (define v (proc js))
                    (unsafe-vector-set! js i0 j0)
                    (unsafe-vector-set! js i1 j1)
                    v)))

This code does not compute a new affine index function from the js indices into the body of arr, it manually swaps the indicated indices each time the result array's unsafe-array-proc is called. array-default-strict either copies the resulting non-strict array to a strict array, or it leaves it as it is.

So it appears that there is no sharing of array elements between the argument arr and the result of array-axis-swap, indexed by different affine mappings from vectors of indices js to an index into the vector holding the elements of the array.

This is not meant as a criticism of math/array.

I'm putting in a fair amount of time to understand the library, as I think there are things there that are worth emulating (like its slicing notation, similar to that of NumPy library of Python). But to emulate these things, I need to understand them in the context of the entire library.

Brad

1 Like

I sent an email to the SRFI 231 mail list listing a few things from NumPy and Racket's math/array that would be good to add to SRFI 231:

Brad

2 Likes