Vectors and matrices

(ns vector-matrix
  (:require [fastmath.vector :as v]
            [fastmath.matrix :as mat]
            [fastmath.dev.codox :as codox]
            [fastmath.dev.clay :as utls]
            [fastmath.dev.plotly :as plt]
            [fastmath.core :as m]
            [scicloj.kindly.v4.kind :as kind]
            [fastmath.dev.ggplot :as gg]
            [fastmath.stats :as stats])
  (:import [fastmath.vector Vec2 Vec3 Vec4]
           [fastmath.matrix Mat2x2 Mat3x3 Mat4x4]))

Vectors

The fastmath.vector namespace provides a comprehensive set of utilities for working with N-dimensional mathematical vectors in Clojure. It supports various vector representations, including custom fixed-size types (Vec2, Vec3, Vec4), Clojure persistent vectors and sequences, Java double arrays, and Apache Commons Math ArrayRealVector, all unified under the fastmath.protocols/VectorProto.

Vector Types

fastmath.vector supports several underlying representations for vectors, providing flexibility and performance trade-offs. The VectorProto ensures that most operations work consistently across these types.

Supported Types
  • A number (1D vector)
  • Vec2 (2D vector, custom type)
  • Vec3 (3D vector, custom type)
  • Vec4 (4D vector, custom type)
  • ArrayVec (N-dimensional, wrapper around double array, deprecated)
  • double[] (Java double array, N-dimensional)
  • Clojure IPersistentVector ([], N-dimensional)
  • Clojure ISeq (any sequence, N-dimensional)
  • Apache Commons Math ArrayRealVector (N-dimensional)
Warning

The ArrayVec type should be considered as deprecated. This is just a double-array wrapper. double-array itself is instrumented in VectorProto functions and can be used directly.

Let’s define fixed size vectors to use in examples:

(def V2 (Vec2. -1 2.5))
(def V3 (Vec3. -1 2.5 -3.25))
(def V4 (Vec4. -1 0.0 -3.25 4))
Examples
V2 ;; => #vec2 [-1.0, 2.5]
V3 ;; => #vec3 [-1.0, 2.5, -3.25]
V4 ;; => #vec4 [-1.0, 0.0, -3.25, 4.0]

Creation and Conversion

Defined functions
  • vec2, vec3, vec4
  • array-vec
  • make-vector
  • generate-vec2, generate-vec3, generate-vec4
  • array->vec2, array->vec3, array->vec4
  • seq->vec2, seq->vec3, seq->vec4
  • vec->array, vec->seq, vec->RealVector, real-vector, vec->Vec
  • as-vec

Creation

  • Fixed-size constructors: vec2, vec3, and vec4 create vectors with 2, 3, and 4 dimensions, respectively. They can be called with no arguments for a zero vector, or with explicit components.
  • Arbitrary-size constructor: array-vec takes a sequence and creates an ArrayVec wrapping a double array.
  • Generic constructor: make-vector takes a dimension and optionally a sequence of values. It automatically selects the appropriate fixed-size type (Vec2, Vec3, Vec4) for dimensions 2, 3, or 4, or creates an ArrayVec for other positive dimensions.
  • Generator functions: generate-vec2, generate-vec3, and generate-vec4 create vectors whose components are generated by one or more provided functions.
  • Conversion functions: array->vec2/3/4 and seq->vec2/3/4 provide convenience for converting double arrays or arbitrary sequences into the fixed-size types.
Examples
(v/vec2) ;; => #vec2 [0.0, 0.0]
(v/vec2 1 2) ;; => #vec2 [1.0, 2.0]
(class (v/vec2)) ;; => fastmath.vector.Vec2
(v/vec3) ;; => #vec3 [0.0, 0.0, 0.0]
(v/vec3 V2 3) ;; => #vec3 [-1.0, 2.5, 3.0]
(v/vec3 1 2 3) ;; => #vec3 [1.0, 2.0, 3.0]
(class (v/vec3)) ;; => fastmath.vector.Vec3
(v/vec4) ;; => #vec4 [0.0, 0.0, 0.0, 0.0]
(v/vec4 V2 3 4) ;; => #vec4 [-1.0, 2.5, 3.0, 4.0]
(v/vec4 V3 4) ;; => #vec4 [-1.0, 2.5, -3.25, 4.0]
(v/vec4 1 2 3 4) ;; => #vec4 [1.0, 2.0, 3.0, 4.0]
(class (v/vec4)) ;; => fastmath.vector.Vec4
(v/array-vec [1 2 3 4 5]) ;; => [1.0 2.0 3.0 4.0 5.0]
(v/make-vector 1) ;; => 0.0
(v/make-vector 2) ;; => #vec2 [0.0, 0.0]
(v/make-vector 3) ;; => #vec3 [0.0, 0.0, 0.0]
(v/make-vector 4) ;; => #vec4 [0.0, 0.0, 0.0, 0.0]
(v/make-vector 5 [1 2 3 4 5 8]) ;; => [1.0 2.0 3.0 4.0 5.0]
(class (v/make-vector 5 [1 2 3 4 5 8])) ;; => fastmath.vector.ArrayVec
(v/generate-vec2 rand) ;; => #vec2 [0.5703869815688357, 0.6485673453839519]
(v/generate-vec3 (constantly 4)) ;; => #vec3 [4.0, 4.0, 4.0]
(v/generate-vec4 (comp m/sin rand)) ;; => #vec4 [0.7183927005523126, 0.27697293919166044, 0.15770185653888744, 0.7933000970612148]
(v/array->vec2 (double-array [1 2 3 4 5])) ;; => #vec2 [1.0, 2.0]
(v/array->vec3 (double-array [1 2 3 4 5])) ;; => #vec3 [1.0, 2.0, 3.0]
(v/array->vec4 (double-array [1 2 3 4 5])) ;; => #vec4 [1.0, 2.0, 3.0, 4.0]
(v/seq->vec2 [1 2 3 4 5]) ;; => #vec2 [1.0, 2.0]
(v/seq->vec3 [1 2 3 4 5]) ;; => #vec3 [1.0, 2.0, 3.0]
(v/seq->vec4 [1 2 3 4 5]) ;; => #vec4 [1.0, 2.0, 3.0, 4.0]

Conversion

