8.2

## OpenGL Mathematics (GLM) for Racket

OpenGL Mathematics (GLM) for Racket is a Racket port of OpenGL Mathematics (GLM), a mathematics library for graphics software based on the OpenGL Shading Language (GLSL) specifications.

GLM for Racket provides GLM’s core functions and data types along with support for popular Racket idioms such as sequence-based looping, variadic keyword-based constructors, and match-based de-structuring.

### 1Swizzling

 #lang glm/swizzle package: glm

The glm/swizzle meta-language customizes the syntax of identifiers to enable component swizzling.

 #lang glm/swizzle racket/base (define v (vec4 1 2 3 4)) v.x ;; expands to (vec-ref v 0) v.xy ;; expands to (vec2 (vec-ref v 0) (vec-ref v 1))

All of the bindings exported by glm/vector-types are available whenever swizzling is enabled.

### 2GLM Core

 (require glm) package: glm

This module re-exports glm/matrix-types and glm/vector-types.

#### 2.1Vector Types

 (require glm/vector-types) package: glm

This module re-exports glm/bvec, glm/dvec, glm/ivec, glm/uvec, and glm/vec.

##### 2.1.1Single Precision Floats

 (require glm/vec) package: glm

A vector is an array of 32-bit floating point component values.

Two vectors are equal? iff they have the same number of components and each pair of consecutive components are =.

 procedure(vec? v) → boolean? v : any/c
