matrix

Matrices built off arrays. Matrix(rows, cols) holds a size; its methods build a new Matrix of that size each time and leave the original alone, so one Matrix can make as many as you like. Every method that builds or transforms returns a new Matrix, so calls chain: matrix.Matrix(2, 3).ones().transpose().

Oxigen
introduce matrix

mat := matrix.Matrix(4, 4)
ones := mat.ones()
zeros := mat.zeros()
r_mat := matrix.Matrix(4, 4).rand_int()
matrix.print_matrix(r_mat)

arr := [[0, 2], [2, 3]]
mat := matrix.Matrix(2, 2).init(arr)
transposed := mat.transpose()
dp := matrix.dot_product(mat, transposed)

A Matrix made from its size alone reads as all zeros, like init(), in the transformations.

Errors. Sizes that don't fit fail with <Error<size_mismatch>>; trace, determinant and inverse of a non-square matrix fail with <Error<not_square>>, and inverse of a matrix whose determinant is 0 fails with <Error<singular>>. Catch one with <type<Error> || <Value>>(...).

ItemSignatureReturns
initmat.init(value?)Matrix
zeros_matrixmat.zeros_matrix()Matrix
ones_matrixmat.ones_matrix()Matrix
zerosmat.zeros()Matrix
onesmat.ones()Matrix
random_matrixmat.random_matrix(random_value)Matrix
randomized_matrixmat.randomized_matrix(value_type)Matrix
rand_intmat.rand_int()Matrix
to_arraymat.to_array()array of rows
shapemat.shape()[rows, cols]
transposemat.transpose()Matrix
flattenmat.flatten()array
reshapemat.reshape(new_row_size, new_col_size)Matrix
scalemat.scale(k)Matrix
get_rowmat.get_row(row)array
get_colmat.get_col(col)array
diagonalmat.diagonal()array
tracemat.trace()number
determinantmat.determinant()number
inversemat.inverse()Matrix
identityidentity(size)Matrix
addadd(mat1, mat2)Matrix
subtractsubtract(mat1, mat2)Matrix
multiplymultiply(mat1, mat2)Matrix
dot_productdot_product(mat1, mat2)Matrix
print_matrixprint_matrix(matrix)None

#Struct: Matrix

FieldTypeContents
row_sizeintnumber of rows
col_sizeintnumber of columns
dataarray or Nonethe values, set by init(arr); left off, it is None
Oxigen
mat := matrix.Matrix(2, 3)
mat := matrix.Matrix(row_size=2, col_size=3)

#Methods

#mat.init(value?)

A new row_size x col_size Matrix with every value set to value, or to 0 when value is left off.

Oxigen
mat := matrix.Matrix(2, 3)
println(mat.init().to_array())    // [[0, 0, 0], [0, 0, 0]]
println(mat.init(7).to_array())   // [[7, 7, 7], [7, 7, 7]]

Given an array of rows, init holds those values instead. The array must be exactly row_size x col_size, and its rows are copied, so changing the array later doesn't change the matrix.

Oxigen
mat := matrix.Matrix(2, 2).init([[0, 2], [2, 3]])
println(mat.shape())                       // [2, 2]
matrix.Matrix(4, 4).init([[0, 2], [2, 3]])   // fails: Array doesn't fit the matrix: expected 4x4

#mat.zeros_matrix()

mat.init(0).

Oxigen
println(matrix.Matrix(2, 2).zeros_matrix().to_array())   // [[0, 0], [0, 0]]

#mat.ones_matrix()

mat.init(1).

Oxigen
println(matrix.Matrix(2, 2).ones_matrix().to_array())   // [[1, 1], [1, 1]]

#mat.zeros()

Same as mat.zeros_matrix().

Oxigen
zeros_matrix := matrix.Matrix(4, 4).zeros()

#mat.ones()

Same as mat.ones_matrix().

Oxigen
mat := matrix.Matrix(4, 4)
ones := mat.ones()

#mat.random_matrix(random_value)

mat.init(random_value): every value is random_value, an int or a float.

Oxigen
println(matrix.Matrix(1, 3).random_matrix(5).to_array())   // [[5, 5, 5]]

#mat.randomized_matrix(value_type)

A matrix of random values. value_type defaults to "int", giving integers from 0 to 1000; "float" gives floats in [0.0, 1.0). Built on the random module, so random.seed makes it repeatable.

Oxigen
println(matrix.Matrix(2, 2).randomized_matrix().to_array())          // [[493, 412], [57, 655]]
println(matrix.Matrix(1, 2).randomized_matrix("float").to_array())   // [[0.383..., 0.859...]]

#mat.rand_int()

Same as mat.randomized_matrix("int").

Oxigen
r_mat := matrix.Matrix(4, 4).rand_int()

#Transformations

#mat.to_array()