fastmath.vector provides several functions to convert vectors between the supported types and representations, facilitating integration with other libraries or specific processing needs.

  • vec->array: Converts any vector type to a double array ([D).
  • vec->seq: Returns a standard Clojure lazy sequence representation of the vector. Note that all fastmath.vector types already implement clojure.lang.Seqable and clojure.lang.Sequential, so you can use the built-in seq function or treat them as sequences directly.
  • real-vector orvec->RealVector: Converts any vector type into an Apache Commons Math RealVector object, specifically an ArrayRealVector.
  • vec->Vec: Converts any vector type into a Clojure primitive vector (Vec), which is an optimized implementation of persistent vectors for numerical data.
Examples
(v/vec->array V2) ;; => #object["[D" 0xf0c8db "[D@f0c8db"]
(v/vec->seq V2) ;; => (-1.0 2.5)
(v/vec->RealVector V2) ;; => #object[org.apache.commons.math3.linear.ArrayRealVector 0x5ea8aabb "{-1; 2.5}"]
(v/vec->Vec V2) ;; => [-1.0 2.5]
(class (v/vec->Vec V2)) ;; => clojure.core.Vec
(v/vec->array [1 2 3]) ;; => #object["[D" 0x4e730125 "[D@4e730125"]
(v/vec->seq [1 2 3]) ;; => (1 2 3)
(v/vec->RealVector [1 2 3]) ;; => #object[org.apache.commons.math3.linear.ArrayRealVector 0x48c3be20 "{1; 2; 3}"]
(v/real-vector [1 2 3]) ;; => #object[org.apache.commons.math3.linear.ArrayRealVector 0x410429d5 "{1; 2; 3}"]
(v/real-vector (double-array 4)) ;; => #object[org.apache.commons.math3.linear.ArrayRealVector 0x5a62ae3c "{0; 0; 0; 0}"]
(v/real-vector (seq (v/vec2 9 8))) ;; => #object[org.apache.commons.math3.linear.ArrayRealVector 0xc4ee67c "{9; 8}"]
(v/vec->Vec [1 2 3]) ;; => [1.0 2.0 3.0]

as-vec creates a new vector of a specific type using elements from xs sequence. If the sequence is shorter than the target vector’s dimension, the remaining elements are filled with 0.0. The first argument specifies the target type (by providing an instance of that type). In short: as-vec ensures a type and size of the first argument with the content of the second argument.

Examples
(v/as-vec (list 3) [1 2 3]) ;; => (1)
(v/as-vec (list 3 4 5) [1 2 3]) ;; => (1 2 3)
(v/as-vec (list 3 4 5 6) [1 2 3]) ;; => (1 2 3 0.0)
(v/as-vec (v/vec2) [1 2 3]) ;; => #vec2 [1.0, 2.0]
(v/as-vec (v/vec3) [1 2 3]) ;; => #vec3 [1.0, 2.0, 3.0]
(v/as-vec (v/vec4) [1 2 3]) ;; => #vec4 [1.0, 2.0, 3.0, 0.0]
(seq (v/as-vec (double-array 6) [1])) ;; => (1.0 0.0 0.0 0.0 0.0 0.0)

Interoperability

The core idea behind fastmath.vector’s flexibility is the fastmath.protocols/VectorProto protocol. This protocol defines the common set of operations (addition, multiplication, dot product, magnitude, etc.) that all supported vector types must implement. By relying on this protocol, functions in fastmath.vector can work seamlessly with Vec2, Vec3, Vec4, ArrayVec, Clojure vectors, double arrays, and even Apache Commons Math RealVector instances. This protocol-oriented design allows for easy interoperability between different vector representations. Several functions are provided to facilitate conversions between these types:

Fixed-size vector types like Vec2, Vec3, and Vec4, as well as ArrayVec, also implement several standard Clojure and Java interfaces, allowing them to be used similarly to built-in Clojure persistent vectors:

  • clojure.lang.Seqable: Enables treating the vector as a sequence for functions like seq, map, filter, etc.
  • clojure.lang.Reversible: Enables reversing a vector with rseq
  • clojure.lang.Sequential: Marks that the vector is sequential, ie. sequence is linear and order is persistent
  • clojure.lang.Indexed: Allows efficient access to elements by integer index using nth.
  • clojure.lang.ILookup: Enables lookup of elements by index using the function call syntax (v index) or get.
  • clojure.lang.Counted: Provides the count function to get the dimension of the vector.
  • clojure.lang.IFn: Allows the vector itself to be invoked as a function to retrieve elements by index, e.g., (v 0).
  • clojure.lang.Associative: Supports assoc, containsKey, and entryAt, allowing index-based association (updating elements). Note that assoc returns a new vector instance.
  • clojure.lang.IReduce/IReduceInit: Allows using reduce directly on the vector’s elements.
  • clojure.lang.IPersistentVector: Implements basic persistent vector behavior.
  • clojure.lang.IPersistentCollection: Implements equiv for efficient structural equality checks.
  • clojure.lang.IPersistentStack: Implements pop and peek
  • java.lang.Object: Standard Java methods like equals, hashCode, and toString.
  • clojure.lang.IHashEq: Provides hasheq for efficient hashing, especially important when using vectors as keys in hash maps or sets.
Examples

Seqable

(seq V2) ;; => (-1.0 2.5)
(seq V3) ;; => (-1.0 2.5 -3.25)
(seq V4) ;; => (-1.0 0.0 -3.25 4.0)
(map inc V4) ;; => (0.0 1.0 -2.25 5.0)

Reversible

(rseq V2) ;; => (2.5 -1.0)
(rseq V3) ;; => (-3.25 2.5 -1.0)
(rseq V4) ;; => (4.0 -3.25 0.0 -1.0)

Indexed

(nth V4 0) ;; => -1.0
(try (nth V4 5) (catch Exception e (.getMessage e))) ;; => "Index 5 out of bounds for length 4"
(nth V4 5 ##NaN) ;; => ##NaN

ILookup

(get V4 3) ;; => 4.0
(get V4 5) ;; => nil

Counted

(count V2) ;; => 2
(count V3) ;; => 3
(count V4) ;; => 4

IFn

(V2 0) ;; => -1.0
(V3 1) ;; => 2.5
(V4 2) ;; => -3.25
(try (V4 5) (catch Exception e (.getMessage e))) ;; => "Index 5 out of bounds for length 2"

Associative

(contains? V4 0) ;; => true
(contains? V4 5) ;; => false
(assoc V4 3 100) ;; => #vec4 [-1.0, 0.0, -3.25, 100.0]
(find V4 3) ;; => [3 4.0]

IReduce/IReduceInit

(reduce * V4) ;; => 0.0
(reduce * 100 V4) ;; => 0.0

IPersistentVector

(conj V2 100) ;; => #vec3 [-1.0, 2.5, 100.0]
(conj V3 100) ;; => #vec4 [-1.0, 2.5, -3.25, 100.0]
(conj V4 100) ;; => [-1.0 0.0 -3.25 4.0 100]

IPersistentStack

(peek V2) ;; => 2.5
(pop V2) ;; => [-1.0]
(peek V3) ;; => -3.25
(pop V3) ;; => #vec2 [-1.0, 2.5]
(peek V4) ;; => 4.0
(pop V4) ;; => #vec3 [-1.0, 0.0, -3.25]

IPersistentCollection

(= V2 (v/vec2 -1 2)) ;; => false
(= V2 V3) ;; => false

IHashEq

(hash V2) ;; => 969236348
(hash V3) ;; => 1071439709
(hash V4) ;; => 663401910

Object

(str V2) ;; => "#vec2 [-1.0, 2.5]"
(.equals V2 (v/vec2 -1 2)) ;; => false
(.hashCode V2) ;; => 969236348

Vector Arithmetic and Operations

fastmath.vector provides a comprehensive suite of functions for performing standard vector arithmetic and element-wise mathematical operations. These operations are designed to work efficiently and consistently across all supported vector types, leveraging the VectorProto protocol.

Basic operations

Defined functions
  • add, sub, shift, mult, div, reciprocal, emult, ediv
  • abs
  • mn, mx, emn, emx, mindim, maxdim
  • approx
  • sum, prod, average, logsumexp, logmeanexp
  • zero-count, nonzero-count, size
  • permute
  • fmap
  • Basic Arithmetic:
    • add: Vector addition. Takes one or two vectors. \(\mathbf{u} + \mathbf{v} = [u_1+v_1, u_2+v_2, \dots, u_n+v_n]\).
    • sub: Vector subtraction. Takes one (negation) or two vectors. \(\mathbf{u} - \mathbf{v} = [u_1-v_1, u_2-v_2, \dots, u_n-v_n]\).
    • shift: Adds a scalar value to each element of a vector. \(\mathbf{v} + c = [v_1+c, v_2+c, \dots, v_n+c]\).
    • mult: Scalar multiplication of a vector. \(c \mathbf{v} = [c v_1, c v_2, \dots, c v_n]\).
    • div: Scalar division of a vector (v1 / v) or element-wise reciprocal (v1). \(\mathbf{v} / c = [v_1/c, v_2/c, \dots, v_n/c]\) or \(1/\mathbf{v} = [1/v_1, 1/v_2, \dots, 1/v_n]\).
    • reciprocal: Element-wise reciprocal. \(1/\mathbf{v} = [1/v_1, 1/v_2, \dots, 1/v_n]\).
    • emult: Element-wise multiplication (Hadamard product). \(\mathbf{u} \odot \mathbf{v} = [u_1 v_1, u_2 v_2, \dots, u_n v_n]\).
    • ediv: Element-wise division. \(\mathbf{u} \oslash \mathbf{v} = [u_1/v_1, u_2/v_2, \dots, u_n/v_n]\).
  • Element-wise Functions:
    • abs: Element-wise absolute value. \(|\mathbf{v}| = [|v_1|, |v_2|, \dots, |v_n|]\).
    • fmap: Applies a function to each element of the vector, returning a new vector of the same type. \(f(\mathbf{v}) = [f(v_1), f(v_2), \dots, f(v_n)]\).
  • Statistical/Aggregate Functions:
    • mn: Minimum value among elements.
    • mx: Maximum value among elements.
    • emn: Element-wise minimum of two vectors.
    • emx: Element-wise maximum of two vectors.
    • mindim: Index of the minimum value.
    • maxdim: Index of the maximum value.
    • sum: Sum of all elements. \(\sum \mathbf{v} = \sum_{i=1}^n v_i\).
    • prod: Product of all elements. \(\prod \mathbf{v} = \prod_{i=1}^n v_i\).
    • average: Mean or weighted average of elements. \(\text{mean}(\mathbf{v}) = \frac{1}{n} \sum_{i=1}^n v_i\).
    • logsumexp: Numerically stable computation of \(\log(\sum \exp(v_i))\).
    • logmeanexp: Numerically stable computation of \(\log(\frac{1}{n} \sum \exp(v_i))\).
  • Utility Functions:
    • approx: Rounds elements to a specified number of decimal places.
    • zero-count: Counts how many elements are approximately zero.
    • nonzero-count: Counts how many elements are not approximately zero.
    • size: Returns the dimension (number of elements) of the vector. Same as count.
    • permute: Rearranges vector elements according to a list of indices.

Most binary operations (add, sub, emult, ediv, emn, emx) require the input vectors to have the same dimension and type. Scalar operations (shift, mult, div) work with a vector and a number.

Examples
(v/add V2 (v/vec2 1 1)) ;; => #vec2 [0.0, 3.5]
(v/sub V3 (v/vec3 1 1 1)) ;; => #vec3 [-2.0, 1.5, -4.25]
(v/shift V4 10.0) ;; => #vec4 [9.0, 10.0, 6.75, 14.0]
(v/mult V3 0.5) ;; => #vec3 [-0.5, 1.25, -1.625]
(v/div V4 2.0) ;; => #vec4 [-0.5, 0.0, -1.625, 2.0]
(v/div V3) ;; => #vec3 [-1.0, 0.4, -0.3076923076923077]
(v/reciprocal V3) ;; => #vec3 [-1.0, 0.4, -0.3076923076923077]
(v/emult V2 (v/vec2 2 2)) ;; => #vec2 [-2.0, 5.0]
(v/ediv V2 (v/vec2 2 10)) ;; => #vec2 [-0.5, 0.25]
(v/abs V4) ;; => #vec4 [1.0, 0.0, 3.25, 4.0]
(v/mn V3) ;; => -3.25
(v/mx V4) ;; => 4.0
(v/emn V3 (v/vec3 0 3 -4)) ;; => #vec3 [-1.0, 2.5, -4.0]
(v/emx V4 (v/vec4 -2 1 -3 5)) ;; => #vec4 [-1.0, 1.0, -3.0, 5.0]
(v/mindim V4) ;; => 2
(v/maxdim V4) ;; => 3
(v/sum) ;; => 0.0
(v/sum V2) ;; => 1.5
(v/prod) ;; => 1.0
(v/prod V3) ;; => 8.125
(v/average V4) ;; => -0.0625
(v/average V4 (v/vec4 1 1 10 1)) ;; => -2.269230769230769
(v/approx (v/vec4 1.2345 6.789 0.123 4.567)) ;; => #vec4 [1.23, 6.79, 0.12, 4.57]
(v/approx (v/vec4 1.2345 6.789 0.123 4.567) 1) ;; => #vec4 [1.2, 6.8, 0.1, 4.6]
(v/zero-count V4) ;; => 1
(v/nonzero-count V4) ;; => 3
(v/size V3) ;; => 3
(count V3) ;; => 3
(v/permute V4 [3 1 0 2]) ;; => #vec4 [4.0, 0.0, -1.0, -3.25]
(v/permute V4 [0 0 0 3]) ;; => #vec4 [-1.0, -1.0, -1.0, 4.0]
(v/fmap V3 m/cos) ;; => #vec3 [0.5403023058681398, -0.8011436155469337, -0.9941296760805461]
(v/logsumexp [-10 10 20 30 40]) ;; => 40.00004540096037
(v/logmeanexp [-10 10 20 30 40]) ;; => 38.39060748852627

Comparison and Equality

Functions for comparing vectors, including approximate equality checks. These functions are essential for robust numerical comparisons, especially when dealing with floating-point numbers where exact equality (=) can be unreliable due to precision issues.

Defined functions
  • is-zero?, zero?, is-near-zero?, near-zero?
  • delta-eq, edelta-eq
  • aligned?
  • Zero Check:
    • is-zero? / zero?: Checks if all elements of the vector are exactly zero. Returns true if \(\mathbf{v} = [0, 0, \dots, 0]\).
    • is-near-zero? / near-zero?: Checks if the vector’s magnitude is close to zero within a specified absolute or relative tolerance. Returns true if \(\Vert \mathbf{v} \Vert \approx 0\).
  • Equality Check:
    • delta-eq: Checks if the Euclidean distance between two vectors is within a given absolute and/or relative tolerance. Returns true if \(\Vert \mathbf{u} - \mathbf{v} \Vert \approx 0\).
    • edelta-eq: Performs an element-wise approximate equality check between two vectors. Returns true if \(|u_i - v_i| \approx 0\) for all elements \(i\), considering tolerance.
  • Alignment Check:
    • aligned?: Checks if the angle between two vectors is less than a specified tolerance, indicating they point in approximately the same direction. Returns true if Angle\((\mathbf{u}, \mathbf{v}) < \text{tolerance}\).
Examples
(v/is-zero? (v/vec2)) ;; => true
(v/zero? (v/vec3 0 0 0)) ;; => true
(v/is-zero? V2) ;; => false
(v/near-zero? (v/vec4 1.0E-9 0 0 -1.0E-9)) ;; => true
(v/near-zero? (v/vec4 1.0E-5 0 0 -1.0E-5) 1.0E-6) ;; => false
(v/near-zero? (v/vec4 1.0E-5 0 0 -1.0E-5) 1.0E-4) ;; => true
(v/delta-eq V2 (v/vec2 -1.0 2.5)) ;; => true
(v/delta-eq V2 (v/vec2 -1.0000001 2.5000001)) ;; => true
(v/delta-eq V2 (v/vec2 -1.000001 2.500001) 1.0E-6) ;; => false
(v/edelta-eq V2 (v/vec2 -1.0 2.5)) ;; => true
(v/edelta-eq V2 (v/vec2 -1.0000001 2.5000001)) ;; => true
(v/edelta-eq V2 (v/vec2 -1.000001 2.500001) 1.0E-6) ;; => false
(v/aligned? (v/vec2 1 0) (v/vec2 1 1.0E-7)) ;; => true
(v/aligned? (v/vec2 1 0) (v/vec2 1 1.0E-5)) ;; => false
(v/aligned? (v/vec2 1 0) (v/vec2 1 1.0E-5) 1.0E-4) ;; => true

Interpolation and Clamping

Functions for blending vectors and bounding element values.

Defined functions
  • interpolate, einterpolate, lerp
  • econstrain, clamp

These functions provide tools for combining vectors based on a parameter (interpolation) or ensuring that vector elements stay within specified bounds (clamping and constraining).

  • Interpolation:
    • interpolate: Blends two vectors v1 and v2 based on a scalar parameter t. The default interpolation function is linear interpolation (lerp).
    • einterpolate: Performs element-wise interpolation between vectors v1 and v2, using corresponding elements from a third vector v as the interpolation parameters t.
    • lerp: Performs linear interpolation between two vectors \(\mathbf{v}_1\) and \(\mathbf{v}_2\). The resulting vector is \(\mathbf{v}_1 + t (\mathbf{v}_2 - \mathbf{v}_1)\). This is a specific case of interpolate using the standard fastmath.core/lerp function.
  • Clamping/Constraining:
    • econstrain: Clamps each element of a vector v between a minimum value val1 and a maximum value val2 element-wise.
    • clamp: A convenience function that uses econstrain. It clamps elements between 0.0 and Double/MAX_VALUE when called with one argument [v], or between mn and mx when called with three arguments [v mn mx].
Examples
(v/lerp (v/vec2) (v/vec2 10 -10) 0.5) ;; => #vec2 [5.0, -5.0]
(v/interpolate (v/vec4) (v/vec4 1 1 1 1) 0.75) ;; => #vec4 [0.75, 0.75, 0.75, 0.75]
(v/interpolate (v/vec4) (v/vec4 1 1 1 1) 0.75 m/smoothstep) ;; => #vec4 [0.84375, 0.84375, 0.84375, 0.84375]
(v/einterpolate (v/vec2) (v/vec2 10 -10) (v/vec2 0.2 0.8)) ;; => #vec2 [2.0, -8.0]
(v/einterpolate (v/vec4) (v/vec4 1 1 1 1) (v/vec4 0 0.2 0.8 1) m/smoothstep) ;; => #vec4 [0.0, 0.10400000000000002, 0.8960000000000001, 1.0]
(v/econstrain (v/vec4 -2 0.5 5 1.2) 0.0 1.0) ;; => #vec4 [0.0, 0.5, 1.0, 1.0]
(v/clamp (v/vec3 -5 10 0.5) 0 1) ;; => #vec3 [0.0, 1.0, 0.5]
(v/clamp (v/vec3 -5 10 0.5)) ;; => #vec3 [0.0, 10.0, 0.5]

Element-wise Functions

Applying common mathematical functions from fastmath.core element-wise.

Defined functions
  • sin, cos, tan, asin, acos, atan
  • sinh, cosh, tanh, asinh, acosh, atanh
  • cot, sec, csc, acot, asec, acsc
  • coth, sech, csch, acoth, asech, acsch
  • sq, cb, safe-sqrt, sqrt, cbrt, pow
  • exp, log, log10, log2, ln, log1p, expm1
  • log1pexp, log1mexp, log1psq, log1pmx, logmxp1, logexpm1
  • radians, degrees, sinc, sigmoid, logit, xlogx
  • floor, ceil, round, rint, trunc, frac, sfrac, signum, sgn
Examples

Trigonometry

(v/sin V2) ;; => #vec2 [-0.8414709848078964, 0.5984721441039565]
(v/cos V2) ;; => #vec2 [0.5403023058681398, -0.8011436155469337]
(v/tan V2) ;; => #vec2 [-1.5574077246549018, -0.7470222972386602]
(v/cot V2) ;; => #vec2 [-0.6420926159343309, -1.3386481283041516]
(v/sec V2) ;; => #vec2 [1.8508157176809255, -1.2482156514688179]
(v/csc V2) ;; => #vec2 [-1.1883951057781215, 1.6709215455586797]
(v/asin (v/vec2 -0.5 0.5)) ;; => #vec2 [-0.5235987755982989, 0.5235987755982989]
(v/acos (v/vec2 -0.5 0.5)) ;; => #vec2 [2.0943951023931957, 1.0471975511965976]
(v/atan (v/vec2 -0.5 0.5)) ;; => #vec2 [-0.4636476090008061, 0.4636476090008061]
(v/acot (v/vec2 -0.5 0.5)) ;; => #vec2 [2.0344439357957027, 1.1071487177940904]
(v/asec (v/vec2 1 2)) ;; => #vec2 [0.0, 1.0471975511965976]
(v/acsc (v/vec2 1 2)) ;; => #vec2 [1.5707963267948966, 0.5235987755982989]

Hyperbolic

(v/sinh V2) ;; => #vec2 [-1.1752011936438016, 6.0502044810397875]
(v/cosh V2) ;; => #vec2 [1.543080634815244, 6.132289479663686]
(v/tanh V2) ;; => #vec2 [-0.7615941559557649, 0.9866142981514303]
(v/coth V2) ;; => #vec2 [-1.3130352854993315, 1.0135673098126083]
(v/sech V2) ;; => #vec2 [0.6480542736638853, 0.16307123192997783]
(v/csch V2) ;; => #vec2 [-0.8509181282393214, 0.16528366985509557]
(v/asinh (v/vec2 -0.5 0.5)) ;; => #vec2 [-0.48121182505960347, 0.48121182505960347]
(v/acosh (v/vec2 1 2)) ;; => #vec2 [0.0, 1.3169578969248166]
(v/atanh (v/vec2 -0.5 0.5)) ;; => #vec2 [-0.5493061443340548, 0.5493061443340548]
(v/acoth (v/vec2 1 2)) ;; => #vec2 [Infinity, 0.5493061443340548]
(v/asech (v/vec2 1 0.5)) ;; => #vec2 [0.0, 1.3169578969248166]
(v/acsch (v/vec2 1 2)) ;; => #vec2 [0.8813735870195429, 0.48121182505960347]

Powers

(v/sq V3) ;; => #vec3 [1.0, 6.25, 10.5625]
(v/cb V3) ;; => #vec3 [-1.0, 15.625, -34.328125]
(v/safe-sqrt V3) ;; => #vec3 [0.0, 1.5811388300841898, 0.0]
(v/sqrt V3) ;; => #vec3 [NaN, 1.5811388300841898, NaN]
(v/cbrt V3) ;; => #vec3 [-1.0, 1.3572088082974534, -1.4812480342036853]
(v/pow V3 5) ;; => #vec3 [-1.0, 97.65625, -362.5908203125]

Exp and logarithm

(v/exp V3) ;; => #vec3 [0.36787944117144233, 12.182493960703473, 0.03877420783172201]
(v/expm1 V3) ;; => #vec3 [-0.6321205588285577, 11.182493960703473, -0.961225792168278]
(v/log (v/abs V3)) ;; => #vec3 [0.0, 0.9162907318741551, 1.1786549963416462]
(v/ln (v/abs V3)) ;; => #vec3 [0.0, 0.9162907318741551, 1.1786549963416462]
(v/log10 (v/abs V3)) ;; => #vec3 [0.0, 0.3979400086720376, 0.5118833609788743]
(v/log2 (v/abs V3)) ;; => #vec3 [0.0, 1.3219280948873624, 1.7004397181410922]
(v/log1p (v/abs V3)) ;; => #vec3 [0.6931471805599453, 1.252762968495368, 1.4469189829363254]
(v/log1pexp V3) ;; => #vec3 [0.31326168751822303, 2.578889734292549, 0.03804137168778312]
(v/log1mexp V3) ;; => #vec3 [-0.458675145387082, NaN, -0.039545942179498944]
(v/log1psq V3) ;; => #vec3 [0.6931471805599453, 1.9810014688665833, 2.4477671028385433]
(v/log1pmx V3) ;; => #vec3 [-Infinity, -1.247237031504632, NaN]
(v/logmxp1 V3) ;; => #vec3 [NaN, -0.5837092681258449, NaN]
(v/logexpm1 V3) ;; => #vec3 [NaN, 2.414349516257962, NaN]
(v/xlogx (v/abs V3)) ;; => #vec3 [0.0, 2.2907268296853878, 3.83062873811035]

Sign

(v/signum V4) ;; => #vec4 [-1.0, 0.0, -1.0, 1.0]
(v/sgn V4) ;; => #vec4 [-1.0, 1.0, -1.0, 1.0]

Rounding

(v/floor V4) ;; => #vec4 [-1.0, 0.0, -4.0, 4.0]
(v/ceil V4) ;; => #vec4 [-1.0, 0.0, -3.0, 4.0]
(v/round V4) ;; => #vec4 [-1.0, 0.0, -3.0, 4.0]
(v/rint V4) ;; => #vec4 [-1.0, 0.0, -3.0, 4.0]
(v/trunc V4) ;; => #vec4 [-1.0, 0.0, -3.0, 4.0]
(v/frac V4) ;; => #vec4 [0.0, 0.0, 0.25, 0.0]
(v/sfrac V4) ;; => #vec4 [0.0, 0.0, -0.25, 0.0]

Other

(v/radians V3) ;; => #vec3 [-0.017453292519943295, 0.04363323129985824, -0.05672320068981571]
(v/degrees V3) ;; => #vec3 [-57.29577951308232, 143.2394487827058, -186.21128341751756]
(v/sinc V3) ;; => #vec3 [3.898171832295186E-17, 0.12732395447351627, -0.06925510124285433]
(v/sigmoid V3) ;; => #vec3 [0.2689414213699951, 0.9241418199787566, 0.03732688734412946]
(v/logit (v/vec3 0.1 0.5 0.9)) ;; => #vec3 [-2.197224577336219, 0.0, 2.1972245773362196]

Geometric Properties and Operations

Functions related to the length, direction, and orientation of vectors.

Defined functions
  • mag, magsq
  • normalize, set-mag, limit
  • heading, angle-between, relative-angle-between
  • perpendicular, base-from, faceforward, project
  • transform
  • average-vectors
  • dot, cross, triple-product
  • rotate, axis-rotate
  • to-polar, from-polar

These functions allow you to compute vector lengths, angles between vectors, project one vector onto another, normalize vectors, perform rotations, and work with different coordinate representations.

  • Magnitude and Length:
    • magsq: Computes the squared Euclidean magnitude (length) of a vector. \(\Vert \mathbf{v} \Vert^2 = \sum_{i=1}^n v_i^2\). Useful for comparisons as it avoids the expensive square root calculation.
    • mag: Computes the Euclidean magnitude (length) of a vector. \(\Vert \mathbf{v} \Vert = \sqrt{\sum_{i=1}^n v_i^2}\).
  • Normalization and Scaling:
    • normalize: Returns a unit vector (magnitude 1) with the same direction as the input vector. \(\hat{\mathbf{v}} = \mathbf{v} / \Vert \mathbf{v} \Vert\). Returns a zero vector if the input is a zero vector.
    • set-mag: Returns a new vector with the same direction as the input vector but a specified magnitude. \(\mathbf{v}' = \text{len} \cdot \hat{\mathbf{v}}\).
    • limit: Returns a new vector with the same direction as the input, but limits its magnitude to a maximum value. If the current magnitude is less than the limit, the original vector is returned.
  • Angles and Direction:
    • heading: For 2D vectors, returns the angle (in radians) relative to the positive x-axis. For 3D/4D vectors, it returns the angle between the vector and the positive x-axis ([1,0,...]).
    • angle-between: Computes the angle (in radians, \(0 \le \theta \le \pi\)) between two vectors. \(\theta = \operatorname{acos}(\frac{\mathbf{u} \cdot \mathbf{v}}{\Vert \mathbf{u} \Vert \Vert \mathbf{v} \Vert})\). Returns 0 if either vector is zero.
    • relative-angle-between: Computes the difference between the heading of two vectors. Primarily useful for 2D vectors to find the signed angle difference. Returns a value from \(-2\pi\) to \(2\pi\).
  • Projections and Basis:
    • project: Computes the vector projection of v1 onto v2. This is the component of v1 that lies along the direction of v2. \(\text{proj}_{\mathbf{v}_2} \mathbf{v}_1 = \frac{\mathbf{v}_1 \cdot \mathbf{v}_2}{\Vert \mathbf{v}_2 \Vert^2} \mathbf{v}_2\).
    • perpendicular: For 2D vectors, returns a vector perpendicular to the input ([-y, x]). For 3D vectors, perpendicular(v1, v2) computes a vector perpendicular to both v1 and v2 (their normalized cross product). Only defined for Vec2 and Vec3.
    • base-from: Computes an orthogonal basis starting from the input vector. For Vec2, returns [v, perpendicular(v)]. For Vec3, returns [v, v', v''] where v' and v'' are orthogonal to v and each other. Only defined for Vec2 and Vec3.
    • faceforward: Returns vector n or -n such that it faces the same general direction as v. Specifically, if \(\mathbf{n} \cdot \mathbf{v} < 0\), returns \(-\mathbf{n}\); otherwise, returns \(\mathbf{n}\). Useful for ensuring normals face outwards or towards a view direction.
  • Transformations:
    • transform: Transforms a point (represented by a vector v) from one coordinate system to another defined by an origin o and basis vectors (vx, vy, vz). Only defined for Vec2 and Vec3.
  • Aggregate/Statistical (Geometric Context):
    • average-vectors: Computes the centroid (average position) of a collection of vectors.
  • Vector Products:
    • dot: Computes the dot product of two vectors. \(\mathbf{u} \cdot \mathbf{v} = \sum_{i=1}^n u_i v_i\). Returns a scalar value.
    • cross: Computes the cross product of two 3D vectors. \(\mathbf{u} \times \mathbf{v} = [u_y v_z - u_z v_y, u_z v_x - u_x v_z, u_x v_y - u_y v_x]\). Returns a vector perpendicular to both inputs. Only defined for Vec3.
    • triple-product: Computes the scalar triple product of three 3D vectors: \(\mathbf{a} \cdot (\mathbf{b} \times \mathbf{c})\). Returns a scalar value equal to the signed volume of the parallelepiped spanned by the vectors. Only defined for Vec3.
  • Rotations:
    • rotate: Rotates a 2D vector by a given angle around the origin. Rotates a 3D vector around the origin by specified angles around the x, y, and z axes (intrinsic ZYX rotation). Only defined for Vec2 and Vec3.
    • axis-rotate: Rotates a 3D vector around a specified axis by a given angle. Can also specify an optional pivot point. Only defined for Vec3.
  • Coordinate Systems:
    • to-polar: Converts a 2D vector ([x, y]) to polar coordinates ([r, \theta]) or a 3D vector ([x, y, z]) to spherical coordinates ([r, \theta, \phi]), where r is magnitude, \theta is the angle from the positive z-axis (for 3D) or x-axis (for 2D), and \phi is the azimuthal angle in the xy-plane (for 3D). Only defined for Vec2 and Vec3.
    • from-polar: Converts a vector from polar (2D) or spherical (3D) coordinates back to Cartesian coordinates. Assumes input elements represent [r, \theta] for 2D or [r, \theta, \phi] for 3D. Only defined for Vec2 and Vec3.
Examples
(v/magsq V3) ;; => 17.8125
(v/mag V3) ;; => 4.220485754033533
(v/normalize V3) ;; => #vec3 [-0.23693955110363693, 0.5923488777590923, -0.77005354108682]
(v/set-mag V3 10.0) ;; => #vec3 [-2.369395511036369, 5.923488777590923, -7.7005354108682]
(v/limit V3 2.0) ;; => #vec3 [-0.47387910220727386, 1.1846977555181846, -1.54010708217364]
(v/heading V2) ;; => 1.9513027039072615
(v/angle-between (v/vec2 1 0) (v/vec2 0 1)) ;; => 1.5707963267948966
(v/relative-angle-between (v/vec2 1 0) (v/vec2 0 1)) ;; => 1.5707963267948966
(v/project V3 (v/vec3 1 1 1)) ;; => #vec3 [-0.5833333333333334, -0.5833333333333334, -0.5833333333333334]
(v/project (v/vec3 1 1 1) V3) ;; => #vec3 [0.09824561403508772, -0.24561403508771928, 0.3192982456140351]
(v/perpendicular (v/vec2 1 0)) ;; => #vec2 [-0.0, 1.0]
(v/perpendicular V3 (v/vec3 0 0 1)) ;; => #vec3 [0.9284766908852593, 0.3713906763541037, -0.0]
(v/base-from V2) ;; => [#vec2 [-1.0, 2.5] #vec2 [-0.9284766908852593, -0.3713906763541037]]
(v/base-from V3) ;; => [#vec3 [-1.0, 2.5, -3.25] #vec3 [0.0, -0.7926239891046, -0.6097107608496923] #vec3 [-4.100304866714181, -0.6097107608496923, 0.7926239891046]]
(v/faceforward (v/vec3 0 0 1) (v/vec3 0 0 -1)) ;; => #vec3 [-0.0, -0.0, -1.0]
(v/faceforward (v/vec3 0 0 1) (v/vec3 0 0 1)) ;; => #vec3 [0.0, 0.0, 1.0]
(v/transform (v/vec2 1 1) (v/vec2 10 10) (v/vec2 1 0) (v/vec2 0 1)) ;; => #vec2 [11.0, 11.0]
(v/transform (v/vec3 1 1 1) (v/vec3 10 10 10) (v/vec3 1 0 0) (v/vec3 0 1 0) (v/vec3 0 0 1)) ;; => #vec3 [11.0, 11.0, 11.0]
(v/average-vectors [V2 (v/vec2 1 1) (v/vec2 -2 -2)]) ;; => #vec2 [-0.6666666666666666, 0.5]
(v/dot V3 (v/vec3 1 1 1)) ;; => -1.75
(v/dot V3 (v/perpendicular V3 (v/vec3 0 0 1))) ;; => 0.0
(v/cross (v/vec3 1 0 0) (v/vec3 0 1 0)) ;; => #vec3 [0.0, 0.0, 1.0]
(v/triple-product (v/vec3 1 0 0) (v/vec3 0 1 0) (v/vec3 0 0 1)) ;; => 1.0
(v/rotate V2 m/HALF_PI) ;; => #vec2 [-2.5, -0.9999999999999999]
(v/rotate V3 m/HALF_PI 0 0) ;; => #vec3 [-1.0, 3.25, 2.5]
(v/axis-rotate V3 m/HALF_PI (v/vec3 1 0 0)) ;; => #vec3 [-1.0, 3.25, 2.5]
(v/axis-rotate (v/vec3 1 1 1) m/HALF_PI (v/vec3 0 0 1) (v/vec3 0 0 0)) ;; => #vec3 [-0.9999999999999999, 1.0, 1.0]
(v/axis-rotate (v/vec3 1 1 1) m/HALF_PI (v/vec3 0 0 1) (v/vec3 1 1 0)) ;; => #vec3 [1.0, 1.0, 1.0]
(v/to-polar V2) ;; => #vec2 [2.692582403567252, 1.9513027039072615]
(v/from-polar (v/vec2 (v/mag V2) (v/heading V2))) ;; => #vec2 [-0.9999999999999997, 2.5]
(v/to-polar V3) ;; => #vec3 [4.220485754033533, 2.4497213971395904, 1.9513027039072615]
(v/from-polar (v/vec3 (v/mag V3) 2.45 1.95)) ;; => #vec3 [-0.9964071702802869, 2.500459349968364, -3.250750035018045]

Distances and Similarities

Functions for measuring the distance or similarity between vectors using various metrics.

Defined functions
  • dist, dist-sq
  • dist-abs, dist-cheb
  • dist-discrete
  • dist-canberra, dist-emd
  • dist-ang, sim-cos
  • distances

These functions provide ways to quantify how “far apart” two vectors are (distance) or how similar their directions are (similarity), based on different mathematical definitions.

  • Euclidean Distance:
    • dist: Computes the standard Euclidean distance between two vectors. \(\Vert \mathbf{u} - \mathbf{v} \Vert = \sqrt{\sum_{i=1}^n (u_i - v_i)^2}\).
    • dist-sq: Computes the squared Euclidean distance. \(\Vert \mathbf{u} - \mathbf{v} \Vert^2 = \sum_{i=1}^n (u_i - v_i)^2\). Faster than dist if only comparing distances.
  • Other Common Distances:
    • dist-abs: Computes the Manhattan distance (L1 norm of the difference). \(\sum_{i=1}^n |u_i - v_i|\).
    • dist-cheb: Computes the Chebyshev distance (L-infinity norm of the difference). \(\max_{i} |u_i - v_i|\).
    • dist-discrete: Computes the discrete distance (Hamming distance for numerical vectors), counting the number of elements that are approximately different. \(\sum_{i=1}^n \mathbb{I}(|u_i - v_i| > \epsilon)\).
    • dist-canberra: Computes the Canberra distance. \(\sum_{i=1}^n \frac{|u_i - v_i|}{|u_i| + |v_i|}\), handles division by zero by treating \(\frac{0}{0}\) as 0.
    • dist-emd: Computes the 1D Earth Mover’s Distance (Wasserstein distance) between two vectors treated as 1D distributions. It is calculated as the sum of absolute differences of their cumulative sums. \(\sum_{i=1}^n \left| \sum_{j=1}^i u_j - \sum_{j=1}^i v_j \right|\).
  • Angular Metrics:
    • dist-ang: Computes the angular distance, which is the angle between normalized vectors, scaled to the range \([0, 1]\) by dividing by \(\pi\). \(\frac{1}{\pi} \operatorname{acos}(\frac{\mathbf{u} \cdot \mathbf{v}}{\Vert \mathbf{u} \Vert \Vert \mathbf{v} \Vert})\).
    • sim-cos: Computes the cosine similarity between two vectors. This is the cosine of the angle between them. \(\frac{\mathbf{u} \cdot \mathbf{v}}{\Vert \mathbf{u} \Vert \Vert \mathbf{v} \Vert}\). A value of 1 indicates identical direction, -1 opposite, and 0 orthogonality.
  • Distance Map:
    • distances: A map where keys are keywords (e.g., :euclid, :abs) and values are the corresponding distance functions. Useful for selecting metrics programmatically.
Examples
(v/dist V2 (v/vec2 0 0)) ;; => 2.692582403567252
(v/dist V3 (v/vec3 1 2 3)) ;; => 6.5812232905440915
(v/dist-sq V2 (v/vec2 0 0)) ;; => 7.25
(v/dist-sq V3 (v/vec3 1 2 3)) ;; => 43.3125
(v/dist-abs V4 (v/vec4 0 0 0 0)) ;; => 8.25
(v/dist-abs V4 (v/vec4 -1 1 -3 5)) ;; => 2.25
(v/dist-cheb V4 (v/vec4 0 0 0 0)) ;; => 4.0
(v/dist-cheb V4 (v/vec4 -1 1 -3 5)) ;; => 1.0
(v/dist-discrete V3 (v/vec3 -1 2.5 -3.25)) ;; => 0.0
(v/dist-discrete V3 (v/vec3 -1 2.5 -3.251) 1.0E-4) ;; => 1.0
(v/dist-discrete V3 (v/vec3 -1 2.5 -3.251) 0.001) ;; => 0.0
(v/dist-discrete V3 (v/vec3 -1 0 -3.25)) ;; => 1.0
(v/dist-canberra V3 (v/vec3 1 1 1)) ;; => 2.428571428571429
(v/dist-canberra (v/vec3 1 0 1) (v/vec3 0 1 0)) ;; => 3.0
(v/dist-emd (v/vec3 1 2 3) (v/vec3 3 2 1)) ;; => 4.0
(v/dist-ang (v/vec2 1 0) (v/vec2 0 1)) ;; => 0.5
(v/dist-ang (v/vec3 1 0 0) (v/vec3 0 0 1)) ;; => 0.5
(v/sim-cos (v/vec2 1 0) (v/vec2 0 1)) ;; => 0.0
(v/sim-cos (v/vec2 1 0) (v/vec2 -1 0)) ;; => -1.0
((v/distances :euclid) V3 (v/vec3 1 2 3)) ;; => 6.5812232905440915
((v/distances :abs) V4 (v/vec4 -1 1 -3 5)) ;; => 2.25
(keys v/distances)
(:euclid :euclid-sq :abs :cheb :canberra :emd :angular :discrete)

Advanced and Specific Operations

Other utility and more specialized vector operations.

Defined Functions
  • orthogonal-polynomials, orthonormal-polynomials
  • softmax, logsoftmax

This section covers advanced operations that are useful in specific mathematical or statistical contexts, such as generating orthogonal bases for polynomial fitting or numerical stability functions common in machine learning.

  • Polynomial Bases:
    • orthogonal-polynomials: Generates a sequence of vectors representing orthogonal polynomials evaluated at the points in the input sequence xs. Orthogonality is with respect to the discrete inner product \(\sum_i p_k(x_i) p_j(x_i) = 0\) for \(k \ne j\). The sequence includes vectors up to degree (count xs) - 1.
    • orthonormal-polynomials: Similar to orthogonal-polynomials, but normalizes each resulting vector to have unit magnitude. This creates an orthonormal basis.
(v/orthogonal-polynomials [1 2 3 4 5])
([-2.0 -1.0 0.0 1.0 2.0]
 [2.0 -1.0 -2.0 -1.0 2.0]
 [-1.2000000000000002 2.4 -0.0 -2.4 1.2000000000000002]
 [0.3428571428571425 -1.3714285714285703 2.0571428571428574 -1.371428571428572
  0.3428571428571434]
 [1.1102230246251565E-16 1.1102230246251565E-15 -2.7406648379318155E-15
  6.661338147750939E-16 7.771561172376096E-16])
(v/orthonormal-polynomials [1 2 3 4 5])
([-0.6324555320336759 -0.31622776601683794 0.0 0.31622776601683794
  0.6324555320336759]
 [0.5345224838248488 -0.2672612419124244 -0.5345224838248488 -0.2672612419124244
  0.5345224838248488]
 [-0.31622776601683794 0.6324555320336758 -0.0 -0.6324555320336758
  0.31622776601683794]
 [0.11952286093343926 -0.4780914437337571 0.7171371656006363 -0.4780914437337577
  0.11952286093343957]
 [0.0354577718339618 0.35457771833961804 -0.8753004247012286 0.2127466310037708
  0.2482044028377326])
  • Softmax and Log-Softmax:
    • softmax: Applies the softmax function element-wise to a vector, converting arbitrary real values into a probability distribution. \(\operatorname{softmax}(\mathbf{v})_i = \frac{\exp(v_i)}{\sum_j \exp(v_j)}\). Supports an optional temperature parameter t: \(\operatorname{softmax}(\mathbf{v}, t)_i = \frac{\exp(v_i/t)}{\sum_j \exp(v_j/t)}\). It uses a numerically stable implementation.
    • logsoftmax: Computes the element-wise natural logarithm of the softmax function in a numerically stable way. \(\operatorname{logsoftmax}(\mathbf{v})_i = \log(\operatorname{softmax}(\mathbf{v})_i) = v_i - \log(\sum_j \exp(v_j))\). Also supports a temperature parameter t.
Examples
(v/softmax [1 2 3]) ;; => [0.09003057317038045 0.2447284710547976 0.6652409557748218]
(v/softmax [1 2 3] 0.5) ;; => [0.015876239976466765 0.11731042782619838 0.8668133321973349]
(v/logsoftmax [1 2 3]) ;; => [-2.4076059644443806 -1.4076059644443804 -0.4076059644443804]
(v/logsoftmax [1 2 3] 2.0) ;; => [-1.6802696706417346 -1.1802696706417346 -0.6802696706417346]

Matrices

The fastmath.matrix namespace provides tools for working with 2x2, 3x3, 4x4 fixed-size matrices and arbitrary-sized matrices represented as Java double[][] arrays or Apache Commons Math RealMatrix. It is designed to provide efficient mathematical operations for linear algebra, geometric transformations, and data preprocessing.

Supported Matrix Types

fastmath.matrix works with several matrix representations, balancing convenience, performance, and compatibility.

Supported Types
  • Mat2x2 (2x2 matrix, custom type)
  • Mat3x3 (3x3 matrix, custom type)
  • Mat4x4 (4x4 matrix, custom type)
  • double[][] (Java 2D double array, N x M)
  • org.apache.commons.math3.linear.RealMatrix (N x M)
(def M2x2 (Mat2x2. 1 2 3 4))
(def M3x3 (Mat3x3. 1 2 3 -4 5 6 9 -8 7))
(def M4x4 (Mat4x4. 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16))
(def RealMat (mat/real-matrix [[1 2 3] [4 5 6]]))
M2x2
#mat2x2 [[1.0, 2.0]
         [3.0, 4.0]]
M3x3
#mat3x3 [[1.0, 2.0, 3.0]
         [-4.0, 5.0, 6.0]
         [9.0, -8.0, 7.0]]
M4x4
#mat4x4 [[1.0, 2.0, 3.0, 4.0]
         [5.0, 6.0, 7.0, 8.0]
         [9.0, 10.0, 11.0, 12.0]
         [13.0, 14.0, 15.0, 16.0]]
RealMat
#object[org.apache.commons.math3.linear.Array2DRowRealMatrix 0x61f98b82 "Array2DRowRealMatrix{{1.0,2.0,3.0},{4.0,5.0,6.0}}"]

Creation and Conversion

Functions for generating new matrices or converting between the supported types and standard Clojure/Java representations.

Defined functions
  • mat2x2, mat3x3, mat4x4
  • rows->mat2x2, rows->mat3x3, rows->mat4x4
  • cols->mat2x2, cols->mat3x3, cols->mat4x4
  • diag->mat2x2, diag->mat3x3, diag->mat4x4
  • real-matrix, rows->RealMatrix, cols->RealMatrix
  • mat, rows->mat, cols->mat
  • array2d->mat2x2, array2d->mat3x3, array2d->mat4x4, array2d->RealMatrix
  • mat->seq, mat->array2d, mat->float-array2d, mat->array, mat->float-array, mat->RealMatrix
  • eye, zero, diagonal

Creating Fixed-Size Matrices

Use mat2x2, mat3x3, mat4x4 for creating small, performance-optimized matrices.

Single value

(mat/mat2x2 1)
#mat2x2 [[1.0, 1.0]
         [1.0, 1.0]]

(mat/mat3x3 2)
#mat3x3 [[2.0, 2.0, 2.0]
         [2.0, 2.0, 2.0]
         [2.0, 2.0, 2.0]]

(mat/mat4x4 3)
#mat4x4 [[3.0, 3.0, 3.0, 3.0]
         [3.0, 3.0, 3.0, 3.0]
         [3.0, 3.0, 3.0, 3.0]
         [3.0, 3.0, 3.0, 3.0]]