Returns #t if v is a vector.

 procedure(vec [#:length len #:fill fill] x ...) → vec? len : (or/c exact-positive-integer? #f) = #f fill : (or/c real? 'no-fill) = 0 x : (or/c vec? real?)
Allocates a vector with the xs as its components.

 > (vec 1 2/3 4.5 -670000000.0) (vec 1 0.67 4.5 -670000000)

The components of any vectors in the xs are spliced into the final component list.

 > (vec (vec 1 2) 3 4 (vec 5 6 (vec 7 8)) 9) (vec 1 2 3 4 5 6 7 8 9)

When both len and fill are numbers, the final component list can have any number of values. If its length exceeds len, the excess values are truncated; otherwise, any missing values default to fill.

 > (vec #:length 5 1 2 3) (vec 1 2 3 0 0) > (vec #:length 5 1 2 3 4 5 6 7) (vec 1 2 3 4 5)

When only len is a number, the final component list must have exactly len values. Giving more or less than len values is an error.

 > (vec #:length 3 #:fill 'no-fill (vec 1 2) (vec 3 4)) vec3: contract violation expected: exactly 3 values given: '(1.0 2.0 3.0 4.0)
 > (vec #:length 3 #:fill 'no-fill) vec3: contract violation expected: exactly 3 values given: '()

If len ≥ 2 and only one component value is given, every value defaults to it.

 > (vec #:length 3 7) (vec 7 7 7)

vec is also a match pattern identifier for deconstructing vectors.

 > (match (vec 1 2 3) [(vec a b c) (+ a b c)])

6.0

Vectors of indeterminate length can be matched with a final #:rest pattern.

 > (match (vec 1 2 3 4 5) [(vec x y z #:rest tail) (list x y z (apply + tail))])

'(1.0 2.0 3.0 9.0)

 procedure(make-vec data len fixed? fill) → vec? data : array? len : exact-positive-integer? fixed? : boolean? fill : (or/c real? 'no-fill)
Constructs a fresh vector on the first len components of some existing data. The array is not copied; the new Racket representation is backed by the existing C representation.

If fixed? is true and len is between 0 and 4, the vector displays its length-suffixed name. Otherwise, it uses the more general (vec ...) form.

Example:
 > (define v1 (vec #:length 5 1)) > (define v2 (make-vec (vec-data v1) 3 #t 0)) > v2 (vec3 1 1 1) > (vec-set! v2 2 0) > v1 (vec 1 1 0 1 1)

 procedure(vec-data v) → array? v : vec?
Returns the underlying C representation of v.

Example:
 > (define v (vec 1 2 3)) > (sequence->list (in-array (vec-data v))) '(1.0 2.0 3.0)

 procedure v : vec?
Returns the number of components in v.

Example:
 > (vec-length (vec 0 1 2)) 3

 procedure(make-vec-data x ...) → array? x : real?
Allocates an array of _floats that works with array-ref and array-set!.

Example:
 > (array-ref (make-vec-data 9 8 7) 2) 7.0

 procedure(vec-copy v) → vec? v : vec?
Returns a fresh copy of v.

Example:
 > (define v1 (vec 1 2 3)) > (eq? (vec-data v1) (vec-data v1)) #t > (define v2 (vec-copy v1)) > (eq? (vec-data v1) (vec-data v2)) #f

 procedure(vec-name v) → symbol? v : vec?
Returns the length-suffixed name of v.

Example:
 > (vec-name (vec #:length 5)) 'vec5

 procedure(vec-ref v i) → real? v : vec? i : exact-nonnegative-integer?
Returns the ith component of v.

Example:
 > (vec-ref (vec 9 8 7 6) 2) 7.0

 procedure(vec-set! v i x) → void? v : vec? i : exact-nonnegative-integer? x : real?
Changes the ith component of v to x.

Example:
 > (define v (vec 1 2 3)) > (vec-set! v 1 0) > v (vec 1 0 3)

 procedure(vec->list v) → (listof real?) v : vec?
Returns the component values of v.

Example:
 > (vec->list (vec 1 2 3)) '(1.0 2.0 3.0)

 procedure v : vec?
Returns the underlying C representation of v cast as an f32vector.

Example:
 > (define v (vec 9 8 7)) > (define fv (vec->f32vector v)) > (f32vector-set! fv 1 0.0) > v (vec 9 0 7)

 procedure(in-vec v [start stop step]) → sequence? v : vec? start : exact-nonnegative-integer? = 0 stop : (or/c exact-integer? #f) = #f step : (and/c exact-integer? (not/c zero?)) = 1
Returns a sequence equivalent to v when no optional arguments are supplied.

The optional arguments start, stop, and step are as in in-vector.

Example:
 > (for ([x (in-vec (vec 1 2 3))]) (println x))
 1 2 3

 syntax(for/vec maybe-length (for-clause ...) body-or-break ... body)
 syntax(for*/vec maybe-length (for-clause ...) body-or-break ... body)
Like for/list and for*/list, but the results are accumulated into a vector instead of a list.

 > (for/vec ([x (in-list '(9 8 7))]) (sub1 x))

(vec 8 7 6)

 > (for*/vec ([x (in-range 3)] [y (in-range 3)]) (* x (+ x y)))

(vec 0 0 0 1 2 3 4 6 8)

If the optional #:length clause is specified, it determines the length of the result vector.

 > (for/vec #:length 5 ([x (in-list '(1 2 3))]) (add1 x))

(vec 2 3 4 0 0)

If an optional #:fill clause is specified and its value is not 'no-fill, it determines the value of any unspecified components.

 > (for/vec #:length 4 #:fill -1 ([x (in-naturals)] #:break (= x 2)) x)

(vec 0 1 -1 -1)

 > (for*/vec #:length 10 #:fill -1 ([x (in-range 3)] [y (in-range 3)]) (+ x (* x y)))

(vec 0 0 0 1 2 3 2 4 6 -1)

 procedure v : vec?
Returns a constructor function for vectors with the same length as v.

Example:
 > ((vec-constructor (vec 1 2 3)) 4 5) (vec 4 5 0)

 procedure(vec=! v u) → void? v : vec? u : vec?
Overwrites the component values of v with the values of u.

Example:
 > (define v (vec 1 2 3)) > (vec=! v (vec 4 5 6)) > v (vec 4 5 6)

 > (vec=! v (vec 7 8)) > v (vec 7 8 6)
 > (vec=! v (vec 9 10 11 12)) > v (vec 9 10 11)

 procedure(vec+ a ...) → (or/c vec? real?) a : (or/c vec? real?)
 procedure(vec- a ...) → (or/c vec? real?) a : (or/c vec? real?)
 procedure(vec* a ...) → (or/c vec? real?) a : (or/c vec? real?)
 procedure(vec/ a ...) → (or/c vec? real?) a : (or/c vec? real?)
Like +, -, *, and /, but generalized to consume vectors or numbers.

 > (vec+ 1 2 3) 6
 > (vec- 3 (vec 4 5)) (vec -1 -2)
 > (vec* (vec 6 7) 8) (vec 48 56)
 > (vec/ (vec 9 0) (vec 3 11)) (vec 3 0)

 procedure(vec+=! a b) → void? a : vec? b : (or/c vec? real?)
 procedure(vec-=! a b) → void? a : vec? b : (or/c vec? real?)
 procedure(vec*=! a b) → void? a : vec? b : (or/c vec? real?)
 procedure(vec/=! a b) → void? a : vec? b : (or/c vec? real?)
Like vec+, vec-, vec*, and vec/, except the result is stored in a.

 > (define v (vec 1 2)) > (vec+=! v (vec 3 4)) > v (vec 4 6)
 > (vec-=! v 5) > v (vec -1 1)
 > (vec*=! v (vec 6 7 8)) > v (vec -6 7)
 > (vec/=! v (vec 9 10)) > v (vec -0.67 0.7)

 procedure(++vec! v) → vec? v : vec?
 procedure(--vec! v) → vec? v : vec?
Increments or decrements the components of v by 1 and then returns v.

Example:
 > (define v (vec 1 2)) > (++vec! v) (vec 2 3) > v (vec 2 3)

 procedure(vec++! v) → vec? v : vec?
 procedure(vec--! v) → vec? v : vec?
Increments or decrements the components of v by 1 and then returns a fresh vector with the original components of v.

Example:
 > (define v (vec 1 2)) > (vec++! v) (vec 1 2) > v (vec 2 3)

parameter

(current-vec-precision precision)  void?
precision : exact-nonnegative-integer?
 = 2
A parameter that controls the maximum number of digits displayed after the decimal point of a vector component.

Example:
 > (current-vec-precision 3) > (vec 1/2 2/3 3/4) (vec 0.5 0.667 0.75)

 > (parameterize ([current-vec-precision 6]) (println (vec 1/2 2/3 3/4)))

(vec 0.5 0.666667 0.75)

procedure

(_vec len)  ctype?

len : exact-positive-integer?
 = (_array _float len)
Creates a vector type whose Racket representation is an array that works with array-ref and array-set!.

 syntax(define-vec-type id #:length len)
Binds variables related to vectors of a specific length.

A define-vec-type form defines 2 names:

• id, a vector constructor function that takes up to len arguments and returns a new vector.

• id?, a predicate procedure that returns #t for vectors of length len and #f for any other value.

Example:
 > (define-vec-type vec5 #:length 5) > (vec5? (vec5)) #t > (vec5? (vec 1 2 3)) #f

id is also a match pattern identifier similar to vec, except it only matches vectors with exactly len components.

 > (match (vec5 1 2 3 4 5) [(vec5 a b c d e) (reverse (list a b c d e))])

'(5.0 4.0 3.0 2.0 1.0)

 > (match (vec5 1) [(vec5 _ _ #:rest xs) (apply + xs)])

3.0

 > (match (vec 1 2 3) [(vec5 #:rest xs) (apply + xs)])

match: no matching clause for (vec 1 2 3)

 > (match (vec 1 2 3 4 5 6 7) [(vec5 #:rest xs) (apply + xs)])

match: no matching clause for (vec 1 2 3 4 5 6 7)

##### 2.1.1.1vec Types
 procedure
 procedure
 procedure
 procedure
 procedure(vec1 x) → vec1? x : real?
 procedure(vec2 x y) → vec2? x : real? y : real?
 procedure(vec3 x y z) → vec3? x : real? y : real? z : real?
 procedure(vec4 x y z w) → vec4? x : real? y : real? z : real? w : real?
##### 2.1.2Double Precision Floats

 (require glm/dvec) package: glm

Arrays of 64-bit floating point numbers.

 procedure(dvec? v) → boolean? v : any/c
 procedure(dvec [#:length len #:fill fill] x ...) → dvec? len : (or/c exact-positive-integer? #f) = #f fill : (or/c real? 'no-fill) = 0 x : (or/c dvec? real?)
 procedure(make-dvec data len fixed? fill) → dvec? data : array? len : exact-positive-integer? fixed? : boolean? fill : (or/c real? 'no-fill)
 procedure(dvec-data v) → array? v : dvec?
 procedure v : dvec?
 procedure(make-dvec-data x ...) → array? x : real?
 procedure(dvec-copy v) → dvec? v : dvec?
 procedure(dvec-name v) → symbol? v : dvec?
 procedure(dvec-ref v i) → flonum? v : dvec? i : exact-nonnegative-integer?
 procedure(dvec-set! v i x) → void? v : dvec? i : exact-nonnegative-integer? x : number?
 procedure(dvec->list v) → (listof flonum?) v : dvec?
 procedure v : dvec?
 procedure(in-dvec v [start stop step]) → sequence? v : dvec? start : exact-nonnegative-integer? = 0 stop : (or/c exact-integer? #f) = #f step : (and/c exact-integer? (not/c zero?)) = 1
 syntax(for/dvec maybe-length (for-clause ...) body-or-break ... body)
 syntax(for*/dvec maybe-length (for-clause ...) body-or-break ... body)
 procedure v : dvec?
 procedure(dvec=! v u) → void? v : dvec? u : dvec?
 procedure(dvec+ a ...) → (or/c dvec? real?) a : (or/c dvec? real?)
 procedure(dvec- a ...) → (or/c dvec? real?) a : (or/c dvec? real?)
 procedure(dvec* a ...) → (or/c dvec? real?) a : (or/c dvec? real?)
 procedure(dvec/ a ...) → (or/c dvec? real?) a : (or/c dvec? real?)
 procedure(dvec+=! a b) → void? a : dvec? b : (or/c dvec? real?)
 procedure(dvec-=! a b) → void? a : dvec? b : (or/c dvec? real?)
 procedure(dvec*=! a b) → void? a : dvec? b : (or/c dvec? real?)
 procedure(dvec/=! a b) → void? a : dvec? b : (or/c dvec? real?)
 procedure(++dvec! v) → dvec? v : dvec?
 procedure(--dvec! v) → dvec? v : dvec?
 procedure(dvec++! v) → dvec? v : dvec?
 procedure(dvec--! v) → dvec? v : dvec?

parameter

(current-dvec-precision precision)  void?
precision : exact-nonnegative-integer?
 = 2

procedure

(_dvec len)  ctype?

len : exact-nonnegative-integer?
 = (_array _double len)
 syntax(define-dvec-type id #:length len)
##### 2.1.2.1dvec Types
 procedure
 procedure
 procedure
 procedure
 procedure(dvec1 x) → dvec1? x : real?
 procedure(dvec2 x y) → dvec2? x : real? y : real?
 procedure(dvec3 x y z) → dvec3? x : real? y : real? z : real?
 procedure(dvec4 x y z w) → dvec4? x : real? y : real? z : real? w : real?
##### 2.1.3Signed Integers

 (require glm/ivec) package: glm

Arrays of signed integers.

 procedure(ivec? v) → boolean? v : any/c
 procedure(ivec [#:length len #:fill fill] x ...) → ivec? len : (or/c exact-integer? #f) = #f fill : (or/c integer? 'no-fill) = 0 x : (or/c ivec? integer?)
 procedure(make-ivec data len fixed? fill) → ivec? data : array? len : exact-positive-integer? fixed? : boolean? fill : (or/c integer? 'no-fill)
 procedure(ivec-data v) → array? v : ivec?
 procedure v : ivec?
 procedure(make-ivec-data x ...) → array? x : integer?
 procedure(ivec-copy v) → ivec? v : ivec?
 procedure(ivec-name v) → symbol? v : ivec?
 procedure(ivec-ref v i) → flonum? v : ivec? i : exact-nonnegative-integer?
 procedure(ivec-set! v i x) → void? v : ivec? i : exact-nonnegative-integer? x : number?
 procedure(ivec->list v) → (listof flonum?) v : ivec?
 procedure v : ivec?
 procedure(in-ivec v [start stop step]) → sequence? v : ivec? start : exact-nonnegative-integer? = 0 stop : (or/c exact-integer? #f) = #f step : (and/c exact-integer? (not/c zero?)) = 1
 syntax(for/ivec maybe-length (for-clause ...) body-or-break ... body)
 syntax(for*/ivec maybe-length (for-clause ...) body-or-break ... body)
 procedure v : ivec?
 procedure(ivec=! v u) → void? v : ivec? u : ivec?
 procedure(ivec+ a ...) → (or/c ivec? integer?) a : (or/c ivec? integer?)
 procedure(ivec- a ...) → (or/c ivec? integer?) a : (or/c ivec? integer?)
 procedure(ivec* a ...) → (or/c ivec? integer?) a : (or/c ivec? integer?)
 procedure(ivec/ a ...) → (or/c ivec? integer?) a : (or/c ivec? integer?)
 procedure(ivec+=! a b) → void? a : ivec? b : (or/c ivec? integer?)
 procedure(ivec-=! a b) → void? a : ivec? b : (or/c ivec? integer?)
 procedure(ivec*=! a b) → void? a : ivec? b : (or/c ivec? integer?)
 procedure(ivec/=! a b) → void? a : ivec? b : (or/c ivec? integer?)
 procedure(++ivec! v) → ivec? v : ivec?
 procedure(--ivec! v) → ivec? v : ivec?
 procedure(ivec++! v) → ivec? v : ivec?
 procedure(ivec--! v) → ivec? v : ivec?

procedure

(_ivec len)  ctype?

len : exact-nonnegative-integer?
 = (_array _int len)
 syntax(define-ivec-type id #:length len)
##### 2.1.3.1ivec Types
 procedure
 procedure
 procedure
 procedure
 procedure(ivec1 x) → ivec1? x : integer?
 procedure(ivec2 x y) → ivec2? x : integer? y : integer?
 procedure(ivec3 x y z) → ivec3? x : integer? y : integer? z : integer?
 procedure(ivec4 x y z w) → ivec4? x : integer? y : integer? z : integer? w : integer?
##### 2.1.4Unsigned Integers

 (require glm/uvec) package: glm

Arrays of unsigned integers.

 procedure(uvec? v) → boolean? v : any/c
 procedure(uvec [#:length len #:fill fill] x ...) → uvec? len : (or/c exact-positive-integer? #f) = #f fill : (or/c nonnegative-integer? 'no-fill) = 0 x : (or/c uvec? nonnegative-integer?)
 procedure(make-uvec data len fixed? fill) → uvec? data : array? len : exact-positive-integer? fixed? : boolean? fill : (or/c nonnegative-integer? 'no-fill)
 procedure(uvec-data v) → array? v : uvec?
 procedure v : uvec?
 procedure(make-uvec-data x ...) → array? x : nonnegative-integer?
 procedure(uvec-copy v) → uvec? v : uvec?
 procedure(uvec-name v) → symbol? v : uvec?
 procedure v : uvec? i : exact-nonnegative-integer?
 procedure(uvec-set! v i x) → void? v : uvec? i : exact-nonnegative-integer? x : nonnegative-integer?
 procedure(uvec->list v) → (listof flonum?) v : uvec?
 procedure v : uvec?
 procedure(in-uvec v [start stop step]) → sequence? v : uvec? start : exact-nonnegative-integer? = 0 stop : (or/c exact-integer? #f) = #f step : (and/c exact-integer? (not/c zero?)) = 1
 syntax(for/uvec maybe-length (for-clause ...) body-or-break ... body)
 syntax(for*/uvec maybe-length (for-clause ...) body-or-break ... body)
 procedure v : uvec?
 procedure(uvec=! v u) → void? v : uvec? u : uvec?
 procedure(uvec+ a ...) → (or/c uvec? nonnegative-integer?) a : (or/c uvec? nonnegative-integer?)
 procedure(uvec- a ...) → (or/c uvec? nonnegative-integer?) a : (or/c uvec? nonnegative-integer?)
 procedure(uvec* a ...) → (or/c uvec? nonnegative-integer?) a : (or/c uvec? nonnegative-integer?)
 procedure(uvec/ a ...) → (or/c uvec? nonnegative-integer?) a : (or/c uvec? nonnegative-integer?)
 procedure(uvec+=! a b) → void? a : uvec? b : (or/c uvec? nonnegative-integer?)
 procedure(uvec-=! a b) → void? a : uvec? b : (or/c uvec? nonnegative-integer?)
 procedure(uvec*=! a b) → void? a : uvec? b : (or/c uvec? nonnegative-integer?)
 procedure(uvec/=! a b) → void? a : uvec? b : (or/c uvec? nonnegative-integer?)
 procedure(++uvec! v) → uvec? v : uvec?
 procedure(--uvec! v) → uvec? v : uvec?
 procedure(uvec++! v) → uvec? v : uvec?
 procedure(uvec--! v) → uvec? v : uvec?

procedure

(_uvec len)  ctype?

len : exact-nonnegative-integer?
 = (_array _uint len)
 syntax(define-uvec-type id #:length len)
##### 2.1.4.1uvec Types
 procedure
 procedure
 procedure
 procedure
 procedure(uvec1 x) → uvec1? x : nonnegative-integer?
 procedure(uvec2 x y) → uvec2? x : nonnegative-integer? y : nonnegative-integer?
 procedure(uvec3 x y z) → uvec3? x : nonnegative-integer? y : nonnegative-integer? z : nonnegative-integer?
 procedure(uvec4 x y z w) → uvec4? x : nonnegative-integer? y : nonnegative-integer? z : nonnegative-integer? w : nonnegative-integer?
##### 2.1.5Booleans

 (require glm/bvec) package: glm

Arrays of boolean values.

 procedure(bvec? v) → boolean? v : any/c
 procedure(bvec [#:length len #:fill fill] x ...) → bvec? len : (or/c exact-integer? #f) = #f fill : (or/c boolean? 'no-fill) = #f x : (or/c bvec? boolean?)
 procedure(make-bvec data len fixed? fill) → bvec? data : array? len : exact-nonnegative-integer? fixed? : boolean? fill : (or/c boolean? 'no-fill)
 procedure(bvec-data v) → array? v : bvec?
 procedure v : bvec?
 procedure(make-bvec-data x ...) → array? x : boolean?
 procedure(bvec-copy v) → bvec? v : bvec?
 procedure(bvec-name v) → symbol? v : bvec?
 procedure(bvec-ref v i) → boolean? v : bvec? i : exact-nonnegative-integer?
 procedure(bvec-set! v i x) → void? v : bvec? i : exact-nonnegative-integer? x : boolean?
 procedure(bvec->list v) → (listof boolean?) v : bvec?
 procedure v : bvec?
 procedure(in-bvec v [start stop step]) → sequence? v : bvec? start : exact-nonnegative-integer? = 0 stop : (or/c exact-integer? #f) = #f step : (and/c exact-integer? (not/c zero?)) = 1
 syntax(for/bvec maybe-length (for-clause ...) body-or-break ... body)
 syntax(for*/bvec maybe-length (for-clause ...) body-or-break ... body)
 procedure v : bvec?
 procedure(bvec=! v u) → void? v : bvec? u : bvec?

procedure

(_bvec len)  ctype?

len : exact-nonnegative-integer?
 = (_array _int len)
 syntax(define-bvec-type id #:length len)

 procedure(bvec-and a ...+) → bvec? a : bvec?
Returns the pointwise logical conjunction of the as.

Example:
 > (bvec-and (bvec3 #t #t #t) (bvec3 #t #t #f) (bvec3 #f #t #t))

(bvec #f #t #f)

 procedure(bvec-or a ...+) → bvec? a : bvec?
Returns the pointwise logical disjunction of the as.

Example:
 > (bvec-or (bvec3 #f #f #f) (bvec3 #t #f #f) (bvec3 #f #f #t))

(bvec #t #f #t)

 procedure(bvec-not a) → bvec? a : bvec?
Returns the pointwise logical negation of a.

Example:
 > (bvec-not (bvec3 #f #t #f)) (bvec #t #f #t)

##### 2.1.5.1bvec Types
 procedure
 procedure
 procedure
 procedure
 procedure(bvec1 x) → bvec1? x : boolean?
 procedure(bvec2 x y) → bvec2? x : boolean? y : boolean?
 procedure(bvec3 x y z) → bvec3? x : boolean? y : boolean? z : boolean?
 procedure(bvec4 x y z w) → bvec4? x : boolean? y : boolean? z : boolean? w : boolean?

#### 2.2Matrix Types

 (require glm/matrix-types) package: glm

This module re-exports glm/dmat and glm/mat.

##### 2.2.1Single Precision Floats

 (require glm/mat) package: glm

A matrix is a two-dimensional array of 32-bit floating point component values.

Two matrices are equal? iff they have the same dimensions, the same number of components, and each pair of consecutive components are =.

 procedure(mat? m) → boolean? m : any/c
Returns #t if m is a matrix.

 procedure(mat [#:cols N] #:rows M [#:fill fill] x ...) → mat? N : (or/c exact-positive-integer? #f) = #f M : exact-positive-integer? fill : (or/c real? #f) = 0 x : (or/c mat? vec? real?)
Allocates a matrix with the xs as its components in column-major order.

> (mat #:rows 2 1 2 3 4 5 6)
 [ 1 | 3 | 5 ] [ 2 | 4 | 6 ]
> (mat #:rows 3 1 2 3 4 5 6)
 [ 1 | 4 ] [ 2 | 5 ] [ 3 | 6 ]

When no xs are given, the result is an N×M (cols×rows) matrix with 1’s along its diagonal and 0’s everywhere else.

> (mat #:cols 3 #:rows 2)
 [ 1 | 0 | 0 ] [ 0 | 1 | 0 ]
> (mat #:cols 2 #:rows 3)
 [ 1 | 0 ] [ 0 | 1 ] [ 0 | 0 ]

When N is given and the xs consist of a lone scalar value x, the result is an N×M matrix with x along its diagonal and fill everywhere else.

> (mat #:cols 3 #:rows 2 -1/2)
 [ -0.5 |    0 | 0 ] [    0 | -0.5 | 0 ]

If the lone x is a matrix, the result is an N×M matrix with x embedded in its upper-left corner.

> (mat #:cols 3 #:rows 4 #:fill -3 (mat #:rows 2 2))
 [  2 |  0 | -3 ] [  0 |  2 | -3 ] [ -3 | -3 |  1 ] [ -3 | -3 | -3 ]
> (mat #:cols 3 #:rows 2 #:fill -3 (mat #:rows 4 2))
 [ 2 | 0 | 0 ] [ 0 | 2 | 0 ]

When N = (length '(x ...)), each of the xs becomes the sole argument to a column vector constructor.

> (mat #:cols 3 #:rows 2 9 8 7)
 [ 9 | 8 | 7 ] [ 9 | 8 | 7 ]
> (mat #:cols 2 #:rows 3 (vec2 1 2) (vec3 3 4 5))
 [ 1 | 3 ] [ 2 | 4 ] [ 0 | 5 ]

When N is #f and (length '(x ...)) ≤ 1, the result is an M×M matrix.

> (mat #:rows 2)
 [ 1 | 0 ] [ 0 | 1 ]
> (mat #:rows 3 2)
 [ 2 | 0 | 0 ] [ 0 | 2 | 0 ] [ 0 | 0 | 2 ]

If 2 ≤ (length '(x ...))M, the result is an 1×M matrix.

> (mat #:rows 3 1 2)
 [ 1 ] [ 2 ] [ 0 ]

If L = (length '(x ...)) > M, the result is an L’×M matrix, where L’ = L mod M + (0 if M divides L else 1).

> (mat #:rows 2 1 2 3 4)
 [ 1 | 3 ] [ 2 | 4 ]
> (mat #:rows 3 1 2 3 4)
 [ 1 | 4 ] [ 2 | 0 ] [ 3 | 0 ]

mat is also a match pattern identifier for deconstructing matrices.

 > (match (mat #:rows 3 1 2 3 4 5 6) [(mat x y z r g b) (list (list r g b) (list x y z))])

'((4.0 5.0 6.0) (1.0 2.0 3.0))

Optional #:cols or #:rows patterns may be given, and matrices of indeterminate length can be matched with a final #:rest pattern.

 > (match (mat #:rows 3 1 2 3 4 5 6) [(mat #:cols cols #:rows rows x y z #:rest rgb) (list cols rows rgb x y z)])

'(2 3 (4.0 5.0 6.0) 1.0 2.0 3.0)

 > (match (mat #:rows 3 1 2 3 4 5 6) [(mat #:cols cols #:rows rows #:rest _) (* cols rows)])

6

 procedure(make-mat data num-cols num-rows) → mat? data : array? num-cols : exact-positive-integer? num-rows : exact-positive-integer?
Constructs a fresh matrix on the first num-cols×num-rows components of some existing data. The array is not copied; the new Racket representation is backed by the existing C representation.

Example:
> (define m1 (mat #:rows 5))
> (define m2 (make-mat (mat-data m1) 3 3))
> m2
 [ 1 | 0 | 0 ] [ 0 | 1 | 0 ] [ 0 | 0 | 1 ]
> (mat-set! m1 1 1 -1)
> m2
 [ 1 |  0 | 0 ] [ 0 | -1 | 0 ] [ 0 |  0 | 1 ]

 procedure(mat-data m) → array? m : mat?
Returns the underlying C representation of m.

Example:
 > (define m (mat #:rows 2 1 2 3 4 5 6)) > (sequence->list (in-array (mat-data m))) '(# # #)

 procedure m : mat?
 procedure m : mat?
 procedure m : mat?
Returns the number of columns or rows in m.

Example:
> (define m (mat #:rows 2 1 2 3 4 5 6))
> m
 [ 1 | 3 | 5 ] [ 2 | 4 | 6 ]
> (mat-length m)

3

> (mat-num-cols m)

3

> (mat-num-rows m)

2

 procedure(make-mat-data num-cols num-rows x ...+) → array? num-cols : exact-positive-integer? num-rows : exact-positive-integer? x : real?
Allocates a 2-D array of _floats that works with array-ref and array-set!.

Example:
 > (array-ref (make-mat-data 3 2 1 2 3 4 5 6) 2 1) 6.0

 procedure(mat-copy m) → mat? m : mat?
Returns a fresh copy of m.

Example:
 > (define m1 (mat #:rows 3 1 2 3)) > (eq? (mat-data m1) (mat-data m1)) #t > (define m2 (mat-copy m1)) > (eq? (mat-data m1) (mat-data m2)) #f

 procedure(mat-name m) → symbol? m : mat?
Returns the dimension-suffixed name of m.

Example:
 > (mat-name (mat #:rows 5)) 'mat5 > (mat-name (mat #:cols 5 #:rows 4)) 'mat5x4 > (mat-name (mat #:cols 4 #:rows 5)) 'mat4x5

 procedure(mat-ref m col row) → vec? m : mat? col : exact-nonnegative-integer? row : exact-nonnegative-integer? (mat-ref m i) → vec? m : mat? i : exact-nonnegative-integer?
Returns a component value of m.

Example:
> (define m (mat #:rows 2 1 2 3 4 5 6))
> m
 [ 1 | 3 | 5 ] [ 2 | 4 | 6 ]
> (mat-ref m 5)

6.0

> (mat-ref m 2 1)

6.0

 procedure(mat-row m i) → vec? m : mat? i : exact-nonnegative-integer?
Returns a copy of the ith row vector of m.

Example:
> (define m (mat #:rows 2 1 2 3 4 5 6))
> m
 [ 1 | 3 | 5 ] [ 2 | 4 | 6 ]
> (mat-row m 1)

(vec 2 4 6)

 procedure(mat-column m i) → vec? m : mat? i : exact-nonnegative-integer?
Returns the ith column vector of m. The data is not copied; the new Racket representation is backed by the existing C representation.

Example:
> (define m (mat #:rows 2 1 2 3 4 5 6))
> m
 [ 1 | 3 | 5 ] [ 2 | 4 | 6 ]
> (mat-column m 1)

(vec2 3 4)

> (vec-set! (mat-column m 1) 0 -1)
> m
 [ 1 | -1 | 5 ] [ 2 |  4 | 6 ]

 procedure(mat-set! m col row x) → void? m : mat? col : exact-nonnegative-integer? row : exact-nonnegative-integer? x : real? (mat-set! m i x) → void? m : mat? i : exact-nonnegative-integer? x : real?
Changes a component of m to x.

Example:
> (define m (mat #:rows 2 1 2 3 4 5 6))
> (mat-set! m 5 -1)
> (mat-set! m 2 0 -2)
> m
 [ 1 | 3 | -2 ] [ 2 | 4 | -1 ]

 procedure(mat-set-row! m i v) → void? m : mat? i : exact-nonnegative-integer? v : vec?
Changes the ith row of m to the components of v.

Example:
> (define m (mat #:rows 2 1 2 3 4 5 6))
> (mat-set-row! m 1 (vec -2 -4 -6))
> m
 [  1 |  3 |  5 ] [ -2 | -4 | -6 ]

 procedure(mat-set-column! m i v) → void? m : mat? i : exact-nonnegative-integer? v : vec?
Changes the ith column of m to the components of v.

Example:
> (define m (mat #:rows 2 1 2 3 4 5 6))
> (mat-set-column! m 1 (vec -3 -4))
> m
 [ 1 | -3 | 5 ] [ 2 | -4 | 6 ]

 procedure(mat-columns m) → (listof vec?) m : mat?
 procedure(mat-rows m) → (listof vec?) m : mat?
 procedure(mat->list m) → (listof real?) m : mat?
Returns the component columns, rows, or values of m.

Example:
> (define m (mat #:rows 3 1 2 3 4 5 6))
> m
 [ 1 | 4 ] [ 2 | 5 ] [ 3 | 6 ]
> (mat-columns m)

'((vec3 1 2 3) (vec3 4 5 6))

> (mat-rows m)

'((vec 1 4) (vec 2 5) (vec 3 6))

> (mat->list m)

'(1.0 2.0 3.0 4.0 5.0 6.0)

mat-columns is also a match pattern identifier for deconstructing the columns of a matrix.

 > (match m [(mat-columns xyz rgb) (list rgb xyz)])

'((vec3 4 5 6) (vec3 1 2 3))

Matrices of indeterminate length can be matched with a final #:rest pattern.

 > (match m [(mat-columns (vec x y z) #:rest vs) (list vs z y x)])

'(((vec3 4 5 6)) 3.0 2.0 1.0)

 procedure(mat->f32vector m) → f32vector? m : mat?
Returns the underlying C representation of m cast as an f32vector.

Example:
> (define m (mat #:rows 2 1 2 3 4 5 6))
> (define fv (mat->f32vector m))
> (f32vector-set! fv 5 0.0)
> m
 [ 1 | 3 | 5 ] [ 2 | 4 | 0 ]

 procedure(in-mat m) → sequence? m : mat?
Returns a sequence equivalent to m.

Example:
 > (for ([x (in-mat (mat #:rows 2))]) (println x))
 1 0 0 1

 procedure m : mat?
Returns a sequence equivalent to the rows of m.

Example:
 > (for ([v (in-mat-rows (mat #:rows 2))]) (println v))
 (vec 1 0) (vec 0 1)

 procedure m : mat?
Returns a sequence equivalent to the columns of m.

Example:
 > (for ([v (in-mat-columns (mat #:rows 2))]) (println v))
 (vec2 1 0) (vec2 0 1)

syntax

 (for/mat maybe-cols #:rows length-expr maybe-fill (for-clause ...) body-or-break ... body)

maybe-cols =
| #:cols length-expr

maybe-fill =
| #:fill length-expr

syntax

 (for*/mat maybe-cols #:rows length-expr maybe-fill (for-clause ...) body-or-break ... body)
Like for/list and for*/list, but the results are accumulated into a matrix instead of a list.

 > (for/mat #:rows 2 ([i (in-range 6)]) (add1 i))
 [ 1 | 3 | 5 ] [ 2 | 4 | 6 ]
 > (for*/mat #:rows 3 ([i (in-range 2)] [j (in-range 3)]) (+ j (* i 100)))
 [ 0 | 100 ] [ 1 | 101 ] [ 2 | 102 ]

If the optional #:cols clause is specified, it determines the shape of the result matrix.

 > (for/mat #:cols 5 #:rows 3 ([x (in-range 5)]) (* x x))
 [ 0 | 1 | 4 | 9 | 16 ] [ 0 | 1 | 4 | 9 | 16 ] [ 0 | 1 | 4 | 9 | 16 ]

If the optional #:fill clause is specified, it determines the value of any unspecified components.

 > (for/mat #:rows 3 #:fill -1 ([x (in-range 4)]) x)
 [ 0 |  3 ] [ 1 | -1 ] [ 2 | -1 ]

 procedure m : mat?
 procedure m : mat?
 procedure m : mat?
Returns a predicate function that returns #t when applied to a matrix or vector with the same dimension(s) as m.

Example:
 > (define m (mat #:cols 5 #:rows 4)) > (define mat4x5? (mat-predicate m)) > (define vec5? (mat-row-predicate m)) > (mat4x5? m) #t > (vec5? (mat-row m 0)) #t > (vec5? (mat-column m 0)) #f

 procedure m : mat?
 procedure m : mat?
 procedure m : mat?
Returns a constructor function for matrices or vectors with the same dimension(s) as m.

Example:
> (define m (mat #:cols 5 #:rows 4))
> (define mat4x5 (mat-constructor m))
> (define vec5 (mat-row-constructor m))
> (mat4x5)
 [ 1 | 0 | 0 | 0 | 0 ] [ 0 | 1 | 0 | 0 | 0 ] [ 0 | 0 | 1 | 0 | 0 ] [ 0 | 0 | 0 | 1 | 0 ]
> (vec5)

(vec 0 0 0 0 0)

 procedure(mat=! m n) → void? m : mat? n : mat?
Overwrites the component values of m with the values of n.

Example:
> (define m (mat #:rows 2 1 2 3 4 5 6))
> m
 [ 1 | 3 | 5 ] [ 2 | 4 | 6 ]
> (mat=! m (mat #:rows 2 9 8 7 6 5 4))
> m
 [ 9 | 7 | 5 ] [ 8 | 6 | 4 ]

 procedure(mat+ a ...+) → (or/c mat? vec? real?) a : (or/c mat? vec? real?)
 procedure(mat- a ...+) → (or/c mat? vec? real?) a : (or/c mat? vec? real?)
 procedure(mat* a ...+) → (or/c mat? vec? real?) a : (or/c mat? vec? real?)
 procedure(mat/ a ...+) → (or/c mat? vec? real?) a : (or/c mat? vec? real?)
Like +, -, *, and /, but generalized to consume matrices, vectors, or numbers.

 > (mat+ 1 2 3) 6
 > (mat- 3 (vec 4 5)) (vec -1 -2)
 > (mat* (mat #:rows 3 2) (vec 1 2 3)) (vec 2 4 6)
> (mat/ (mat #:rows 3) 2)
 [ 0.5 |   0 |   0 ] [   0 | 0.5 |   0 ] [   0 |   0 | 0.5 ]
> (mat/ (mat #:rows 3) (mat #:rows 3 2))
 [ 0.5 |   0 |   0 ] [   0 | 0.5 |   0 ] [   0 |   0 | 0.5 ]

 procedure(mat+=! m a) → void? m : mat? a : (or/c mat? vec? real?)
 procedure(mat-=! m a) → void? m : mat? a : (or/c mat? vec? real?)
 procedure(mat*=! m a) → void? m : mat? a : (or/c mat? vec? real?)
 procedure(mat/=! m a) → void? m : mat? a : (or/c mat? vec? real?)
Like mat+, mat-, mat*, and mat/, except the result is stored in m.

> (define m (mat #:cols 3 #:rows 2 1 2 3))
> m
 [ 1 | 2 | 3 ] [ 1 | 2 | 3 ]
> (mat+=! m (mat #:cols 3 #:rows 2 10 10 10))
> m
 [ 11 | 12 | 13 ] [ 11 | 12 | 13 ]
> (mat-=! m (mat #:cols 3 #:rows 2 1 2 3))
> m
 [ 10 | 10 | 10 ] [ 10 | 10 | 10 ]
> (define m (mat #:rows 3 1 2 3 4 5 6 7 8 9))
> m
 [ 1 | 4 | 7 ] [ 2 | 5 | 8 ] [ 3 | 6 | 9 ]
> (mat*=! m (mat #:rows 3 2))
> m
 [  2 |  4 |  6 ] [  8 | 10 | 12 ] [ 14 | 16 | 18 ]
> (define m (mat #:rows 3 1 2 3 4 5 6 7 8 9))
> m
 [ 1 | 4 | 7 ] [ 2 | 5 | 8 ] [ 3 | 6 | 9 ]
> (mat/=! m (mat #:rows 3 2))
> m
 [ 0.5 |   1 | 1.5 ] [   2 | 2.5 |   3 ] [ 3.5 |   4 | 4.5 ]

 procedure(++mat! m) → mat? m : mat?
 procedure(--mat! m) → mat? m : mat?
Increments or decrements the components of m by 1 and then returns m.

Example:
> (define m (mat #:rows 2 1 2 3 4))
> (++mat! m)
 [ 2 | 4 ] [ 3 | 5 ]
> m
 [ 2 | 4 ] [ 3 | 5 ]

 procedure(mat++! m) → mat? m : mat?
 procedure(mat--! m) → mat? m : mat?
Increments or decrements the components of m by 1 and then returns a fresh matrix with the original components of m.

Example:
> (define m (mat #:rows 2 1 2 3 4))
> (mat++! m)
 [ 1 | 3 ] [ 2 | 4 ]
> m
 [ 2 | 4 ] [ 3 | 5 ]

 procedure(_mat cols rows) → ctype? cols : exact-positive-integer? rows : exact-positive-integer?
Creates a matrix type whose Racket representation is an array that works with array-ref and array-set!.

 syntax(define-mat-type id #:cols N #:rows M)
Binds variables related to matrices of specific dimensions.

A define-mat-type form defines 2 names:

• id, a matrix constructor function that takes up to N×M arguments and returns a new matrix.

• id?, a predicate procedure that returns #t for matrices with N columns and M rows, and #f for any other value.

Example:
 > (define-mat-type mat5 #:cols 5 #:rows 5) > (mat5? (mat5)) #t > (mat5? (mat #:rows 3)) #f

id is also a match patterns similar to mat, except it only matches matrices with exactly N columns and M rows.

 > (match (mat5 1 2 3 4 5) [(mat5 a b c #:rest xs) (list a b c (apply + xs))])

'(1.0 1.0 1.0 72.0)

 > (match (mat #:rows 3) [(mat5 #:rest xs) (apply + xs)])

match: no matching clause for [ 1 | 0 | 0 ]

[ 0 | 1 | 0 ]

[ 0 | 0 | 1 ]

##### 2.2.1.1mat Types
 procedure
 procedure
 procedure
 procedure
 procedure
 procedure
 procedure
 procedure
 procedure
 procedure
 procedure
 procedure
 procedure(mat2 a ...) → mat2? a : (or/c mat? vec? real?)
 procedure(mat3 a ...) → mat3? a : (or/c mat? vec? real?)
 procedure(mat4 a ...) → mat4? a : (or/c mat? vec? real?)
 procedure(mat2x2 a ...) → mat2x2? a : (or/c mat? vec? real?)
 procedure(mat2x3 a ...) → mat2x3? a : (or/c mat? vec? real?)
 procedure(mat2x4 a ...) → mat2x4? a : (or/c mat? vec? real?)
 procedure(mat3x2 a ...) → mat3x2? a : (or/c mat? vec? real?)
 procedure(mat3x3 a ...) → mat3x3? a : (or/c mat? vec? real?)
 procedure(mat3x4 a ...) → mat3x4? a : (or/c mat? vec? real?)
 procedure(mat4x2 a ...) → mat4x2? a : (or/c mat? vec? real?)
 procedure(mat4x3 a ...) → mat4x3? a : (or/c mat? vec? real?)
 procedure(mat4x4 a ...) → mat4x4? a : (or/c mat? vec? real?)
 value
 value
 value
 value
 value
 value
 value
 value
 value
 value
 value
 value
##### 2.2.2Double Precision Floats

 (require glm/dmat) package: glm

Two-dimensional arrays of 64-bit floating point numbers.

 procedure(dmat? m) → boolean? m : any/c
 procedure(dmat [#:cols N] #:rows M [#:fill fill] x ...) → dmat? N : (or/c exact-positive-integer? #f) = #f M : exact-positive-integer? fill : (or/c real? #f) = 0 x : (or/c dmat? dvec? real?)
 procedure(make-dmat data num-cols num-rows) → dmat? data : array? num-cols : exact-positive-integer? num-rows : exact-positive-integer?
 procedure(dmat-data m) → array? m : dmat?
 procedure m : dmat?
 procedure m : dmat?
 procedure m : dmat?
 procedure(make-dmat-data num-cols num-rows x ...+) → array? num-cols : exact-positive-integer? num-rows : exact-positive-integer? x : real?
 procedure(dmat-copy m) → dmat? m : dmat?
 procedure(dmat-name m) → symbol? m : dmat?
 procedure(dmat-ref m col row) → dvec? m : dmat? col : exact-nonnegative-integer? row : exact-nonnegative-integer? (dmat-ref m i) → dvec? m : dmat? i : exact-nonnegative-integer?
 procedure(dmat-row m i) → dvec? m : dmat? i : exact-nonnegative-integer?
 procedure(dmat-column m i) → dvec? m : dmat? i : exact-nonnegative-integer?
 procedure(dmat-set-column! m i v) → void? m : dmat? i : exact-nonnegative-integer? v : dvec?
 procedure(dmat-set-row! m i v) → void? m : dmat? i : exact-nonnegative-integer? v : dvec?
 procedure(dmat-set! m col row x) → void? m : dmat? col : exact-nonnegative-integer? row : exact-nonnegative-integer? x : real? (dmat-set! m i x) → void? m : dmat? i : exact-nonnegative-integer? x : real?
 procedure(dmat->list m) → (listof real?) m : dmat?
 procedure(dmat-rows m) → (listof dvec?) m : dmat?
 procedure(dmat-columns m) → (listof dvec?) m : dmat?
 procedure m : dmat?
 procedure m : dmat?
 procedure(in-dmat m) → sequence? m : dmat?

syntax

 (for/dmat maybe-cols #:rows length-expr maybe-fill (for-clause ...) body-or-break ... body)

maybe-cols =
| #:cols length-expr

maybe-fill =
| #:fill length-expr

syntax

 (for*/dmat maybe-cols #:rows length-expr maybe-fill (for-clause ...) body-or-break ... body)
 procedure m : dmat?
 procedure m : dmat?
 procedure m : dmat?
 procedure m : dmat?
 procedure m : dmat?
 procedure m : dmat?
 procedure(dmat=! m n) → void? m : dmat? n : dmat?
 procedure(dmat+ a ...+) → (or/c dmat? dvec? real?) a : (or/c dmat? dvec? real?)
 procedure(dmat- a ...+) → (or/c dmat? dvec? real?) a : (or/c dmat? dvec? real?)
 procedure(dmat* a ...+) → (or/c dmat? dvec? real?) a : (or/c dmat? dvec? real?)
 procedure(dmat+=! m a) → void? m : dmat? a : (or/c dmat? dvec? real?)
 procedure(dmat-=! m a) → void? m : dmat? a : (or/c dmat? dvec? real?)
 procedure(dmat*=! m a) → void? m : dmat? a : (or/c dmat? dvec? real?)
 procedure(++dmat! m) → dmat? m : dmat?
 procedure(--dmat! m) → dmat? m : dmat?
 procedure(dmat++! m) → dmat? m : dmat?
 procedure(dmat--! m) → dmat? m : dmat?
 procedure(_dmat rows cols) → ctype? rows : exact-positive-integer? cols : exact-positive-integer?
 syntax(define-dmat-type id #:cols N #:rows M)
##### 2.2.2.1dmat Types
 procedure
 procedure
 procedure
 procedure
 procedure
 procedure
 procedure
 procedure
 procedure
 procedure
 procedure
 procedure
 procedure(dmat2 a ...) → dmat2? a : (or/c dmat? dvec? real?)
 procedure(dmat3 a ...) → dmat3? a : (or/c dmat? dvec? real?)
 procedure(dmat4 a ...) → dmat4? a : (or/c dmat? dvec? real?)
 procedure(dmat2x2 a ...) → dmat2x2? a : (or/c dmat? dvec? real?)
 procedure(dmat2x3 a ...) → dmat2x3? a : (or/c dmat? dvec? real?)
 procedure(dmat2x4 a ...) → dmat2x4? a : (or/c dmat? dvec? real?)
 procedure(dmat3x2 a ...) → dmat3x2? a : (or/c dmat? dvec? real?)
 procedure(dmat3x3 a ...) → dmat3x3? a : (or/c dmat? dvec? real?)
 procedure(dmat3x4 a ...) → dmat3x4? a : (or/c dmat? dvec? real?)
 procedure(dmat4x2 a ...) → dmat4x2? a : (or/c dmat? dvec? real?)
 procedure(dmat4x3 a ...) → dmat4x3? a : (or/c dmat? dvec? real?)
 procedure(dmat4x4 a ...) → dmat4x4? a : (or/c dmat? dvec? real?)
 value
 value
 value
 value
 value
 value
 value
 value
 value
 value
 value
 value