#### 6.10Pointwise 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)) # # #)

(array #[#["Hello!" "I!"] #["Am!" "Shouting!"]])

 > (array-map string-append (array #[#["Hello" "I"] #["Am" "Shouting"]]) (array "!"))
 - : #(struct:Array (Indexes Index (Boxof Boolean) (-> Void) (-> Indexes String)) # # #)

(array #[#["Hello!" "I!"] #["Am!" "Shouting!"]])

> (array-map + (index-array #(3 3 3)) (array 2))
 - : #(struct:Array (Indexes Index (Boxof Boolean) (-> Void) (-> Indexes Positive-Fixnum)) # # #)
 (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-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)) # # #)

(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)) # # #)

(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)) # # #)

(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)) # # #)

(array #[#[200.0 201.0] #[202.0 203.0]])

> (array+)
 - : #(struct:Array (Indexes Index (Boxof Boolean) (-> Void) (-> Indexes Zero)) # # #)

(array 0)

> (array*)
 - : #(struct:Array (Indexes Index (Boxof Boolean) (-> Void) (-> Indexes One)) # # #)

(array 1)

> (array/ (array #[2 1/2]))
 - : #(struct:Array (Indexes Index (Boxof Boolean) (-> Void) (-> Indexes Positive-Exact-Rational)) # # #)

(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))))))

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

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:

- : 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 (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)) # # #)

(array #[10 10 10 10 10 10 10 10 10 10])

> (array-broadcast (array #[0 1]) #())