Diagonal

(mat/mat2x2 2 -2)
#mat2x2 [[2.0, 0.0]
         [0.0, -2.0]]

(mat/mat3x3 2 -2 1)
#mat3x3 [[2.0, 0.0, 0.0]
         [0.0, -2.0, 0.0]
         [0.0, 0.0, 1.0]]

(mat/mat4x4 2 -2 1 3)
#mat4x4 [[2.0, 0.0, 0.0, 0.0]
         [0.0, -2.0, 0.0, 0.0]
         [0.0, 0.0, 1.0, 0.0]
         [0.0, 0.0, 0.0, 3.0]]

Full matrix

(mat/mat2x2 1 2 3 4)
#mat2x2 [[1.0, 2.0]
         [3.0, 4.0]]

(mat/mat3x3 1 2 3 4 5 6 7 8 9)
#mat3x3 [[1.0, 2.0, 3.0]
         [4.0, 5.0, 6.0]
         [7.0, 8.0, 9.0]]

(mat/mat4x4 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6)
#mat4x4 [[1.0, 2.0, 3.0, 4.0]
         [5.0, 6.0, 7.0, 8.0]
         [9.0, 0.0, 1.0, 2.0]
         [3.0, 4.0, 5.0, 6.0]]

Additionally you can use specialized creation functions from rows, cols or diagonals.

Matrices from rows

(mat/rows->mat2x2 [1 2]
                  [5 6])
#mat2x2 [[1.0, 2.0]
         [5.0, 6.0]]

(mat/rows->mat3x3 [1 2 3]
                  [4 5 6]
                  [7 8 9])
#mat3x3 [[1.0, 2.0, 3.0]
         [4.0, 5.0, 6.0]
         [7.0, 8.0, 9.0]]

(mat/rows->mat4x4 [1 2 3 4]
                  [5 6 7 8]
                  [9 0 1 2]
                  [3 4 5 6])
#mat4x4 [[1.0, 2.0, 3.0, 4.0]
         [5.0, 6.0, 7.0, 8.0]
         [9.0, 0.0, 1.0, 2.0]
         [3.0, 4.0, 5.0, 6.0]]

Matrices from columns

(mat/cols->mat2x2 [1 2]
                  [5 6])
#mat2x2 [[1.0, 5.0]
         [2.0, 6.0]]

(mat/cols->mat3x3 [1 2 3]
                  [4 5 6]
                  [7 8 9])
#mat3x3 [[1.0, 4.0, 7.0]
         [2.0, 5.0, 8.0]
         [3.0, 6.0, 9.0]]

(mat/cols->mat4x4 [1 2 3 4]
                  [5 6 7 8]
                  [9 0 1 2]
                  [3 4 5 6])
#mat4x4 [[1.0, 5.0, 9.0, 3.0]
         [2.0, 6.0, 0.0, 4.0]
         [3.0, 7.0, 1.0, 5.0]
         [4.0, 8.0, 2.0, 6.0]]

Single value diagonal

(mat/diag->mat2x2 1)
#mat2x2 [[1.0, 0.0]
         [0.0, 1.0]]

(mat/diag->mat3x3 1)
#mat3x3 [[1.0, 0.0, 0.0]
         [0.0, 1.0, 0.0]
         [0.0, 0.0, 1.0]]

(mat/diag->mat4x4 1)
#mat4x4 [[1.0, 0.0, 0.0, 0.0]
         [0.0, 1.0, 0.0, 0.0]
         [0.0, 0.0, 1.0, 0.0]
         [0.0, 0.0, 0.0, 1.0]]

Full diagonals

(mat/diag->mat2x2 1 2)
#mat2x2 [[1.0, 0.0]
         [0.0, 2.0]]

(mat/diag->mat3x3 1 2 3)
#mat3x3 [[1.0, 0.0, 0.0]
         [0.0, 2.0, 0.0]
         [0.0, 0.0, 3.0]]

(mat/diag->mat4x4 1 2 3 4)
#mat4x4 [[1.0, 0.0, 0.0, 0.0]
         [0.0, 2.0, 0.0, 0.0]
         [0.0, 0.0, 3.0, 0.0]
         [0.0, 0.0, 0.0, 4.0]]

Creating Arbitrary-Size Matrices

Use real-matrix, rows->RealMatrix, cols->RealMatrix for N x M matrices backed by Apache Commons Math.

(mat/real-matrix [[1 2 3 4] [5 6 7 8]])
#object[org.apache.commons.math3.linear.Array2DRowRealMatrix 0xb64e004 "Array2DRowRealMatrix{{1.0,2.0,3.0,4.0},{5.0,6.0,7.0,8.0}}"]
(mat/rows->RealMatrix [[1 2 3 4] [5 6 7 8]])
#object[org.apache.commons.math3.linear.Array2DRowRealMatrix 0x68e6ce0e "Array2DRowRealMatrix{{1.0,2.0,3.0,4.0},{5.0,6.0,7.0,8.0}}"]
(mat/cols->RealMatrix [[1 2 3 4] [5 6 7 8]])
#object[org.apache.commons.math3.linear.Array2DRowRealMatrix 0x21c330ce "Array2DRowRealMatrix{{1.0,5.0},{2.0,6.0},{3.0,7.0},{4.0,8.0}}"]

Generic Creation

The mat, rows->mat, and cols->mat functions provide convenient constructors that automatically choose the fixed-size type for 2x2, 3x3, or 4x4 inputs, or default to RealMatrix for others.

Matrices from values

(mat/mat 1 2
         3 4)
#mat2x2 [[1.0, 2.0]
         [3.0, 4.0]]

(mat/mat 1 2 3
         4 5 6
         7 8 9)
#mat3x3 [[1.0, 2.0, 3.0]
         [4.0, 5.0, 6.0]
         [7.0, 8.0, 9.0]]

(mat/mat 1 2 3 4
         5 6 7 8
         9 0 1 2
         3 4 5 6)
#mat4x4 [[1.0, 2.0, 3.0, 4.0]
         [5.0, 6.0, 7.0, 8.0]
         [9.0, 0.0, 1.0, 2.0]
         [3.0, 4.0, 5.0, 6.0]]

(mat/mat [[1 2 3 4]
          [5 6 7 8]])
#object[org.apache.commons.math3.linear.Array2DRowRealMatrix 0x69de77e2 "Array2DRowRealMatrix{{1.0,2.0,3.0,4.0},{5.0,6.0,7.0,8.0}}"]

Matrices from rows

(mat/rows->mat [1 2]
               [5 6])
#mat2x2 [[1.0, 2.0]
         [5.0, 6.0]]

(mat/rows->mat [1 2 3]
               [4 5 6]
               [7 8 9])
#mat3x3 [[1.0, 2.0, 3.0]
         [4.0, 5.0, 6.0]
         [7.0, 8.0, 9.0]]

(mat/rows->mat [1 2 3 4]
               [5 6 7 8]
               [9 0 1 2]
               [3 4 5 6])
#mat4x4 [[1.0, 2.0, 3.0, 4.0]
         [5.0, 6.0, 7.0, 8.0]
         [9.0, 0.0, 1.0, 2.0]
         [3.0, 4.0, 5.0, 6.0]]

(mat/rows->mat [[1 2 3 4]
                [5 6 7 8]])
#object[org.apache.commons.math3.linear.Array2DRowRealMatrix 0x2b45d24f "Array2DRowRealMatrix{{1.0,2.0,3.0,4.0},{5.0,6.0,7.0,8.0}}"]

Matrices from columns

(mat/cols->mat [1 2]
               [5 6])
#mat2x2 [[1.0, 5.0]
         [2.0, 6.0]]

(mat/cols->mat [1 2 3]
               [4 5 6]
               [7 8 9])
#mat3x3 [[1.0, 4.0, 7.0]
         [2.0, 5.0, 8.0]
         [3.0, 6.0, 9.0]]

(mat/cols->mat [1 2 3 4]
               [5 6 7 8]
               [9 0 1 2]
               [3 4 5 6])
