I've got more of the multidimensional array code prototyped and I'll put it up on GitHub (<a href="http://github.com/DrDoug/numeric/tree/master">http://github.com/DrDoug/numeric/tree/master</a>). The interface elements are shown below:<br>
<br>(provide object u8 u16 u32 u64 s8 s16 s32 s64 f32 f64 cf32 cf64)<br><br>(provide/contract<br> (vtype?<br> (-> any/c boolean?))<br> (array?<br> (-> any/c boolean?))<br> (array-shape<br> (-> array? (listof exact-nonnegative-integer?)))<br>
(array-type<br> (-> array? vtype?))<br> (array-order<br> (-> array? (symbols 'row 'column)))<br> (array-n-dim<br> (-> array? exact-nonnegative-integer?))<br> (array-size<br> (-> array? exact-nonnegative-integer?))<br>
(describe-array<br> (-> array? void?))<br> (make-array<br> (->* ((listof exact-nonnegative-integer?))<br> (#:type (or/c vtype? symbol?)<br> #:order (symbols 'row 'column)<br> #:fill any/c)<br>
array?))<br> (build-array<br> (->* ((listof exact-nonnegative-integer?)<br> procedure?)<br> (#:type (or/c vtype? symbol?)<br> #:order (symbols 'row 'column))<br> array?))<br> (arange<br>
(->* (exact-nonnegative-integer?)<br> (#:type (or/c vtype? symbol?)<br> #:order (symbols 'row 'column))<br> array?))<br> (transpose<br> (-> array? array?))<br> (reshape<br> (-> array? (listof exact-nonnegative-integer?) array?))<br>
(array-ref<br> (->* (array?) () #:rest (listof exact-nonnegative-integer?) any/c))<br> (array-ref*<br> (-> array? list? any/c))<br> (real<br> (-> array? array?))<br> (imag<br> (-> array? array?))<br> (array->list<br>
(-> array? list?))<br> (print-array<br> (-> array? void?))<br> (list->array<br> (->* (list?)<br> (#:type (or/c vtype? symbol?)<br> #:order (symbols 'row 'column))<br> array?)))<br>
<br>This is prototype code only. It runs, but with limited error checking (although the contracts catch a lot of errors). I'm sure there are fragile areas.<br><br>There are a couple of SRFIs dealing with arrays, but they aren't of the same ilk as what we're looking for here. But, this is somewhat of a superset of those and I should avoid being different just out of ignorance.<br>
<br>Per Scott's suggestion, I have changed the named of the complex floats from c64 and C128 to cf32 and cf64.<br><br>I have both array-ref and array-ref*. The difference is that array-ref* takes the index specification as a list of indices while array-ref takes the indices as parameters. So, (array-ref some-array i j) is equivalent to (array-ref* some-array (list i j)). I've found both to be convenient. I'm also open to alternatives.<br>
<br>I've added slicing to array ref (and array-ref*). A slice specifies a subarray. So: if we define an array, a:<br><br>(define a (reshape (arange 12) '(3 4))) ;; Creates a 3 x 4 array with a[0,0] = 0, a[0,1] = 1, ..., a[2.3] = 11<br>
<br>a = [[0 1 2 3]<br> [4 5 6 7]<br> [8 9 10 11]]<br><br>then (array-ref* a '(0 1)) -> 1, while (array-ref* a '(* 3)) is the 4th column of a and is [3 7 11] and (array-ref* a '(1 *)) is the 2nd row of a and id [4 5 6 7].<br>
<br>An index can also specify indices as (start stop step). So, (array-ref a '(1 (1 * 2))) is every second column starting with index 1 of the first row of a and is [5 7].<br><br>Some examples of index ranges are:<br>
(1), which is equivalent to (1 * *), is index 1 through the last index with a step of 1 (the default)<br>(1 4) is index 1 through 4 with a step of 1<br>(1 * 2) is index 1 through the last index with a step of 2.<br>(* * 2) is every second index starting with 0<br>
<br>This is concise, but maybe not obvious. Also. it differs from the in-range sequence when maybe it should follow that. Some others might prefer a more verbose, but more readable alternative - maybe (#:start 1 #:step 2). Comments are welcome.<br>
<br>So, array-ref can either return a scalar (if the indices are fully specified) or a subarray.<br><br>There are a number of functions to construct arrays: make-array, build-array, arange, and list-> array. [With immutability, the primitive make-array isn't very useful.]<br>
<br>The functions print-array and describe-array are quick-and-dirty implementations to support the prototyping effort.<br><br>The functions like transpose, reshape, real, imag, and array-list show some of the typical functions we'll have to provide.<br>
<br>---<br><br>I think it would be good to move this discussion off the general list - unless others want to keep it here. Github has a wiki we can use. It is set up automatically, but I've never used it and don't know how convenient it is. If anyone here has used it in the past let me know if you think it's a good place to move to. Also, I'll try to find time to update my Scheme blog with what I'm doing.<br>
<br>As always, comments and suggestions are welcome.<br><br>Doug<br><br>