# struct Geode::Matrix(T, M, N)

## Overview

Generic matrix type. Provides a rectangular array of scalars of the same type.

T is the scalar type. M and N are positive integers indicating the number of rows and columns respectively. Indices i and j refer to the zero-based row and column index respectively. Unless noted otherwise, all operations are in row-major order.

## Defined in:

geode/matrices/matrix.cr

## Class Method Summary

• .[](*rows)

Constructs a matrix with existing elements.

## Macro Summary

• [](*rows)

Constructs a matrix with existing elements.

## Constructor Detail

def self.identity : self #

Creates an identity matrix.

An identity matrix is a square matrix with ones along the diagonal and zeroes elsewhere. Raises a compilation error if M and N are not the same (producing a square matrix).

Matrix(Int32, 3, 3).identity
# => [[1, 0, 0], [0, 1, 0], [0, 0, 1]]

def self.new(matrix : CommonMatrix(T, M, N)) #

Copies contents from another matrix.

def self.new(&) #

Creates a new matrix by iterating through each element.

Yields the indices (i and j) for the matrix element. The block should return the value to use for the corresponding element.

Matrix(Int32, 3, 3).new { |i, j| i * 10 + j }
# => [[0, 1, 2], [10, 11, 12], [20, 21, 22]]

def self.new(rows : Indexable(Indexable(T))) #

Creates a new matrix from nested collections.

The size of rows must be equal to the type argument M. Each row of elements in rows must have a size equal to the type argument N.

Matrix(Int32, 3, 2).new([[10, 20], [30, 40], [50, 60]])
# => [[10, 20], [30, 40], [50, 60]]
Matrix(Int32, 3, 2).new({{10, 20}, {30, 40}, {50, 60}})
# => [[10, 20], [30, 40], [50, 60]]

def self.new(elements : Indexable(T)) #

Creates a new matrix from a flat collection of elements.

The size of elements must be equal to M x N. Items in elements are consumed in row-major order.

Matrix(Int32, 3, 2).new([1, 2, 3, 4, 5, 6])
# => [[1, 2], [3, 4], [5, 6]]

def self.new(scalar : T) : self #

Creates a new matrix with the diagonal elements set to a scalar value.

The main diagonal will be filled with scalar. All other elements will be zeroes. Raises a compilation error if M and N are not the same (producing a square matrix).

Matrix(Int32, 3, 3).new(5)
# => [[5, 0, 0], [0, 5, 0], [0, 0, 5]]

def self.zero : self #

Creates a matrix filled with zeroes.

Matrix(Int32, 2, 2).zero
# => [[0, 0], [0, 0]]

## Class Method Detail

def self.[](*rows) #

Constructs a matrix with existing elements.

The type of the elements is specified by the type parameter. Each value is cast to the type T.

Matrix(Float32, 3, 3)[[1, 2, 3], [4, 5, 6], [7, 8, 9]]
# => [[1.0, 2.0, 3.0], [4.0, 5.0, 6.0], [7.0, 8.0, 9.0]]

## Instance Method Detail

def &*(other : CommonMatrix(U, N, P)) : Matrix forall U, P #

Multiplies this matrix by another.

The other matrix's row count (M) must be equal to this matrix's column count (N). Produces a new matrix with the row count from this matrix and the column count from other. Matrices can be of any size and type as long as this condition is met.

Values will wrap instead of overflowing and raising an error.

m1 = Matrix[[1, 2, 3], [4, 5, 6]]
m2 = Matrix[[1, 2], [3, 4], [5, 6]]
m1 &* m2 # => [[28, 29], [49, 64]]

def *(other : CommonMatrix(U, N, P)) : Matrix forall U, P #

Multiplies this matrix by another.

The other matrix's row count (M) must be equal to this matrix's column count (N). Produces a new matrix with the row count from this matrix and the column count from other. Matrices can be of any size and type as long as this condition is met.

m1 = Matrix[[1, 2, 3], [4, 5, 6]]
m2 = Matrix[[1, 2], [3, 4], [5, 6]]
m1 * m2 # => [[28, 29], [49, 64]]

def map(& : T -> U) : Matrix forall U #

Returns a new matrix with elements mapped by the given block.

matrix = Matrix[[1, 2], [3, 4], [5, 6]]
matrix.map { |e| e * 2 } # => [[2, 4], [6, 8], [10, 12]]

def sub(i : Int, j : Int) : CommonMatrix #

Returns a smaller matrix by removing a row and column.

The row indicated by i and the column indicated by j are removed in the resulting matrix. This method can only be called if the matrix has two or more rows and columns.

matrix = Matrix[[1, 2, 3], [4, 5, 6], [7, 8, 9]]
matrix.sub(1, 1) # => [[1, 3], [7, 9]]

def to_slice : Slice(T) #

Returns a slice that points to the elements in this matrix.

def to_unsafe : Pointer(T) #

Returns a pointer to the data for this matrix.

The elements are tightly packed and ordered consecutively in memory.

def transpose : Matrix(T, N, M) #

Returns a new matrix that is transposed from this one.

matrix = Matrix[[1, 2, 3], [4, 5, 6]]
matrix.transpose # => [[1, 4], [2, 5], [3, 6]]

def unsafe_fetch(index : Int) #

Retrieves the scalar value of the component at the given index, without checking size boundaries.

End-users should never invoke this method directly. Instead, methods like #[] and #[]? should be used.

This method should only be directly invoked if the index is certain to be in bounds.

## Macro Detail

macro [](*rows) #

Constructs a matrix with existing elements.

The type of the components is derived from the type of each argument. The size of the vector is determined by the number of components.

Matrix[[1, 2, 3], [4, 5, 6], [7, 8, 9]]
# => [[1, 2, 3], [4, 5, 6], [7, 8, 9]]