#mat4x4 [[1.0, 5.0, 9.0, 3.0]
         [2.0, 6.0, 0.0, 4.0]
         [3.0, 7.0, 1.0, 5.0]
         [4.0, 8.0, 2.0, 6.0]]

(mat/cols->mat [[1 2 3 4]
                [5 6 7 8]])
#object[org.apache.commons.math3.linear.Array2DRowRealMatrix 0x6a452b68 "Array2DRowRealMatrix{{1.0,5.0},{2.0,6.0},{3.0,7.0},{4.0,8.0}}"]

Conversion to/from Arrays and Sequences

Functions like array2d->mat2x2, mat->seq, mat->array2d, etc., facilitate conversions between fastmath.matrix types and primitive arrays or Clojure sequences.

(def dda (m/seq->double-double-array [[1 2 3 4] [5 6 7 8] [9 0 1 2] [3 4 5 6]]))
dda
[[1.0, 2.0, 3.0, 4.0], [5.0, 6.0, 7.0, 8.0], [9.0, 0.0, 1.0, 2.0], [3.0, 4.0, 5.0, 6.0]]
(mat/array2d->mat2x2 dda)
#mat2x2 [[1.0, 2.0]
         [5.0, 6.0]]
(mat/array2d->mat3x3 dda)
#mat3x3 [[1.0, 2.0, 3.0]
         [5.0, 6.0, 7.0]
         [9.0, 0.0, 1.0]]
(mat/array2d->mat4x4 dda)
#mat4x4 [[1.0, 2.0, 3.0, 4.0]
         [5.0, 6.0, 7.0, 8.0]
         [9.0, 0.0, 1.0, 2.0]
         [3.0, 4.0, 5.0, 6.0]]
(mat/array2d->RealMatrix dda)
#object[org.apache.commons.math3.linear.Array2DRowRealMatrix 0x514ca0b4 "Array2DRowRealMatrix{{1.0,2.0,3.0,4.0},{5.0,6.0,7.0,8.0},{9.0,0.0,1.0,2.0},{3.0,4.0,5.0,6.0}}"]
Examples
(mat/mat->seq M3x3) ;; => (1.0 2.0 3.0 -4.0 5.0 6.0 9.0 -8.0 7.0)
(mat/mat->array M2x2) ;; => #object["[D" 0x4ad62875 "[D@4ad62875"]
(mat/mat->array2d M2x2) ;; => #object["[[D" 0x1c62f8ab "[[D@1c62f8ab"]
(mat/mat->RealMatrix M2x2) ;; => #object[org.apache.commons.math3.linear.Array2DRowRealMatrix 0x23cfa102 "Array2DRowRealMatrix{{1.0,2.0},{3.0,4.0}}"]
(mat/mat->float-array M2x2) ;; => #object["[F" 0x47862366 "[F@47862366"]
(mat/mat->float-array2d M2x2) ;; => #object["[[F" 0x37c42ef5 "[[F@37c42ef5"]
(seq (mat/mat->array M2x2)) ;; => (1.0 2.0 3.0 4.0)
(m/double-double-array->seq (mat/mat->array2d M2x2)) ;; => ((1.0 2.0) (3.0 4.0))

Special Matrices

  • eye creates an identity matrix. When argument is between 2 and 4, creates fixed size types unless real-matrix is set to true.
  • zero creates a zero matrix. When argument is between 2 and 4, creates fixed size types unless real-matrix is set to true.
  • diagonal creates a diagonal matrix from a vector or sequence of values.

Identity matrix

(mat/eye 2)
#mat2x2 [[1.0, 0.0]
         [0.0, 1.0]]
(mat/eye 3)
#mat3x3 [[1.0, 0.0, 0.0]
         [0.0, 1.0, 0.0]
         [0.0, 0.0, 1.0]]
(mat/eye 4)
#mat4x4 [[1.0, 0.0, 0.0, 0.0]
         [0.0, 1.0, 0.0, 0.0]
         [0.0, 0.0, 1.0, 0.0]
         [0.0, 0.0, 0.0, 1.0]]
(mat/eye 2 true)
#object[org.apache.commons.math3.linear.Array2DRowRealMatrix 0x33512a4e "Array2DRowRealMatrix{{1.0,0.0},{0.0,1.0}}"]

Zero

(mat/zero 2)
#mat2x2 [[0.0, 0.0]
         [0.0, 0.0]]
(mat/zero 3)
#mat3x3 [[0.0, 0.0, 0.0]
         [0.0, 0.0, 0.0]
         [0.0, 0.0, 0.0]]
(mat/zero 4)
#mat4x4 [[0.0, 0.0, 0.0, 0.0]
         [0.0, 0.0, 0.0, 0.0]
         [0.0, 0.0, 0.0, 0.0]
         [0.0, 0.0, 0.0, 0.0]]
(mat/zero 2 true)
#object[org.apache.commons.math3.linear.Array2DRowRealMatrix 0x3af6b6bd "Array2DRowRealMatrix{{0.0,0.0},{0.0,0.0}}"]
(mat/zero 2 2 false)
#mat2x2 [[0.0, 0.0]
         [0.0, 0.0]]
(mat/zero 2 2 true)
#object[org.apache.commons.math3.linear.Array2DRowRealMatrix 0x72a0e33b "Array2DRowRealMatrix{{0.0,0.0},{0.0,0.0}}"]

Diagonal

(mat/diagonal 1 2)
#mat2x2 [[1.0, 0.0]
         [0.0, 2.0]]
(mat/diagonal 1 2 3)
#mat3x3 [[1.0, 0.0, 0.0]
         [0.0, 2.0, 0.0]
         [0.0, 0.0, 3.0]]
(mat/diagonal 1 2 3 4)
#mat4x4 [[1.0, 0.0, 0.0, 0.0]
         [0.0, 2.0, 0.0, 0.0]
         [0.0, 0.0, 3.0, 0.0]
         [0.0, 0.0, 0.0, 4.0]]
(mat/diagonal [1 2])
#object[org.apache.commons.math3.linear.Array2DRowRealMatrix 0x5057360e "Array2DRowRealMatrix{{1.0,0.0},{0.0,2.0}}"]

Interoperability

Like vectors, the fastmath.matrix types (Mat2x2, Mat3x3, Mat4x4) implement several standard Clojure and Java interfaces. This allows them to be treated as collections of numbers, integrating smoothly with built-in Clojure functions and providing familiar access patterns. This interoperability complements the type-specific and protocol-based operations defined in fastmath.matrix.

  • java.lang.Object: Standard Java methods like equals, hashCode, and toString.
  • clojure.lang.IHashEq: Provides hasheq for efficient hashing, enabling use as keys in hash maps or elements in sets.
  • clojure.lang.Seqable: Enables treating the matrix elements (in row-major order) as a sequence for functions like seq, map, filter, etc.
  • clojure.lang.Reversible: Allows reversing the sequence of elements with rseq.
  • clojure.lang.Counted: Provides the count function to get the total number of elements (rows * cols).
  • clojure.lang.ILookup: Enables lookup of elements by linear index using get or function call syntax (m index). Also supports lookup by a [row col] tuple.
  • clojure.lang.IFn: Allows the matrix itself to be invoked as a function to retrieve elements by [row col] tuple (m [row col]) or two arguments (m row col).
Examples

Seqable

(seq M2x2) ;; => (1.0 2.0 3.0 4.0)
(seq M3x3) ;; => (1.0 2.0 3.0 -4.0 5.0 6.0 9.0 -8.0 7.0)
(seq M4x4) ;; => (1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 10.0 11.0 12.0 13.0 14.0 15.0 16.0)
(map inc M4x4) ;; => (2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 10.0 11.0 12.0 13.0 14.0 15.0 16.0 17.0)

Reversible

(rseq M2x2) ;; => (4.0 3.0 2.0 1.0)
(rseq M3x3) ;; => (7.0 -8.0 9.0 6.0 5.0 -4.0 3.0 2.0 1.0)
(rseq M4x4) ;; => (16.0 15.0 14.0 13.0 12.0 11.0 10.0 9.0 8.0 7.0 6.0 5.0 4.0 3.0 2.0 1.0)

Counted

(count M2x2) ;; => 4
(count M3x3) ;; => 9
(count M4x4) ;; => 16

ILookup

(get M4x4 [0 0]) ;; => 1.0
(get M4x4 [3 3]) ;; => 16.0
(get M4x4 [5 5]) ;; => nil

IFn

(M2x2 [0 0]) ;; => 1.0
(M3x3 [1 2]) ;; => 6.0
(M4x4 [3 3]) ;; => 16.0
(try (M4x4 [5 5]) (catch Exception e (.getMessage e))) ;; => "Index [5 5] out of bounds for mat4x4"

IHashEq

(.hashCode M3x3) ;; => -1942507899
(hash M3x3) ;; => -1942507899

Object

(str M2x2) ;; => "#mat2x2 [[1.0, 2.0]\n         [3.0, 4.0]]"
(.equals M2x2 (mat/mat2x2 1 2 3 4)) ;; => true

Accessing Elements and Properties

Functions to retrieve matrix elements, rows, or columns, and to query matrix properties like size, shape, symmetry, determinant, and trace.

Element, Row, and Column Access

Functions to retrieve individual matrix elements or extract entire rows or columns as vectors. These are fundamental for inspecting and manipulating matrix data.

Defined functions
  • entry, row, col
  • cols, rows
  • entry: Retrieves the element at a specific [row col] index.
  • row: Extracts a specified row as a vector.
  • col: Extracts a specified column as a vector.
  • rows: Returns sequence of rows
  • cols: Returns sequence of columns
Examples
(mat/entry M3x3 0 2) ;; => 3.0
(mat/row M4x4 2) ;; => #vec4 [9.0, 10.0, 11.0, 12.0]
(mat/col RealMat 1) ;; => #object[org.apache.commons.math3.linear.ArrayRealVector 0x16f2673c "{2; 5}"]
(mat/rows M2x2) ;; => [#vec2 [1.0, 2.0] #vec2 [3.0, 4.0]]
(mat/cols RealMat) ;; => (#object[org.apache.commons.math3.linear.ArrayRealVector 0x16528fa0 "{1; 4}"] #object[org.apache.commons.math3.linear.ArrayRealVector 0x476ee51c "{2; 5}"] #object[org.apache.commons.math3.linear.ArrayRealVector 0x11b8531c "{3; 6}"])

Size and Shape

nrow, ncol, and shape provide the dimensions of the matrix.

Defined functions
  • nrow, ncol, shape
  • nrow: Returns the number of rows in the matrix.
  • ncol: Returns the number of columns in the matrix.
  • shape: Returns a vector or list containing the number of rows and columns, respectively, as a [rows, cols] pair.
Examples
(mat/nrow M2x2) ;; => 2
(mat/ncol M3x3) ;; => 3
(mat/shape M2x2) ;; => [2 2]
(mat/shape M3x3) ;; => [3 3]
(mat/shape M4x4) ;; => [4 4]
(mat/shape RealMat) ;; => [2 3]

Properties

Defined functions
  • symmetric?
  • diag
  • det
  • singular?
  • trace
  • Symmetry:
    • symmetric?: Checks if the matrix A is symmetric, meaning \(A = A^T\). For a square matrix \(A\), this holds if \(a_{ij} = a_{ji}\) for all indices \(i, j\). Can optionally take a tolerance parameter for approximate symmetry checks with floating-point numbers.
  • Diagonal:
    • diag: Returns the main diagonal elements of a square matrix as a vector. For a matrix \(A\), the diagonal vector is \([a_{11}, a_{22}, \dots, a_{nn}]\).
  • Determinant:
    • det: Computes the determinant of a square matrix \(A\), denoted as \(|A|\) or \(\det(A)\). The determinant is a scalar value that provides information about the matrix’s properties, such as invertibility.
  • Singularity:
    • singular?: Checks if a square matrix \(A\) is singular (non-invertible). A matrix is singular if and only if its determinant is zero, i.e., \(\det(A) = 0\).
  • Trace:
    • trace: Computes the trace of a square matrix \(A\), which is the sum of the elements on the main diagonal: \(\operatorname{tr}(A) = \sum_{i=1}^n a_{ii}\). The trace is invariant under cyclic permutations and similarity transformations.
Examples
(mat/symmetric? M2x2) ;; => false
(mat/symmetric? (mat/eye 2)) ;; => true
(mat/symmetric? (mat/mat2x2 1 0.1 0.001 1)) ;; => false
(mat/symmetric? (mat/mat2x2 1 0.1 0.001 1) 0.1) ;; => true
(mat/diag M2x2) ;; => #vec2 [1.0, 4.0]
(mat/diag M3x3) ;; => #vec3 [1.0, 5.0, 7.0]
(mat/diag M4x4) ;; => #vec4 [1.0, 6.0, 11.0, 16.0]
(mat/trace M2x2) ;; => 5.0
(mat/trace M3x3) ;; => 13.0
(mat/trace M4x4) ;; => 34.0
(mat/det M2x2) ;; => -2.0
(mat/det M3x3) ;; => 208.0
(mat/det M4x4) ;; => 0.0
(mat/singular? M2x2) ;; => false
(mat/singular? M3x3) ;; => false
(mat/singular? M4x4) ;; => true

Matrix Arithmetic and Operations

Standard matrix addition, subtraction, and multiplication, as well as element-wise operations.

Basic Arithmetic

Functions for basic matrix arithmetic operations like addition and subtraction, including scalar operations.

Defined functions
  • add, adds
  • sub, negate
  • Addition:
    • add: Computes the sum of two matrices \(\mathbf{C} = \mathbf{A} + \mathbf{B}\). This is an element-wise operation where \(c_{ij} = a_{ij} + b_{ij}\). Both matrices must have the same dimensions. The function also handles summing a collection of matrices: \(\sum \mathbf{A}_k\).
    • adds: Adds a scalar value \(s\) to each element of a matrix \(\mathbf{A}\). \(\mathbf{C} = \mathbf{A} + s\), where \(c_{ij} = a_{ij} + s\).
  • Subtraction:
    • sub: Computes the difference between two matrices \(\mathbf{C} = \mathbf{A} - \mathbf{B}\), where \(c_{ij} = a_{ij} - b_{ij}\). Both matrices must have the same dimensions. When called with a single matrix A, it performs negation.
    • negate: Computes the negation of a matrix \(\mathbf{C} = -\mathbf{A}\), where \(c_{ij} = -a_{ij}\). This is equivalent to sub with one argument.

For addition and subtraction of two matrices, they must have the same number of rows and columns.

Addition

(mat/add M2x2 M2x2)
#mat2x2 [[2.0, 4.0]
         [6.0, 8.0]]

Subtraction

(mat/sub M2x2 (mat/eye 2))
#mat2x2 [[0.0, 2.0]
         [3.0, 3.0]]

Scalar addition

(mat/adds M2x2 100)
#mat2x2 [[101.0, 102.0]
         [103.0, 104.0]]

Negation

(mat/negate M2x2)
#mat2x2 [[-1.0, -2.0]
         [-3.0, -4.0]]

Matrix Multiplication

This section covers functions for performing matrix multiplication and related products, including standard matrix-matrix multiplication, element-wise products, and matrix-vector multiplication. These operations are fundamental in linear algebra and are used extensively in transformations, solving linear systems, and many data science tasks.

Defined functions
  • mulm, mulmt, tmulm, tmulmt
  • emulm
  • muls
  • mulv, vtmul
  • outer, kronecker
  • Standard Matrix Multiplication:
    • mulm: Computes the matrix product \(\mathbf{C} = \mathbf{A} \mathbf{B}\). The number of columns in \(\mathbf{A}\) must equal the number of rows in \(\mathbf{B}\). Can optionally perform multiplication involving transposed matrices: \(\mathbf{A}^T \mathbf{B}\), \(\mathbf{A} \mathbf{B}^T\), or \(\mathbf{A}^T \mathbf{B}^T\).
    • mulmt: Computes the matrix product \(\mathbf{C} = \mathbf{A} \mathbf{B}^T\).
    • tmulm: Computes the matrix product \(\mathbf{C} = \mathbf{A}^T \mathbf{B}\).
    • tmulmt: Computes the matrix product \(\mathbf{C} = \mathbf{A}^T \mathbf{B}^T\).
  • Element-wise and Scalar Multiplication:
    • emulm: Computes the element-wise product (Hadamard product) \(\mathbf{C} = \mathbf{A} \odot \mathbf{B}\), where \(c_{ij} = a_{ij} \cdot b_{ij}\). Requires input matrices to have the same dimensions.
    • muls: Multiplies every element of matrix \(\mathbf{A}\) by a scalar \(s\): \(\mathbf{C} = s \mathbf{A}\), where \(c_{ij} = s \cdot a_{ij}\). This is also covered in basic operations but is relevant here.
  • Matrix-Vector Multiplication:
    • mulv: Multiplies a matrix \(\mathbf{A}\) by a column vector \(\mathbf{v}\): \(\mathbf{x} = \mathbf{A} \mathbf{v}\). The number of columns in \(\mathbf{A}\) must equal the dimension of \(\mathbf{v}\). Returns a vector.
    • vtmul: Multiplies a row vector \(\mathbf{v}^T\) by a matrix \(\mathbf{A}\): \(\mathbf{x}^T = \mathbf{v}^T \mathbf{A}\). The dimension of \(\mathbf{v}\) must equal the number of rows in \(\mathbf{A}\). Returns a vector.
  • Special Products:
    • outer: Computes the outer product of two vectors \(\mathbf{u}\) and \(\mathbf{v}\). Returns a matrix \(\mathbf{M} = \mathbf{u} \mathbf{v}^T\), where \(m_{ij} = u_i v_j\).
    • kronecker: Computes the Kronecker product of two matrices \(\mathbf{A}\) and \(\mathbf{B}\), denoted \(\mathbf{A} \otimes \mathbf{B}\). If \(\mathbf{A}\) is \(m \times n\) and \(\mathbf{B}\) is \(p \times q\), the result is an \(mp \times nq\) block matrix: \[ \mathbf{A} \otimes \mathbf{B} = \begin{bmatrix} a_{11}\mathbf{B} & \dots & a_{1n}\mathbf{B} \\ \vdots & \ddots & \vdots \\ a_{m1}\mathbf{B} & \dots & a_{mn}\mathbf{B} \end{bmatrix} \]

\(\mathbf{C} = \mathbf{A} \mathbf{B}\)

(mat/mulm M2x2 M2x2)
#mat2x2 [[7.0, 10.0]
         [15.0, 22.0]]
(mat/mulm M2x2 false M2x2 false)
#mat2x2 [[7.0, 10.0]
         [15.0, 22.0]]

\(\mathbf{C} = \mathbf{A} \mathbf{B}^T\)

(mat/mulmt M2x2 M2x2)
#mat2x2 [[5.0, 11.0]
         [11.0, 25.0]]
(mat/mulm M2x2 false M2x2 true)
#mat2x2 [[5.0, 11.0]
         [11.0, 25.0]]

\(\mathbf{C} = \mathbf{A}^T \mathbf{B}\)

(mat/tmulm M2x2 M2x2)
#mat2x2 [[10.0, 14.0]
         [14.0, 20.0]]
(mat/mulm M2x2 true M2x2 false)
#mat2x2 [[10.0, 14.0]
         [14.0, 20.0]]

\(\mathbf{C} = \mathbf{A}^T \mathbf{B}^T\)

(mat/tmulmt M2x2 M2x2)
#mat2x2 [[7.0, 15.0]
         [10.0, 22.0]]
(mat/mulm M2x2 true M2x2 true)
#mat2x2 [[7.0, 15.0]
         [10.0, 22.0]]

Element-wise multiplication

(mat/emulm M3x3 M3x3)
#mat3x3 [[1.0, 4.0, 9.0]
         [16.0, 25.0, 36.0]
         [81.0, 64.0, 49.0]]

Outer product

(mat/outer (v/vec2 1 2) (v/vec2 3 4))
#mat2x2 [[3.0, 4.0]
         [6.0, 8.0]]

Scalar multiplication

(mat/muls M3x3 0.5)
#mat3x3 [[0.5, 1.0, 1.5]
         [-2.0, 2.5, 3.0]
         [4.5, -4.0, 3.5]]
(mat/outer (v/vec4 -1 1 2 3) (v/vec4 3 4 -2 -2))
#mat4x4 [[-3.0, -4.0, 2.0, 2.0]
         [3.0, 4.0, -2.0, -2.0]
         [6.0, 8.0, -4.0, -4.0]
         [9.0, 12.0, -6.0, -6.0]]
