Array changes in response to user feedback (and my personal neuroses)
* `list->array' now accepts an optional shape argument, and always returns an immutable array * `vector->array' now accepts an optional shape argument, and always returns a mutable array * Removed `make-mutable-array' because `vector->array' does its job now (I never liked the name anyway) * Renamed `unsafe-mutable-array' to `unsafe-vector->array' * Added optional type annotation to `array' macro to match `mutable-array' * Reworded error messages in array broadcasting functions * Made minor array doc fixes
This commit is contained in:
parent
8c66be33e7
commit
b8efd58aca
|
@ -21,7 +21,7 @@
|
|||
(let ([shift (- new-dims old-dims)])
|
||||
(cond [(index? shift) shift]
|
||||
[else (error 'array-broadcast
|
||||
"cannot broadcast to lower-dimensional array; given ~e and ~e"
|
||||
"cannot broadcast to a lower-dimensional shape; given ~e and ~e"
|
||||
arr new-ds)])))
|
||||
(define old-js (make-thread-local-indexes old-dims))
|
||||
(define old-f (unsafe-array-proc arr))
|
||||
|
@ -95,8 +95,10 @@
|
|||
(: array-shape-broadcast (case-> ((Listof Indexes) -> Indexes)
|
||||
((Listof Indexes) (U #f #t 'permissive) -> Indexes)))
|
||||
(define (array-shape-broadcast dss [broadcasting (array-broadcasting)])
|
||||
(define (fail) (error 'array-shape-broadcast "incompatible array shapes (broadcasting ~v): ~a"
|
||||
broadcasting (string-join (map (λ (ds) (format "~e" ds)) dss) ", ")))
|
||||
(define (fail) (error 'array-shape-broadcast
|
||||
"incompatible array shapes (array-broadcasting ~v): ~a"
|
||||
broadcasting
|
||||
(string-join (map (λ (ds) (format "~e" ds)) dss) ", ")))
|
||||
(cond [(empty? dss) #()]
|
||||
[else (for/fold ([new-ds (first dss)]) ([ds (in-list (rest dss))])
|
||||
(shape-broadcast2 new-ds ds fail broadcasting))]))
|
||||
|
|
|
@ -23,14 +23,14 @@
|
|||
ds (λ () (raise-argument-error 'name "Indexes" ds)))])
|
||||
(define vs (for/vector #:length (array-shape-size ds) maybe-fill ...
|
||||
(clause ...) maybe-type ... body ...))
|
||||
(unsafe-mutable-array ds vs))))]
|
||||
(unsafe-vector->array ds vs))))]
|
||||
[(_ name:id for/vector:id (clause ...) (~optional (~seq : A:expr)) body:expr ...+)
|
||||
(with-syntax ([(maybe-type ...) (if (attribute A) #'(: A) #'())])
|
||||
(syntax/loc stx
|
||||
(let ()
|
||||
(define vs (for/vector (clause ...) maybe-type ... body ...))
|
||||
(define ds ((inst vector Index) (vector-length vs)))
|
||||
(unsafe-mutable-array ds vs))))]))
|
||||
(unsafe-vector->array ds vs))))]))
|
||||
|
||||
(define-syntax-rule (for/array: e ...)
|
||||
(base-for/array: for/array: for/vector: e ...))
|
||||
|
@ -49,13 +49,13 @@
|
|||
ds (λ () (raise-argument-error 'name "Indexes" ds)))])
|
||||
(define vs (for/vector #:length (array-shape-size ds) maybe-fill ...
|
||||
(clause ...) body ...))
|
||||
(unsafe-mutable-array ds vs))))]
|
||||
(unsafe-vector->array ds vs))))]
|
||||
[(_ name:id for/vector:id (clause ...) body:expr ...+)
|
||||
(syntax/loc stx
|
||||
(let ()
|
||||
(define vs (for/vector (clause ...) body ...))
|
||||
(define ds ((inst vector Index) (vector-length vs)))
|
||||
(unsafe-mutable-array ds vs)))]))
|
||||
(unsafe-vector->array ds vs)))]))
|
||||
|
||||
(define-syntax-rule (for/array e ...)
|
||||
(base-for/array for/array for/vector e ...))
|
||||
|
|
|
@ -15,8 +15,6 @@
|
|||
vector*->array
|
||||
array->list*
|
||||
array->vector*
|
||||
list->array
|
||||
vector->array
|
||||
array->list
|
||||
array->vector)
|
||||
|
||||
|
|
|
@ -37,7 +37,7 @@
|
|||
(define (parallel-array->mutable-array arr)
|
||||
(define size (array-size arr))
|
||||
(cond
|
||||
[(zero? size) (unsafe-mutable-array (array-shape arr) (vector))]
|
||||
[(zero? size) (unsafe-vector->array (array-shape arr) (vector))]
|
||||
[else
|
||||
(define ds (array-shape arr))
|
||||
(define dims (vector-length ds))
|
||||
|
@ -61,7 +61,7 @@
|
|||
(for: ([f (in-list futures)])
|
||||
(touch f))
|
||||
|
||||
(unsafe-mutable-array ds vs))]))
|
||||
(unsafe-vector->array ds vs))]))
|
||||
|
||||
(: parallel-array-strict (All (A) ((Array A) -> (Array A))))
|
||||
(define (parallel-array-strict arr)
|
||||
|
|
|
@ -4,13 +4,18 @@
|
|||
typed/racket/base
|
||||
(for-syntax racket/base syntax/parse)
|
||||
"array-syntax.rkt"
|
||||
(except-in "typed-array-struct.rkt" build-array build-strict-array))
|
||||
(except-in "typed-array-struct.rkt"
|
||||
build-array
|
||||
build-strict-array
|
||||
list->array))
|
||||
|
||||
(require/untyped-contract
|
||||
(begin (require "typed-array-struct.rkt"))
|
||||
"typed-array-struct.rkt"
|
||||
[build-array (All (A) ((Vectorof Integer) ((Vectorof Index) -> A) -> (Array A)))]
|
||||
[build-strict-array (All (A) ((Vectorof Integer) ((Vectorof Index) -> A) -> (Array A)))])
|
||||
[build-strict-array (All (A) ((Vectorof Integer) ((Vectorof Index) -> A) -> (Array A)))]
|
||||
[list->array (All (A) (case-> ((Listof A) -> (Array A))
|
||||
((Vectorof Integer) (Listof A) -> (Array A))))])
|
||||
|
||||
(define-syntax array? (make-rename-transformer #'Array?))
|
||||
(define-syntax array-shape (make-rename-transformer #'Array-shape))
|
||||
|
@ -27,10 +32,13 @@
|
|||
array-strict
|
||||
array-strict!
|
||||
array-strict?
|
||||
make-unsafe-array-proc
|
||||
build-array
|
||||
build-strict-array
|
||||
list->array
|
||||
make-unsafe-array-proc
|
||||
unsafe-build-array
|
||||
unsafe-build-strict-array
|
||||
unsafe-list->array
|
||||
unsafe-array-proc
|
||||
array-lazy
|
||||
array
|
||||
|
@ -46,8 +54,11 @@
|
|||
array-lift-comparison)
|
||||
|
||||
(define-syntax (array stx)
|
||||
(syntax-parse stx
|
||||
[(_ e:expr) (syntax/loc stx (array/syntax array list flat-list->array e))]
|
||||
(syntax-parse stx #:literals (:)
|
||||
[(_ e:expr)
|
||||
(syntax/loc stx (array/syntax array list unsafe-list->array e))]
|
||||
[(_ e:expr : T:expr)
|
||||
(syntax/loc stx (array/syntax array (inst list T) unsafe-list->array e))]
|
||||
[_:id (raise-syntax-error 'array "not allowed as an expression" stx)]))
|
||||
|
||||
(define-syntax-rule (array-strict arr-expr)
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
#lang racket/base
|
||||
|
||||
(require (for-syntax racket/base))
|
||||
(require (for-syntax racket/base)
|
||||
(only-in typed/racket/base inst Index))
|
||||
|
||||
(provide array/syntax)
|
||||
|
||||
|
@ -40,4 +41,4 @@
|
|||
(with-syntax ([(d ...) ds]
|
||||
[(v ...) (syntax-vector-flatten #'e)])
|
||||
(syntax/loc stx
|
||||
(->array (vector d ...) (constr v ...)))))]))
|
||||
(->array ((inst vector Index) d ...) (constr v ...)))))]))
|
||||
|
|
|
@ -5,20 +5,21 @@
|
|||
(for-syntax racket/base syntax/parse)
|
||||
"array-syntax.rkt"
|
||||
(except-in "typed-mutable-array.rkt"
|
||||
make-mutable-array))
|
||||
vector->array))
|
||||
|
||||
(require/untyped-contract
|
||||
(begin (require "typed-mutable-array.rkt"))
|
||||
"typed-mutable-array.rkt"
|
||||
[make-mutable-array (All (A) ((Vectorof Integer) (Vectorof A) -> (Mutable-Array A)))])
|
||||
[vector->array (All (A) (case-> ((Vectorof A) -> (Mutable-Array A))
|
||||
((Vectorof Integer) (Vectorof A) -> (Mutable-Array A))))])
|
||||
|
||||
(provide
|
||||
;; Mutable-Array
|
||||
Mutable-Array
|
||||
mutable-array?
|
||||
mutable-array-data
|
||||
make-mutable-array
|
||||
unsafe-mutable-array
|
||||
vector->array
|
||||
unsafe-vector->array
|
||||
mutable-array-copy
|
||||
mutable-array
|
||||
;; Conversion
|
||||
|
@ -28,7 +29,7 @@
|
|||
(define-syntax (mutable-array stx)
|
||||
(syntax-parse stx #:literals (:)
|
||||
[(_ e:expr)
|
||||
(syntax/loc stx (array/syntax mutable-array vector make-mutable-array e))]
|
||||
(syntax/loc stx (array/syntax mutable-array vector unsafe-vector->array e))]
|
||||
[(_ e:expr : T:expr)
|
||||
(syntax/loc stx (array/syntax mutable-array (inst vector T) make-mutable-array e))]
|
||||
(syntax/loc stx (array/syntax mutable-array (inst vector T) unsafe-vector->array e))]
|
||||
[_:id (raise-syntax-error 'mutable-array "not allowed as an expression" stx)]))
|
||||
|
|
|
@ -11,14 +11,6 @@
|
|||
;; Conversion to arrays
|
||||
(make-to-array-functions list*->array vector*->array)
|
||||
|
||||
(: list->array (All (A) ((Listof A) -> (Array A))))
|
||||
(define (list->array xs)
|
||||
(vector->array (list->vector xs)))
|
||||
|
||||
(: vector->array (All (A) ((Vectorof A) -> (Array A))))
|
||||
(define (vector->array xs)
|
||||
(unsafe-mutable-array ((inst vector Index) (vector-length xs)) xs))
|
||||
|
||||
(: array->list (All (A) ((Array A) -> (Listof A))))
|
||||
(define (array->list arr)
|
||||
(vector->list (array->vector arr)))
|
||||
|
|
|
@ -113,12 +113,25 @@
|
|||
(unsafe-build-strict-array ds (λ: ([js : Indexes])
|
||||
(proc (vector->immutable-vector js))))))
|
||||
|
||||
(: flat-list->array (All (A) (In-Indexes (Listof A) -> (Array A))))
|
||||
(define (flat-list->array ds lst)
|
||||
(let ([ds (check-array-shape ds (λ () (raise-argument-error 'array "(Vectorof Index)" ds)))])
|
||||
(define vs (list->vector lst))
|
||||
(unsafe-build-strict-array
|
||||
ds (λ: ([js : Indexes]) (unsafe-vector-ref vs (unsafe-array-index->value-index ds js))))))
|
||||
(: unsafe-list->array (All (A) (Indexes (Listof A) -> (Array A))))
|
||||
(define (unsafe-list->array ds xs)
|
||||
(define vs (list->vector xs))
|
||||
(unsafe-build-strict-array
|
||||
ds (λ: ([js : Indexes]) (unsafe-vector-ref vs (unsafe-array-index->value-index ds js)))))
|
||||
|
||||
(: list->array (All (A) (case-> ((Listof A) -> (Array A))
|
||||
(In-Indexes (Listof A) -> (Array A)))))
|
||||
(define list->array
|
||||
(case-lambda
|
||||
[(xs) (unsafe-list->array ((inst vector Index) (length xs)) xs)]
|
||||
[(ds xs)
|
||||
(let* ([ds (check-array-shape
|
||||
ds (λ () (raise-argument-error 'list->array "(Vectorof Index)" 0 ds xs)))]
|
||||
[size (array-shape-size ds)]
|
||||
[n (length xs)])
|
||||
(if (= size n)
|
||||
(unsafe-list->array ds xs)
|
||||
(raise-argument-error 'list->array (format "List of length ~e" size) 1 ds xs)))]))
|
||||
|
||||
(: array-lazy (All (A) ((Array A) -> (Array A))))
|
||||
(define (array-lazy arr)
|
||||
|
|
|
@ -17,28 +17,33 @@
|
|||
(define mutable-array? Mutable-Array?)
|
||||
(define mutable-array-data Mutable-Array-data)
|
||||
|
||||
(: unsafe-mutable-array (All (A) (Indexes (Vectorof A) -> (Mutable-Array A))))
|
||||
(define (unsafe-mutable-array ds vs)
|
||||
(: unsafe-vector->array (All (A) (Indexes (Vectorof A) -> (Mutable-Array A))))
|
||||
(define (unsafe-vector->array ds vs)
|
||||
(define proc (make-unsafe-array-proc ds (λ (j) (unsafe-vector-ref vs j))))
|
||||
(define set-proc (make-unsafe-array-set-proc A ds (λ (j v) (unsafe-vector-set! vs j v))))
|
||||
(Mutable-Array ds (vector-length vs) (box #t) void proc set-proc vs))
|
||||
|
||||
(: make-mutable-array (All (A) (In-Indexes (Vectorof A) -> (Mutable-Array A))))
|
||||
(define (make-mutable-array ds vs)
|
||||
(let* ([ds (check-array-shape
|
||||
ds (λ () (raise-argument-error 'make-mutable-array "(Vectorof Index)" 0 ds vs)))]
|
||||
[size (array-shape-size ds)]
|
||||
[n (vector-length vs)])
|
||||
(cond [(= size n) (unsafe-mutable-array ds vs)]
|
||||
[else (raise-argument-error 'mutable-array (format "Vector of length ~e" size) 1 ds vs)])))
|
||||
(: vector->array (All (A) (case-> ((Vectorof A) -> (Mutable-Array A))
|
||||
(In-Indexes (Vectorof A) -> (Mutable-Array A)))))
|
||||
(define vector->array
|
||||
(case-lambda
|
||||
[(vs) (unsafe-vector->array ((inst vector Index) (vector-length vs)) vs)]
|
||||
[(ds vs)
|
||||
(let* ([ds (check-array-shape
|
||||
ds (λ () (raise-argument-error 'vector->array "(Vectorof Index)" 0 ds vs)))]
|
||||
[size (array-shape-size ds)]
|
||||
[n (vector-length vs)])
|
||||
(if (= size n)
|
||||
(unsafe-vector->array ds vs)
|
||||
(raise-argument-error 'vector->array (format "Vector of length ~e" size) 1 ds vs)))]))
|
||||
|
||||
(: mutable-array-copy (All (A) ((Mutable-Array A) -> (Mutable-Array A))))
|
||||
(define (mutable-array-copy arr)
|
||||
(unsafe-mutable-array (array-shape arr) (vector-copy-all (mutable-array-data arr))))
|
||||
(unsafe-vector->array (array-shape arr) (vector-copy-all (mutable-array-data arr))))
|
||||
|
||||
(: flat-vector->matrix : (All (A) (Index Index (Vectorof A) -> (Array A))))
|
||||
(define (flat-vector->matrix m n v)
|
||||
(make-mutable-array (vector m n) v))
|
||||
(vector->array (vector m n) v))
|
||||
|
||||
;; ===================================================================================================
|
||||
;; Conversions
|
||||
|
@ -47,4 +52,4 @@
|
|||
(define (array->mutable-array arr)
|
||||
(define ds (array-shape arr))
|
||||
(define g (unsafe-array-proc arr))
|
||||
(unsafe-mutable-array ds (inline-build-array-data ds (λ (js j) (g js)) A)))
|
||||
(unsafe-vector->array ds (inline-build-array-data ds (λ (js j) (g js)) A)))
|
||||
|
|
|
@ -87,7 +87,7 @@
|
|||
(cond [(pred? lst) (unsafe-build-strict-array #() (λ (js) lst))]
|
||||
[ds (let ([ds (check-array-shape ds raise-shape-error)])
|
||||
(define size (array-shape-size ds))
|
||||
(unsafe-mutable-array ds (list*->flat-vector lst size pred?)))]
|
||||
(unsafe-vector->array ds (list*->flat-vector lst size pred?)))]
|
||||
[else (raise-shape-error)]))
|
||||
|
||||
(: vector*->array (All (A) ((Vectorof* A) ((Vectorof* A) -> Any : A) -> (Array A))))
|
||||
|
|
|
@ -24,9 +24,9 @@
|
|||
@title[#:tag "arrays" #:style 'toc]{Arrays}
|
||||
@(author-neil)
|
||||
|
||||
@bold{Performance Warning:} Most of the array-producing functions exported by
|
||||
@racketmodname[math/array] run 25-50 times slower in untyped Racket, due to the
|
||||
overhead of checking higher-order contracts. We are working on it.
|
||||
@bold{Performance Warning:} Indexing the elements of arrays created in untyped Racket
|
||||
is currently 25-50 times slower than doing the same in Typed Racket, due to the overhead
|
||||
of checking higher-order contracts. We are working on it.
|
||||
|
||||
For now, if you need speed, use the @racketmodname[typed/racket] language.
|
||||
|
||||
|
@ -301,8 +301,8 @@ operations to succeed only if array shapes match exactly:
|
|||
(array* (index-array #(3 3)) (array 10)))]
|
||||
|
||||
Another option is @hyperlink["http://www.r-project.org"]{R}-style permissive broadcasting,
|
||||
which allows pointwise operations to @italic{always} succeed, by repeating any axis instead
|
||||
of stretching just singleton axes:
|
||||
which allows pointwise operations to @italic{always} succeed, by repeating shorter axes' rows
|
||||
instead of repeating just singleton axes' rows:
|
||||
@interaction[#:eval typed-eval
|
||||
(define arr10 (array-map number->string (index-array #(10))))
|
||||
(define arr3 (array-map number->string (index-array #(3))))
|
||||
|
@ -479,12 +479,14 @@ Returns the vector of data that @racket[arr] contains.
|
|||
|
||||
@section{Construction}
|
||||
|
||||
@defform[(array #[#[...] ...])]{
|
||||
@defform/subs[(array #[#[...] ...] maybe-type-ann)
|
||||
[(maybe-type-ann (code:line) (code:line : type))]]{
|
||||
Creates a @tech{strict} @racket[Array] from nested rows of expressions.
|
||||
|
||||
The vector syntax @racket[#[...]] delimits rows. These may be nested to any depth, and must have a
|
||||
rectangular shape. Using square parentheses is not required, but is encouraged to help distinguish
|
||||
array contents from array shapes and other vectors.
|
||||
rectangular shape. Using square parentheses is not required, but is encouraged to help visually
|
||||
distinguish array contents from array indexes and other vectors.
|
||||
(See the examples for @racket[indexes-array] for an illustration.)
|
||||
|
||||
@examples[#:eval typed-eval
|
||||
(array 0)
|
||||
|
@ -492,13 +494,16 @@ array contents from array shapes and other vectors.
|
|||
(array #[#[1 2 3] #[4 5 6]])
|
||||
(array #[#[1 2 3] #[4 5]])]
|
||||
As with the @racket[list] constructor, the type chosen for the array is the narrowest type
|
||||
all the elements can have. Unlike @racket[list], because @racket[array] is syntax, the only way
|
||||
to change the element type is to annotate the result.
|
||||
all the elements can have. Unlike @racket[list], because @racket[array] is syntax, instantiating
|
||||
@racket[array] with the desired element type is a syntax error:
|
||||
@interaction[#:eval typed-eval
|
||||
(list 1 2 3)
|
||||
(array #[1 2 3])
|
||||
((inst list Real) 1 2 3)
|
||||
((inst array Real) #[1 2 3])
|
||||
((inst array Real) #[1 2 3])]
|
||||
There are two easy ways to annotate the element type:
|
||||
@interaction[#:eval typed-eval
|
||||
(array #[1 2 3] : Real)
|
||||
(ann (array #[1 2 3]) (Array Real))]
|
||||
Annotating should rarely be necessary because the @racket[Array] type is covariant.
|
||||
|
||||
|
@ -509,6 +514,8 @@ Normally, the datums within literal vectors are implicitly quoted. However, when
|
|||
(array #[not okay])
|
||||
(array #['this 'is 'okay])
|
||||
(array #['#(an) '#(array) '#(of) '#(vectors)])]
|
||||
|
||||
Another way to create an immutable, strict array from literal data is to use @racket[list->array].
|
||||
}
|
||||
|
||||
@defform/subs[(mutable-array #[#[...] ...] maybe-type-ann)
|
||||
|
@ -528,6 +535,8 @@ the array's elements:
|
|||
arr
|
||||
(array-set! arr #(0) 10.0)
|
||||
arr]
|
||||
|
||||
Another way to create a mutable array from literal data is to use @racket[vector->array].
|
||||
}
|
||||
|
||||
@defproc[(make-array [ds In-Indexes] [value A]) (Array A)]{
|
||||
|
@ -586,16 +595,6 @@ Printing a lazy array computes and caches all of its elements, as does applying
|
|||
@racket[array-strict!] to it.
|
||||
}
|
||||
|
||||
@defproc[(make-mutable-array [ds In-Indexes] [vs (Vectorof A)]) (Mutable-Array A)]{
|
||||
Returns a mutable array with @tech{shape} @racket[ds] and elements @racket[vs]; assumes
|
||||
@racket[vs] are in row-major order. If there are too many or too few elements in @racket[vs],
|
||||
@racket[(make-mutable-array ds vs)] raises an error.
|
||||
@examples[#:eval typed-eval
|
||||
(make-mutable-array #(3 3) #(0 1 2 3 4 5 6 7 8))
|
||||
(make-mutable-array #() #(singleton))
|
||||
(make-mutable-array #(4) #(1 2 3 4 5))]
|
||||
}
|
||||
|
||||
@defproc[(array->mutable-array [arr (Array A)]) (Mutable-Array A)]{
|
||||
Returns a mutable array with the same elements as @racket[arr]. The result is a copy of
|
||||
@racket[arr], even when @racket[arr] is mutable.
|
||||
|
@ -664,37 +663,60 @@ This is used as an argument type to @racket[list*->array] and as the return type
|
|||
Like @racket[(Listof* A)], but for vectors. See @racket[vector*->array] and @racket[array->vector*].
|
||||
}
|
||||
|
||||
@deftogether[(@defproc[(list->array [lst (Listof A)]) (Array A)]
|
||||
@deftogether[(@defproc*[([(list->array [lst (Listof A)]) (Array A)]
|
||||
[(list->array [ds In-Indexes] [lst (Listof A)]) (Array A)])]
|
||||
@defproc[(array->list [arr (Array A)]) (Listof A)])]{
|
||||
Convert lists to single-axis arrays and back. If @racket[arr] has no axes or more than one axis,
|
||||
it is (conceptually) flattened before being converted to a list.
|
||||
Convert lists to @tech{strict}, immutable arrays and back.
|
||||
|
||||
The two-argument variant of @racket[list->array] assumes the elements in @racket[lst] are in
|
||||
row-major order.
|
||||
|
||||
For @racket[array->list], if @racket[arr] has no axes or more than one axis, it is (conceptually)
|
||||
flattened before being converted to a list.
|
||||
|
||||
@examples[#:eval typed-eval
|
||||
(list->array '(1 2 3))
|
||||
(list->array '((1 2 3) (4 5)))
|
||||
(list->array #(2 2) '(1 2 3 4))
|
||||
(array->list (array #[1 2 3]))
|
||||
(array->list (array 10))
|
||||
(array->list (array #[#[1 2 3] #[4 5 6]]))]
|
||||
For conversion between nested lists and multidimensional arrays, see @racket[list*->array] and
|
||||
@racket[array->list*].
|
||||
For conversion from flat values to mutable arrays, see @racket[vector->array].
|
||||
}
|
||||
|
||||
@deftogether[(@defproc[(vector->array [vec (Vectorof A)]) (Array A)]
|
||||
@deftogether[(@defproc*[([(vector->array [vec (Vectorof A)]) (Mutable-Array A)]
|
||||
[(vector->array [ds In-Indexes] [vec (Vectorof A)]) (Mutable-Array A)])]
|
||||
@defproc[(array->vector [arr (Array A)]) (Vectorof A)])]{
|
||||
Like @racket[list->array] and @racket[array->list], but for vectors.
|
||||
@examples[#:eval typed-eval
|
||||
(vector->array #(1 2 3))
|
||||
(vector->array #((1 2 3) (4 5)))
|
||||
(vector->array #(2 2) #(1 2 3 4))
|
||||
(array->vector (array #[1 2 3]))
|
||||
(array->vector (array 10))
|
||||
(array->vector (array #[#[1 2 3] #[4 5 6]]))]
|
||||
For conversion between nested vectors and multidimensional arrays, see @racket[vector*->array] and
|
||||
@racket[array->vector*].
|
||||
}
|
||||
|
||||
@defproc[(list*->array [lsts (Listof* A)] [pred? ((Listof* A) -> Any : A)]) (Array A)]{
|
||||
Converts a nested list of elements of type @racket[A] to an array. The predicate @racket[pred?]
|
||||
identifies elements of type @racket[A]. The shape of @racket[lsts] must be rectangular.
|
||||
Converts a nested list of elements of type @racket[A] to a @tech{strict} array.
|
||||
The predicate @racket[pred?] identifies elements of type @racket[A].
|
||||
The shape of @racket[lsts] must be rectangular.
|
||||
|
||||
@examples[#:eval typed-eval
|
||||
(list*->array 'singleton symbol?)
|
||||
(list*->array '(0 1 2 3) byte?)
|
||||
(list*->array (list (list (list 5) (list 2 3))
|
||||
(list (list 4.0) (list 1.4 0.2 9.3)))
|
||||
(make-predicate (Listof Nonnegative-Real)))]
|
||||
The last example demonstrates why a predicate is required. There is no well-typed Typed Racket
|
||||
function that behaves like @racket[list*->array] but does not require @racket[pred?], because
|
||||
without it, there is no way to distinguish between rows and elements.
|
||||
|
||||
There is no well-typed Typed Racket function that behaves like @racket[list*->array] but does not
|
||||
require @racket[pred?].
|
||||
Without an element predicate, there is no way to prove to the type checker that
|
||||
@racket[list*->array]'s implementation correctly distinguishes elements from rows.
|
||||
}
|
||||
|
||||
@defproc[(array->list* [arr (Array A)]) (Listof* A)]{
|
||||
|
@ -715,9 +737,10 @@ Like @racket[array->list*], but produces nested vectors of elements.
|
|||
}
|
||||
|
||||
@defproc[(array-list->array [arrs (Listof (Array A))] [axis Integer 0]) (Array A)]{
|
||||
Concatenates @racket[arrs] along axis @racket[axis] to form a new array. If the arrays have
|
||||
different shapes, they are broadcast first. The axis number @racket[axis] must be nonnegative
|
||||
and @italic{no greater than} the number of axes after broadcasting.
|
||||
Concatenates @racket[arrs] along axis @racket[axis] to form a new array.
|
||||
If the arrays have different shapes, they are broadcast first.
|
||||
The axis number @racket[axis] must be nonnegative and @italic{no greater than} the number of axes in
|
||||
the highest dimensional array in @racket[arrs].
|
||||
@examples[#:eval typed-eval
|
||||
(array-list->array (list (array 0) (array 1) (array 2) (array 3)))
|
||||
(array-list->array (list (array 0) (array 1) (array 2) (array 3)) 1)
|
||||
|
@ -1756,7 +1779,7 @@ in-unsafe-array-indexes
|
|||
make-unsafe-array-set-proc
|
||||
make-unsafe-array-proc
|
||||
unsafe-build-array
|
||||
unsafe-mutable-array
|
||||
unsafe-vector->array
|
||||
unsafe-flarray
|
||||
unsafe-array-transform
|
||||
unsafe-array-axis-reduce
|
||||
|
|
|
@ -48,7 +48,7 @@
|
|||
(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))])
|
||||
(let ([arr (vector->array #(4) #(a b c d))])
|
||||
(check-eq? arr (array-strict arr)))
|
||||
|
||||
(let ([arr (build-array #() (λ (js) 'foo))])
|
||||
|
@ -87,34 +87,34 @@
|
|||
;; list*->array
|
||||
|
||||
(check-equal? (list*->array 1.0 flonum?)
|
||||
(make-mutable-array #() #(1.0)))
|
||||
(vector->array #() #(1.0)))
|
||||
|
||||
(check-equal? (list*->array '[] flonum?)
|
||||
(make-mutable-array #(0) #()))
|
||||
(vector->array #(0) #()))
|
||||
|
||||
(check-equal? (list*->array '[[]] flonum?)
|
||||
(make-mutable-array #(1 0) #()))
|
||||
(vector->array #(1 0) #()))
|
||||
|
||||
(check-equal? (list*->array '[1.0] flonum?)
|
||||
(make-mutable-array #(1) #(1.0)))
|
||||
(vector->array #(1) #(1.0)))
|
||||
|
||||
(check-equal? (list*->array '[[1.0]] flonum?)
|
||||
(make-mutable-array #(1 1) #(1.0)))
|
||||
(vector->array #(1 1) #(1.0)))
|
||||
|
||||
(check-equal? (list*->array '[[[1.0]]] flonum?)
|
||||
(make-mutable-array #(1 1 1) #(1.0)))
|
||||
(vector->array #(1 1 1) #(1.0)))
|
||||
|
||||
(check-equal? (list*->array '() listof-flonum?)
|
||||
(make-mutable-array #() #(())))
|
||||
(vector->array #() #(())))
|
||||
|
||||
(check-equal? (list*->array '[()] listof-flonum?)
|
||||
(make-mutable-array #(1) #(())))
|
||||
(vector->array #(1) #(())))
|
||||
|
||||
(check-equal? (list*->array '[(1.0) (2.0)] listof-flonum?)
|
||||
(make-mutable-array #(2) #((1.0) (2.0))))
|
||||
(vector->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))))
|
||||
(vector->array #(2 1) #((1.0) (2.0))))
|
||||
|
||||
;; ---------------------------------------------------------------------------------------------------
|
||||
;; array->list*
|
||||
|
@ -156,22 +156,22 @@
|
|||
;; vector*->array
|
||||
|
||||
(check-equal? (vector*->array 1.0 flonum?)
|
||||
(make-mutable-array #() #(1.0)))
|
||||
(vector->array #() #(1.0)))
|
||||
|
||||
(check-equal? ((inst vector*->array Float) #() flonum?)
|
||||
(make-mutable-array #(0) #()))
|
||||
(vector->array #(0) #()))
|
||||
|
||||
(check-equal? ((inst vector*->array Float) #(#()) flonum?)
|
||||
(make-mutable-array #(1 0) #()))
|
||||
(vector->array #(1 0) #()))
|
||||
|
||||
(check-equal? ((inst vector*->array Float) #(1.0) flonum?)
|
||||
(make-mutable-array #(1) #(1.0)))
|
||||
(vector->array #(1) #(1.0)))
|
||||
|
||||
(check-equal? ((inst vector*->array Float) #(#(1.0)) flonum?)
|
||||
(make-mutable-array #(1 1) #(1.0)))
|
||||
(vector->array #(1 1) #(1.0)))
|
||||
|
||||
(check-equal? ((inst vector*->array Float) #(#(#(1.0))) flonum?)
|
||||
(make-mutable-array #(1 1 1) #(1.0)))
|
||||
(vector->array #(1 1 1) #(1.0)))
|
||||
|
||||
;; ---------------------------------------------------------------------------------------------------
|
||||
;; array->vector
|
||||
|
@ -303,7 +303,7 @@
|
|||
(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)]))
|
||||
(vector->array #(2) #[(1.0 . 10.0) (2.0 . 20.0)]))
|
||||
|
||||
;; ---------------------------------------------------------------------------------------------------
|
||||
;; Fold
|
||||
|
|
Loading…
Reference in New Issue
Block a user