
in the original GitHub fork: https://github.com/ntoronto/racket Some things about this are known to be broken (most egregious is that the array tests DO NOT RUN because of a problem in typed/rackunit), about half has no coverage in the tests, and half has no documentation. Fixes and docs are coming. This is committed now to allow others to find errors and inconsistency in the things that appear to be working, and to give the author a (rather incomplete) sense of closure.
991 lines
41 KiB
Racket
991 lines
41 KiB
Racket
#lang typed/racket
|
|
|
|
(require racket/flonum
|
|
math/array
|
|
typed/rackunit
|
|
math/private/array/utils)
|
|
|
|
(define-predicate listof-index? (Listof Index))
|
|
(define-predicate listof-flonum? (Listof Float))
|
|
(define-predicate undefined? Undefined)
|
|
|
|
;; ---------------------------------------------------------------------------------------------------
|
|
;; array-mutable
|
|
|
|
(: make-indexes-vector (Integer Integer -> (Vectorof (Vectorof Integer))))
|
|
(define (make-indexes-vector n dims)
|
|
(list->vector
|
|
((inst map (Vectorof Integer) (Listof Integer))
|
|
list->vector
|
|
(let: loop : (Listof (Listof Integer)) ([n : Integer n])
|
|
(cond [(= n 0) (list null)]
|
|
[else (define lsts (loop (- n 1)))
|
|
(append* (for/list: : (Listof (Listof (Listof Integer))) ([k (in-range dims)])
|
|
(map (λ: ([lst : (Listof Integer)]) (cons k lst)) lsts)))])))))
|
|
|
|
(check-equal? (make-indexes-vector 2 3)
|
|
#(#(0 0) #(0 1) #(0 2) #(1 0) #(1 1) #(1 2) #(2 0) #(2 1) #(2 2)))
|
|
|
|
(let ([arr (make-mutable-array #(4) #(a b c d))])
|
|
(check-eq? arr (array-strict arr)))
|
|
|
|
(let ([arr (build-array #() (λ (js) 'foo))])
|
|
(check-equal? (mutable-array-data (array->mutable-array arr))
|
|
#(foo)))
|
|
|
|
(let ([arr ((inst build-array Float) #(4) (λ (js) (exact->inexact (vector-ref js 0))))])
|
|
(check-equal? (mutable-array-data (array->mutable-array arr))
|
|
#(0.0 1.0 2.0 3.0)))
|
|
|
|
(let ([arr ((inst build-array Float) #(0) (λ (js) (exact->inexact (vector-ref js 0))))])
|
|
(check-equal? (mutable-array-data (array->mutable-array arr))
|
|
#()))
|
|
|
|
(let ([arr (build-array #(3 3) (λ (js) js))])
|
|
(check-equal? (mutable-array-data (array->mutable-array arr))
|
|
(make-indexes-vector 2 3)))
|
|
|
|
(let ([arr (build-array #(2 2 2) (λ (js) js))])
|
|
(check-equal? (mutable-array-data (array->mutable-array arr))
|
|
(make-indexes-vector 3 2)))
|
|
|
|
(let ([arr (build-array #(2 2 2 2) (λ (js) js))])
|
|
(check-equal? (mutable-array-data (array->mutable-array arr))
|
|
(make-indexes-vector 4 2)))
|
|
|
|
(let ([arr (build-array #(2 2 2 2 2) (λ (js) js))])
|
|
(check-equal? (mutable-array-data (array->mutable-array arr))
|
|
(make-indexes-vector 5 2)))
|
|
|
|
(let ([arr (build-array #(2 2 2 2 2 2) (λ (js) js))])
|
|
(check-equal? (mutable-array-data (array->mutable-array arr))
|
|
(make-indexes-vector 6 2)))
|
|
|
|
;; ---------------------------------------------------------------------------------------------------
|
|
;; list*->array
|
|
|
|
(check-equal? (list*->array 1.0 flonum?)
|
|
(make-mutable-array #() #(1.0)))
|
|
|
|
(check-equal? (list*->array '[] flonum?)
|
|
(make-mutable-array #(0) #()))
|
|
|
|
(check-equal? (list*->array '[[]] flonum?)
|
|
(make-mutable-array #(1 0) #()))
|
|
|
|
(check-equal? (list*->array '[1.0] flonum?)
|
|
(make-mutable-array #(1) #(1.0)))
|
|
|
|
(check-equal? (list*->array '[[1.0]] flonum?)
|
|
(make-mutable-array #(1 1) #(1.0)))
|
|
|
|
(check-equal? (list*->array '[[[1.0]]] flonum?)
|
|
(make-mutable-array #(1 1 1) #(1.0)))
|
|
|
|
(check-equal? (list*->array '() listof-flonum?)
|
|
(make-mutable-array #() #(())))
|
|
|
|
(check-equal? (list*->array '[()] listof-flonum?)
|
|
(make-mutable-array #(1) #(())))
|
|
|
|
(check-equal? (list*->array '[(1.0) (2.0)] listof-flonum?)
|
|
(make-mutable-array #(2) #((1.0) (2.0))))
|
|
|
|
(check-equal? (list*->array '[((1.0)) ((2.0))] listof-flonum?)
|
|
(make-mutable-array #(2 1) #((1.0) (2.0))))
|
|
|
|
;; ---------------------------------------------------------------------------------------------------
|
|
;; array->list*
|
|
|
|
(let ([arr (build-array #() (λ (js) 'foo))])
|
|
(check-equal? (array->list* arr) 'foo)
|
|
(check-equal? arr (list*->array (array->list* arr) symbol?)))
|
|
|
|
(let ([arr ((inst build-array Float) #(4) (λ (js) (exact->inexact (vector-ref js 0))))])
|
|
(check-equal? (array->list* arr) '[0.0 1.0 2.0 3.0])
|
|
(check-equal? arr (list*->array (array->list* arr) flonum?)))
|
|
|
|
(let ([arr (build-array #(3 3) (inst vector->list Index))])
|
|
(check-equal? (array->list* arr) '[[(0 0) (0 1) (0 2)]
|
|
[(1 0) (1 1) (1 2)]
|
|
[(2 0) (2 1) (2 2)]])
|
|
(check-equal? arr (list*->array (array->list* arr) listof-index?)))
|
|
|
|
(let ([arr (build-array #(2 2 2) (inst vector->list Index))])
|
|
(check-equal? (array->list* arr)
|
|
'[[[(0 0 0) (0 0 1)] [(0 1 0) (0 1 1)]]
|
|
[[(1 0 0) (1 0 1)] [(1 1 0) (1 1 1)]]])
|
|
(check-equal? arr (list*->array (array->list* arr) listof-index?)))
|
|
|
|
(let ([arr (build-array #(2 2 2 2) (inst vector->list Index))])
|
|
(check-equal? (array->list* arr)
|
|
'[[[[(0 0 0 0) (0 0 0 1)] [(0 0 1 0) (0 0 1 1)]]
|
|
[[(0 1 0 0) (0 1 0 1)] [(0 1 1 0) (0 1 1 1)]]]
|
|
[[[(1 0 0 0) (1 0 0 1)] [(1 0 1 0) (1 0 1 1)]]
|
|
[[(1 1 0 0) (1 1 0 1)] [(1 1 1 0) (1 1 1 1)]]]])
|
|
(check-equal? arr (list*->array (array->list* arr) listof-index?)))
|
|
|
|
(check-equal? (array->list* (list*->array '[1.0 2.0] flonum?))
|
|
'[1.0 2.0])
|
|
(check-equal? (array->list* (list*->array '[[1.0 2.0] [3.0 4.0]] flonum?))
|
|
'[[1.0 2.0] [3.0 4.0]])
|
|
|
|
;; ---------------------------------------------------------------------------------------------------
|
|
;; vector*->array
|
|
|
|
(check-equal? (vector*->array 1.0 flonum?)
|
|
(make-mutable-array #() #(1.0)))
|
|
|
|
(check-equal? ((inst vector*->array Float) #() flonum?)
|
|
(make-mutable-array #(0) #()))
|
|
|
|
(check-equal? ((inst vector*->array Float) #(#()) flonum?)
|
|
(make-mutable-array #(1 0) #()))
|
|
|
|
(check-equal? ((inst vector*->array Float) #(1.0) flonum?)
|
|
(make-mutable-array #(1) #(1.0)))
|
|
|
|
(check-equal? ((inst vector*->array Float) #(#(1.0)) flonum?)
|
|
(make-mutable-array #(1 1) #(1.0)))
|
|
|
|
(check-equal? ((inst vector*->array Float) #(#(#(1.0))) flonum?)
|
|
(make-mutable-array #(1 1 1) #(1.0)))
|
|
|
|
;; ---------------------------------------------------------------------------------------------------
|
|
;; array->vector
|
|
|
|
(let ([arr (build-array #() (λ (js) 'foo))])
|
|
(check-equal? (array->vector* arr) 'foo)
|
|
(check-equal? arr (vector*->array (array->vector* arr) symbol?)))
|
|
|
|
(let ([arr ((inst build-array Float) #(4) (λ (js) (exact->inexact (vector-ref js 0))))])
|
|
(check-equal? (array->vector* arr) #(0.0 1.0 2.0 3.0))
|
|
(check-equal? arr (vector*->array (array->vector* arr) flonum?)))
|
|
|
|
(let ([arr (build-array #(3 3) (inst vector->list Index))])
|
|
(check-equal? (array->vector* arr) #[#[(0 0) (0 1) (0 2)]
|
|
#[(1 0) (1 1) (1 2)]
|
|
#[(2 0) (2 1) (2 2)]])
|
|
(check-equal? arr (vector*->array (array->vector* arr) listof-index?)))
|
|
|
|
(let ([arr (build-array #(2 2 2) (inst vector->list Index))])
|
|
(check-equal? (array->vector* arr)
|
|
#[#[#[(0 0 0) (0 0 1)] #[(0 1 0) (0 1 1)]]
|
|
#[#[(1 0 0) (1 0 1)] #[(1 1 0) (1 1 1)]]])
|
|
(check-equal? arr (vector*->array (array->vector* arr) listof-index?)))
|
|
|
|
(let ([arr (build-array #(2 2 2 2) (inst vector->list Index))])
|
|
(check-equal? (array->vector* arr)
|
|
#[#[#[#[(0 0 0 0) (0 0 0 1)] #[(0 0 1 0) (0 0 1 1)]]
|
|
#[#[(0 1 0 0) (0 1 0 1)] #[(0 1 1 0) (0 1 1 1)]]]
|
|
#[#[#[(1 0 0 0) (1 0 0 1)] #[(1 0 1 0) (1 0 1 1)]]
|
|
#[#[(1 1 0 0) (1 1 0 1)] #[(1 1 1 0) (1 1 1 1)]]]])
|
|
(check-equal? arr (vector*->array (array->vector* arr) listof-index?)))
|
|
|
|
(check-equal? (array->vector* ((inst vector*->array Flonum) #[1.0 2.0] flonum?))
|
|
#[1.0 2.0])
|
|
(check-equal? (array->vector* ((inst vector*->array Flonum) #[#[1.0 2.0] #[3.0 4.0]] flonum?))
|
|
#[#[1.0 2.0] #[3.0 4.0]])
|
|
|
|
;; ---------------------------------------------------------------------------------------------------
|
|
;; Array syntax
|
|
|
|
(check-equal? (array 1.0)
|
|
(list*->array 1.0 flonum?))
|
|
|
|
(check-equal? (array [])
|
|
(list*->array '[] flonum?))
|
|
|
|
(check-equal? (array [[]])
|
|
(list*->array '[[]] flonum?))
|
|
|
|
(check-equal? (array [1.0])
|
|
(list*->array '[1.0] flonum?))
|
|
|
|
(check-equal? (array [[1.0]])
|
|
(list*->array '[[1.0]] flonum?))
|
|
|
|
(check-equal? (array [[[1.0]]])
|
|
(list*->array '[[[1.0]]] flonum?))
|
|
|
|
(check-equal? (mutable-array 1.0)
|
|
(list*->array 1.0 flonum?))
|
|
|
|
(check-equal? (mutable-array [])
|
|
(list*->array '[] flonum?))
|
|
|
|
(check-equal? (mutable-array [[]])
|
|
(list*->array '[[]] flonum?))
|
|
|
|
(check-equal? (mutable-array [1.0])
|
|
(list*->array '[1.0] flonum?))
|
|
|
|
(check-equal? (mutable-array [[1.0]])
|
|
(list*->array '[[1.0]] flonum?))
|
|
|
|
(check-equal? (mutable-array [[[1.0]]])
|
|
(list*->array '[[[1.0]]] flonum?))
|
|
|
|
;; ---------------------------------------------------------------------------------------------------
|
|
;; Other constructors
|
|
|
|
(check-equal? (make-array #(3 3) 0)
|
|
(build-array #(3 3) (λ (js) 0)))
|
|
|
|
(check-equal? (axis-index-array #(3 3) 0)
|
|
(build-array #(3 3) (λ: ([js : Indexes]) (vector-ref js 0))))
|
|
|
|
(check-exn exn? (λ () (axis-index-array #(3 3) -1)))
|
|
(check-exn exn? (λ () (axis-index-array #() 0)))
|
|
|
|
(check-equal? (index-array #()) (array 0))
|
|
(check-equal? (index-array #(4)) (array [0 1 2 3]))
|
|
(check-equal? (index-array #(2 2)) (array [[0 1] [2 3]]))
|
|
|
|
(check-equal? (indexes-array #(3 3))
|
|
(build-array #(3 3) (λ: ([js : Indexes]) (vector-copy js))))
|
|
|
|
(check-equal? (diagonal-array 0 0 1.0 0.0)
|
|
(array 1.0))
|
|
|
|
(check-equal? (diagonal-array 1 0 1.0 0.0)
|
|
(array []))
|
|
|
|
(check-equal? (diagonal-array 1 1 1.0 0.0)
|
|
(array [1.0]))
|
|
|
|
(check-equal? (diagonal-array 2 1 1.0 0.0)
|
|
(array [[1.0]]))
|
|
|
|
(check-equal? (diagonal-array 2 2 1.0 0.0)
|
|
(array [[1.0 0.0] [0.0 1.0]]))
|
|
|
|
(check-equal? (diagonal-array 3 2 1.0 0.0)
|
|
(array [[[1.0 0.0] [0.0 0.0]]
|
|
[[0.0 0.0] [0.0 1.0]]]))
|
|
|
|
;; ---------------------------------------------------------------------------------------------------
|
|
;; Pointwise
|
|
;; Not much to test here because most pointwise ops are defined by the same two lifts
|
|
|
|
(check-equal? (array-sqrt (array [1.0 4.0 9.0 16.0]))
|
|
(array [1.0 2.0 3.0 4.0]))
|
|
|
|
(check-equal? (array+ (array [1.0 2.0])
|
|
(array [10.0 20.0]))
|
|
(array [11.0 22.0]))
|
|
|
|
(check-equal? (array-map inexact->exact (array [1.0 2.0]))
|
|
(array [1 2]))
|
|
|
|
(check-equal? (array-map (inst cons Float Float)
|
|
(array [1.0 2.0])
|
|
(array [10.0 20.0]))
|
|
(make-mutable-array #(2) #[(1.0 . 10.0) (2.0 . 20.0)]))
|
|
|
|
;; ---------------------------------------------------------------------------------------------------
|
|
;; Fold
|
|
|
|
(let ([arr (array [[ 1.0 4.0 9.0 16.0]
|
|
[-1.0 -4.0 -9.0 -16.0]])])
|
|
(check-equal? (array-axis-sum arr 0) (array [0.0 0.0 0.0 0.0]))
|
|
(check-equal? (array-axis-prod arr 0) (array [-1.0 -16.0 -81.0 -256.0]))
|
|
(check-equal? (array-axis-min arr 0) (array [-1.0 -4.0 -9.0 -16.0]))
|
|
(check-equal? (array-axis-max arr 0) (array [ 1.0 4.0 9.0 16.0]))
|
|
(check-equal? (array-axis-fold arr 0 (inst cons Float (Listof Float)) null)
|
|
(list*->array '[[-1.0 1.0] [-4.0 4.0] [-9.0 9.0] [-16.0 16.0]]
|
|
listof-flonum?))
|
|
(check-equal? (array-axis-sum arr 1) (array [30.0 -30.0]))
|
|
(check-equal? (array-axis-prod arr 1) (array [576.0 576.0]))
|
|
(check-equal? (array-axis-min arr 1) (array [1.0 -16.0]))
|
|
(check-equal? (array-axis-max arr 1) (array [16.0 -1.0]))
|
|
(check-equal? (array-axis-fold arr 1 (inst cons Float (Listof Float)) null)
|
|
(list*->array '[[ 16.0 9.0 4.0 1.0]
|
|
[-16.0 -9.0 -4.0 -1.0]]
|
|
listof-flonum?))
|
|
(check-equal? (array-all-sum arr) 0.0)
|
|
(check-equal? (array-all-prod arr) (* 576.0 576.0))
|
|
(check-equal? (array-all-min arr) -16.0)
|
|
(check-equal? (array-all-max arr) 16.0))
|
|
|
|
(let ([arr (make-array #(3 0) 0)])
|
|
(check-equal? (array-axis-sum arr 0) (array []))
|
|
(check-equal? (array-axis-prod arr 0) (array []))
|
|
(check-equal? (array-axis-min arr 0) (array []))
|
|
(check-equal? (array-axis-max arr 0) (array []))
|
|
(check-exn exn? (λ () (array-axis-sum arr 1)))
|
|
(check-exn exn? (λ () (array-axis-prod arr 1)))
|
|
(check-exn exn? (λ () (array-axis-min arr 1)))
|
|
(check-exn exn? (λ () (array-axis-max arr 1)))
|
|
(check-equal? (array-axis-sum arr 1 0) (array [0 0 0]))
|
|
(check-equal? (array-axis-min arr 1 +inf.0) (array [+inf.0 +inf.0 +inf.0]))
|
|
(check-equal? (array-axis-max arr 1 -inf.0) (array [-inf.0 -inf.0 -inf.0]))
|
|
(check-equal? (array-axis-prod arr 1 1) (array [1 1 1]))
|
|
(check-exn exn? (λ () (array-all-sum arr)))
|
|
(check-exn exn? (λ () (array-all-prod arr)))
|
|
(check-exn exn? (λ () (array-all-min arr)))
|
|
(check-exn exn? (λ () (array-all-max arr)))
|
|
(check-equal? (array-all-sum arr 0) 0)
|
|
(check-equal? (array-all-prod arr 1) 1)
|
|
(check-equal? (array-all-min arr +inf.0) +inf.0)
|
|
(check-equal? (array-all-max arr -inf.0) -inf.0))
|
|
|
|
(let ([arr (make-array #() 0)])
|
|
(check-exn exn? (λ () (array-axis-sum arr 0)))
|
|
(check-exn exn? (λ () (array-axis-prod arr 0)))
|
|
(check-exn exn? (λ () (array-axis-min arr 0)))
|
|
(check-exn exn? (λ () (array-axis-max arr 0)))
|
|
(check-equal? (array-all-sum arr) 0)
|
|
(check-equal? (array-all-prod arr) 0)
|
|
(check-equal? (array-all-min arr) 0)
|
|
(check-equal? (array-all-max arr) 0))
|
|
|
|
(let ([arr (array [[1.0 1.0 2.0 3.0] [0.0 -1.0 2.0 3.0]])])
|
|
(check-equal? (array-axis-count arr 0 positive?) (array [1 1 2 2]))
|
|
(check-equal? (array-axis-count arr 1 positive?) (array [4 2]))
|
|
(check-equal? (array-all-count arr positive?) 6))
|
|
|
|
(let ([arr (array [[1.0 1.0 2.0 3.0] [0.0 -1.0 2.0 3.0]])])
|
|
(check-equal? (array-axis-andmap arr 0 positive?) (array [#f #f #t #t]))
|
|
(check-equal? (array-axis-andmap arr 1 positive?) (array [#t #f]))
|
|
(check-equal? (array-all-andmap arr positive?) #f))
|
|
|
|
(let ([arr (array [[1.0 1.0 2.0 3.0] [2.0 3.0 2.0 3.0]])])
|
|
(check-equal? (array-axis-andmap arr 0 positive?) (array [#t #t #t #t]))
|
|
(check-equal? (array-axis-andmap arr 1 positive?) (array [#t #t]))
|
|
(check-equal? (array-all-andmap arr positive?) #t))
|
|
|
|
(let ([arr (array [[-1.0 -1.0 -2.0 -3.0] [0.0 -1.0 2.0 3.0]])])
|
|
(check-equal? (array-axis-ormap arr 0 positive?) (array [#f #f #t #t]))
|
|
(check-equal? (array-axis-ormap arr 1 positive?) (array [#f #t]))
|
|
(check-equal? (array-all-ormap arr positive?) #t))
|
|
|
|
(let ([arr (array [[-1.0 -1.0 -2.0 -3.0] [-2.0 -3.0 -2.0 -3.0]])])
|
|
(check-equal? (array-axis-ormap arr 0 positive?) (array [#f #f #f #f]))
|
|
(check-equal? (array-axis-ormap arr 1 positive?) (array [#f #f]))
|
|
(check-equal? (array-all-ormap arr positive?) #f))
|
|
|
|
(let ([arr (make-array #() 0.0)])
|
|
(check-equal? (array-all-count arr positive?) 0)
|
|
(check-equal? (array-all-andmap arr positive?) #f)
|
|
(check-equal? (array-all-ormap arr positive?) #f))
|
|
|
|
(let ([arr (make-array #() 1.0)])
|
|
(check-equal? (array-all-count arr positive?) 1)
|
|
(check-equal? (array-all-andmap arr positive?) #t)
|
|
(check-equal? (array-all-ormap arr positive?) #t))
|
|
|
|
(let ([arr (make-array #(4 0) 0.0)])
|
|
(check-equal? (array-axis-count arr 0 positive?) (array []))
|
|
(check-equal? (array-axis-andmap arr 0 positive?) (array []))
|
|
(check-equal? (array-axis-ormap arr 0 positive?) (array []))
|
|
(check-equal? (array-axis-count arr 1 positive?) (array [0 0 0 0]))
|
|
(check-equal? (array-axis-andmap arr 1 positive?) (array [#t #t #t #t]))
|
|
(check-equal? (array-axis-ormap arr 1 positive?) (array [#f #f #f #f]))
|
|
(check-equal? (array-all-count arr positive?) 0)
|
|
(check-equal? (array-all-andmap arr positive?) #t)
|
|
(check-equal? (array-all-ormap arr positive?) #f))
|
|
|
|
;; ---------------------------------------------------------------------------------------------------
|
|
;; FFT
|
|
|
|
(check-exn exn? (λ () (array-fft (make-array #() 1))))
|
|
(check-exn exn? (λ () (array-fft (make-array #(0) 1))))
|
|
(check-exn exn? (λ () (array-fft (make-array #(3) 1))))
|
|
|
|
(let ([arr (make-array #(4) 1)])
|
|
(check array-all= (array-fft arr) (array [4 0 0 0]))
|
|
(check array-all= (array-inverse-fft (array-fft arr)) arr))
|
|
|
|
(let ([arr (make-array #(2 2) 1)])
|
|
(check array-all= (array-fft arr) (array [[4 0] [0 0]]))
|
|
(check array-all= (array-inverse-fft (array-fft arr)) arr))
|
|
|
|
;; ---------------------------------------------------------------------------------------------------
|
|
;; Unsafe ref
|
|
|
|
(check-equal? (unsafe-array-ref (make-array #() 0) (vector)) 0)
|
|
|
|
(let* ([arr (indexes-array #(2))])
|
|
(check-equal? (unsafe-array-ref arr ((inst vector Index) 0)) #(0))
|
|
(check-equal? (unsafe-array-ref arr ((inst vector Index) 1)) #(1)))
|
|
|
|
(let* ([arr (indexes-array #(2 2))])
|
|
(check-equal? (unsafe-array-ref arr ((inst vector Index) 0 0)) #(0 0))
|
|
(check-equal? (unsafe-array-ref arr ((inst vector Index) 1 1)) #(1 1)))
|
|
|
|
;; ---------------------------------------------------------------------------------------------------
|
|
;; Unsafe set!
|
|
|
|
(let* ([arr ((inst array->mutable-array Byte) (make-array #() 0))]
|
|
[idxs (vector)])
|
|
(unsafe-array-set! arr (vector) 1)
|
|
(check-equal? (unsafe-array-ref arr #()) 1)
|
|
(unsafe-array-set! arr #() 2)
|
|
(check-equal? (unsafe-array-ref arr #()) 2)
|
|
(unsafe-array-set! arr idxs 3)
|
|
(check-equal? (unsafe-array-ref arr #()) 3))
|
|
|
|
(let* ([arr (array->mutable-array (indexes-array #(2)))]
|
|
[idxs0 ((inst vector Index) 0)]
|
|
[idxs1 ((inst vector Index) 1)])
|
|
(unsafe-array-set! arr idxs0 ((inst vector Index) 6))
|
|
(unsafe-array-set! arr idxs1 ((inst vector Index) 7))
|
|
(check-equal? (unsafe-array-ref arr idxs0) #(6))
|
|
(check-equal? (unsafe-array-ref arr idxs1) #(7)))
|
|
|
|
(let* ([arr (array->mutable-array (indexes-array #(2 2)))]
|
|
[idxs0 ((inst vector Index) 0 0)]
|
|
[idxs1 ((inst vector Index) 1 1)])
|
|
(unsafe-array-set! arr idxs0 ((inst vector Index) 6 6))
|
|
(unsafe-array-set! arr idxs1 ((inst vector Index) 7 7))
|
|
(check-equal? (unsafe-array-ref arr idxs0) #(6 6))
|
|
(check-equal? (unsafe-array-ref arr idxs1) #(7 7)))
|
|
|
|
;; ---------------------------------------------------------------------------------------------------
|
|
;; Safe ref
|
|
|
|
(let* ([l-arr (make-array #() 0)]
|
|
[s-arr (array->mutable-array l-arr)]
|
|
[idxs #()]
|
|
[bad-idxs #(1)])
|
|
(check-equal? (array-ref l-arr (vector)) 0)
|
|
(check-equal? (array-ref s-arr (vector)) 0)
|
|
(check-equal? (array-ref l-arr #()) 0)
|
|
(check-equal? (array-ref s-arr #()) 0)
|
|
(check-equal? (array-ref l-arr idxs) 0)
|
|
(check-equal? (array-ref s-arr idxs) 0)
|
|
(check-exn exn? (λ () (array-ref l-arr (vector 1))))
|
|
(check-exn exn? (λ () (array-ref s-arr (vector 1))))
|
|
(check-exn exn? (λ () (array-ref l-arr #(1))))
|
|
(check-exn exn? (λ () (array-ref s-arr #(1))))
|
|
(check-exn exn? (λ () (array-ref l-arr bad-idxs)))
|
|
(check-exn exn? (λ () (array-ref s-arr bad-idxs))))
|
|
|
|
(let* ([l-arr (indexes-array #(2))]
|
|
[s-arr (array->mutable-array l-arr)]
|
|
[idxs0 #(0)]
|
|
[idxs1 #(1)]
|
|
[bad-idxs0 #(0 0)]
|
|
[bad-idxs1 #(-1)]
|
|
[bad-idxs2 #( 2)])
|
|
(check-equal? (array-ref l-arr (vector 0)) #(0))
|
|
(check-equal? (array-ref s-arr (vector 0)) #(0))
|
|
(check-equal? (array-ref l-arr (vector 1)) #(1))
|
|
(check-equal? (array-ref s-arr (vector 1)) #(1))
|
|
(check-equal? (array-ref l-arr #(0)) #(0))
|
|
(check-equal? (array-ref s-arr #(0)) #(0))
|
|
(check-equal? (array-ref l-arr #(1)) #(1))
|
|
(check-equal? (array-ref s-arr #(1)) #(1))
|
|
(check-equal? (array-ref l-arr idxs0) #(0))
|
|
(check-equal? (array-ref s-arr idxs0) #(0))
|
|
(check-equal? (array-ref l-arr idxs1) #(1))
|
|
(check-equal? (array-ref s-arr idxs1) #(1))
|
|
(check-exn exn? (λ () (array-ref l-arr (vector 0 0))))
|
|
(check-exn exn? (λ () (array-ref s-arr (vector 0 0))))
|
|
(check-exn exn? (λ () (array-ref l-arr (vector -1))))
|
|
(check-exn exn? (λ () (array-ref s-arr (vector -1))))
|
|
(check-exn exn? (λ () (array-ref l-arr (vector 2))))
|
|
(check-exn exn? (λ () (array-ref s-arr (vector 2))))
|
|
(check-exn exn? (λ () (array-ref l-arr #(0 0))))
|
|
(check-exn exn? (λ () (array-ref s-arr #(0 0))))
|
|
(check-exn exn? (λ () (array-ref l-arr #(-1))))
|
|
(check-exn exn? (λ () (array-ref s-arr #(-1))))
|
|
(check-exn exn? (λ () (array-ref l-arr #(2))))
|
|
(check-exn exn? (λ () (array-ref s-arr #(2))))
|
|
(check-exn exn? (λ () (array-ref l-arr bad-idxs0)))
|
|
(check-exn exn? (λ () (array-ref s-arr bad-idxs0)))
|
|
(check-exn exn? (λ () (array-ref l-arr bad-idxs1)))
|
|
(check-exn exn? (λ () (array-ref s-arr bad-idxs1)))
|
|
(check-exn exn? (λ () (array-ref l-arr bad-idxs2)))
|
|
(check-exn exn? (λ () (array-ref s-arr bad-idxs2))))
|
|
|
|
(let* ([l-arr (indexes-array #(2 2))]
|
|
[s-arr (array->mutable-array l-arr)]
|
|
[idxs0 #(0 0)]
|
|
[idxs1 #(1 1)])
|
|
(check-equal? (array-ref l-arr (vector 0 0)) #(0 0))
|
|
(check-equal? (array-ref s-arr (vector 0 0)) #(0 0))
|
|
(check-equal? (array-ref l-arr (vector 1 1)) #(1 1))
|
|
(check-equal? (array-ref s-arr (vector 1 1)) #(1 1))
|
|
(check-equal? (array-ref l-arr #(0 0)) #(0 0))
|
|
(check-equal? (array-ref s-arr #(0 0)) #(0 0))
|
|
(check-equal? (array-ref l-arr #(1 1)) #(1 1))
|
|
(check-equal? (array-ref s-arr #(1 1)) #(1 1))
|
|
(check-equal? (array-ref l-arr idxs0) #(0 0))
|
|
(check-equal? (array-ref s-arr idxs0) #(0 0))
|
|
(check-equal? (array-ref l-arr idxs1) #(1 1))
|
|
(check-equal? (array-ref s-arr idxs1) #(1 1)))
|
|
|
|
;; ---------------------------------------------------------------------------------------------------
|
|
;; Safe set!
|
|
|
|
(let* ([arr ((inst array->mutable-array Byte) (make-array #() 0))]
|
|
[idxs #()]
|
|
[bad-idxs #(1)])
|
|
(array-set! arr (vector) 1)
|
|
(check-equal? (array-ref arr #()) 1)
|
|
(array-set! arr #() 2)
|
|
(check-equal? (array-ref arr #()) 2)
|
|
(array-set! arr idxs 3)
|
|
(check-equal? (array-ref arr #()) 3)
|
|
(check-exn exn? (λ () (array-set! arr (vector 1) 2)))
|
|
(check-exn exn? (λ () (array-set! arr #(1) 2)))
|
|
(check-exn exn? (λ () (array-set! arr bad-idxs 2))))
|
|
|
|
(let* ([arr (array->mutable-array (indexes-array #(2)))]
|
|
[idxs0 #(0)]
|
|
[idxs1 #(1)]
|
|
[bad-idxs0 #(0 0)]
|
|
[bad-idxs1 #(-1)]
|
|
[bad-idxs2 #(2)]
|
|
[one ((inst vector Index) 1)])
|
|
(array-set! arr (vector 0) ((inst vector Index) 2))
|
|
(array-set! arr (vector 1) ((inst vector Index) 3))
|
|
(check-equal? (array-ref arr #(0)) #(2))
|
|
(check-equal? (array-ref arr #(1)) #(3))
|
|
(array-set! arr #(0) ((inst vector Index) 4))
|
|
(array-set! arr #(1) ((inst vector Index) 5))
|
|
(check-equal? (array-ref arr #(0)) #(4))
|
|
(check-equal? (array-ref arr #(1)) #(5))
|
|
(array-set! arr idxs0 ((inst vector Index) 6))
|
|
(array-set! arr idxs1 ((inst vector Index) 7))
|
|
(check-equal? (array-ref arr #(0)) #(6))
|
|
(check-equal? (array-ref arr #(1)) #(7))
|
|
(check-exn exn? (λ () (array-set! arr (vector 0 0) one)))
|
|
(check-exn exn? (λ () (array-set! arr (vector -1) one)))
|
|
(check-exn exn? (λ () (array-set! arr (vector 2) one)))
|
|
(check-exn exn? (λ () (array-set! arr #(0 0) one)))
|
|
(check-exn exn? (λ () (array-set! arr #(-1) one)))
|
|
(check-exn exn? (λ () (array-set! arr #(2) one)))
|
|
(check-exn exn? (λ () (array-set! arr bad-idxs0 one)))
|
|
(check-exn exn? (λ () (array-set! arr bad-idxs1 one)))
|
|
(check-exn exn? (λ () (array-set! arr bad-idxs2 one))))
|
|
|
|
(let* ([arr (array->mutable-array (indexes-array #(2 2)))]
|
|
[idxs0 #(0 0)]
|
|
[idxs1 #(1 1)])
|
|
(array-set! arr (vector 0 0) ((inst vector Index) 2 2))
|
|
(array-set! arr (vector 1 1) ((inst vector Index) 3 3))
|
|
(check-equal? (array-ref arr #(0 0)) #(2 2))
|
|
(check-equal? (array-ref arr #(1 1)) #(3 3))
|
|
(array-set! arr #(0 0) ((inst vector Index) 4 4))
|
|
(array-set! arr #(1 1) ((inst vector Index) 5 5))
|
|
(check-equal? (array-ref arr #(0 0)) #(4 4))
|
|
(check-equal? (array-ref arr #(1 1)) #(5 5))
|
|
(array-set! arr idxs0 ((inst vector Index) 6 6))
|
|
(array-set! arr idxs1 ((inst vector Index) 7 7))
|
|
(check-equal? (array-ref arr #(0 0)) #(6 6))
|
|
(check-equal? (array-ref arr #(1 1)) #(7 7)))
|
|
|
|
;; ---------------------------------------------------------------------------------------------------
|
|
;; Indexing
|
|
|
|
(let ([arr (mutable-array [[0 1 2 3 4 5]
|
|
[1 2 3 4 5 6]
|
|
[2 3 4 5 6 7]
|
|
[3 4 5 6 7 8]]
|
|
(U Integer Symbol))]
|
|
[idxs (array [#(0 0) #(1 1) #(1 2) #(2 3) #(3 4) #(3 5)])]
|
|
[vals (array ['a 'b 'c 'd 'e 'f])]
|
|
[slices (list (:: 0 4 2) (:: 2 -1 -2))])
|
|
(check-equal? (array-indexes-ref arr idxs)
|
|
(array [0 2 3 5 7 8]))
|
|
(check-equal? (array-indexes-ref arr (slice-indexes-array (array-shape arr) slices))
|
|
(array-slice-ref arr slices))
|
|
(array-indexes-set! arr idxs vals)
|
|
(check-equal? arr (array [['a 1 2 3 4 5]
|
|
[1 'b 'c 4 5 6]
|
|
[2 3 4 'd 6 7]
|
|
[3 4 5 6 'e 'f]])))
|
|
|
|
(check-equal? (array-slice-ref (indexes-array #()) (list (::new 2)))
|
|
(make-array #(2) #()))
|
|
|
|
(let ([arr (indexes-array #(2))])
|
|
(check-equal? (array-slice-ref arr (list (::) (::new 2)))
|
|
(array [[#(0) #(0)] [#(1) #(1)]]))
|
|
(check-equal? (array-slice-ref arr (list (::new 2) (::)))
|
|
(array [[#(0) #(1)] [#(0) #(1)]]))
|
|
(check-equal? (array-slice-ref arr (list (::)))
|
|
arr)
|
|
(check-equal? (array-slice-ref arr (list ::...))
|
|
arr))
|
|
|
|
(let ([arr (index-array #(10))])
|
|
(check-equal? (array-slice-ref arr (list (:: 0 10 2)))
|
|
(array [0 2 4 6 8]))
|
|
(check-equal? (array-slice-ref arr (list (:: #f 10 2)))
|
|
(array [0 2 4 6 8]))
|
|
(check-equal? (array-slice-ref arr (list (:: 0 #f 2)))
|
|
(array [0 2 4 6 8]))
|
|
(check-equal? (array-slice-ref arr (list (:: #f #f 2)))
|
|
(array [0 2 4 6 8]))
|
|
(check-equal? (array-slice-ref arr (list (:: 9 -1 -2)))
|
|
(array [9 7 5 3 1]))
|
|
(check-equal? (array-slice-ref arr (list (:: 9 #f -2)))
|
|
(array [9 7 5 3 1]))
|
|
(check-equal? (array-slice-ref arr (list (:: #f -1 -2)))
|
|
(array [9 7 5 3 1]))
|
|
(check-equal? (array-slice-ref arr (list (:: #f #f -2)))
|
|
(array [9 7 5 3 1]))
|
|
(check-equal? (array-slice-ref arr (list 4))
|
|
(array 4))
|
|
(check-exn exn? (λ () (array-slice-ref arr (list -1))))
|
|
(check-exn exn? (λ () (array-slice-ref arr (list 10))))
|
|
(check-exn exn? (λ () (array-slice-ref arr (list (:: 0 11 2)))))
|
|
(check-exn exn? (λ () (array-slice-ref arr (list (:: -1 10 2)))))
|
|
(check-exn exn? (λ () (array-slice-ref arr (list (:: 10 -1 -2)))))
|
|
(check-exn exn? (λ () (array-slice-ref arr (list (:: 9 -2 -2))))))
|
|
|
|
(let ([arr (index-array #(4 4))])
|
|
(check-equal? (array-slice-ref arr (list ::...))
|
|
arr)
|
|
(check-equal? (array-slice-ref arr (list (:: 0 4 2) (:: 0 4 2)))
|
|
(array [[0 2] [8 10]]))
|
|
(check-equal? (array-slice-ref arr (list (:: 0 4 2) ::...))
|
|
(array [[0 1 2 3] [8 9 10 11]]))
|
|
(check-equal? (array-slice-ref arr (list ::... (:: 0 4 2)))
|
|
(array [[0 2] [4 6] [8 10] [12 14]]))
|
|
(check-equal? (array-slice-ref arr (list (:: 0 4 2) 0))
|
|
(array [0 8]))
|
|
(check-equal? (array-slice-ref arr (list 0 (:: 0 4 2)))
|
|
(array [0 2]))
|
|
(check-equal? (array-slice-ref arr (list (::new 0) ::...))
|
|
(make-array #(0 4 4) 0))
|
|
(check-equal? (array-slice-ref arr (list (::new 1) ::...))
|
|
(array-axis-insert arr 0 1))
|
|
(check-equal? (array-slice-ref arr (list (::) (::new 1) (::)))
|
|
(array-axis-insert arr 1 1))
|
|
(check-equal? (array-slice-ref arr (list (::) (::) (::new 1)))
|
|
(array-axis-insert arr 2 1)))
|
|
|
|
;; ---------------------------------------------------------------------------------------------------
|
|
;; Transforms
|
|
|
|
(check-equal? (array-transform (indexes-array #(4 2))
|
|
#(2 4) (λ: ([js : (Vectorof Index)])
|
|
(match-define (vector j0 j1) js)
|
|
(vector j1 j0)))
|
|
(array [[#(0 0) #(1 0) #(2 0) #(3 0)]
|
|
[#(0 1) #(1 1) #(2 1) #(3 1)]]))
|
|
|
|
(check-exn exn? (λ () (array-strict (array-transform (indexes-array #(2 2)) #(3 3) identity))))
|
|
(check-exn exn? (λ () (array-strict (array-transform (indexes-array #(2 2)) #(2) identity))))
|
|
|
|
(check-equal? (unsafe-array-transform (indexes-array #(4 2))
|
|
((inst vector Index) 2 4)
|
|
(λ: ([js : (Vectorof Index)])
|
|
(match-define (vector j0 j1) js)
|
|
((inst vector Index) j1 j0)))
|
|
(array [[#(0 0) #(1 0) #(2 0) #(3 0)]
|
|
[#(0 1) #(1 1) #(2 1) #(3 1)]]))
|
|
|
|
;; Permutation
|
|
|
|
(let ([arr (make-array #() 0)])
|
|
(check-equal? (array-axis-permute arr '())
|
|
(array 0))
|
|
(check-exn exn? (λ () (array-axis-permute arr '(0)))))
|
|
|
|
(let ([arr (indexes-array #(4))])
|
|
(check-exn exn? (λ () (array-axis-permute arr '())))
|
|
(check-equal? (array-axis-permute arr '(0)) arr)
|
|
(check-exn exn? (λ () (array-axis-permute arr '(1)))))
|
|
|
|
(let ([arr (indexes-array #(2 2))])
|
|
(check-exn exn? (λ () (array-axis-permute arr '())))
|
|
(check-equal? (array-axis-permute arr '(0 1)) arr)
|
|
(check-equal? (array-axis-permute arr '(1 0))
|
|
(array [[#(0 0) #(1 0)]
|
|
[#(0 1) #(1 1)]])))
|
|
|
|
;; Transposition
|
|
|
|
(let ([arr (indexes-array #(4))])
|
|
(check-exn exn? (λ () (array-axis-swap arr 0 1)))
|
|
(check-equal? (array-axis-swap arr 0 0) arr))
|
|
|
|
(let ([arr (indexes-array #(2 2))])
|
|
(check-exn exn? (λ () (array-axis-swap arr 0 2)))
|
|
(check-equal? (array-axis-swap arr 0 0) arr)
|
|
(check-equal? (array-axis-swap arr 1 0)
|
|
(array [[#(0 0) #(1 0)]
|
|
[#(0 1) #(1 1)]])))
|
|
|
|
(check-equal? (array-axis-swap (indexes-array #(2 2 2)) 1 2)
|
|
(array [[[#(0 0 0) #(0 1 0)]
|
|
[#(0 0 1) #(0 1 1)]]
|
|
[[#(1 0 0) #(1 1 0)]
|
|
[#(1 0 1) #(1 1 1)]]]))
|
|
|
|
;; Adding axes
|
|
|
|
(let ([arr (indexes-array #())])
|
|
(check-exn exn? (λ () (array-axis-insert arr 1 1)))
|
|
(check-equal? (array-axis-insert arr 0 2)
|
|
(array [#() #()])))
|
|
|
|
(let ([arr (indexes-array #(4))])
|
|
(check-equal? (array-axis-insert arr 0 2)
|
|
(array [[#(0) #(1) #(2) #(3)]
|
|
[#(0) #(1) #(2) #(3)]]))
|
|
(check-equal? (array-axis-insert arr 1 2)
|
|
(array [[#(0) #(0)] [#(1) #(1)] [#(2) #(2)] [#(3) #(3)]])))
|
|
|
|
;; Removing axes
|
|
|
|
(let ([arr (indexes-array #())])
|
|
(check-exn exn? (λ () (array-axis-ref arr 0 0))))
|
|
|
|
(let ([arr (indexes-array #(4))])
|
|
(check-exn exn? (λ () (array-axis-ref arr 1 0)))
|
|
(check-equal? (array-axis-ref arr 0 2)
|
|
(array #(2))))
|
|
|
|
(let ([arr (indexes-array #(2 2))])
|
|
(check-equal? (array-axis-ref arr 0 0)
|
|
(array [#(0 0) #(0 1)]))
|
|
(check-equal? (array-axis-ref arr 1 0)
|
|
(array [#(0 0) #(1 0)])))
|
|
|
|
;; Reshape, flatten
|
|
|
|
(let ([arr (indexes-array #())])
|
|
(check-exn exn? (λ () (array-reshape arr #(0))))
|
|
(check-equal? (array-reshape arr #(1))
|
|
(array [#()]))
|
|
(check-equal? (array-flatten arr)
|
|
(array [#()])))
|
|
|
|
(let ([arr (array-map (λ: ([js : Indexes]) (vector-ref js 0))
|
|
(indexes-array #(4)))])
|
|
(check-exn exn? (λ () (array-reshape arr #())))
|
|
(check-equal? (array-reshape arr #(2 2))
|
|
(array [[0 1] [2 3]]))
|
|
(check-equal? (array-flatten arr)
|
|
(array [0 1 2 3])))
|
|
|
|
;; Append
|
|
|
|
(check-exn exn? (λ () (array-append* (list))))
|
|
(check-exn exn? (λ () (array-append* (list (array 0) (array 1)))))
|
|
|
|
(check-equal? (array-append* (list (array [0])))
|
|
(array [0]))
|
|
(check-equal? (array-append* (list (array [0]) (array [1])))
|
|
(array [0 1]))
|
|
(check-equal? (array-append* (list (array [0]) (array 1)))
|
|
(array [0 1]))
|
|
(check-equal? (array-append* (list (array 0) (array [1])))
|
|
(array [0 1]))
|
|
(check-equal? (array-append* (list (array [0 1 2]) (array [3 4 5])))
|
|
(array [0 1 2 3 4 5]))
|
|
(check-exn exn? (λ () (array-append* (list (array [0]) (array [1])) 1)))
|
|
|
|
(check-equal? (array-append* (list (array [[0 1] [2 3]]) (array [[4 5] [6 7]])))
|
|
(array [[0 1] [2 3] [4 5] [6 7]]))
|
|
(check-equal? (array-append* (list (array [[0 1] [2 3]]) (array [[4 5] [6 7]])) 1)
|
|
(array [[0 1 4 5] [2 3 6 7]]))
|
|
(check-equal? (array-append* (list (array [[0 1] [2 3]]) (array 0)) 0)
|
|
(array [[0 1] [2 3] [0 0]]))
|
|
(check-equal? (array-append* (list (array [[0 1] [2 3]]) (array 0)) 1)
|
|
(array [[0 1 0] [2 3 0]]))
|
|
(check-equal? (array-append* (list (array [[0 1 2] [3 4 5]]) (array [0 1])) 1)
|
|
(array [[0 1 2 0 1] [3 4 5 0 1]]))
|
|
(check-exn exn? (λ () (array-append* (list (array [[0 1 2] [3 4 5]]) (array [0 1])) 0)))
|
|
|
|
;; ---------------------------------------------------------------------------------------------------
|
|
;; Comprehensions
|
|
|
|
(check-equal? (for/array: #:shape #() () : Integer 3)
|
|
(mutable-array 3))
|
|
(check-equal? (for/array: #:shape #() () : Symbol 'foo)
|
|
(mutable-array 'foo))
|
|
(check-equal? (for/array: #:shape #(2) ([x (in-naturals)]) : Integer x)
|
|
(mutable-array [0 1]))
|
|
(check-equal? (for/array: #:shape #(2 3) ([i (in-range 0 6)]) : (Vectorof Integer)
|
|
(vector (quotient i 3) (remainder i 3)))
|
|
(indexes-array #(2 3)))
|
|
|
|
(check-equal? (for*/array: #:shape #() () : Integer 3)
|
|
(mutable-array 3))
|
|
(check-equal? (for*/array: #:shape #() () : Symbol 'foo)
|
|
(mutable-array 'foo))
|
|
(check-equal? (for*/array: #:shape #(2) ([x (in-naturals)]) : Integer x)
|
|
(mutable-array [0 1]))
|
|
(check-equal? (for*/array: #:shape #(2 3) ([i (in-range 0 2)]
|
|
[j (in-range 0 3)]
|
|
) : (Vectorof Integer)
|
|
(vector i j))
|
|
(indexes-array #(2 3)))
|
|
|
|
(check-equal? (for*/array: #:shape #() () : Integer 3)
|
|
(for*/array: #:shape #() () : Integer 3))
|
|
(check-equal? (for*/array: #:shape #() () : Symbol 'foo)
|
|
(for*/array: #:shape #() () : Symbol 'foo))
|
|
(check-equal? (for*/array: #:shape #(2) ([x (in-naturals)]) : Integer x)
|
|
(for*/array: #:shape #(2) ([x (in-naturals)]) : Integer x))
|
|
(check-equal? (for*/array: #:shape #(2 3) ([i (in-range 0 2)]
|
|
[j (in-range 0 3)]
|
|
) : (Listof Integer)
|
|
(list i j))
|
|
(for*/array: #:shape #(2 3) ([i (in-range 0 2)]
|
|
[j (in-range 0 3)]
|
|
) : (Listof Integer)
|
|
(list i j)))
|
|
|
|
;; ---------------------------------------------------------------------------------------------------
|
|
;; Sequences
|
|
|
|
(check-equal? (for/list: : (Listof Number) ([x (in-array (array [[1 2 3] [4 5 6]]))]) x)
|
|
'(1 2 3 4 5 6))
|
|
|
|
(check-equal? (for/list: : (Listof Indexes) ([js (in-array (indexes-array #()))]) js)
|
|
'(#()))
|
|
(check-equal? (for/list: : (Listof Indexes) ([js (in-array (indexes-array #(0)))]) js)
|
|
'())
|
|
(check-equal? (for/list: : (Listof Indexes) ([js (in-array (indexes-array #(2 2)))]) js)
|
|
'(#(0 0) #(0 1) #(1 0) #(1 1)))
|
|
|
|
(check-equal? (sequence->list (in-array (indexes-array #())))
|
|
'(#()))
|
|
(check-equal? (sequence->list (in-array (indexes-array #(0))))
|
|
'())
|
|
(check-equal? (sequence->list (in-array (indexes-array #(2 2))))
|
|
'(#(0 0) #(0 1) #(1 0) #(1 1)))
|
|
|
|
(check-equal? (for/list: : (Listof Indexes) ([js (in-array-indexes #())]) js)
|
|
'(#()))
|
|
(check-equal? (for/list: : (Listof Indexes) ([js (in-array-indexes #(0))]) js)
|
|
'())
|
|
(check-equal? (for/list: : (Listof Indexes) ([js (in-array-indexes #(2 2))]) js)
|
|
'(#(0 0) #(0 1) #(1 0) #(1 1)))
|
|
(check-equal? (sequence->list (in-array-indexes #()))
|
|
'(#()))
|
|
(check-equal? (sequence->list (in-array-indexes #(0)))
|
|
'())
|
|
(check-equal? (sequence->list (in-array-indexes #(2 2)))
|
|
'(#(0 0) #(0 1) #(1 0) #(1 1)))
|
|
|
|
(check-equal? (for/list: : (Listof Indexes) ([js (in-unsafe-array-indexes #(2 2))]) js)
|
|
'(#(0 0) #(0 0) #(0 0) #(0 0)))
|
|
(check-equal? (for/list: : (Listof Indexes) ([js (in-unsafe-array-indexes #())]) (vector-copy js))
|
|
'(#()))
|
|
(check-equal? (for/list: : (Listof Indexes) ([js (in-unsafe-array-indexes #(0))]) (vector-copy js))
|
|
'())
|
|
(check-equal? (for/list: : (Listof Indexes) ([js (in-unsafe-array-indexes #(2 2))]) (vector-copy js))
|
|
'(#(0 0) #(0 1) #(1 0) #(1 1)))
|
|
(check-equal? (sequence->list (in-unsafe-array-indexes #()))
|
|
'(#()))
|
|
(check-equal? (sequence->list (in-unsafe-array-indexes #(0)))
|
|
'())
|
|
(check-equal? (sequence->list (in-unsafe-array-indexes #(2 2)))
|
|
'(#(0 0) #(0 1) #(1 0) #(1 1)))
|
|
|
|
(let ([arr (indexes-array #(4 5))])
|
|
(check-equal? (for/list: : (Listof (Listof Indexes)) ([brr (in-array-axis arr 0)])
|
|
(for/list: : (Listof Indexes) ([js (in-array brr)])
|
|
js))
|
|
(array->list* arr))
|
|
(check-equal? (for/list: : (Listof (Listof Indexes)) ([brr (in-array-axis arr 1)])
|
|
(for/list: : (Listof Indexes) ([js (in-array brr)])
|
|
js))
|
|
(array->list* (array-axis-swap arr 0 1))))
|
|
|
|
(check-equal? (array-list->array empty 0)
|
|
(array []))
|
|
(check-exn exn? (λ () (array-list->array empty 1)))
|
|
|
|
(check-equal? (array-list->array (list (array 0) (array 1) (array 2)) 0)
|
|
(array [0 1 2]))
|
|
(check-exn exn? (λ () (array-list->array (list (array 0) (array 1) (array 2)) 1)))
|
|
|
|
(check-equal? (array-list->array (list (array [0 1]) (array [2 3])) 0)
|
|
(array [[0 1] [2 3]]))
|
|
(check-equal? (array-list->array (list (array [0 1]) (array [2 3])) 1)
|
|
(array [[0 2] [1 3]]))
|
|
|
|
(check-equal? (array-list->array (list (array [0 1 2]) (array 0)) 0)
|
|
(array [[0 1 2] [0 0 0]]))
|
|
(check-equal? (array-list->array (list (array [0 1 2]) (array 0)) 1)
|
|
(array [[0 0] [1 0] [2 0]]))
|
|
(check-exn exn? (λ () (array-list->array (list (array [0 1 2]) (array 0)) 2)))
|
|
|
|
(check-equal? (array-list->array (list (array [[0 1] [2 3]]) (array 0)) 0)
|
|
(array [[[0 1] [2 3]] [[0 0] [0 0]]]))
|
|
|
|
(check-equal? (array->array-list (array-list->array empty 0) 0)
|
|
empty)
|
|
(check-exn exn? (λ () (array->array-list (array-list->array empty 0) 1)))
|
|
|
|
(check-equal? (array->array-list (array-list->array (list (array 0) (array 1) (array 2)) 0) 0)
|
|
(list (array 0) (array 1) (array 2)))
|
|
|
|
(check-equal? (array->array-list (array-list->array (list (array [0 1]) (array [2 3])) 0) 0)
|
|
(list (array [0 1]) (array [2 3])))
|
|
(check-equal? (array->array-list (array-list->array (list (array [0 1]) (array [2 3])) 1) 1)
|
|
(list (array [0 1]) (array [2 3])))
|
|
|
|
(check-equal? (array->array-list (array-list->array (list (array [0 1 2]) (array 0)) 0) 0)
|
|
(list (array [0 1 2]) (array [0 0 0])))
|
|
(check-equal? (array->array-list (array-list->array (list (array [0 1 2]) (array 0)) 1) 1)
|
|
(list (array [0 1 2]) (array [0 0 0])))
|
|
|
|
(check-equal? (array->array-list (array-list->array (list (array [[0 1] [2 3]]) (array 0)) 0) 0)
|
|
(list (array [[0 1] [2 3]]) (array [[0 0] [0 0]])))
|
|
|
|
;; ---------------------------------------------------------------------------------------------------
|
|
;; Conditionals
|
|
|
|
(let ([arr (build-array #(10 10) (λ: ([js : Indexes]) (apply + (vector->list js))))])
|
|
(check-equal? (array-if (array< arr (array 5))
|
|
(array 0)
|
|
(array 1))
|
|
(array-map (λ: ([v : Integer]) (if (v . < . 5) 0 1)) arr))
|
|
(check-equal? (array-or (array< arr (make-array #(10 10) 9))
|
|
(array> arr (make-array #(10 10) 9)))
|
|
(array-map (λ: ([v : Integer]) (or (< v 9) (> v 9))) arr))
|
|
(check-equal? (array-and (array< arr (make-array #(10 10) 10))
|
|
(array> arr (make-array #(10 10) 8)))
|
|
(array-map (λ: ([v : Integer]) (= v 9)) arr)))
|
|
|
|
;; ---------------------------------------------------------------------------------------------------
|
|
;; Lazy arrays
|
|
|
|
(define (make-lazy-arr)
|
|
(: arr (Array Integer))
|
|
(define arr
|
|
(array-lazy
|
|
(build-array
|
|
#(12 12)
|
|
(λ: ([js : Indexes])
|
|
(match-define (vector j0 j1) js)
|
|
(cond [(or (= j0 0) (= j1 0)) 1]
|
|
[(undefined? arr) (error 'undefined)]
|
|
[else (+ (array-ref arr (vector (- j0 1) j1))
|
|
(array-ref arr (vector j0 (- j1 1))))])))))
|
|
arr)
|
|
|
|
(define (make-mutable-arr)
|
|
(define: arr : (Mutable-Array Integer)
|
|
(array->mutable-array
|
|
(build-array
|
|
#(12 12)
|
|
(λ: ([js : Indexes])
|
|
(match-define (vector j0 j1) js)
|
|
(cond [(or (= j0 0) (= j1 0)) 1]
|
|
[else 0])))))
|
|
(for*: ([j0 (in-range 1 12)]
|
|
[j1 (in-range 1 12)])
|
|
(array-set! arr (vector j0 j1)
|
|
(+ (array-ref arr (vector (- j0 1) j1))
|
|
(array-ref arr (vector j0 (- j1 1))))))
|
|
arr)
|
|
|
|
(check-equal? (make-lazy-arr)
|
|
(make-mutable-arr))
|
|
|
|
(check-equal? (array-lazy (array-axis-swap (indexes-array #(4 4)) 0 1))
|
|
(array-axis-swap (indexes-array #(4 4)) 0 1))
|