Examples
(mat/mulv M2x2 (v/vec2 10 20)) ;; => #vec2 [50.0, 110.0]
(mat/mulv RealMat (v/vec->RealVector (v/vec3 1 2 3))) ;; => #object[org.apache.commons.math3.linear.ArrayRealVector 0xc7c6695 "{14; 32}"]
(mat/vtmul M2x2 (v/vec2 10 20)) ;; => #vec2 [70.0, 100.0]
(mat/vtmul RealMat (v/vec->RealVector [1 2])) ;; => #object[org.apache.commons.math3.linear.ArrayRealVector 0x6c7514fb "{9; 12; 15}"]
(mat/outer (v/vec2 1 2) [1 2 3 9]) ;; => #object[org.apache.commons.math3.linear.Array2DRowRealMatrix 0x7a6b7e60 "Array2DRowRealMatrix{{1.0,2.0,3.0,9.0},{2.0,4.0,6.0,18.0}}"]
(mat/outer [2 3] [9 1 2]) ;; => #object[org.apache.commons.math3.linear.Array2DRowRealMatrix 0x722ca90 "Array2DRowRealMatrix{{18.0,2.0,4.0},{27.0,3.0,6.0}}"]
(mat/kronecker M2x2 M3x3) ;; => #object[org.apache.commons.math3.linear.Array2DRowRealMatrix 0x68055c2f "Array2DRowRealMatrix{{1.0,2.0,3.0,2.0,4.0,6.0},{-4.0,5.0,6.0,-8.0,10.0,12.0},{9.0,-8.0,7.0,18.0,-16.0,14.0},{3.0,6.0,9.0,4.0,8.0,12.0},{-12.0,15.0,18.0,-16.0,20.0,24.0},{27.0,-24.0,21.0,36.0,-32.0,28.0}}"]
(mat/kronecker RealMat M2x2) ;; => #object[org.apache.commons.math3.linear.Array2DRowRealMatrix 0x2c935f18 "Array2DRowRealMatrix{{1.0,2.0,2.0,4.0,3.0,6.0},{3.0,4.0,6.0,8.0,9.0,12.0},{4.0,8.0,5.0,10.0,6.0,12.0},{12.0,16.0,15.0,20.0,18.0,24.0}}"]

Element-wise Operations

A wide range of element-wise mathematical functions (e.g., sin, cos, pow) are provided, mirroring those in fastmath.vector.

fmap applies a function to each element of the vector, returning a new vector of the same type.

Defined functions
  • sin, cos, tan, asin, acos, atan
  • sinh, cosh, tanh, asinh, acosh, atanh
  • cot, sec, csc, acot, asec, acsc
  • coth, sech, csch, acoth, asech, acsch
  • sq, cb, safe-sqrt, sqrt, cbrt, pow
  • exp, log, log10, log2, ln, log1p, expm1
  • log1pexp, log1mexp, log1psq, log1pmx, logmxp1, logexpm1
  • radians, degrees, sinc, sigmoid, logit, xlogx
  • floor, ceil, round, rint, trunc, frac, sfrac, signum, sgn
  • fmap
(mat/sin M4x4)
#mat4x4 [[0.8414709848078964, 0.9092974268256818, 0.1411200080598671, -0.756802495307928]
         [-0.9589242746631386, -0.2794154981989256, 0.6569865987187891, 0.9893582466233817]
         [0.4121184852417563, -0.5440211108893697, -0.9999902065507035, -0.5365729180004354]
         [0.4201670368266409, 0.9906073556948704, 0.6502878401571169, -0.2879033166650652]]
(mat/pow M2x2 0.5)
#mat2x2 [[1.0, 1.4142135623730951]
         [1.7320508075688772, 2.0]]
(mat/fmap M2x2 m/inc)
#mat2x2 [[2.0, 3.0]
         [4.0, 5.0]]

Rows and Columns Operations

Functions for transforming matrices, often used in data analysis or preparation, including normalization, centering, and scaling along rows or columns.

Defined functions
  • map-cols, map-rows
  • shift-rows, shift-cols
  • scale-rows, scale-cols
  • normalize, demean, standardize

These functions provide tools to apply transformations to the rows or columns of a matrix. This is particularly useful for data preprocessing steps such as scaling features, centering data, or applying custom functions to individual dimensions (columns) or samples (rows) of a dataset represented as a matrix. The transformations can be applied element-wise, or based on properties of the rows/columns themselves (like mean or standard deviation).

  • Row/Column Mapping:
    • map-cols: Applies a function f to each column vector of the matrix. The function f should take a vector as input and return a vector of the same dimension. The resulting vectors are assembled into a new matrix where each column is the result of applying f to the original columns.
    • map-rows: Similar to map-cols, but applies the function f to each row vector of the matrix. The function f takes a row vector and should return a vector of the same dimension. The results are assembled into a new matrix where each row is the result of applying f to the original rows.
(mat/map-rows (fn [row] (conj (map (fn [[a b]] (- b a)) (partition 2 1 row)) (first row))) M3x3)
#mat3x3 [[1.0, 1.0, 1.0]
         [-4.0, 9.0, 1.0]
         [9.0, -17.0, 15.0]]
(mat/map-cols (fn [col] (v/shift col (- (stats/median col)))) M3x3)
#mat3x3 [[0.0, 0.0, -3.0]
         [-5.0, 3.0, 0.0]
         [8.0, -10.0, 1.0]]
  • Shifting:
    • shift-rows: Adds a value to each element of each row. The value can be a single number applied to all rows, or the result of a function applied to each row vector (e.g., subtracting the mean of the row). Default function subtracts the mean of each row. For a row \(\mathbf{r}\), the transformation is \(\mathbf{r}' = \mathbf{r} + s\), where \(s\) is the shift value for that row.
    • shift-cols: Adds a value to each element of each column. The value can be a single number applied to all columns, or the result of a function applied to each column vector (e.g., subtracting the mean of the column). Default function subtracts the mean of each column. For a column \(\mathbf{c}\), the transformation is \(\mathbf{c}' = \mathbf{c} + s\).
(mat/shift-rows M3x3)
#mat3x3 [[-1.0, 0.0, 1.0]
         [-6.333333333333334, 2.6666666666666665, 3.6666666666666665]
         [6.333333333333334, -10.666666666666666, 4.333333333333334]]
(mat/shift-rows M3x3 100)
#mat3x3 [[101.0, 102.0, 103.0]
         [96.0, 105.0, 106.0]
         [109.0, 92.0, 107.0]]
(mat/shift-cols RealMat (comp m/- v/sum))
#object[org.apache.commons.math3.linear.Array2DRowRealMatrix 0x4bf71032 "Array2DRowRealMatrix{{6.0,9.0},{9.0,12.0},{12.0,15.0}}"]
  • Scaling:
    • scale-rows: Multiplies each element of each row by a value. The value can be a single number applied to all rows, or the result of a function applied to each row vector (e.g., dividing by the standard deviation of the row). For a row \(\mathbf{r}\), the transformation is \(\mathbf{r}' = s \cdot \mathbf{r}\), where \(s\) is the scale value for that row.
    • scale-cols: Multiplies each element of each column by a value. The value can be a single number applied to all columns, or the result of a function applied to each column vector.

Default function is the root mean square function \(\frac{(n-1)}{\sqrt{(\mathbf{v}\cdot\mathbf{v})}}\)

(v/dot (mat/col (mat/scale-cols M4x4) 1) (mat/col (mat/scale-cols M4x4) 1))
2.999999999999999
(mat/scale-rows M2x2 0.5)
#mat2x2 [[0.5, 1.0]
         [1.5, 2.0]]
(mat/scale-cols RealMat (comp m/sqrt v/sum))
#object[org.apache.commons.math3.linear.Array2DRowRealMatrix 0x686a6130 "Array2DRowRealMatrix{{2.2360679775,8.94427191},{5.2915026221,13.2287565553},{9.0,18.0}}"]
  • Statistical Transformations: These functions apply common statistical preprocessing steps to rows or columns. By default, they operate on columns, which is a common convention in data science where columns represent features. An optional rows? argument (default false) allows applying the transformation to rows instead.
    • normalize: Scales each row (if rows? is true) or column (if rows? is false) vector to have unit Euclidean length (magnitude 1). \(\hat{\mathbf{v}} = \mathbf{v} / \Vert \mathbf{v} \Vert\).
    • demean: Centers each row (if rows? is true) or column (if rows? is false) vector by subtracting its mean. \(\mathbf{v}' = \mathbf{v} - \text{mean}(\mathbf{v})\).
    • standardize: Centers and scales each row (if rows? is true) or column (if rows? is false) vector to have a mean of 0 and a standard deviation of 1. \(\mathbf{v}' = (\mathbf{v} - \text{mean}(\mathbf{v})) / \text{stddev}(\mathbf{v})\). This is also known as Z-score normalization.
(mat/normalize M3x3)
#mat3x3 [[0.10101525445522107, 0.20739033894608505, 0.309426373877638]
         [-0.40406101782088427, 0.5184758473652127, 0.618852747755276]
         [0.9091372900969896, -0.8295613557843402, 0.7219948723811553]]
(mat/normalize M3x3 true)
#mat3x3 [[0.2672612419124244, 0.5345224838248488, 0.8017837257372732]
         [-0.4558423058385518, 0.5698028822981898, 0.6837634587578276]
         [0.6461623427559644, -0.5743665268941905, 0.5025707110324167]]
(mat/demean M3x3)
#mat3x3 [[-1.0, 2.3333333333333335, -2.333333333333333]
         [-6.0, 5.333333333333333, 0.666666666666667]
         [7.0, -7.666666666666667, 1.666666666666667]]
(mat/demean M3x3 true)
#mat3x3 [[-1.0, 0.0, 1.0]
         [-6.333333333333334, 2.6666666666666665, 3.6666666666666665]
         [6.333333333333334, -10.666666666666666, 4.333333333333334]]
(mat/standardize M3x3)
#mat3x3 [[-0.15249857033260467, 0.3427914748120743, -1.12089707663561]
         [-0.914991421995628, 0.7835233709990269, 0.32025630761017443]
         [1.0674899923282326, -1.126314845811101, 0.8006407690254359]]
(mat/standardize M3x3 true)
#mat3x3 [[-1.0, 0.0, 1.0]
         [-1.1499323120707245, 0.48418202613504197, 0.6657502859356828]
         [0.6816212031674663, -1.1479936053346804, 0.4663724021672138]]

Geometric Transformations

Functions specifically for creating transformation matrices, primarily rotations in 2D and 3D space. These matrices are used to transform points or vectors by applying matrix multiplication.

2D Rotation

Functions for creating rotation matrices in 2D space, typically used to rotate points or vectors around the origin.

Defined functions
  • rotation-matrix-2d
  • rotation-matrix-2d: Creates a 2x2 rotation matrix for a given angle \(\theta\) (in radians). The matrix is defined as: \[ R(\theta) = \begin{bmatrix} \cos \theta & -\sin \theta \\ \sin \theta & \cos \theta \end{bmatrix} \] Multiplying a 2D vector \(\mathbf{v} = [x, y]^T\) by this matrix rotates the vector by \(\theta\) counterclockwise: \(\mathbf{v}' = R(\theta) \mathbf{v}\).
(mat/rotation-matrix-2d m/HALF_PI)
#mat2x2 [[6.12323399538461E-17, -1.0]
         [1.0, 6.12323399538461E-17]]

Rotate [1, 0] by pi/2

(mat/mulv (mat/rotation-matrix-2d m/HALF_PI) (v/vec2 1 0))
[6.12323399538461E-17 1.0]
(mat/rotation-matrix-2d m/PI)
#mat2x2 [[-1.0, -1.224646799076922E-16]
         [1.224646799076922E-16, -1.0]]

3D Rotations

rotation-matrix-3d creates a 3x3 rotation matrix from Euler angles (Tait–Bryan z-y′-x″ convention). rotation-matrix-3d-x, -y, and -z create simple rotations around the respective axes. rotation-matrix-axis-3d creates a 3x3 rotation matrix for rotation around an arbitrary axis.

Defined functions
  • rotation-matrix-3d, rotation-matrix-3d-x, rotation-matrix-3d-y, rotation-matrix-3d-z
  • rotation-matrix-axis-3d

These functions generate 3x3 matrices used to rotate 3D points or vectors.

  • Axis Rotations:
    • rotation-matrix-3d-x: Creates a 3x3 matrix for rotation by angle \(\theta\) around the x-axis (right-hand rule). \[ R_x(\theta) = \begin{bmatrix} 1 & 0 & 0 \\ 0 & \cos\theta & -\sin\theta \\ 0 & \sin\theta & \cos\theta \end{bmatrix} \]
    • rotation-matrix-3d-y: Creates a 3x3 matrix for rotation by angle \(\theta\) around the y-axis (right-hand rule). \[ R_y(\theta) = \begin{bmatrix} \cos\theta & 0 & \sin\theta \\ 0 & 1 & 0 \\ -\sin\theta & 0 & \cos\theta \end{bmatrix} \]
    • rotation-matrix-3d-z: Creates a 3x3 matrix for rotation by angle \(\theta\) around the z-axis (right-hand rule). \[ R_z(\theta) = \begin{bmatrix} \cos\theta & -\sin\theta & 0 \\ \sin\theta & \cos\theta & 0 \\ 0 & 0 & 1 \end{bmatrix} \]
(mat/rotation-matrix-3d-x m/HALF_PI)
#mat3x3 [[1.0, 0.0, 0.0]
         [0.0, 6.12323399538461E-17, -1.0]
         [0.0, 1.0, 6.12323399538461E-17]]
(mat/rotation-matrix-3d-y m/HALF_PI)
#mat3x3 [[6.12323399538461E-17, 0.0, 1.0]
         [0.0, 1.0, 0.0]
         [-1.0, 0.0, 6.12323399538461E-17]]
(mat/rotation-matrix-3d-z m/HALF_PI)
#mat3x3 [[6.12323399538461E-17, -1.0, 0.0]
         [1.0, 6.12323399538461E-17, 0.0]
         [0.0, 0.0, 1.0]]
  • Euler Angles:
    • rotation-matrix-3d: Creates a 3x3 rotation matrix from sequential rotations specified by Euler angles (specifically, the Tait–Bryan angles z-y′-x″ convention). Given angles \(\gamma, \beta, \alpha\) for rotations around the Z, Y’, X’’ axes respectively. The function accepts alpha (x), beta (y) and gamma (z).

\[R = R_{x''}(\alpha) R_{y'}(\beta) R_z(\gamma) = \begin{bmatrix} c_\beta c_\gamma & - c_\beta s_\gamma & s_\beta \\ c_\alpha s_\gamma + c_\gamma s_\alpha s_\beta & c_\alpha c_\gamma - s_\alpha s_\beta s_\gamma & - c_\beta s_\alpha \\ s_\alpha s_\gamma - c_\alpha c_\gamma s_\beta & c_\gamma s_\alpha + c_\alpha s_\beta s_\gamma & c_\alpha c_\beta \end{bmatrix}\]

(mat/rotation-matrix-3d m/HALF_PI m/QUARTER_PI 0)
#mat3x3 [[0.7071067811865476, -0.0, 0.7071067811865475]
         [0.7071067811865475, 6.12323399538461E-17, -0.7071067811865476]
         [-4.329780280928454E-17, 1.0, 4.329780280928455E-17]]
  • Arbitrary Axis Rotation:
    • rotation-matrix-axis-3d: Creates a 3x3 rotation matrix for rotating by angle \(\theta\) around a specified arbitrary axis \(\mathbf{k}\). If \(\mathbf{k}\) is a unit vector, the rotation matrix can be constructed using Rodrigues’ rotation formula or its matrix equivalent. \[ R = I + (\sin\theta) K + (1-\cos\theta) K^2 \] where \(I\) is the identity matrix and \(K\) is the skew-symmetric matrix of \(\mathbf{k}\): \[ K = \begin{bmatrix} 0 & -k_z & k_y \\ k_z & 0 & -k_x \\ -k_y & k_x & 0 \end{bmatrix} \] The function can also take an optional pivot point p to represent rotation around a point other than the origin. The transformation of a point \(\mathbf{v}\) around p by angle \(\theta\) and axis \(\mathbf{k}\) is \(R(\mathbf{v} - \mathbf{p}) + \mathbf{p}\).
(mat/rotation-matrix-axis-3d m/HALF_PI (v/vec3 1 1 1))
#mat3x3 [[0.3333333333333334, -0.24401693585629247, 0.9106836025229592]
         [0.9106836025229592, 0.3333333333333334, -0.24401693585629247]
         [-0.24401693585629247, 0.9106836025229592, 0.3333333333333334]]

Rotating point [1 0 0] around [0 0 0] by 90 deg around Z axis

(mat/mulv (mat/rotation-matrix-axis-3d m/HALF_PI (v/vec3 0 0 1)) (v/vec3 1 0 0))
[6.12323399538461E-17 1.0 0.0]

Matrix Decompositions

Matrix decomposition (or factorization) is a technique that breaks down a matrix into a product of other matrices with specific properties. These decompositions simplify complex matrix operations, reveal important characteristics of the matrix (like rank, eigenvalues, stability), and are crucial for solving linear systems, computing inverses, and performing various numerical computations more efficiently and stably. fastmath.matrix leverages Apache Commons Math to provide implementations of several common decompositions.

Defined functions
  • qr-decomposition
  • rrqr-decomposition
  • cholesky-decomposition
  • sv-decomposition
  • lu-decomposition
  • eigen-decomposition
  • decomposition-component
  • singular?
  • inverse
  • solve

Each decomposition function takes a matrix as input and returns a special object (MatrixDecomposition record). This object encapsulates the results of the decomposition and provides a more efficient way to perform subsequent operations that utilize the decomposition (like solving linear systems or finding the inverse) compared to performing these operations directly on the original matrix or calculating the components explicitly.

  • Accessing Components:
    • decomposition-component: Extracts specific matrices (like \(\mathbf{Q}, \mathbf{R}, \mathbf{L}, \mathbf{U}, \mathbf{V}, \mathbf{D}, \mathbf{S}, \mathbf{P}, \mathbf{H}, \mathbf{V}^T=\mathbf{VT}, \mathbf{U}^T=\mathbf{UT}, \mathbf{L}^T=\mathbf{LT}\), \(\mathbf{D}^{1/2}=\mathbf{sqrt}\)) or other results (like :pivot vector, :singular-values vector, :det determinant, :real-eigenvalues / :imag-eigenvalues vectors, :complex? boolean, :info map, :rank-fn function, :covariance-fn function) from a decomposition object. Components are lazy where possible.
  • Using Decomposition Results: The decomposition objects themselves implement the fastmath.protocols/MatrixProto. This means you can directly call solve, inverse, and singular? on the decomposition result:
    • solve: Solves the linear system \(\mathbf{A} \mathbf{x} = \mathbf{b}\) using the pre-computed decomposition. This is generally faster and more numerically stable than solving the system directly using the original matrix, especially for large systems or matrices with poor condition numbers.
    • inverse: Computes the inverse matrix \(\mathbf{A}^{-1}\) from the decomposition. Similar to solve, using the decomposition is typically more efficient. Returns nil if the matrix is singular.
    • singular?: Checks if the matrix is singular based on the decomposition (e.g., checking the determinant for LU/Eigen or pivots/singular values for others).

QR

Computes the QR decomposition \(\mathbf{A} = \mathbf{Q} \mathbf{R}\), where \(\mathbf{Q}\) is an orthogonal matrix (\(\mathbf{Q}^T \mathbf{Q} = \mathbf{I}\)) and \(\mathbf{R}\) is an upper triangular matrix. Useful for solving linear least squares problems and eigenvalue computations.

(def QR (mat/qr-decomposition M3x3))
(mat/decomposition-component QR :Q)
#mat3x3 [[-0.10101525445522119, -0.9072647087265548, 0.40824829046386313]
         [0.4040610178208843, -0.41239304942116134, -0.816496580927726]
         [-0.9091372900969897, -0.08247860988423228, -0.408248290463863]]
(mat/decomposition-component QR :R)
#mat3x3 [[-9.899494936611665, 9.091372900969898, -4.242640687119285]
         [0.0, -3.2166657854850573, -5.773502691896262]
         [0.0, 0.0, -6.531972647421809]]
