module Geode::CommonMatrix(T, M, N)

Overview

Common functionality across all matrix types.

This type primarily serves as a means to unify MatrixMxN(T) and Matrix(T, M, N) types.

There are two indexing schemes for matrices. The first is two-dimension indexing, which is standard for matrix operations. It takes two indices - i and j. i refers to the row index and ranges from 0 to M - 1. j refers to the column index and ranges from 0 to N - 1. Methods with indices in the name use this indexing scheme.

The second is flat, one-dimension indexing. It takes a single index and ranges from 0 to (M * N) - 1. Standard Crystal library types such as Indexable use this indexing scheme. To avoid confusion, this module specifies the flat index as index instead of i.

Unless noted otherwise, all operations are in row-major order.

Included Modules

Direct including types

Defined in:

geode/matrices/common.cr

Instance Method Summary

Instance methods inherited from module Geode::MatrixVectors(M, N)

&*(vector : CommonVector(U, P)) : CommonVector forall U, P &*, *(vector : CommonVector(U, P)) : CommonVector forall U, P *, column? column?, row? row?, to_vector : CommonVector to_vector

Instance methods inherited from module Geode::MatrixOperations(M, N)

&*(scalar : Number) : CommonMatrix &*, &+(other : CommonMatrix(T, M, N)) : CommonMatrix forall T &+, &-(other : CommonMatrix(T, M, N)) : CommonMatrix forall T &-, *(scalar : Number) : CommonMatrix *, +(other : CommonMatrix(T, M, N)) : CommonMatrix forall T +, -(other : CommonMatrix(T, M, N)) : CommonMatrix forall T
- : self
-
, /(scalar : Number) : CommonMatrix /, //(scalar : Number) : CommonMatrix //, abs : self abs, abs2 : self abs2, ceil : self ceil, clamp(min : CommonMatrix(T, M, N), max : CommonMatrix(T, M, N)) : CommonMatrix forall T
clamp(min, max) : CommonMatrix
clamp(range : Range(CommonMatrix(T, M, N), CommonMatrix(T, M, N))) : CommonMatrix forall T
clamp(range : Range) : CommonMatrix
clamp
, edge(edge : CommonMatrix(T, M, N)) : self forall T
edge(edge) : self
edge
, floor : self floor, fraction : self fraction, lerp(other : CommonMatrix(T, M, N), t : Number) : CommonMatrix forall T lerp, round(mode : Number::RoundingMode = :ties_even) : self
round(digits : Number, base = 10, *, mode : Number::RoundingMode = :ties_even) : self
round
, scale(matrix : CommonMatrix(T, M, N)) : CommonMatrix forall T scale, scale!(matrix : CommonMatrix(T, M, N)) : CommonMatrix forall T scale!, sign : self sign

Instance methods inherited from module Geode::MatrixIterators(T, M, N)

each_column : Iterator(CommonVector(T, M)) each_column, each_column_with_index(offset = 0) : Iterator(Tuple(CommonVector(T, M), Int32)) each_column_with_index, each_indices : Iterator(Tuple(Int32, Int32)) each_indices, each_row : Iterator(CommonVector(T, N)) each_row, each_row_with_index(offset = 0) : Iterator(Tuple(CommonVector(T, N), Int32)) each_row_with_index, each_with_indices : Iterator(Tuple(T, Int32, Int32)) each_with_indices

Instance methods inherited from module Geode::MatrixComparison(M, N)

==(other : CommonMatrix(T, M, N)) forall T ==, compare(other : CommonMatrix(T, M, N)) : CommonMatrix(Int32, M, N) forall T compare, eq?(other : CommonMatrix(T, M, N)) : CommonMatrix(Bool, M, N) forall T eq?, ge?(other : CommonMatrix(T, M, N)) : CommonMatrix(Bool, M, N) forall T ge?, gt?(other : CommonMatrix(T, M, N)) : CommonMatrix(Bool, M, N) forall T gt?, le?(other : CommonMatrix(T, M, N)) : CommonMatrix(Bool, M, N) forall T le?, lt?(other : CommonMatrix(T, M, N)) : CommonMatrix(Bool, M, N) forall T lt?, near_zero?(tolerance) near_zero?, zero? zero?

