6.10 Pointwise Operations

► |  | Math Library

1 | Constants and Elementary Functions
2 | Flonums
3 | Special Functions
4 | Number Theory
5 | Arbitrary-Precision Floating-Point Numbers (Bigfloats)
6 | Arrays
7 | Matrices and Linear Algebra
8 | Statistics Functions
9 | Probability Distributions
10 | Stuff That Doesn’t Belong Anywhere Else

▼ | 6 | Arrays

6.1 | Quick Start
6.2 | Definitions
6.3 | Broadcasting
6.4 | Slicing
6.5 | Nonstrict Arrays
6.6 | Types, Predicates and Accessors
6.7 | Construction
6.8 | Conversion
6.9 | Comprehensions and Sequences
6.10 | Pointwise Operations
6.11 | Indexing and Slicing
6.12 | Transformations
6.13 | Folds, Reductions and Expansions
6.14 | Other Array Operations
6.15 | Subtypes
6.16 | Strictness

► | 6.10 | Pointwise Operations

6.10.1 | Broadcasting

On this page:

array-map
inline-array-map
array+
array*
array-
array/
array-min
array-max
array-scale
array-abs
array-sqr
array-sqrt
array-conjugate
array-real-part
array-imag-part
array-make-rectangular
array-magnitude
array-angle
array-make-polar
array<
array<=
array>
array>=
array=
array-not
array-and
array-or
array-if
6.10.1`` Broadcasting
array-broadcasting
array-shape-broadcast
array-broadcast

top contents ← prev up next →

#### 6.10`` Pointwise Operations🔗ℹ

Most of the operations documented in this section are simple macros that apply array-map to a function and their array arguments.

> procedure (array-map f) → (Array R)
> f : (-> R)
> (array-map f arr0) → (Array R)
> f : (A -> R)
> arr0 : (Array A)
> (array-map f arr0 arr1 arrs ...) → (Array R)
> f : (A B Ts ... -> R)
> arr0 : (Array A)
> arr1 : (Array B)
> arrs : (Array Ts)

Composes f with the given arrays’ procedures. When the arrays’ shapes do not match, they are broadcast to the same shape first. If broadcasting fails, array-map raises an error.

Examples:

> > (array-map (λ: ([x : String]) (string-append x "!"))
> (array #[#["Hello" "I"] #["Am" "Shouting"]]))
> - : #(struct:Array
> (Indexes Index (Boxof Boolean) (-> Void) (-> Indexes String))
> #<syntax:/usr/src/packages/BUILD/racket/src/racket-8.17/share/pkgs/math-lib/math/private/array/typed-array-struct.rkt:56:13 prop:equal+hash>
> #<syntax:/usr/src/packages/BUILD/racket/src/racket-8.17/share/pkgs/math-lib/math/private/array/typed-array-struct.rkt:55:13 prop:custom-write>
> #<syntax:/usr/src/packages/BUILD/racket/src/racket-8.17/share/pkgs/math-lib/math/private/array/typed-array-struct.rkt:54:13 prop:custom-print-quotable>)
> (array #[#["Hello!" "I!"] #["Am!" "Shouting!"]])
> > (array-map string-append
> (array #[#["Hello" "I"] #["Am" "Shouting"]])
> (array "!"))
> - : #(struct:Array
> (Indexes Index (Boxof Boolean) (-> Void) (-> Indexes String))
> #<syntax:/usr/src/packages/BUILD/racket/src/racket-8.17/share/pkgs/math-lib/math/private/array/typed-array-struct.rkt:56:13 prop:equal+hash>
> #<syntax:/usr/src/packages/BUILD/racket/src/racket-8.17/share/pkgs/math-lib/math/private/array/typed-array-struct.rkt:55:13 prop:custom-write>
> #<syntax:/usr/src/packages/BUILD/racket/src/racket-8.17/share/pkgs/math-lib/math/private/array/typed-array-struct.rkt:54:13 prop:custom-print-quotable>)
> (array #[#["Hello!" "I!"] #["Am!" "Shouting!"]])
> > (array-map + (index-array #(3 3 3)) (array 2))
> - : #(struct:Array
> (Indexes Index (Boxof Boolean) (-> Void) (-> Indexes Positive-Fixnum))
> #<syntax:/usr/src/packages/BUILD/racket/src/racket-8.17/share/pkgs/math-lib/math/private/array/typed-array-struct.rkt:56:13 prop:equal+hash>
> #<syntax:/usr/src/packages/BUILD/racket/src/racket-8.17/share/pkgs/math-lib/math/private/array/typed-array-struct.rkt:55:13 prop:custom-write>
> #<syntax:/usr/src/packages/BUILD/racket/src/racket-8.17/share/pkgs/math-lib/math/private/array/typed-array-struct.rkt:54:13 prop:custom-print-quotable>)
> (array
> #[#[#[2 3 4]
> #[5 6 7]
> #[8 9 10]]
> #[#[11 12 13]
> #[14 15 16]
> #[17 18 19]]
> #[#[20 21 22]
> #[23 24 25]
> #[26 27 28]]])
> > (array-map + (index-array #(2 2)) (index-array #(3 3)))
> array-shape-broadcast: incompatible array shapes
> (array-broadcasting #t): '#(2 2), '#(3 3)

Typed Racket can often derive fairly precise element types for the resulting array:

> > (array-map * (array #[-4.3 -1.2 -0.2]) (array -2.81))
> - : #(struct:Array
> (Indexes Index (Boxof Boolean) (-> Void) (-> Indexes Nonnegative-Flonum))
> #<syntax:/usr/src/packages/BUILD/racket/src/racket-8.17/share/pkgs/math-lib/math/private/array/typed-array-struct.rkt:56:13 prop:equal+hash>
> #<syntax:/usr/src/packages/BUILD/racket/src/racket-8.17/share/pkgs/math-lib/math/private/array/typed-array-struct.rkt:55:13 prop:custom-write>
> #<syntax:/usr/src/packages/BUILD/racket/src/racket-8.17/share/pkgs/math-lib/math/private/array/typed-array-struct.rkt:54:13 prop:custom-print-quotable>)
> (array #[12.083 3.372 0.562])

How precise the result type is depends on the type of f. Preserving precise result types for lifted arithmetic operators is the main reason most pointwise operations are macro wrappers for array-map.

Unlike map, array-map can map a zero-argument function:

> > (array-map (λ () "Whoa, Nelly!"))
> - : #(struct:Array
> (Indexes Index (Boxof Boolean) (-> Void) (-> Indexes String))
> #<syntax:/usr/src/packages/BUILD/racket/src/racket-8.17/share/pkgs/math-lib/math/private/array/typed-array-struct.rkt:56:13 prop:equal+hash>
> #<syntax:/usr/src/packages/BUILD/racket/src/racket-8.17/share/pkgs/math-lib/math/private/array/typed-array-struct.rkt:55:13 prop:custom-write>
> #<syntax:/usr/src/packages/BUILD/racket/src/racket-8.17/share/pkgs/math-lib/math/private/array/typed-array-struct.rkt:54:13 prop:custom-print-quotable>)
> (array "Whoa, Nelly!")

If the resulting zero-dimensional array is used in a pointwise operation with other arrays, it will be broadcast to their shape:

> > (array-map + (array #[1 2 3]) (array-map (λ () -10)))
> - : #(struct:Array
> (Indexes Index (Boxof Boolean) (-> Void) (-> Indexes Fixnum))
> #<syntax:/usr/src/packages/BUILD/racket/src/racket-8.17/share/pkgs/math-lib/math/private/array/typed-array-struct.rkt:56:13 prop:equal+hash>
> #<syntax:/usr/src/packages/BUILD/racket/src/racket-8.17/share/pkgs/math-lib/math/private/array/typed-array-struct.rkt:55:13 prop:custom-write>
> #<syntax:/usr/src/packages/BUILD/racket/src/racket-8.17/share/pkgs/math-lib/math/private/array/typed-array-struct.rkt:54:13 prop:custom-print-quotable>)
> (array #[-9 -8 -7])

When explicitly instantiating array-map’s types using inst, instantiate R (the return type’s element type) first, then the arguments’ element types in order.

> syntax (inline-array-map f arrs ...)

Like array-map, but possibly faster. Inlining a map operation can allow Typed Racket’s optimizer to replace f with something unchecked and type-specific (for example, replace * with unsafe-fl*), at the expense of code size.

> syntax (array+ arrs ...)
> syntax (array* arrs ...)
> syntax (array- arr0 arrs ...)
> syntax (array/ arr0 arrs ...)
> syntax (array-min arr0 arrs ...)
> syntax (array-max arr0 arrs ...)

Equivalent to mapping arithmetic operators over arrays. Note that because (array-map f) returns sensible answers, so do (array+) and (array*).

Examples:

> > (array+ (array #[#[0.0 1.0] #[2.0 3.0]]) (array 200))
> - : #(struct:Array
> (Indexes Index (Boxof Boolean) (-> Void) (-> Indexes Positive-Flonum))
> #<syntax:/usr/src/packages/BUILD/racket/src/racket-8.17/share/pkgs/math-lib/math/private/array/typed-array-struct.rkt:56:13 prop:equal+hash>
> #<syntax:/usr/src/packages/BUILD/racket/src/racket-8.17/share/pkgs/math-lib/math/private/array/typed-array-struct.rkt:55:13 prop:custom-write>
> #<syntax:/usr/src/packages/BUILD/racket/src/racket-8.17/share/pkgs/math-lib/math/private/array/typed-array-struct.rkt:54:13 prop:custom-print-quotable>)
> (array #[#[200.0 201.0] #[202.0 203.0]])
> > (array+)
> - : #(struct:Array
> (Indexes Index (Boxof Boolean) (-> Void) (-> Indexes Zero))
> #<syntax:/usr/src/packages/BUILD/racket/src/racket-8.17/share/pkgs/math-lib/math/private/array/typed-array-struct.rkt:56:13 prop:equal+hash>
> #<syntax:/usr/src/packages/BUILD/racket/src/racket-8.17/share/pkgs/math-lib/math/private/array/typed-array-struct.rkt:55:13 prop:custom-write>
> #<syntax:/usr/src/packages/BUILD/racket/src/racket-8.17/share/pkgs/math-lib/math/private/array/typed-array-struct.rkt:54:13 prop:custom-print-quotable>)
> (array 0)
> > (array*)
> - : #(struct:Array
> (Indexes Index (Boxof Boolean) (-> Void) (-> Indexes One))
> #<syntax:/usr/src/packages/BUILD/racket/src/racket-8.17/share/pkgs/math-lib/math/private/array/typed-array-struct.rkt:56:13 prop:equal+hash>
> #<syntax:/usr/src/packages/BUILD/racket/src/racket-8.17/share/pkgs/math-lib/math/private/array/typed-array-struct.rkt:55:13 prop:custom-write>
> #<syntax:/usr/src/packages/BUILD/racket/src/racket-8.17/share/pkgs/math-lib/math/private/array/typed-array-struct.rkt:54:13 prop:custom-print-quotable>)
> (array 1)
> > (array/ (array #[2 1/2]))
> - : #(struct:Array
> (Indexes
> Index
> (Boxof Boolean)
> (-> Void)
> (-> Indexes Positive-Exact-Rational))
> #<syntax:/usr/src/packages/BUILD/racket/src/racket-8.17/share/pkgs/math-lib/math/private/array/typed-array-struct.rkt:56:13 prop:equal+hash>
> #<syntax:/usr/src/packages/BUILD/racket/src/racket-8.17/share/pkgs/math-lib/math/private/array/typed-array-struct.rkt:55:13 prop:custom-write>
> #<syntax:/usr/src/packages/BUILD/racket/src/racket-8.17/share/pkgs/math-lib/math/private/array/typed-array-struct.rkt:54:13 prop:custom-print-quotable>)
> (array #[1/2 2])

> syntax (array-scale arr x)

Equivalent to (array* arr (array x)), but faster.

> syntax (array-abs arr)
> syntax (array-sqr arr)
> syntax (array-sqrt arr)
> syntax (array-conjugate arr)

Equivalent to (array-map f arr), where f is respectively abs, sqr, sqrt, or conjugate.

> syntax (array-real-part arr)
> syntax (array-imag-part arr)
> syntax (array-make-rectangular arr0 arr1)
> syntax (array-magnitude arr)
> syntax (array-angle arr)
> syntax (array-make-polar arr0 arr1)

Conversions to and from complex numbers, lifted to operate on arrays.

> syntax (array< arr0 arr1 arrs ...)
> syntax (array<= arr0 arr1 arrs ...)
> syntax (array> arr0 arr1 arrs ...)
> syntax (array>= arr0 arr1 arrs ...)
> syntax (array= arr0 arr1 arrs ...)

Equivalent to (array-map f arr0 arr1 arrs ...), where f is respectively <, <=, >, >=, or =.

> syntax (array-not arr)
> syntax (array-and arr ...)
> syntax (array-or arr ...)
> syntax (array-if cond-arr true-arr false-err)

Boolean operators lifted to operate on arrays.

When given nonstrict arrays, the short-cutting behavior of array-and, array-or and array-if can keep their elements from being referred to (and thus computed). However, these macros cannot be used to distinguish base and inductive cases in a recursive function, because the array arguments are eagerly evaluated. For example, this function never returns, even when array-strictness is #f:

> (: array-factorial ((Array Integer) -> (Array Integer)))
> (define (array-factorial arr)
> (array-if (array<= arr (array 0))
> (array 1)
> (array* arr (array-factorial (array- arr (array 1))))))

##### 6.10.1`` Broadcasting🔗ℹ

> parameter (array-broadcasting) → (U Boolean 'permissive)
> (array-broadcasting broadcasting) → void?
> broadcasting : (U Boolean 'permissive)

Determines the rules used when broadcasting arrays for pointwise operations. See Broadcasting Control.

> procedure (array-shape-broadcast dss [broadcasting]) → Indexes
> dss : (Listof Indexes)
> broadcasting : (U Boolean 'permissive) = (array-broadcasting)

Determines the shape of the resulting array if some number of arrays with shapes dss were broadcast for a pointwise operation using the given broadcasting rules. If broadcasting fails, array-shape-broadcast raises an error.

Examples:

> > (array-shape-broadcast '())
> - : Indexes
> '#()
> > (array-shape-broadcast (list (vector) ((inst vector Index) 10)))
> - : Indexes
> '#(10)
> > (array-shape-broadcast (list ((inst vector Index) 2)
> ((inst vector Index) 10)))
> array-shape-broadcast: incompatible array shapes
> (array-broadcasting #t): '#(2), '#(10)
> > (array-shape-broadcast (list ((inst vector Index) 2)
> ((inst vector Index) 10))
> 'permissive)
> - : Indexes
> '#(10)

> procedure (array-broadcast arr ds) → (Array A)
> arr : (Array A)
> ds : Indexes

Returns an array with shape ds made by inserting new axes and repeating rows. This is used for both (array-broadcasting #t) and (array-broadcasting 'permissive).

Examples:

> > (array-broadcast (array 10) ((inst vector Index) 10))
> - : #(struct:Array
> (Indexes Index (Boxof Boolean) (-> Void) (-> Indexes Positive-Byte))
> #<syntax:/usr/src/packages/BUILD/racket/src/racket-8.17/share/pkgs/math-lib/math/private/array/typed-array-struct.rkt:56:13 prop:equal+hash>
> #<syntax:/usr/src/packages/BUILD/racket/src/racket-8.17/share/pkgs/math-lib/math/private/array/typed-array-struct.rkt:55:13 prop:custom-write>
> #<syntax:/usr/src/packages/BUILD/racket/src/racket-8.17/share/pkgs/math-lib/math/private/array/typed-array-struct.rkt:54:13 prop:custom-print-quotable>)
> (array #[10 10 10 10 10 10 10 10 10 10])
> > (array-broadcast (array #[0 1]) #())
> array-broadcast: cannot broadcast to a lower-dimensional
> shape; given (array #[0 1]) and '#()
> > (array-broadcast (array #[0 1]) ((inst vector Index) 5))
> - : #(struct:Array
> (Indexes Index (Boxof Boolean) (-> Void) (-> Indexes (U One Zero)))
> #<syntax:/usr/src/packages/BUILD/racket/src/racket-8.17/share/pkgs/math-lib/math/private/array/typed-array-struct.rkt:56:13 prop:equal+hash>
> #<syntax:/usr/src/packages/BUILD/racket/src/racket-8.17/share/pkgs/math-lib/math/private/array/typed-array-struct.rkt:55:13 prop:custom-write>
> #<syntax:/usr/src/packages/BUILD/racket/src/racket-8.17/share/pkgs/math-lib/math/private/array/typed-array-struct.rkt:54:13 prop:custom-print-quotable>)
> (array #[0 1 0 1 0])

When array-strictness is #f, array-broadcast always returns a nonstrict array.

When array-strictness is #t, array-broadcast returns a strict array when arr is nonstrict and the result has more elements than arr.

top contents ← prev up next →