(mat/decomposition-component QR :QT)
#mat3x3 [[-0.10101525445522119, 0.4040610178208843, -0.9091372900969897]
         [-0.9072647087265548, -0.41239304942116134, -0.08247860988423228]
         [0.40824829046386313, -0.816496580927726, -0.408248290463863]]
(mat/decomposition-component QR :H)
#mat3x3 [[1.101015254455221, 0.0, 0.0]
         [-0.40406101782088427, 1.7453496548429523, 0.0]
         [0.9091372900969896, -0.6666737523147975, 2.0]]
(mat/singular? QR)
false
(mat/inverse QR)
#mat3x3 [[0.39903846153846173, -0.18269230769230776, -0.014423076923076986]
         [0.3942307692307694, -0.09615384615384628, -0.0865384615384616]
         [-0.06250000000000003, 0.12499999999999996, 0.062499999999999986]]
(mat/solve QR V3)
[-0.8088942307692313 -0.35336538461538497 0.171875]

RRQR

Computes the Rank-Revealing QR decomposition \(\mathbf{A} = \mathbf{Q} \mathbf{R} \mathbf{P}^T\), similar to QR but with a permutation matrix \(\mathbf{P}\) that helps determine the numerical rank. Useful for rank determination and handling rank-deficient matrices.

(def RRQR (mat/rrqr-decomposition M3x3))
(mat/decomposition-component RRQR :Q)
#mat3x3 [[-0.10101525445522119, -0.2949630864050082, 0.9501540380516091]
         [0.4040610178208843, -0.8848892592150241, -0.2317448873296608]
         [-0.9091372900969897, -0.36051043893945434, -0.20857039859669468]]
(mat/decomposition-component RRQR :R)
#mat3x3 [[-9.899494936611665, -4.242640687119285, 9.091372900969898]
         [0.0, -8.717797887081348, -2.1302889573695025]
         [0.0, 0.0, 2.4101468282284717]]
(mat/decomposition-component RRQR :QT)
#mat3x3 [[-0.10101525445522119, 0.4040610178208843, -0.9091372900969897]
         [-0.2949630864050082, -0.8848892592150241, -0.36051043893945434]
         [0.9501540380516091, -0.2317448873296608, -0.20857039859669468]]
(mat/decomposition-component RRQR :H)
#mat3x3 [[1.101015254455221, 0.0, 0.0]
         [-0.40406101782088427, 1.9931376094809508, 0.0]
         [0.9091372900969896, 0.11695165084111954, 2.0]]
(mat/decomposition-component RRQR :P)
#mat3x3 [[1.0, 0.0, 0.0]
         [0.0, 0.0, 1.0]
         [0.0, 1.0, 0.0]]
(def rrqr-rank (mat/decomposition-component RRQR :rank-fn))
(rrqr-rank 0)
3
(mat/singular? RRQR)
false
(mat/inverse RRQR)
#mat3x3 [[0.39903846153846156, -0.18269230769230768, -0.014423076923076941]
         [0.3942307692307693, -0.09615384615384616, -0.08653846153846154]
         [-0.06250000000000001, 0.12500000000000006, 0.06250000000000001]]
(mat/solve RRQR V3)
[-0.8088942307692313 -0.353365384615385 0.1718750000000001]

Cholesky

Computes the Cholesky decomposition \(\mathbf{A} = \mathbf{L} \mathbf{L}^T\) (or \(\mathbf{A} = \mathbf{U}^T \mathbf{U}\)), applicable to symmetric positive-definite matrices. \(\mathbf{L}\) is a lower triangular matrix. Efficient for solving symmetric linear systems.

(def Cholesky (mat/cholesky-decomposition (mat/mulmt M3x3 M3x3)))
(mat/decomposition-component Cholesky :L)
#mat3x3 [[3.7416573867739413, 0.0, 0.0]
         [6.4142698058981855, 5.988083404324196, 0.0]
         [3.7416573867739418, -9.68590383328934, 9.283494327690995]]
(mat/decomposition-component Cholesky :LT)
#mat3x3 [[3.7416573867739413, 6.4142698058981855, 3.7416573867739418]
         [0.0, 5.988083404324196, -9.68590383328934]
         [0.0, 0.0, 9.283494327690995]]
(mat/decomposition-component Cholesky :det)
43263.99999999998
(mat/singular? Cholesky)
false
(mat/inverse Cholesky)
#mat3x3 [[0.3185558431952665, -0.1186205621301776, -0.04377773668639056]
         [-0.1186205621301776, 0.058247041420118384, 0.018768491124260368]
         [-0.04377773668639057, 0.018768491124260368, 0.011603180473372787]]
(mat/solve Cholesky V3)
[-0.47282960428994114 0.20324056952662733 0.05298862795857993]

SVD

Computes the Singular Value Decomposition (SVD) \(\mathbf{A} = \mathbf{U} \mathbf{S} \mathbf{V}^T\), where \(\mathbf{U}\) and \(\mathbf{V}\) are orthogonal matrices and \(\mathbf{S}\) is a diagonal matrix containing the singular values. The SVD is one of the most powerful decompositions, providing insights into matrix rank, approximation, and used in dimensionality reduction (like PCA).

(def SVD (mat/sv-decomposition M3x3))
(mat/decomposition-component SVD :S)
#mat3x3 [[14.26358979914213, 0.0, 0.0]
         [0.0, 8.879932448938339, 0.0]
         [0.0, 0.0, 1.642195403750888]]
(mat/decomposition-component SVD :U)
#mat3x3 [[0.03946194000852533, 0.3798892187494038, 0.9241898813386404]
         [-0.25246462913394213, 0.8986920160245726, -0.3586283192526073]
         [0.9668010996720184, 0.2191730864217972, -0.13137272114605367]]
(mat/decomposition-component SVD :UT)
#mat3x3 [[0.03946194000852533, -0.25246462913394213, 0.9668010996720184]
         [0.3798892187494038, 0.8986920160245726, 0.2191730864217972]
         [0.9241898813386404, -0.3586283192526073, -0.13137272114605367]]
(mat/decomposition-component SVD :V)
#mat3x3 [[0.6835958192080719, -0.13990208537016968, 0.7163268544947359]
         [-0.6252148434305902, 0.3941306813280687, 0.6736225987820889]
         [0.37656759753769004, 0.9083437744295657, -0.181957225577173]]
(mat/decomposition-component SVD :VT)
#mat3x3 [[0.6835958192080719, -0.6252148434305902, 0.37656759753769004]
         [-0.13990208537016968, 0.3941306813280687, 0.9083437744295657]
         [0.7163268544947359, 0.6736225987820889, -0.181957225577173]]
(mat/decomposition-component SVD :singular-values)
[14.26358979914213 8.879932448938339 1.642195403750888]
(mat/decomposition-component SVD :info)
{:condition-number 8.685683668681026,
 :inv-condition-number 0.11513198478616204,
 :norm 14.26358979914213,
 :rank 3}
(def svd-covariance (mat/decomposition-component SVD :covariance-fn))
(svd-covariance)
#mat3x3 [[0.19281619822485202, 0.17612795857988167, -0.04867788461538463]
         [0.17612795857988167, 0.1721523668639054, -0.04206730769230772]
         [-0.04867788461538463, -0.04206730769230772, 0.023437500000000007]]
(mat/singular? SVD)
false
(mat/inverse SVD)
#mat3x3 [[0.39903846153846134, -0.18269230769230768, -0.01442307692307692]
         [0.3942307692307692, -0.09615384615384621, -0.08653846153846154]
         [-0.06250000000000003, 0.12499999999999999, 0.062499999999999986]]
(mat/solve SVD V3)
[-0.8088942307692306 -0.3533653846153848 0.17187500000000006]

LU

Computes the LU decomposition with partial pivoting \(\mathbf{P} \mathbf{A} = \mathbf{L} \mathbf{U}\) (equivalent to \(\mathbf{A} = \mathbf{P}^{-1} \mathbf{L} \mathbf{U}\)), where \(\mathbf{P}\) is a permutation matrix, \(\mathbf{L}\) is a lower triangular matrix with unit diagonal, and \(\mathbf{U}\) is an upper triangular matrix. Used for solving square linear systems and computing determinants and inverses.

(def LU (mat/lu-decomposition M3x3))
(mat/decomposition-component LU :L)
#mat3x3 [[1.0, 0.0, 0.0]
         [0.1111111111111111, 1.0, 0.0]
         [-0.4444444444444444, 0.5000000000000001, 1.0]]
(mat/decomposition-component LU :U)
#mat3x3 [[9.0, -8.0, 7.0]
         [0.0, 2.888888888888889, 2.2222222222222223]
         [0.0, 0.0, 7.999999999999999]]
(mat/decomposition-component LU :P)
#mat3x3 [[0.0, 0.0, 1.0]
         [1.0, 0.0, 0.0]
         [0.0, 1.0, 0.0]]
(mat/decomposition-component LU :pivot)
[2.0 0.0 1.0]
(mat/decomposition-component LU :det)
207.99999999999997
(mat/singular? LU)
false
(mat/inverse LU)
#mat3x3 [[0.39903846153846156, -0.18269230769230774, -0.014423076923076934]
         [0.3942307692307692, -0.09615384615384617, -0.08653846153846154]
         [-0.06250000000000003, 0.12500000000000003, 0.06250000000000001]]
(mat/solve LU V3)
[-0.8088942307692308 -0.3533653846153847 0.17187500000000003]

Eigen

Computes the Eigen decomposition \(\mathbf{A} = \mathbf{V} \mathbf{D} \mathbf{V}^{-1}\), where \(\mathbf{D}\) is a diagonal or block diagonal matrix containing the eigenvalues, and \(\mathbf{V}\) is a matrix whose columns are the corresponding eigenvectors. Applies to square matrices (real or complex eigenvalues/vectors). Reveals how a linear transformation stretches or compresses space. :sqrt component is computed only for symmetric and positive definite matrices.

(def Eigen (mat/eigen-decomposition (mat/mulmt M3x3 M3x3)))
(mat/decomposition-component Eigen :V)
#mat3x3 [[-0.03946194000852534, -0.37988921874940373, 0.924189881338641]
         [0.2524646291339424, -0.8986920160245726, -0.3586283192526073]
         [-0.9668010996720185, -0.2191730864217975, -0.1313727211460537]]
(mat/decomposition-component Eigen :D)
#mat3x3 [[203.4499939581915, 0.0, 0.0]
         [0.0, 78.85320029770806, 0.0]
         [0.0, 0.0, 2.696805744100544]]
(mat/decomposition-component Eigen :VT)
#mat3x3 [[-0.03946194000852534, 0.2524646291339424, -0.9668010996720185]
         [-0.37988921874940373, -0.8986920160245726, -0.2191730864217975]
         [0.924189881338641, -0.3586283192526073, -0.1313727211460537]]
(mat/decomposition-component Eigen :sqrt)
#mat3x3 [[2.706369949319761, 2.3452443705450374, 1.0841542970655804]
         [2.345244370545037, 8.29220181873904, -1.6550582587110794]
         [1.0841542970655804, -1.6550582587110794, 13.787145883772553]]
(mat/decomposition-component Eigen :det)
43264.00000000005
(mat/decomposition-component Eigen :complex?)
false
(mat/decomposition-component Eigen :real-eigenvalues)
[203.4499939581915 78.85320029770806 2.696805744100544]
(mat/decomposition-component Eigen :imag-eigenvalues)
[0.0 0.0 0.0]
(mat/decomposition-component Eigen :eigenvectors)
[[-0.03946194000852534 0.2524646291339424 -0.9668010996720185] [-0.37988921874940373 -0.8986920160245726 -0.2191730864217975] [0.924189881338641 -0.3586283192526073 -0.1313727211460537]]
(mat/singular? Eigen)
false
(mat/inverse Eigen)
#mat3x3 [[0.31855584319526614, -0.11862056213017746, -0.04377773668639051]
         [-0.11862056213017746, 0.0582470414201183, 0.018768491124260343]
         [-0.04377773668639051, 0.018768491124260343, 0.011603180473372774]]
(mat/solve Eigen V3)
[-0.47282960428994064 0.20324056952662714 0.05298862795857986]

Solving Linear Systems

This section covers functions for solving linear systems (\(\mathbf{A} \mathbf{x} = \mathbf{b}\)) and computing matrix inverses (\(\mathbf{A}^{-1}\)), which are fundamental operations in linear algebra. A matrix is invertible if and only if it is not singular (i.e., its determinant is non-zero). fastmath.matrix provides functions to check for singularity and compute the inverse, leveraging the underlying matrix types and decomposition results for efficiency and numerical stability.

Defined functions
  • solve
  • inverse
  • singular?
  • solve: Solves the linear system \(\mathbf{A} \mathbf{x} = \mathbf{b}\) for the unknown vector \(\mathbf{x}\). It can be called with the matrix \(\mathbf{A}\) and the right-hand side vector \(\mathbf{b}\) directly. For better performance and numerical stability, especially with large or ill-conditioned matrices, it is recommended to first compute a matrix decomposition of \(\mathbf{A}\) and then call solve on the resulting decomposition object. Returns the solution vector \(\mathbf{x}\).

QR, RRQR, Cholesky and SVD decompositions solve in a least squares sense by finding \(\hat{\boldsymbol{x}} = \underset{\boldsymbol{x}}{\operatorname{arg\,min}}\left\|\mathbf b - \mathbf{A} \boldsymbol x \right\|^2\)

Examples
(mat/solve M2x2 (v/vec2 1 1)) ;; => #vec2 [-1.0, 1.0]
(mat/solve M3x3 V3) ;; => #vec3 [-0.8088942307692308, -0.3533653846153847, 0.171875]
(-> (mat/lu-decomposition M2x2) (mat/solve (v/vec2 1 1))) ;; => #vec2 [-1.0, 1.0]
(-> (mat/sv-decomposition M3x3) (mat/solve V3)) ;; => #vec3 [-0.8088942307692306, -0.3533653846153848, 0.17187500000000006]
(mat/singular? M4x4) ;; => true
(-> (mat/qr-decomposition M4x4) (mat/solve V4)) ;; => #vec4 [2.4518612799761375E14, -4.262324200108071E15, 7.789090016223313E15, -3.771951944112856E15]
  • inverse: Computes the inverse matrix \(\mathbf{A}^{-1}\) such that \(\mathbf{A} \mathbf{A}^{-1} = \mathbf{A}^{-1} \mathbf{A} = \mathbf{I}\), where \(\mathbf{I}\) is the identity matrix. Like solve, it can be called directly on a matrix \(\mathbf{A}\), but is more efficient when called on a pre-computed matrix decomposition object.

When used on directly on a matrix \(\mathbf{A}\), returns the inverse matrix \(\mathbf{A}^{-1}\), or nil if the matrix is singular.

When used on decomposition, finds a pseudoinverse \(\mathbf{A^{+}}\).

(mat/inverse M2x2)
#mat2x2 [[-2.0, 1.0]
         [1.5, -0.5]]
(mat/inverse M3x3)
#mat3x3 [[0.39903846153846156, -0.1826923076923077, -0.014423076923076924]
         [0.3942307692307693, -0.09615384615384616, -0.08653846153846154]
         [-0.0625, 0.125, 0.0625]]
(mat/inverse M4x4)
nil

Pseudoinverse

(mat/inverse (mat/sv-decomposition M4x4))
#mat4x4 [[-0.2849999999999999, -0.14499999999999996, -0.0049999999999998795, 0.13499999999999987]
         [-0.10749999999999997, -0.05249999999999999, 0.002500000000000044, 0.057499999999999954]
         [0.06999999999999976, 0.039999999999999876, 0.009999999999999959, -0.019999999999999872]
         [0.2475000000000001, 0.1325000000000001, 0.017499999999999898, -0.09749999999999998]]

\(\mathbf{A}\mathbf{A^{+}}\mathbf{A}=\mathbf{A}\)

(-> M4x4
    (mat/mulm (mat/inverse (mat/sv-decomposition M4x4)))
    (mat/mulm M4x4))
#mat4x4 [[1.0000000000000004, 2.0, 3.0000000000000004, 4.0]
         [5.0, 6.000000000000001, 7.000000000000002, 8.0]
         [8.999999999999998, 9.999999999999996, 10.999999999999996, 11.999999999999996]
         [13.0, 14.0, 15.0, 15.999999999999998]]
  • singular?: Checks if a square matrix \(\mathbf{A}\) is singular. A matrix is singular if its determinant is zero (\(\det(\mathbf{A}) = 0\)), which means it is not invertible and the linear system \(\mathbf{A} \mathbf{x} = \mathbf{b}\) may have no unique solution. This function can be called directly on a matrix or on a matrix decomposition object. Returns true if the matrix is singular, false otherwise.
Examples
(mat/singular? M2x2) ;; => false
(mat/singular? M3x3) ;; => false
(mat/singular? M4x4) ;; => true
(mat/singular? (mat/sv-decomposition M4x4)) ;; => true

Eigenvalues and Singular Values

This section provides functions to compute the eigenvalues and eigenvectors of square matrices and the singular values of arbitrary matrices. Eigenvalues and eigenvectors characterize how a linear transformation stretches or compresses space and the directions along which this occurs. Singular values generalize this concept to non-square matrices and are fundamental in dimensionality reduction, least squares problems, and matrix approximation. These functions rely on matrix decompositions, specifically the Eigen decomposition and Singular Value Decomposition (SVD).

See also [Eigen]

Defined functions
  • eigenvalues, singular-values, eigenvalues-matrix, eigenvectors
  • eigenvalues: Computes the eigenvalues of a square matrix \(A\). Returns a sequence of 2D vectors (Vec2), where the x component is the real part of the eigenvalue and the y component is the imaginary part. If the matrix is real and symmetric, all imaginary parts will be zero.

  • singular-values: Computes the singular values of an arbitrary matrix \(A\). These are the non-negative square roots of the eigenvalues of the positive semi-definite matrix \(A^T A\). Returns a sequence of non-negative double values, typically sorted in descending order.

  • eigenvalues-matrix: Returns a matrix \(\mathbf{D}\) from the Eigen decomposition \(\mathbf{A} = \mathbf{V} \mathbf{D} \mathbf{V}^{-1}\), where \(\mathbf{D}\) is a diagonal matrix containing the real eigenvalues on its main diagonal, or a block diagonal matrix for complex conjugate pairs of eigenvalues. Only applies to square matrices.

  • eigenvectors: Computes the eigenvectors of a square matrix \(A\). Returns a matrix \(\mathbf{V}\) whose columns are the corresponding eigenvectors. If the matrix has complex eigenvalues, the corresponding eigenvectors will also be complex (represented by the columns of V from EigenDecomposition in ACM, which may not directly align with the real/imaginary pairs from eigenvalues). Can optionally normalize the eigenvectors.

Examples
(mat/eigenvalues M3x3) ;; => [#vec2 [6.139295738866405, 0.0] #vec2 [3.430352130566805, 4.7024240370595765] #vec2 [3.430352130566805, -4.7024240370595765]]
(mat/singular-values M3x3) ;; => (14.263589799142128 8.879932448938343 1.6421954037508997)
(mat/singular-values RealMat) ;; => (9.508032000695724 0.7728696356734822 0.0)
(mat/eigenvalues-matrix M3x3)
#mat3x3 [[6.139295738866405, 0.0, 0.0]
         [0.0, 3.430352130566805, 4.7024240370595765]
         [0.0, -4.7024240370595765, 3.430352130566805]]
(mat/eigenvectors M3x3)
#mat3x3 [[-0.5504760994745062, 0.7356992766680194, -0.6062798689976012]
         [-0.672507425622208, 1.623147213100584, -0.5083272487209609]
         [-0.4946815403775702, 0.4642329691550204, 1.0009169629182892]]
(mat/eigenvectors M3x3 true)
#mat3x3 [[-0.5504760994745058, 0.3994961319423593, -0.47519486669838584]
         [-0.6725074256222076, 0.8813941426495508, -0.3984207814692755]
         [-0.49468154037756984, 0.2520857113486531, 0.7845066727293754]]

Matrix Norms and Condition Number

Functions to compute various matrix norms and the condition number. Matrix norms measure the “size” or “magnitude” of a matrix, and the condition number quantifies how sensitive the solution of a linear system is to changes in the input data. These concepts are vital for analyzing the properties of matrices, assessing the numerical stability of algorithms (like solving linear systems or computing inverses), and understanding the behaviour of transformations represented by matrices.