Instance Method Detail

def [](i : Int, j : Int) : T #

Retrieves the element at the specified indices.

Raises an IndexError if the indices are outside the bounds of the matrix.

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

[View source]
def []?(i : Int, j : Int) : T? #

Retrieves the element at the specified indices.

Returns nil if the indices are outside the bounds of the matrix.

matrix = Matrix[[1, 2, 3], [4, 5, 6]]
matrix[1, 2]? # => 6
matrix[3, 3]? # => nil

[View source]
def column(j : Int) : CommonVector(T, M) #

Retrieves the column at the specified index.

Returns the elements as a vector. The vector will have a size equal to the number of rows in this matrix. If the column j is out of range, an IndexError is raised.

matrix = Matrix[[1, 2, 3], [4, 5, 6]]
matrix.column(1) # => (2, 5)
matrix.column(3) # IndexError

[View source]
def column?(j : Int) : CommonVector(T, M)? #

Retrieves the column at the specified index.

Returns the elements as a vector. The vector will have a size equal to the number of rows in this matrix. If the column j is out of range, nil is returned.

matrix = Matrix[[1, 2, 3], [4, 5, 6]]
matrix.column?(1) # => (2, 5)
matrix.column?(3) # => nil

[View source]
def columns : Int #

Returns the number of columns in this matrix.

Is always equal to the type argument N.


[View source]
def columns_at(*indices) : Tuple #

Retrieves multiple columns at the specified indices.

Returns the columns as vectors in a tuple. Each vector will have a size equal to the number of rows in this matrix. If a column index (j) from indices is out of range, an IndexError is raised.

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

[View source]
def each_column(& : CommonVector(T, M) -> _) #

Enumerates through each column of the matrix.

Yields a vector with the elements from the current column. The size of the vector is equal to the number of rows.

Matrix[[1, 2, 3], [4, 5, 6]].each_column do |column|
  puts column
end

# Output:
# (1, 4)
# (2, 5)
# (3, 6)

[View source]
def each_column_with_index(offset = 0, & : CommonVector(T, M), Int32 -> _) #

Enumerates through each column of the matrix.

Yields a vector with the elements from the current column and the column index. The size of the vector is equal to the number of rows. An offset can be specified, which is added to the yielded column index. This does not affect the starting column.

Matrix[[1, 2, 3], [4, 5, 6]].each_column_with_index(1) do |column, j|
  puts "#{j}: #{column}"
end

# Output:
# 1: (1, 4)
# 2: (2, 5)
# 3: (3, 6)

[View source]
def each_indices(& : Int32, Int32 -> _) #

Enumerates through each of the indices (not the elements).

Yields for each index combination in the matrix. Two arguments are supplied to the block: i and j.

Matrix[[0, 1], [2, 3]].each_indices do |i, j|
  puts "#{i}, #{j}"
end

# Output:
# 0, 0
# 0, 1
# 1, 0
# 1, 1

[View source]
def each_row(& : CommonVector(T, N) -> _) #

Enumerates through each row of the matrix.

Yields a vector with the elements from the current row. The size of the vector is equal to the number of columns.

Matrix[[1, 2, 3], [4, 5, 6]].each_row do |row|
  puts row
end

# Output:
# (1, 2, 3)
# (4, 5, 6)

[View source]
def each_row_with_index(offset = 0, & : CommonVector(T, N), Int32 -> _) #

Enumerates through each row of the matrix.

Yields a vector with the elements from the current row and the row index. The size of the vector is equal to the number of columns. An offset can be specified, which is added to the yielded row index. This does not affect the starting row.

Matrix[[1, 2, 3], [4, 5, 6]].each_row_with_index(1) do |row, i|
  puts "#{i}: #{row}"
end

# Output:
# 1: (1, 2, 3)
# 2: (4, 5, 6)

[View source]
def each_with_indices(& : T, Int32, Int32 -> _) #

Enumerates through each element and its indices.

Yields for each element in the matrix. Three arguments are supplied to the block: the element, i, and j.

Matrix[[0, 1], [2, 3]].each_with_indices do |e, i, j|
  puts "#{i}, #{j}: #{e}"
end