The values as an array of rows, copied. For a Matrix made from its size alone, this is all zeros.

Oxigen
println(matrix.Matrix(2, 2).init([[0, 2], [2, 3]]).to_array())   // [[0, 2], [2, 3]]
println(matrix.Matrix(1, 2).to_array())                          // [[0, 0]]

#mat.shape()

[row_size, col_size].

Oxigen
println(matrix.Matrix(2, 3).shape())   // [2, 3]

#mat.transpose()

Rows become columns, so a 2 x 3 matrix becomes 3 x 2.

Oxigen
transposed := matrix.Matrix(2, 3).init([[1, 2, 3], [4, 5, 6]]).transpose()
println(transposed.shape())        // [3, 2]
println(transposed.to_array())     // [[1, 4], [2, 5], [3, 6]]

#mat.flatten()

Every value in one array, row by row.

Oxigen
println(matrix.Matrix(2, 2).init([[0, 2], [2, 3]]).flatten())   // [0, 2, 2, 3]

#mat.reshape(new_row_size, new_col_size)

The same values, row by row, in a new size. The new size must hold exactly as many values as the old one.

Oxigen
mat := matrix.Matrix(2, 3).init([[1, 2, 3], [4, 5, 6]])
println(mat.reshape(3, 2).to_array())   // [[1, 2], [3, 4], [5, 6]]
mat.reshape(4, 2)   // fails: Can't reshape 2x3 into 4x2: expected 6 values, got 8

#mat.scale(k)

Every value times k.

Oxigen
println(matrix.Matrix(2, 2).init([[1, 2], [3, 4]]).scale(2).to_array())   // [[2, 4], [6, 8]]

#mat.get_row(row)

Row row, copied.

Oxigen
println(matrix.Matrix(2, 2).init([[0, 2], [2, 3]]).get_row(1))   // [2, 3]

#mat.get_col(col)

Column col.

Oxigen
println(matrix.Matrix(2, 2).init([[0, 2], [2, 3]]).get_col(1))   // [2, 3]

#mat.diagonal()

The values where the row equals the column, from the top left.

Oxigen
println(matrix.Matrix(2, 3).init([[1, 2, 3], [4, 5, 6]]).diagonal())   // [1, 5]

#mat.trace()

The sum of the diagonal. The matrix must be square.

Oxigen
println(matrix.Matrix(2, 2).init([[0, 2], [2, 3]]).trace())   // 3

#mat.determinant()

The determinant. The matrix must be square. A matrix of ints gives an exact int.

Oxigen
println(matrix.Matrix(2, 2).init([[0, 2], [2, 3]]).determinant())   // -4

#mat.inverse()

The inverse, as floats: dot_product(mat, mat.inverse()) is the identity. The matrix must be square and its determinant not 0.

Oxigen
mat := matrix.Matrix(2, 2).init([[0, 2], [2, 3]])
println(mat.inverse().to_array())   // [[-0.75, 0.5], [0.5, 0]]
matrix.Matrix(2, 2).init([[1, 2], [2, 4]]).inverse()   // fails: Matrix has no inverse: its determinant is 0

#Module functions

#identity(size)

The size x size identity matrix: 1 on the diagonal, 0 elsewhere.

Oxigen
println(matrix.identity(2).to_array())   // [[1, 0], [0, 1]]

#add(mat1, mat2)

Value by value. Both must be the same size.

Oxigen
mat1 := matrix.Matrix(2, 2).init([[1, 2], [3, 4]])
mat2 := matrix.Matrix(2, 2).init([[5, 6], [7, 8]])
println(matrix.add(mat1, mat2).to_array())   // [[6, 8], [10, 12]]

#subtract(mat1, mat2)

Value by value, mat1 minus mat2. Both must be the same size.

Oxigen
println(matrix.subtract(mat2, mat1).to_array())   // [[4, 4], [4, 4]]

#multiply(mat1, mat2)

Value by value. Both must be the same size. For the matrix product, use dot_product.

Oxigen
println(matrix.multiply(mat1, mat2).to_array())   // [[5, 12], [21, 32]]

#dot_product(mat1, mat2)

The matrix product: an n x m and an m x p give an n x p. mat1's columns must equal mat2's rows.

Oxigen
mat1 := matrix.Matrix(2, 3).init([[1, 2, 3], [4, 5, 6]])
mat2 := matrix.Matrix(3, 1).init([[1], [0], [2]])
println(matrix.dot_product(mat1, mat2).to_array())   // [[7], [16]]

#Output

Prints a matrix one row per line. matrix may be an array of rows or a Matrix.

Oxigen
matrix.print_matrix(matrix.Matrix(2, 2).ones())
// [1, 1]
// [1, 1]
matrix.print_matrix(matrix.Matrix(2, 2).init([[0, 2], [2, 3]]).transpose())
// [0, 2]
// [2, 3]