Defined functions
  • norm
  • condition
  • norm: Computes a specific matrix norm of A. The type of norm is specified by the norm-type argument. Supported types include:

    • 1: The L1 norm (maximum absolute column sum). \(\Vert A \Vert_1 = \max_{j} \sum_{i=1}^m |a_{ij}|\).
    • :inf: The L-infinity norm (maximum absolute row sum). \(\Vert A \Vert_\infty = \max_{i} \sum_{j=1}^n |a_{ij}|\).
    • 2: The spectral norm (largest singular value). \(\Vert A \Vert_2 = \sigma_{\max}(A)\).
    • :max: The maximum absolute value norm. \(\Vert A \Vert_{\max} = \max_{i,j} |a_{ij}|\).
    • :frobenius: The Frobenius norm. \(\Vert A \Vert_F = \sqrt{\sum_{i=1}^m \sum_{j=1}^n |a_{ij}|^2} = \sqrt{\operatorname{tr}(A^T A)}\). This is a special case of the generalized L\(_{p,q}\) norm with \(p=2, q=2\).
    • [p, q]: The generalized L\(_{p,q}\) norm. A specific implementation is provided for \([2,2]\) (Frobenius) and \([p,p]\) (entrywise p-norm).
    • [p]: The Schatten p-norm, which is the L-p norm of the vector of singular values. \(\Vert A \Vert_p = (\sum_{i=1}^{\min(m,n)} \sigma_i^p)^{1/p}\). Includes :nuclear or :trace norm for \(p=1\).

    If no norm-type is provided, it defaults to the L1 norm (1).

  • condition: Computes the condition number of a matrix A with respect to a given norm norm-type. It is defined as \(\operatorname{cond}(A) = \Vert A \Vert \Vert A^{-1} \Vert\). A large condition number indicates that the matrix is close to being singular, and linear systems involving the matrix may be ill-conditioned, meaning small changes in the input can lead to large changes in the output solution.

    Defaults to the L2 norm (2) for calculation.

Examples
(mat/norm M2x2) ;; => 6.0
(mat/norm M2x2 :inf) ;; => 7.0
(mat/norm M2x2 2) ;; => 5.464985704219042
(mat/norm M2x2 :frobenius) ;; => 5.477225575051661
(mat/norm M2x2 :max) ;; => 4.0
(mat/norm M2x2 [2 2]) ;; => 5.477225575051661
(mat/norm M2x2 [3 3]) ;; => 4.641588833612778
(mat/norm M2x2 [1]) ;; => 5.830951894845294
(mat/norm M4x4) ;; => 40.0
(mat/norm M4x4 :inf) ;; => 58.0
(mat/norm M4x4 2) ;; => ##NaN
(mat/norm M4x4 :frobenius) ;; => 38.67815921162743
(mat/norm M4x4 :max) ;; => 16.0
(mat/norm M4x4 [2 2]) ;; => 38.67815921162743
(mat/norm M4x4 [3 3]) ;; => 26.445956073831777
(mat/norm M4x4 [1]) ;; => ##NaN
(mat/condition M2x2) ;; => 14.93303437365925
(mat/condition M2x2 :inf) ;; => 21.0
(mat/condition M2x2 1) ;; => 21.0

Reference

fastmath.vector

Provides mathematical vector operations for various vector types, inspired by libraries like Processing and openFrameworks.