# Output:
# 0, 0: 0
# 0, 1: 1
# 1, 0: 2
# 1, 1: 3

[View source]
def inspect(io : IO) : Nil #

Produces a debugger-friendly string representation of the matrix.


[View source]
abstract def map(& : T -> U) : CommonMatrix forall U #

Returns a new matrix where elements are mapped by the given block.

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

[View source]
def map_with_index(offset = 0, & : T, Int32 -> U) : CommonMatrix(U, M, N) forall U #

Like #map, but the block gets the elements and its flat index as arguments.

Accepts an optional offset parameter, which to start the index at.

matrix = Matrix[[1, 2], [3, 4]]
matrix.map_with_index { |e, i| e * i }    # => [[0, 2], [6, 12]]
matrix.map_with_index(3) { |e, i| e + i } # => [[4, 6], [8, 10]]

[View source]
def map_with_indices(& : T, Int32, Int32 -> U) : CommonMatrix(U, M, N) forall U #

Like #map, but the block gets the elements and its indices as arguments.

matrix = Matrix[[1, 2], [3, 4]]
matrix.map_with_indices { |e, i, j| e * i + j } # => [[0, 1], [3, 5]]

[View source]
def row(i : Int) : CommonVector(T, N) #

Retrieves the row at the specified index.

Returns the elements as a vector. The vector will have a size equal to the number of columns in this matrix. If the row i is out of range, an IndexError is raised.

matrix = Matrix[[1, 2, 3], [4, 5, 6]]
matrix.row(1) # => (4, 5, 6)
matrix.row(2) # IndexError

[View source]
def row?(i : Int) : CommonVector(T, N)? #

Retrieves the row at the specified index.

Returns the elements as a vector. The vector will have a size equal to the number of columns in this matrix. If the row i is out of range, nil is returned.

matrix = Matrix[[1, 2, 3], [4, 5, 6]]
matrix.row?(1) # => (4, 5, 6)
matrix.row?(2) # => nil

[View source]
def rows : Int #

Returns the number of rows in this matrix.

Is always equal to the type argument M.


[View source]
def rows_at(*indices) : Tuple #

Retrieves multiple rows at the specified indices.

Returns the rows as vectors in a tuple. Each vector will have a size equal to the number of columns in this matrix. If a row index (i) from indices is out of range, an IndexError is raised.

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

[View source]
def size #

Returns the number of elements in this matrix.


[View source]
def square? #

Checks if this matrix is square.

Returns true if M equals N.


[View source]
def to_columns : Array #

Converts the matrix to an array of columns.

Each element in the array is a column vector. The vectors will have a size equal to the number of rows in this matrix.

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

[View source]
def to_rows : Array #

Converts the matrix to an array of rows.

Each element in the array is a row vector. The vectors will have a size equal to the number of columns in this matrix.

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

[View source]
def to_s(io : IO) : Nil #

Produces a string representation of the matrix.

The format is: [[a_00, a_01], [a_10, a_11]] but with the corresponding number of elements.


[View source]
def unsafe_fetch(i : Int, j : Int) : T #

Retrieves the scalar value of the component at the given indices, 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 i and j are certain to be in bounds.


[View source]
def unsafe_fetch_column(j : Int) : CommonVector(T, M) #

Retrieves the column at the specified index.

Returns the elements as a vector. The vector will have a size equal to the number of rows in this matrix. This method does not perform any bounds checks. It should only be used if the indices are guaranteed to be in bounds.

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

[View source]
def unsafe_fetch_row(i : Int) : CommonVector(T, N) #

Retrieves the row at the specified index.

Returns the elements as a vector. The vector will have a size equal to the number of columns in this matrix. This method does not perform any bounds checks. It should only be used if the indices are guaranteed to be in bounds.

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

[View source]
def zip_map(other : CommonMatrix(U, M, N), & : T, U -> V) : CommonMatrix(V, M, N) forall U, V #

Returns a new matrix by iterating through each element of this matrix and another.

m1 = Matrix[[1, 2], [3, 4]]
m2 = Matrix[[4, 3], [2, 1]]
m1.zip_map { |a, b| Math.min(a, b) } # => [[1, 2], [2, 1]]

[View source]