Supported vector representations include:

  • Fixed-size custom types: Vec2 (2D), Vec3 (3D), Vec4 (4D), and ArrayVec (N-dimensional wrapper around double[]).
  • Built-in array type: double arrays ([D).
  • Variable-size Clojure collections: persistent vectors ([]) and sequences (ISeq).
  • Numbers: Treated as 1D vectors.

Most operations are defined via the VectorProto protocol, which is extended for all supported types.

These vector types also implement standard Clojure/Java protocols like Seqable, Indexed, IFn, Counted, Associative, IReduce, ILookup, etc., enabling them to be used flexibly as sequences, arrays, or functions.

->ArrayVec

  • (->ArrayVec array)

Positional factory function for class fastmath.vector.ArrayVec.

->Vec2

  • (->Vec2 x y)

Positional factory function for class fastmath.vector.Vec2.

->Vec3

  • (->Vec3 x y z)

Positional factory function for class fastmath.vector.Vec3.

->Vec4

  • (->Vec4 x y z w)

Positional factory function for class fastmath.vector.Vec4.

abs

  • (abs v)

Absolute value of vector elements

acos

  • (acos vector)

Applies acos to vector elements.

acosh

  • (acosh vector)

Applies acosh to vector elements.

acot

  • (acot vector)

Applies acot to vector elements.

acoth

  • (acoth vector)

Applies acoth to vector elements.

acsc

  • (acsc vector)

Applies acsc to vector elements.

acsch

  • (acsch vector)

Applies acsch to vector elements.

add

  • (add v)
  • (add v1 v2)

Sum of two vectors.

aligned?

  • (aligned? v1 v2 tol)
  • (aligned? v1 v2)

Checks if two vectors are aligned, meaning they point in approximately the same direction. This is determined by checking if the angle between them (calculated using angle-between) is less than the specified tolerance.

Defaults to an absolute tolerance of 1.0e-6.

angle-between

  • (angle-between v1 v2)

Returns the angle between two vectors in radians.

The angle is always positive and lies between 0 and π. Returns 0 if either vector is zero.

applyf DEPRECATED

Deprecated: v1.3.0

Same as fmap. Deprecated.

approx

  • (approx v)
  • (approx v d)

Rounds to d (default: 2) decimal places

array->vec2

  • (array->vec2 arr)

Converts doubles array to Vec2

array->vec3

  • (array->vec3 arr)

Converts doubles array to Vec3

array->vec4

  • (array->vec4 arr)

Converts doubles array to Vec4

array-vec

  • (array-vec xs)

Creates ArrayVec type based on provided sequence xs.

as-vec

  • (as-vec v)
  • (as-vec v xs)

Creates vector from sequence as given type. If there is no sequence fill with 0.0.

asec

  • (asec vector)

Applies asec to vector elements.

asech

  • (asech vector)

Applies asech to vector elements.

asin

  • (asin vector)

Applies asin to vector elements.

asinh

  • (asinh vector)

Applies asinh to vector elements.

atan

  • (atan vector)

Applies atan to vector elements.

atanh

  • (atanh vector)

Applies atanh to vector elements.

average

  • (average v)
  • (average v weights)

Mean or weighted average of the vector

average-vectors

  • (average-vectors init vs)
  • (average-vectors vs)

Average / centroid of vectors. Input: initial vector (optional), list of vectors

axis-rotate

  • (axis-rotate v angle axis)
  • (axis-rotate v angle axis pivot)

Rotates vector. Only for Vec3 types

base-from

  • (base-from v)

List of perpendicular vectors (basis). Works only for Vec2 and Vec3 types.

cb

  • (cb vector)

Applies cb to vector elements.

cbrt

  • (cbrt vector)

Applies cbrt to vector elements.

ceil

  • (ceil vector)

Applies ceil to vector elements.

clamp

  • (clamp v mn mx)
  • (clamp v)

Clamps the elements of vector v element-wise between a minimum (mn) and maximum (mx) value.

In the single-arity version [v], elements are clamped between 0.0 and Double/MAX_VALUE.

cos

  • (cos vector)

Applies cos to vector elements.

cosh

  • (cosh vector)

Applies cosh to vector elements.

cot

  • (cot vector)

Applies cot to vector elements.

coth

  • (coth vector)

Applies coth to vector elements.

cross

  • (cross v1 v2)

Cross product

csc

  • (csc vector)

Applies csc to vector elements.

csch

  • (csch vector)

Applies csch to vector elements.

degrees

  • (degrees vector)

Applies degrees to vector elements.

delta-eq

  • (delta-eq v1 v2)
  • (delta-eq v1 v2 abs-tol)
  • (delta-eq v1 v2 abs-tol rel-tol)

Equality with given absolute (and/or relative) toleance.

dhash-code

  • (dhash-code state a)
  • (dhash-code a)

double hashcode

dist

  • (dist v1 v2)

Euclidean distance between vectors

dist-abs

  • (dist-abs v1 v2)

Manhattan distance between vectors

dist-ang

  • (dist-ang v1 v2)

Angular distance

dist-canberra

  • (dist-canberra v1 v2)

Canberra distance

dist-cheb

  • (dist-cheb v1 v2)

Chebyshev distance between 2d vectors

dist-discrete

  • (dist-discrete v1 v2)
  • (dist-discrete v1 v2 eps)

Computes the discrete distance between two vectors v1 and v2.

This is the number of positions where the corresponding elements are considered different. With an optional absolute tolerance eps, elements at index i are considered different if |v1_i - v2_i| > eps.

Returns the count of differing elements.

dist-emd

  • (dist-emd v1 v2)

Earth Mover’s Distance

dist-sq

  • (dist-sq v1 v2)

Squared Euclidean distance between vectors

distances

div

  • (div v1 v)
  • (div v1)

Vector division or reciprocal.

dot

  • (dot v1 v2)

Dot product of two vectors.

econstrain

  • (econstrain v mn mx)

Element-wise constrain

edelta-eq

  • (edelta-eq v1 v2)
  • (edelta-eq v1 v2 abs-tol)
  • (edelta-eq v1 v2 abs-tol rel-tol)

Element-wise equality with given absolute (and/or relative) toleance.

ediv

  • (ediv v1 v2)

Element-wise division of two vectors.

einterpolate

  • (einterpolate v1 v2 v)
  • (einterpolate v1 v2 v f)

Interpolates vector selement-wise, optionally set interpolation fn (default: lerp)

emn

  • (emn v1 v2)

Element-wise min from two vectors.

emult

  • (emult v1)
  • (emult v1 v2)

Element-wise vector multiplication (Hadamard product).

emx

  • (emx v1 v2)

Element-wise max from two vectors.

exp

  • (exp vector)

Applies exp to vector elements.

expm1

  • (expm1 vector)

Applies expm1 to vector elements.

faceforward

  • (faceforward n v)

Flips vector n if dot(n, v) is negative. Returns n if dot(n, v) is non-negative. Useful for ensuring consistent vector orientation, such as making a normal vector face towards a reference vector v.

floor

  • (floor vector)

Applies floor to vector elements.

fmap

  • (fmap v f)

Applies function to all vector values (like map but returns the same type).

frac

  • (frac vector)

Applies frac to vector elements.

from-polar

  • (from-polar v)

From polar coordinates (2d, 3d only)

generate-vec2

  • (generate-vec2 f1 f2)
  • (generate-vec2 f)

Generates Vec2 with fn(s)

generate-vec3

  • (generate-vec3 f1 f2 f3)
  • (generate-vec3 f)

Generates Vec3 with fn(s)

generate-vec4

  • (generate-vec4 f1 f2 f3 f4)
  • (generate-vec4 f)

Generates Vec4 with fn(s)

heading

  • (heading v)

Angle between vector and unit vector [1,0,...]

interpolate

  • (interpolate v1 v2 t)
  • (interpolate v1 v2 t f)

Interpolates vectors, optionally set interpolation fn (default: lerp)

is-near-zero?

  • (is-near-zero? v)
  • (is-near-zero? v abs-tol)
  • (is-near-zero? v abs-tol rel-tol)

Equality to zero 0 with given absolute (and/or relative) toleance.

is-zero?

  • (is-zero? v)

Is vector zero?

lerp

  • (lerp v1 v2 t)

Linear interpolation of vectors

limit

  • (limit v len)

Limits length of the vector by given value

ln

  • (ln vector)

Applies ln to vector elements.

log

  • (log vector)

Applies log to vector elements.

log10

  • (log10 vector)

Applies log10 to vector elements.

log1mexp

  • (log1mexp vector)

Applies log1mexp to vector elements.

log1p

  • (log1p vector)

Applies log1p to vector elements.

log1pexp

  • (log1pexp vector)

Applies log1pexp to vector elements.

log1pmx

  • (log1pmx vector)

Applies log1pmx to vector elements.

log1psq

  • (log1psq vector)

Applies log1psq to vector elements.

log2

  • (log2 vector)

Applies log2 to vector elements.

logexpm1

  • (logexpm1 vector)

Applies logexpm1 to vector elements.

logit

  • (logit vector)

Applies logit to vector elements.

logmeanexp

  • (logmeanexp v)

Calculates the numerically stable log of the mean of the exponential of each element in vector v.

This is equivalent to log(mean(exp(v_i))) for all elements v_i in v. It provides a numerically stable way to compute log(sum(exp(v_i))) - log(count(v)) by shifting values to prevent overflow during exponentiation.

Often used in machine learning and statistical contexts where dealing with large values inside exponentials is common.

Returns a double value.

logmxp1

  • (logmxp1 vector)

Applies logmxp1 to vector elements.

logsoftmax

  • (logsoftmax v)
  • (logsoftmax v t)

Calculates the element-wise natural logarithm of the softmax function for the given vector v.

The standard log-softmax of an element \(v_i\) is \(\log(\operatorname{softmax}(v)_i)\), which is mathematically equivalent to \(v_i - \log(\sum_j \exp(v_j))\). This function provides a numerically stable implementation of this calculation, particularly useful for avoiding overflow and underflow issues when dealing with large or small exponential values.

It supports two arities: - [v]: Computes the standard log-softmax using the numerically stable form. - [v t]: Computes the temperature-scaled log-softmax. Elements are divided by the temperature t before applying the log-softmax formula, i.e., \(\frac{v_i}{t} - \log(\sum_j \wxp(\fac{v_j}{t}))\). The temperature influences the shape of the corresponding softmax output distribution: \(t > 1\) softens it, \(t < 1\) sharpens it.

Log-softmax is frequently used in numerical computations, especially in machine learning (e.g., as part of the cross-entropy loss function) for its superior numerical properties.

Returns a new vector of the same type and dimension as the input.

logsumexp

  • (logsumexp v)

Calculates the LogSumExp of the vector v.

This is the numerically stable computation of log(sum(exp(x_i))) for all elements x_i in v. It is often used to prevent overflow when exponentiating large numbers, especially in machine learning and statistics.

Returns a double value.

mag

  • (mag v)

Returns length of the vector.

magsq

  • (magsq v)

Returns length of the vector squared.

make-vector

  • (make-vector dims xs)
  • (make-vector dims)

Returns fixed size vector for given number of dimensions.

Proper type is used.

maxdim

  • (maxdim v)

Index of maximum value.

mindim

  • (mindim v)

Index of minimum value.

mn

  • (mn v)

Minimum value of vector elements

mult

  • (mult v)
  • (mult v x)

Multiplies vector by number x.

mx

  • (mx v)

Maximum value of vector elements

near-zero?

  • (near-zero? v)
  • (near-zero? v abs-tol)
  • (near-zero? v abs-tol rel-tol)

Equality to zero 0 with given absolute (and/or relative) toleance.

nonzero-count

  • (nonzero-count v)

Counts non zero velues in vector

normalize

  • (normalize v)

Returns a new vector with the same direction as v but with a magnitude of 1.

If v is a zero vector (magnitude is zero), returns a zero vector of the same type.

orthogonal-polynomials

  • (orthogonal-polynomials xs)

Generates a sequence of orthogonal vectors by evaluating orthogonal polynomials at the points specified in the input sequence xs.

The output vectors represent the values of orthogonal polynomials evaluated at the elements of xs. Orthogonality is defined with respect to the discrete inner product based on summation over the points in xs.

The sequence starts with the vector for the polynomial of degree 1 and includes vectors up to degree (count xs) - 1.

This function is useful for constructing orthogonal bases for polynomial approximation or regression on discrete data.

orthonormal-polynomials

  • (orthonormal-polynomials xs)

Generates a sequence of orthonormal vectors by evaluating orthogonal polynomials at the points specified in the input sequence xs and normalizing the resulting vectors.

The sequence starts with the vector for the polynomial of degree 1 and includes vectors up to degree (count xs) - 1. Orthogonality (and thus orthonormality after normalization) is with respect to the discrete inner product based on summation over the points in xs.

This function produces an orthonormal basis suitable for polynomial approximation or regression on discrete data points defined by xs, derived from the orthogonal basis computed by orthogonal-polynomials.

permute

  • (permute v idxs)

Permutes vector elements with given indices.

perpendicular

  • (perpendicular v)
  • (perpendicular v1 v2)

Perpendicular vector. Only for Vec2 and Vec3 types.

pow

  • (pow v exponent)

Applies power to a vector elements.

prod

  • (prod)
  • (prod v)

Product of elements

project

  • (project v1 v2)

Calculates the vector projection of v1 onto v2. The projection is a vector along the direction of v2 that represents the component of v1 in that direction.

radians

  • (radians vector)

Applies radians to vector elements.

real-vector

  • (real-vector v)

Converts to Apache Commons Math RealVector

reciprocal

  • (reciprocal v)

Reciprocal of elements.

relative-angle-between

  • (relative-angle-between v1 v2)

Returns the difference between the heading of v2 and the heading of v1. The heading is the angle relative to the positive primary axis ([1,0,…]). For 2D vectors, this is the difference between their polar angles.

Returns value from \(-2\pi\) to \(2\pi\).

See also angle-between (absolute angle between vectors) and heading.

rint

  • (rint vector)

Applies rint to vector elements.

rotate

  • (rotate v angle)
  • (rotate v angle-x angle-y angle-z)

Rotates vector. Only for Vec2 and Vec3 types.

round

  • (round vector)

Applies round to vector elements.

safe-sqrt

  • (safe-sqrt vector)

Applies safe-sqrt to vector elements.

sec

  • (sec vector)

Applies sec to vector elements.

sech

  • (sech vector)

Applies sech to vector elements.

seq->vec2

  • (seq->vec2 xs)

Converts any seq to Vec2

seq->vec3

  • (seq->vec3 xs)

Converts any seq to Vec3

seq->vec4

  • (seq->vec4 xs)

Converts any seq to Vec4

set-mag

  • (set-mag v len)

Sets length of the vector.

sfrac

  • (sfrac vector)

Applies sfrac to vector elements.

sgn

  • (sgn vector)

Applies sgn to vector elements.

shift

  • (shift v)
  • (shift v x)

Adds a value to every vector element.

sigmoid

  • (sigmoid vector)

Applies sigmoid to vector elements.

signum

  • (signum vector)

Applies signum to vector elements.

sim-cos

  • (sim-cos v1 v2)

Cosine similarity

sin

  • (sin vector)

Applies sin to vector elements.

sinc

  • (sinc vector)

Applies sinc to vector elements.

sinh

  • (sinh vector)

Applies sinh to vector elements.

size

  • (size v)

Returns elements count of the vector.

softmax

  • (softmax v)
  • (softmax v t)

Calculates the softmax function for the given vector v.

The softmax function transforms a vector of arbitrary real values into a probability distribution, where each element is a value between 0 and 1, and all elements sum to 1.

It has two arities: - [v]: Computes the standard softmax: softmax(v)_i = exp(v_i) / sum_j(exp(v_j)). - [v t]: Computes the temperature-scaled softmax: softmax(v)_i = exp(v_i / t) / sum_j(exp(v_j / t)). The t parameter (temperature, defaults to 1) controls the shape of the output distribution; higher temperatures produce softer, more uniform distributions, while lower temperatures produce sharper distributions closer to a one-hot encoding.

The implementation uses a numerically stable approach (by shifting values based on the vector’s maximum) to prevent overflow when exponentiating large numbers.

Returns a new vector of the same type and dimension as the input.

sq

  • (sq vector)

Applies sq to vector elements.

sqrt

  • (sqrt vector)

Applies sqrt to vector elements.

sub

  • (sub v)
  • (sub v1 v2)

Subtraction of two vectors.

sum

  • (sum)
  • (sum v)

Sum of elements

tan

  • (tan vector)

Applies tan to vector elements.

tanh

  • (tanh vector)

Applies tanh to vector elements.

to-polar

  • (to-polar v)

To polar coordinates (2d, 3d only), first element is length, the rest angle.

to-vec DEPRECATED

Deprecated: v1.5.0

Same as vec->Vec. Deprecated.

transform

  • (transform v o vx vy)
  • (transform v o vx vy vz)

Transforms vector.

Maps point to a coordinate system defined by origin, vx, vy and vz (as bases).

Only for Vec2 and Vec3 types.

triple-product

  • (triple-product a b c)

a o (b x c)

trunc

  • (trunc vector)

Applies trunc to vector elements.

vec->RealVector

  • (vec->RealVector v)

Converts to Apache Commons Math RealVector

vec->Vec

  • (vec->Vec v)

Converts to Clojure primitive vector Vec.

vec->array

  • (vec->array v)

Converts to double array

vec->seq

  • (vec->seq v)

Converts to sequence (same as seq)

vec2

  • (vec2 x y)
  • (vec2 [x y])
  • (vec2)

Creates 2d vector.

vec3

  • (vec3 x y z)
  • (vec3 v z)
  • (vec3 [x y z])
  • (vec3)

Creates Vec2 vector

vec4

  • (vec4 x y z w)
  • (vec4 v w)
  • (vec4 v z w)
  • (vec4 [x y z w])
  • (vec4)

Creates Vec4 vector

xlogx

  • (xlogx vector)

Applies xlogx to vector elements.

zero-count

  • (zero-count v)

Counts zeros in vector

zero?

  • (zero? v)

Is vector zero?

fastmath.matrix

Provides tools for working with various matrix types, including fixed-size (2x2, 3x3, 4x4), Java double[][] arrays, and Apache Commons Math RealMatrix.

It offers efficient mathematical operations for linear algebra, geometric transformations, and data manipulation, unifying different representations under a common protocol approach where appropriate.

->Mat2x2

  • (->Mat2x2 a00 a01 a10 a11)

Positional factory function for class fastmath.matrix.Mat2x2.

->Mat3x3

  • (->Mat3x3 a00 a01 a02 a10 a11 a12 a20 a21 a22)

Positional factory function for class fastmath.matrix.Mat3x3.

->Mat4x4

  • (->Mat4x4 a00 a01 a02 a03 a10 a11 a12 a13 a20 a21 a22 a23 a30 a31 a32 a33)

Positional factory function for class fastmath.matrix.Mat4x4.

->MatrixDecomposition

  • (->MatrixDecomposition source components solver singular? s)

Positional factory function for class fastmath.matrix.MatrixDecomposition.

acos

  • (acos vector)

Applies acos to matrix elements.

acosh

  • (acosh vector)

Applies acosh to matrix elements.

acot

  • (acot vector)

Applies acot to matrix elements.

acoth

  • (acoth vector)

Applies acoth to matrix elements.

acsc

  • (acsc vector)

Applies acsc to matrix elements.

acsch

  • (acsch vector)

Applies acsch to matrix elements.

add

  • (add A)
  • (add A B)

Adds matrices, C=A+B.

adds

  • (adds A s)

Adds scalar to all matrix elements

array2d->RealMatrix

  • (array2d->RealMatrix arrs)

Creates RealMatrix matrix from 2d double array.

array2d->mat2x2

  • (array2d->mat2x2 arrs)

Creates 2x2 matrix from 2d double array.

array2d->mat3x3

  • (array2d->mat3x3 arrs)

Creates 3x3 matrix from 2d double array.

array2d->mat4x4

  • (array2d->mat4x4 arrs)

Creates 4x4 matrix from 2d double array.

asec

  • (asec vector)

Applies asec to matrix elements.

asech

  • (asech vector)

Applies asech to matrix elements.

asin

  • (asin vector)

Applies asin to matrix elements.

asinh

  • (asinh vector)

Applies asinh to matrix elements.

atan

  • (atan vector)

Applies atan to matrix elements.

atanh

  • (atanh vector)

Applies atanh to matrix elements.

cb

  • (cb vector)

Applies cb to matrix elements.

cbrt

  • (cbrt vector)

Applies cbrt to matrix elements.

ceil

  • (ceil vector)

Applies ceil to matrix elements.

cholesky DEPRECATED

Deprecated: Use cholesky-decomposition instead.

  • (cholesky A)
  • (cholesky A upper?)

Calculates L (lower by default) triangular for where L * L^T = A.

Checks only for symmetry, can return NaNs when A is not positive-definite.

cholesky-decomposition

  • (cholesky-decomposition mat)
  • (cholesky-decomposition mat symmetry_threshold positivity_threshold)

Performs Cholesky decomposition.

Decomposition of real symmetric positive-definite matrix. A = L x LT

Solver minimizes using least squares method.

Components, access with decomposition-component function:

  • :L, :LT - matrices
  • :det - determinant.

Can be used as input for solve, inverse and singular? functions.

col

  • (col A c)

Returns column as a vector

cols

  • (cols A)

Returns matrix columns

cols->RealMatrix

  • (cols->RealMatrix cols)

Returns Apache Commons Math Array2DRowMatrix from sequence of columns

cols->mat

  • (cols->mat real-matrix-cols)
  • (cols->mat [a00 a10] [a01 a11])
  • (cols->mat [a00 a10 a20] [a01 a11 a21] [a02 a12 a22])
  • (cols->mat [a00 a10 a20 a30] [a01 a11 a21 a31] [a02 a12 a22 a32] [a03 a13 a23 a33])

Creates nxn matrix from nd vectors (columns).

cols->mat2x2

  • (cols->mat2x2 [a00 a10] [a01 a11])

Create 2x2 matrix from 2d vectors (columns).

cols->mat3x3

  • (cols->mat3x3 [a00 a10 a20] [a01 a11 a21] [a02 a12 a22])

Creates 3x3 matrix from 3d vectors (columns).

cols->mat4x4

  • (cols->mat4x4 [a00 a10 a20 a30] [a01 a11 a21 a31] [a02 a12 a22 a32] [a03 a13 a23 a33])

Creates 4x4 matrix from 4d vectors (columns).

condition

  • (condition A)
  • (condition A norm-type)

Condition number calculated for L2 norm by default (see norm for other norm types).

Cond(A) = norm(A) * norm(inv(A))

cos

  • (cos vector)

Applies cos to matrix elements.

cosh

  • (cosh vector)

Applies cosh to matrix elements.

cot

  • (cot vector)

Applies cot to matrix elements.

coth

  • (coth vector)

Applies coth to matrix elements.

csc

  • (csc vector)

Applies csc to matrix elements.

csch

  • (csch vector)

Applies csch to matrix elements.

decomposition-component

  • (decomposition-component decomposition-matrix component-name)

Returns value of the component of matrix decomposition

degrees

  • (degrees vector)

Applies degrees to matrix elements.

demean

  • (demean A)
  • (demean A rows?)

Subracts mean from columns (or rows)

det

  • (det A)

Returns determinant of the matrix.

diag

  • (diag A)

Returns diagonal of the matrix as a vector.

diag->mat2x2

  • (diag->mat2x2 d)
  • (diag->mat2x2 d1 d2)

Creates 2x2 diagonal matrix.

diag->mat3x3

  • (diag->mat3x3 d)
  • (diag->mat3x3 d1 d2 d3)

Creates 3x3 diagonal matrix.

diag->mat4x4

  • (diag->mat4x4 d)
  • (diag->mat4x4 d1 d2 d3 d4)

Creates 4x4 diagonal matrix.

diagonal

  • (diagonal v)
  • (diagonal a11 a22)
  • (diagonal a11 a22 a33)
  • (diagonal a11 a22 a33 a44)

Creates diagonal matrix.

eigen-decomposition

  • (eigen-decomposition mat)

Performs Eigen decomposition.

A = V x D x VT, D contains eigenvalues (diagonal: real values, subdiagonal: imaginary), V - eigenvectors.

Solver is exact.

Components, access with decomposition-component function:

  • :D, :V, :VT, :sqrt - matrices.
  • :det - determinant
  • :real-eigenvalues, imag-eigenvalues - eigenvalues
  • :eigenvectors - sequence of eigenvectors
  • :complex? - are eigenvalues complex?

Can be used as input for solve, inverse and singular? functions.

eigenvalues

  • (eigenvalues A)

Returns complex eigenvalues for given matrix as a sequence

eigenvalues-matrix

  • (eigenvalues-matrix A)

Returns eigenvalues for given matrix as a diagonal or block diagonal matrix

eigenvectors

  • (eigenvectors A)
  • (eigenvectors A normalize?)

Returns eigenvectors as a matrix (columns). Vectors can be normalized.

emulm

  • (emulm A B)

Multiplies two matrices element-wise, Hadamard product, C=AoB

entry

  • (entry A row col)

Returns entry at given row and column

exp

  • (exp vector)

Applies exp to matrix elements.

expm1

  • (expm1 vector)

Applies expm1 to matrix elements.

eye

  • (eye size real-matrix?)
  • (eye size)

Creates identity matrix for given size.

floor

  • (floor vector)

Applies floor to matrix elements.

fmap

  • (fmap A f)

Applies a function f to each matrix element.

frac

  • (frac vector)

Applies frac to matrix elements.

inverse

  • (inverse m)

Matrix inversion.

Returns nil if inversion doesn’t exist.

kronecker

  • (kronecker mat1 mat2)

Returns Kronecker product of two matrices.

ln

  • (ln vector)

Applies ln to matrix elements.

log

  • (log vector)

Applies log to matrix elements.

log10

  • (log10 vector)

Applies log10 to matrix elements.

log1mexp

  • (log1mexp vector)

Applies log1mexp to matrix elements.

log1p

  • (log1p vector)

Applies log1p to matrix elements.

log1pexp

  • (log1pexp vector)

Applies log1pexp to matrix elements.

log1pmx

  • (log1pmx vector)

Applies log1pmx to matrix elements.

log1psq

  • (log1psq vector)

Applies log1psq to matrix elements.

log2

  • (log2 vector)

Applies log2 to matrix elements.

logexpm1

  • (logexpm1 vector)

Applies logexpm1 to matrix elements.

logit

  • (logit vector)

Applies logit to matrix elements.

logmxp1

  • (logmxp1 vector)

Applies logmxp1 to matrix elements.

lu-decomposition

  • (lu-decomposition mat)
  • (lu-decomposition mat threshold)

Performs QR decomposition.

A = inv(P) x L x U, L is lower triangular, U is upper triangular.

Solver is exact.

Components, access with decomposition-component function:

  • :L, :U, :P (permutation) - matrices.
  • :det - determinant
  • :pivot - pivot permutation vector

Can be used as input for solve, inverse and singular? functions.

map->MatrixDecomposition

  • (map->MatrixDecomposition m__7997__auto__)

Factory function for class fastmath.matrix.MatrixDecomposition, taking a map of keywords to field values.

map-cols

  • (map-cols f A)

Operate on columns, f should return a column

map-rows

  • (map-rows f A)

Operate on rows, f should return a row

mat

  • (mat real-matrix-rows)
  • (mat a00 a01 a10 a11)
  • (mat a00 a01 a02 a10 a11 a12 a20 a21 a22)
  • (mat a00 a01 a02 a03 a10 a11 a12 a13 a20 a21 a22 a23 a30 a31 a32 a33)

Creates mat2x2, mat3x3 or mat4x4 or RealMatrix from rows

mat->RealMatrix

  • (mat->RealMatrix A)

Returns Apache Commons Math Array2DRowMatrix from a 2x2, 3x3 or 4x4 matrix

mat->array

  • (mat->array A)

Returns flat double array of entries (row order)

mat->array2d

  • (mat->array2d A)

Returns doubles of doubles

mat->float-array

  • (mat->float-array A)

Returns flat float array of entries (row order)

mat->float-array2d

  • (mat->float-array2d A)

Returns doubles of doubles

mat->seq

  • (mat->seq A)

Returns flat sequence of entries (row order)

mat2x2

  • (mat2x2 v)
  • (mat2x2 d1 d2)
  • (mat2x2 a00 a01 a10 a11)

Creates 2x2 matrix.

Arity:

  • 1 - fills matrix with given value
  • 2 - creates diagonal matrix
  • 4 - creates row ordered matrix

mat3x3

  • (mat3x3 v)
  • (mat3x3 d1 d2 d3)
  • (mat3x3 a00 a01 a02 a10 a11 a12 a20 a21 a22)

Creates 3x3 matrix.

Arity:

  • 1 - fills matrix with given value
  • 3 - creates diagonal matrix
  • 9 - creates row ordered matrix

mat4x4

  • (mat4x4 v)
  • (mat4x4 d1 d2 d3 d4)
  • (mat4x4 a00 a01 a02 a03 a10 a11 a12 a13 a20 a21 a22 a23 a30 a31 a32 a33)

Creates 4x4 matrix.

Arity:

  • 1 - fills matrix with given value
  • 4 - creates diagonal matrix
  • 16 - creates row ordered matrix

mulm

  • (mulm A B)
  • (mulm A transposeA? B transposeB?)

Multiplies two matrices, C=AxB.

Optionally you can apply transposition of matrices.

mulmt

  • (mulmt A B)

Multiplies with transposed matrix, C=AxB^T

muls

  • (muls A s)

Multplies matrix by a scalar, C=sA

mulv

  • (mulv A v)

Multplies matrix by a vector, x=Av

ncol

  • (ncol A)

Returns number of rows

negate

  • (negate A)

Negates all matrix elements, C=-A

norm

  • (norm A)
  • (norm A norm-type)

Calculates norm of the matrix for given type, default: 1 (maximum absolute column sum).

All norm types are:

  • 1 - maximum absolute column sum
  • :inf - maximum absolute row sum
  • 2 - spectral norm, maximum singular value
  • :max - maximum absolute value
  • :frobenius - Frobenius norm
  • [p,q] - generalized L_pq norm, [2,2] - Frobenius norm, [p,p] - entrywise p-norm
  • [p] - Shatten p-norm, [1] - nuclear/trace norm

normalize

  • (normalize A)
  • (normalize A rows?)

Normalizes columns (or rows)

nrow

  • (nrow A)

Returns number of rows

outer

  • (outer v1 v2)

Outer project for two vectors.

pow

  • (pow m exponent)

Applies power to a vector elements.

qr-decomposition

  • (qr-decomposition mat)
  • (qr-decomposition mat threshold)

Performs QR decomposition.

A = Q x R, Q is orthogonal (QT x Q = I), R is upper triangular.

Solver minimizes using least squares method.

Components, access with decomposition-component function:

  • :H (Hauseholder reflecors), :Q, :QT, :R - matrices.

Can be used as input for solve, inverse and singular? functions.

radians

  • (radians vector)

Applies radians to matrix elements.

real-matrix

  • (real-matrix rows)

Creates Apache Commons Math Array2DRowMatrix from sequence of rows

rint

  • (rint vector)

Applies rint to matrix elements.

rotation-matrix-2d

  • (rotation-matrix-2d theta)

Creates rotation matrix for a plane

rotation-matrix-3d

  • (rotation-matrix-3d [x y z])
  • (rotation-matrix-3d x y z)

Creates rotation matrix for a 3d space. Tait–Bryan angles z-y′-x″

rotation-matrix-3d-x

  • (rotation-matrix-3d-x a)

Creates rotation matrix for a 3d space, x-axis, right hand rule.

rotation-matrix-3d-y

  • (rotation-matrix-3d-y a)

Creates rotation matrix for a 3d space, y-axis, right hand rule.

rotation-matrix-3d-z

  • (rotation-matrix-3d-z a)

Creates rotation matrix for a 3d space, z-axis, right hand rule.

rotation-matrix-axis-3d

  • (rotation-matrix-axis-3d angle axis)

Creates 3d rotation matrix for axis ratation.

round

  • (round vector)

Applies round to matrix elements.

row

  • (row A r)

Returns row as a vector

rows

  • (rows A)

Returns matrix rows

rows->RealMatrix

  • (rows->RealMatrix rows)

Returns Apache Commons Math Array2DRowMatrix from sequence of rows

rows->mat

  • (rows->mat real-matrix-rows)
  • (rows->mat [a00 a01] [a10 a11])
  • (rows->mat [a00 a01 a02] [a10 a11 a12] [a20 a21 a22])
  • (rows->mat [a00 a01 a02 a03] [a10 a11 a12 a13] [a20 a21 a22 a23] [a30 a31 a32 a33])

Creates nxn matrix from nd vectors (rows).

rows->mat2x2

  • (rows->mat2x2 [a00 a01] [a10 a11])

Creates 2x2 matrix from 2d vectors (rows).

rows->mat3x3

  • (rows->mat3x3 [a00 a01 a02] [a10 a11 a12] [a20 a21 a22])

Creates 3x3 matrix from 3d vectors (rows).

rows->mat4x4

  • (rows->mat4x4 [a00 a01 a02 a03] [a10 a11 a12 a13] [a20 a21 a22 a23] [a30 a31 a32 a33])

Creates 4x4 matrix from 4d vectors (rows).

rrqr-decomposition

  • (rrqr-decomposition mat)
  • (rrqr-decomposition mat threshold)

Performs Rank-Revealing QR decomposition.

A = Q x R x inv(P), Q is orthogonal (QT x Q = I), R is upper triangular.

Solver minimizes using least squares method.

Components, access with decomposition-component function:

  • :H (Hauseholder reflecors), :Q, :QT, :R, :P (permutation) - matrices
  • :rank-fn - calculates numerical matrix rank, accepts threshold for rank computation (default: 0.0).

Can be used as input for solve, inverse and singular? functions.

safe-sqrt

  • (safe-sqrt vector)

Applies safe-sqrt to matrix elements.

scale-cols

  • (scale-cols A)
  • (scale-cols A scale)

Multiplies cols by a value (default: 1/(sqrt(sum(x^2)/(n-1)))) or a result of the function

scale-rows

  • (scale-rows A)
  • (scale-rows A scale)

Multiplies rows by a value (default: 1/(sqrt(sum(x^2)/(n-1)))) or a result of the function

sec

  • (sec vector)

Applies sec to matrix elements.

sech

  • (sech vector)

Applies sech to matrix elements.

sfrac

  • (sfrac vector)

Applies sfrac to matrix elements.

sgn

  • (sgn vector)

Applies sgn to matrix elements.

shape

  • (shape A)

Returns [nrow, ncol] pair.

shift-cols

  • (shift-cols A)
  • (shift-cols A shift)

Shifts columns by a value or a result of the function (negative of mean by default)

shift-rows

  • (shift-rows A)
  • (shift-rows A shift)

Shifts rows by a value or a result of the function (nagetive of mean by default)

sigmoid

  • (sigmoid vector)

Applies sigmoid to matrix elements.

signum

  • (signum vector)

Applies signum to matrix elements.

sin

  • (sin vector)

Applies sin to matrix elements.

sinc

  • (sinc vector)

Applies sinc to matrix elements.

singular-values

  • (singular-values A)

Returuns singular values of the matrix as sqrt of eigenvalues of A^T * A matrix.

singular?

  • (singular? mat)

Returns singularity of the matrix

sinh

  • (sinh vector)

Applies sinh to matrix elements.

solve

  • (solve A b)

Solve linear equation Ax=b, if decomposition is provided, decomposition is used.

Some decompositions solve using least squares method.

sq

  • (sq vector)

Applies sq to matrix elements.

sqrt

  • (sqrt vector)

Applies sqrt to matrix elements.

standardize

  • (standardize A)
  • (standardize A rows?)

Normalizes columns (or rows) to have mean = 0 and stddev = 1

sub

  • (sub A)
  • (sub A B)

Subracts matrices, C=A-B.

sv-decomposition

  • (sv-decomposition mat)

Performs Singular Value Decomposition (SVD).

A = U x S x VT

Solver minimizes using least squares method.

Components, access with decomposition-component function:

  • :S, :U, :UT, :V :VT - matrices
  • :singular-values - vector of singular values
  • :info
    • :condition-number
    • :inv-condition-number
    • :norm - L2 norm
    • :rank - effective numerical rank
  • coviariance-fn - convariance function, returns covariance V x J x VT, where J is inverse of squares of singular values. When min-sv argument is provided, ignores singular values lower than its value.

Can be used as input for solve, inverse and singular? functions.

symmetric?

  • (symmetric? A)
  • (symmetric? A tolerance)

Checks if matrix is symmetric

tan

  • (tan vector)

Applies tan to matrix elements.

tanh

  • (tanh vector)

Applies tanh to matrix elements.

tmulm

  • (tmulm A B)

Transposes and multiplies, C=A^TxB

tmulmt

  • (tmulmt A B)

Transposes both and multiplies, C=ATxBT

trace

  • (trace A)

Returns trace of the matrix (sum of diagonal elements)

transpose

  • (transpose A)

Transposes matrix, C=A^T

trunc

  • (trunc vector)

Applies trunc to matrix elements.

vtmul

  • (vtmul A v)

Multiplies transposed vector by matrix, C=v^T A

xlogx

  • (xlogx vector)

Applies xlogx to matrix elements.

zero

  • (zero rows cols real-matrix?)
  • (zero size real-matrix?)
  • (zero size)

Creates zero matrix for given size.