matrex v0.6.2 Matrex View Source
Performs fast operations on matrices using native C code and CBLAS library.
Access behaviour
Access behaviour is partly implemented for Matrex, so you can do:
iex> m = Matrex.magic(3)
#Matrex[3×3]
┌ ┐
│ 8.0 1.0 6.0 │
│ 3.0 5.0 7.0 │
│ 4.0 9.0 2.0 │
└ ┘
iex> m[2][3]
7.0
Or even:
iex> m[1..2]
#Matrex[2×3]
┌ ┐
│ 8.0 1.0 6.0 │
│ 3.0 5.0 7.0 │
└ ┘
There are also several shortcuts for getting dimensions of matrix:
iex> m[:rows]
3
iex> m[:size]
{3, 3}
calculating maximum value of the whole matrix:
iex> m[:max]
9.0
or just one of it’s rows:
iex> m[2][:max]
7.0
calculating one-based index of the maximum element for the whole matrix:
iex> m[:argmax]
8
and a row:
iex> m[2][:argmax]
3
Inspect protocol
Matrex implements Inspect
and looks nice in your console:
Math operators overloading
Matrex.Operators
module redefines Kernel
math operators (+, -, *, / <|>) and
defines some convenience functions, so you can write calculations code in more natural way.
It should be used with great caution. We suggest using it only inside specific functions
and only for increased readability, because using Matrex
module functions, especially
ones which do two or more operations at one call, are 2-3 times faster.
Example
def lr_cost_fun_ops(%Matrex{} = theta, {%Matrex{} = x, %Matrex{} = y, lambda} = _params)
when is_number(lambda) do
# Turn off original operators
import Kernel, except: [-: 1, +: 2, -: 2, *: 2, /: 2, <|>: 2]
import Matrex.Operators
import Matrex
m = y[:rows]
h = sigmoid(x * theta)
l = ones(size(theta)) |> set(1, 1, 0.0)
j = (-t(y) * log(h) - t(1 - y) * log(1 - h) + lambda / 2 * t(l) * pow2(theta)) / m
grad = (t(x) * (h - y) + (theta <|> l) * lambda) / m
{scalar(j), grad}
end
The same function, coded with module methods calls (2.5 times faster):
def lr_cost_fun(%Matrex{} = theta, {%Matrex{} = x, %Matrex{} = y, lambda} = _params)
when is_number(lambda) do
m = y[:rows]
h = Matrex.dot_and_apply(x, theta, :sigmoid)
l = Matrex.ones(theta[:rows], theta[:cols]) |> Matrex.set(1, 1, 0)
regularization =
Matrex.dot_tn(l, Matrex.square(theta))
|> Matrex.scalar()
|> Kernel.*(lambda / (2 * m))
j =
y
|> Matrex.dot_tn(Matrex.apply(h, :log), -1)
|> Matrex.substract(
Matrex.dot_tn(
Matrex.substract(1, y),
Matrex.apply(Matrex.substract(1, h), :log)
)
)
|> Matrex.scalar()
|> (fn
NaN -> NaN
x -> x / m + regularization
end).()
grad =
x
|> Matrex.dot_tn(Matrex.substract(h, y))
|> Matrex.add(Matrex.multiply(theta, l), 1.0, lambda)
|> Matrex.divide(m)
{j, grad}
end
Enumerable protocol
Matrex implements Enumerable
, so, all kinds of Enum
functions are applicable:
iex> Enum.member?(m, 2.0)
true
iex> Enum.count(m)
9
iex> Enum.sum(m)
45
For functions, that exist both in Enum
and in Matrex
it’s preferred to use Matrex
version, beacuse it’s usually much, much faster. I.e., for 1 000 x 1 000 matrix Matrex.sum/1
and Matrex.to_list/1
are 438 and 41 times faster, respectively, than their Enum
counterparts.
Saving and loading matrix
You can save/load matrix with native binary file format (extra fast) and CSV (slow, especially on large matrices).
Matrex CSV format is compatible with GNU Octave CSV output, so you can use it to exchange data between two systems.
Example
iex> Matrex.random(5) |> Matrex.save("rand.mtx")
:ok
iex> Matrex.load("rand.mtx")
#Matrex[5×5]
┌ ┐
│ 0.05624 0.78819 0.29995 0.25654 0.94082 │
│ 0.50225 0.22923 0.31941 0.3329 0.78058 │
│ 0.81769 0.66448 0.97414 0.08146 0.21654 │
│ 0.33411 0.59648 0.24786 0.27596 0.09082 │
│ 0.18673 0.18699 0.79753 0.08101 0.47516 │
└ ┘
iex> Matrex.magic(5) |> Matrex.divide(Matrex.eye(5)) |> Matrex.save("nan.csv")
:ok
iex> Matrex.load("nan.csv")
#Matrex[5×5]
┌ ┐
│ 16.0 ∞ ∞ ∞ ∞ │
│ ∞ 4.0 ∞ ∞ ∞ │
│ ∞ ∞ 12.0 ∞ ∞ │
│ ∞ ∞ ∞ 25.0 ∞ │
│ ∞ ∞ ∞ ∞ 8.0 │
└ ┘
NaN and Infinity
Float special values, like NaN
and Inf
live well inside matrices,
can be loaded from and saved to files.
But when getting them into Elixir they are transferred to NaN
,Inf
and NegInf
atoms,
because BEAM does not accept special values as valid floats.
iex> m = Matrex.eye(3)
#Matrex[3×3]
┌ ┐
│ 1.0 0.0 0.0 │
│ 0.0 1.0 0.0 │
│ 0.0 0.0 1.0 │
└ ┘
iex> n = Matrex.divide(m, Matrex.zeros(3))
#Matrex[3×3]
┌ ┐
│ ∞ NaN NaN │
│ NaN ∞ NaN │
│ NaN NaN ∞ │
└ ┘
iex> n[1][1]
Inf
iex> n[1][2]
NaN
Link to this section Summary
Functions
Adds scalar to matrix
Adds two matrices or scalar to each element of matrix. NIF
Applies given function to each element of the matrix and returns the matrex of results. NIF
Applies function to elements of two matrices and returns matrix of function results
Returns one-based index of the biggest element. NIF
Get element of a matrix at given one-based (row, column) position
Get column of matrix as matrix (vector) in matrex form. One-based
Get column of matrix as list of floats. One-based, NIF
Concatenate list of matrices along columns
Concatenate two matrices along rows or columns. NIF
Checks if given element exists in the matrix
Divides two matrices element-wise or matrix by scalar or scalar by matrix. NIF through find/2
Matrix multiplication. NIF, via cblas_sgemm()
Matrix multiplication with addition of third matrix. NIF, via cblas_sgemm()
Computes dot product of two matrices, then applies math function to each element of the resulting matrix
Matrix multiplication where the second matrix needs to be transposed. NIF, via cblas_sgemm()
Matrix dot multiplication where the first matrix needs to be transposed. NIF, via cblas_sgemm()
Create eye (identity) square matrix of given size
Create square matrix filled with given value. Inlined
Create matrix filled with given value. NIF
Find position of the first occurence of the given value in the matrix. NIF
Return first element of a matrix
Prints monochrome or color heatmap of the matrix to the console
An alias for eye/1
Displays a visualization of the matrix
Load matrex from file
Creates “magic” n*n matrix, where sums of all dimensions are equal
Maximum element in a matrix. NIF
Returns maximum finite element of a matrex. NIF
Minimum element in a matrix. NIF
Returns minimum finite element of a matrex. NIF
Elementwise multiplication of two matrices or matrix and a scalar. NIF
Negates each element of the matrix. NIF
Creates new matrix from list of lists or text representation (compatible with MathLab/Octave)
Creates new matrix with values provided by the given function
Bring all values of matrix into [0, 1] range. NIF
Create matrex of ones of square dimensions or consuming output of size/1
function
Create matrix filled with ones
Create square matrix of random floats
Create matrix of random floats in [0, 1] range. NIF
Reshapes list of values into a matrix of given size or changes the shape of existing matrix
Resize matrix by scaling its dimenson with scale
. NIF
Get row of matrix as matrix (vector) in matrex form. One-based
Return matrix row as list by one-based index
Saves matrex into file
Transfer one-element matrix to a scalar value
Set element of matrix at the specified position (one-based) to new value
Set column of a matrix to the values from the given 1-column matrix. NIF
Return size of matrix as {rows, cols}
Produces element-wise squared matrix. NIF through multiply/4
Returns submatrix for a given matrix. NIF
Substracts two matrices or matrix from scalar element-wise. NIF
Substracts the second matrix from the first. Inlined
Sums all elements. NIF
Converts to flat list. NIF
Converts to list of lists. NIF
Convert any matrix m×n to a row matrix 1×(m*n)
Transposes a matrix. NIF
Create square matrix of size size
rows × size
columns, filled with zeros. Inlined
Create matrix of zeros of the specified size. NIF, using memset()
Link to this section Types
Link to this section Functions
Adds scalar to matrix.
See Matrex.add/4
for details.
Adds two matrices or scalar to each element of matrix. NIF.
Can optionally scale any of the two matrices.
C = αA + βB
Raises ErlangError
if matrices’ sizes do not match.
Examples
iex> Matrex.add(Matrex.new([[1,2,3],[4,5,6]]), Matrex.new([[7,8,9],[10,11,12]]))
#Matrex[2×3]
┌ ┐
│ 8.0 10.0 12.0 │
│ 14.0 16.0 18.0 │
└ ┘
Adding with scalar:
iex> m = Matrex.magic(3)
#Matrex[3×3]
┌ ┐
│ 8.0 1.0 6.0 │
│ 3.0 5.0 7.0 │
│ 4.0 9.0 2.0 │
└ ┘
iex> Matrex.add(m, 1)
#Matrex[3×3]
┌ ┐
│ 9.0 2.0 7.0 │
│ 4.0 6.0 8.0 │
│ 5.0 10.0 3.0 │
└ ┘
With scaling each matrix:
iex> Matrex.add(Matrex.new("1 2 3; 4 5 6"), Matrex.new("3 2 1; 6 5 4"), 2.0, 3.0)
#Matrex[2×3]
┌ ┐
│ 11.0 10.0 9.0 │
│ 26.0 25.0 24.0 │
└ ┘
Applies given function to each element of the matrix and returns the matrex of results. NIF.
If second argument is an atom, then applies C language math function.
Example
iex> Matrex.magic(5) |> Matrex.apply(:sigmoid)
#Matrex[5×5]
┌ ┐
│-0.95766-0.53283 0.28366 0.7539 0.13674 │
│-0.99996-0.65364 0.96017 0.90745 0.40808 │
│-0.98999-0.83907 0.84385 0.9887-0.54773 │
│-0.91113 0.00443 0.66032 0.9912-0.41615 │
│-0.75969-0.27516 0.42418 0.5403 -0.1455 │
└ ┘
The following math functions from C
:exp, :exp2, :sigmoid, :expm1, :log, :log2, :sqrt, :cbrt, :ceil, :floor, :truncate, :round,
:abs, :sin, :cos, :tan, :asin, :acos, :atan, :sinh, :cosh, :tanh, :asinh, :acosh, :atanh,
:erf, :erfc, :tgamma, :lgamm
If second argument is a function that takes one argument, then this function receives the element of the matrix.
Example
iex> Matrex.magic(5) |> Matrex.apply(&:math.cos/1)
#Matrex[5×5]
┌ ┐
│-0.95766-0.53283 0.28366 0.7539 0.13674 │
│-0.99996-0.65364 0.96017 0.90745 0.40808 │
│-0.98999-0.83907 0.84385 0.9887-0.54773 │
│-0.91113 0.00443 0.66032 0.9912-0.41615 │
│-0.75969-0.27516 0.42418 0.5403 -0.1455 │
└ ┘
If second argument is a function that takes two arguments, then this function receives the element of the matrix and its one-based index.
Example
iex> Matrex.ones(5) |> Matrex.apply(fn val, index -> val + index end)
#Matrex[5×5]
┌ ┐
│ 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 18.0 19.0 20.0 21.0 │
│ 22.0 23.0 24.0 25.0 26.0 │
└ ┘
If second argument is a function that takes three arguments, then this function receives the element of the matrix one-based row index and one-based column index of the element.
Example
iex> Matrex.ones(5) |> Matrex.apply(fn val, row, col -> val + row + col end)
#Matrex[5×5]
┌ ┐
│ 3.0 4.0 5.0 6.0 7.0 │
│ 4.0 5.0 6.0 7.0 8.0 │
│ 5.0 6.0 7.0 8.0 9.0 │
│ 6.0 7.0 8.0 9.0 10.0 │
│ 7.0 8.0 9.0 10.0 11.0 │
└ ┘
Applies function to elements of two matrices and returns matrix of function results.
Matrices must be of the same size.
Example
iex(11)> Matrex.apply(Matrex.random(5), Matrex.random(5), fn x1, x2 -> min(x1, x2) end)
#Matrex[5×5]
┌ ┐
│ 0.02025 0.15055 0.69177 0.08159 0.07237 │
│ 0.03252 0.14805 0.03627 0.1733 0.58721 │
│ 0.10865 0.49192 0.12166 0.0573 0.66522 │
│ 0.13642 0.23838 0.14403 0.57151 0.12359 │
│ 0.12877 0.12745 0.10933 0.27281 0.35957 │
└ ┘
Returns one-based index of the biggest element. NIF.
There is also matrex[:argmax]
shortcut for this function.
Example
iex> m = Matrex.magic(3)
#Matrex[3×3]
┌ ┐
│ 8.0 1.0 6.0 │
│ 3.0 5.0 7.0 │
│ 4.0 9.0 2.0 │
└ ┘
iex> Matrex.argmax(m)
7
Get element of a matrix at given one-based (row, column) position.
Example
iex> m = Matrex.magic(3)
#Matrex[3×3]
┌ ┐
│ 8.0 1.0 6.0 │
│ 3.0 5.0 7.0 │
│ 4.0 9.0 2.0 │
└ ┘
iex> Matrex.at(m, 3, 2)
9.0
You can use Access
behaviour square brackets for the same purpose,
but it will be slower:
iex> m[3][2]
9.0
Get column of matrix as matrix (vector) in matrex form. One-based.
Example
iex> m = Matrex.magic(3)
#Matrex[3×3]
┌ ┐
│ 8.0 1.0 6.0 │
│ 3.0 5.0 7.0 │
│ 4.0 9.0 2.0 │
└ ┘
iex> Matrex.column(m, 2)
#Matrex[3×1]
┌ ┐
│ 1.0 │
│ 5.0 │
│ 9.0 │
└ ┘
Get column of matrix as list of floats. One-based, NIF.
Example
iex> m = Matrex.magic(3)
#Matrex[3×3]
┌ ┐
│ 8.0 1.0 6.0 │
│ 3.0 5.0 7.0 │
│ 4.0 9.0 2.0 │
└ ┘
iex> Matrex.column_to_list(m, 3)
[6.0, 7.0, 2.0]
Concatenate list of matrices along columns.
The number of rows must be equal.
Example
iex> Matrex.concat([Matrex.fill(2, 0), Matrex.fill(2, 1), Matrex.fill(2, 2)]) #Matrex[2×6]
┌ ┐
│ 0.0 0.0 1.0 1.0 2.0 2.0 │
│ 0.0 0.0 1.0 1.0 2.0 2.0 │
└ ┘
Concatenate two matrices along rows or columns. NIF.
The number of rows or columns must be equal.
Examples
iex> m1 = Matrex.new([[1, 2, 3], [4, 5, 6]])
#Matrex[2×3]
┌ ┐
│ 1.0 2.0 3.0 │
│ 4.0 5.0 6.0 │
└ ┘
iex> m2 = Matrex.new([[7, 8, 9], [10, 11, 12]])
#Matrex[2×3]
┌ ┐
│ 7.0 8.0 9.0 │
│ 10.0 11.0 12.0 │
└ ┘
iex> Matrex.concat(m1, m2)
#Matrex[2×6]
┌ ┐
│ 1.0 2.0 3.0 7.0 8.0 9.0 │
│ 4.0 5.0 6.0 10.0 11.0 12.0 │
└ ┘
iex> Matrex.concat(m1, m2, :rows)
#Matrex[4×3]
┌ ┐
│ 1.0 2.0 3.0 │
│ 4.0 5.0 6.0 │
│ 7.0 8.0 9.0 │
│ 10.0 11.0 12.0 │
└ ┘
Checks if given element exists in the matrix.
Example
iex> m = Matrex.new("1 NaN 3; Inf 10 23")
#Matrex[2×3]
┌ ┐
│ 1.0 NaN 3.0 │
│ ∞ 10.0 23.0 │
└ ┘
iex> Matrex.contains?(m, 1.0)
true
iex> Matrex.contains?(m, NaN)
true
iex> Matrex.contains?(m, 9)
false
Divides two matrices element-wise or matrix by scalar or scalar by matrix. NIF through find/2
.
Raises ErlangError
if matrices’ sizes do not match.
Examples
iex> Matrex.new([[10, 20, 25], [8, 9, 4]])
...> |> Matrex.divide(Matrex.new([[5, 10, 5], [4, 3, 4]]))
#Matrex[2×3]
┌ ┐
│ 2.0 2.0 5.0 │
│ 2.0 3.0 1.0 │
└ ┘
iex> Matrex.new([[10, 20, 25], [8, 9, 4]])
...> |> Matrex.divide(2)
#Matrex[2×3]
┌ ┐
│ 5.0 10.0 12.5 │
│ 4.0 4.5 2.0 │
└ ┘
iex> Matrex.divide(100, Matrex.new([[10, 20, 25], [8, 16, 4]]))
#Matrex[2×3]
┌ ┐
│ 10.0 5.0 4.0 │
│ 12.5 6.25 25.0 │
└ ┘
Matrix multiplication. NIF, via cblas_sgemm()
.
Number of columns of the first matrix must be equal to the number of rows of the second matrix.
Raises ErlangError
if matrices’ sizes do not match.
Example
iex> Matrex.new([[1, 2, 3], [4, 5, 6]]) |>
...> Matrex.dot(Matrex.new([[1, 2], [3, 4], [5, 6]]))
#Matrex[2×2]
┌ ┐
│ 22.0 28.0 │
│ 49.0 64.0 │
└ ┘
Matrix multiplication with addition of third matrix. NIF, via cblas_sgemm()
.
Raises ErlangError
if matrices’ sizes do not match.
Example
iex> Matrex.new([[1, 2, 3], [4, 5, 6]]) |>
...> Matrex.dot_and_add(Matrex.new([[1, 2], [3, 4], [5, 6]]), Matrex.new([[1, 2], [3, 4]]))
#Matrex[2×2]
┌ ┐
│ 23.0 30.0 │
│ 52.0 68.0 │
└ ┘
Computes dot product of two matrices, then applies math function to each element of the resulting matrix.
Example
iex> Matrex.new([[1, 2, 3], [4, 5, 6]]) |>
...> Matrex.dot_and_add(Matrex.new([[1, 2], [3, 4], [5, 6]]), :sqrt)
#Matrex[2×2]
┌ ┐
│ 4.69042 5.2915 │
│ 7.0 8.0 │
└ ┘
Matrix multiplication where the second matrix needs to be transposed. NIF, via cblas_sgemm()
.
Raises ErlangError
if matrices’ sizes do not match.
Example
iex> Matrex.new([[1, 2, 3], [4, 5, 6]]) |>
...> Matrex.dot_nt(Matrex.new([[1, 3, 5], [2, 4, 6]]))
#Matrex[2×2]
┌ ┐
│ 22.0 28.0 │
│ 49.0 64.0 │
└ ┘
Matrix dot multiplication where the first matrix needs to be transposed. NIF, via cblas_sgemm()
.
The result is multiplied by scalar alpha
.
Raises ErlangError
if matrices’ sizes do not match.
Example
iex> Matrex.new([[1, 4], [2, 5], [3, 6]]) |>
...> Matrex.dot_tn(Matrex.new([[1, 2], [3, 4], [5, 6]]))
#Matrex[2×2]
┌ ┐
│ 22.0 28.0 │
│ 49.0 64.0 │
└ ┘
Create eye (identity) square matrix of given size.
Examples
iex> Matrex.eye(3)
#Matrex[3×3]
┌ ┐
│ 1.0 0.0 0.0 │
│ 0.0 1.0 0.0 │
│ 0.0 0.0 1.0 │
└ ┘
iex> Matrex.eye(3, 2.95)
#Matrex[3×3]
┌ ┐
│ 2.95 0.0 0.0 │
│ 0.0 2.95 0.0 │
│ 0.0 0.0 2.95 │
└ ┘
Create square matrix filled with given value. Inlined.
Example
iex> Matrex.fill(3, 55)
#Matrex[3×3]
┌ ┐
│ 33.0 33.0 33.0 │
│ 33.0 33.0 33.0 │
│ 33.0 33.0 33.0 │
└ ┘
Create matrix filled with given value. NIF.
Example
iex> Matrex.fill(4,3, 55)
#Matrex[4×3]
┌ ┐
│ 55.0 55.0 55.0 │
│ 55.0 55.0 55.0 │
│ 55.0 55.0 55.0 │
│ 55.0 55.0 55.0 │
└ ┘
Find position of the first occurence of the given value in the matrix. NIF.
Returns {row, column} tuple or nil, if nothing was found. One-based.
Example
Prints monochrome or color heatmap of the matrix to the console.
Supports 8, 256 and 16mln of colors terminals. Monochrome on 256 color palette is the default.
Examples





An alias for eye/1
.
Displays a visualization of the matrix.
Set the second parameter to true to show full numbers. Otherwise, they are truncated.
Load matrex from file.
.csv and .mtx (binary) formats are supported.
Example
iex> Matrex.load("test/matrex.csv")
#Matrex[5×4]
┌ ┐
│ 0.0 4.8e-4-0.00517-0.01552 │
│-0.01616-0.01622 -0.0161-0.00574 │
│ 6.8e-4 0.0 0.0 0.0 │
│ 0.0 0.0 0.0 0.0 │
│ 0.0 0.0 0.0 0.0 │
└ ┘
Creates “magic” n*n matrix, where sums of all dimensions are equal
Example
iex> Matrex.magic(5)
#Matrex[5×5]
┌ ┐
│ 16.0 23.0 5.0 7.0 14.0 │
│ 22.0 4.0 6.0 13.0 20.0 │
│ 3.0 10.0 12.0 19.0 21.0 │
│ 9.0 11.0 18.0 25.0 2.0 │
│ 15.0 17.0 24.0 1.0 8.0 │
└ ┘
Maximum element in a matrix. NIF.
Example
iex> m = Matrex.magic(5)
#Matrex[5×5]
┌ ┐
│ 16.0 23.0 5.0 7.0 14.0 │
│ 22.0 4.0 6.0 13.0 20.0 │
│ 3.0 10.0 12.0 19.0 21.0 │
│ 9.0 11.0 18.0 25.0 2.0 │
│ 15.0 17.0 24.0 1.0 8.0 │
└ ┘
iex> Matrex.max(m)
25.0
Returns maximum finite element of a matrex. NIF.
Used on matrices which may contain infinite values.
Example
iex>Matrex.reshape([1, 2, Inf, 3, NaN, 5], 3, 2) |> Matrex.max_finite()
5.0
Minimum element in a matrix. NIF.
Example
iex> m = Matrex.magic(5)
#Matrex[5×5]
┌ ┐
│ 16.0 23.0 5.0 7.0 14.0 │
│ 22.0 4.0 6.0 13.0 20.0 │
│ 3.0 10.0 12.0 19.0 21.0 │
│ 9.0 11.0 18.0 25.0 2.0 │
│ 15.0 17.0 24.0 1.0 8.0 │
└ ┘
iex> Matrex.min(m)
1.0
Returns minimum finite element of a matrex. NIF.
Used on matrices which may contain infinite values.
Example
iex>Matrex.reshape([1, 2, NegInf, 3, 4, 5], 3, 2) |> Matrex.min_finite()
1.0
Elementwise multiplication of two matrices or matrix and a scalar. NIF.
Raises ErlangError
if matrices’ sizes do not match.
Examples
iex> Matrex.new([[1, 2, 3], [4, 5, 6]]) |>
...> Matrex.multiply(Matrex.new([[5, 2, 1], [3, 4, 6]]))
#Matrex[2×3]
┌ ┐
│ 5.0 4.0 3.0 │
│ 12.0 20.0 36.0 │
└ ┘
iex> Matrex.new([[1, 2, 3], [4, 5, 6]]) |> Matrex.multiply(2)
#Matrex[2×3]
┌ ┐
│ 2.0 4.0 6.0 │
│ 8.0 10.0 12.0 │
└ ┘
Negates each element of the matrix. NIF.
Example
iex> Matrex.new([[1, 2, 3], [4, 5, 6]]) |> Matrex.neg()
#Matrex[2×3]
┌ ┐
│ -1.0 -2.0 -3.0 │
│ -4.0 -5.0 -6.0 │
└ ┘
Creates new matrix from list of lists or text representation (compatible with MathLab/Octave).
List of lists can contain other matrices, which are concatenated in one.
Example
iex> Matrex.new([[1, 2, 3], [4, 5, 6]])
#Matrex[2×3]
┌ ┐
│ 1.0 2.0 3.0 │
│ 4.0 5.0 6.0 │
└ ┘
iex> Matrex.new([[Matrex.fill(2, 1.0), Matrex.fill(2, 3, 2.0)],
...> [Matrex.fill(1, 2, 3.0), Matrex.fill(1, 3, 4.0)]])
#Matrex[5×5]
┌ ┐
│ 1.0 1.0 2.0 2.0 2.0 │
│ 1.0 1.0 2.0 2.0 2.0 │
│ 3.0 3.0 4.0 4.0 4.0 │
└ ┘
iex> Matrex.new("1;0;1;0;1")
#Matrex[5×1]
┌ ┐
│ 1.0 │
│ 0.0 │
│ 1.0 │
│ 0.0 │
│ 1.0 │
└ ┘
iex> Matrex.new("""
...> 1.00000 0.10000 0.60000 1.10000
...> 1.00000 0.20000 0.70000 1.20000
...> 1.00000 NaN 0.80000 1.30000
...> Inf 0.40000 0.90000 1.40000
...> 1.00000 0.50000 NegInf 1.50000
...> """)
#Matrex[5×4]
┌ ┐
│ 1.0 0.1 0.6 1.1 │
│ 1.0 0.2 0.7 1.2 │
│ 1.0 NaN 0.8 1.3 │
│ ∞ 0.4 0.9 1.4 │
│ 1.0 0.5 -∞ 1.5 │
└ ┘
Creates new matrix with values provided by the given function.
If function accepts two arguments one-based row and column of each element are passed to it.
Examples
iex> Matrex.new(3, 3, fn -> :rand.uniform() end)
#Matrex[3×3]
┌ ┐
│ 0.45643 0.91533 0.25332 │
│ 0.29095 0.21241 0.9776 │
│ 0.42451 0.05422 0.92863 │
└ ┘
iex> Matrex.new(3, 3, fn row, col -> row*col end)
#Matrex[3×3]
┌ ┐
│ 1.0 2.0 3.0 │
│ 2.0 4.0 6.0 │
│ 3.0 6.0 9.0 │
└ ┘
Bring all values of matrix into [0, 1] range. NIF.
Where 0 corresponds to the minimum value of the matrix, and 1 — to the maxixmim.
Example
iex> m = Matrex.reshape(1..9, 3, 3)
#Matrex[3×3]
┌ ┐
│ 1.0 2.0 3.0 │
│ 4.0 5.0 6.0 │
│ 7.0 8.0 9.0 │
└ ┘
iex> Matrex.normalize(m)
#Matrex[3×3]
┌ ┐
│ 0.0 0.125 0.25 │
│ 0.375 0.5 0.625 │
│ 0.75 0.875 1.0 │
└ ┘
Create matrex of ones of square dimensions or consuming output of size/1
function.
Examples
iex> Matrex.ones(3)
#Matrex[3×3]
┌ ┐
│ 1.0 1.0 1.0 │
│ 1.0 1.0 1.0 │
│ 1.0 1.0 1.0 │
└ ┘
iex> m = Matrex.new("1 2 3; 4 5 6")
#Matrex[2×3]
┌ ┐
│ 1.0 2.0 3.0 │
│ 4.0 5.0 6.0 │
└ ┘
iex> Matrex.ones(Matrex.size(m))
#Matrex[2×3]
┌ ┐
│ 1.0 1.0 1.0 │
│ 1.0 1.0 1.0 │
└ ┘
Create matrix filled with ones.
Example
iex> Matrex.ones(2, 3)
#Matrex[2×3]
┌ ┐
│ 1.0 1.0 1.0 │
│ 1.0 1.0 1.0 │
└ ┘
Create square matrix of random floats.
See random/2
for details.
Example
iex> Matrex.random(3)
#Matrex[3×3]
┌ ┐
│ 0.66438 0.31026 0.98602 │
│ 0.82127 0.04701 0.13278 │
│ 0.96935 0.70772 0.98738 │
└ ┘
Create matrix of random floats in [0, 1] range. NIF.
C language RNG is seeded on NIF libray load with srandom(time(NULL) + clock())
.
Example
iex> Matrex.random(4,3)
#Matrex[4×3]
┌ ┐
│ 0.32994 0.28736 0.88012 │
│ 0.51782 0.68608 0.29976 │
│ 0.52953 0.9071 0.26743 │
│ 0.82189 0.59311 0.8451 │
└ ┘
Reshapes list of values into a matrix of given size or changes the shape of existing matrix.
Takes a list or anything, that implements Enumerable.to_list/1
.
Can take a list of matrices and concatenate into one big matrix.
Raises ArgumentError
if lsit size and given shape do not match.
Example
iex> [1, 2, 3, 4, 5, 6] |> Matrex.reshape(2, 3)
#Matrex[2×3]
┌ ┐
│ 1.0 2.0 3.0 │
│ 4.0 5.0 6.0 │
└ ┘
iex> Matrex.reshape([Matrex.zeros(2), Matrex.ones(2),
...> Matrex.fill(3, 2, 2.0), Matrex.fill(3, 2, 3.0)], 2, 2)
#Matrex[5×4]
┌ ┐
│ 0.0 0.0 1.0 1.0 │
│ 0.0 0.0 1.0 1.0 │
│ 2.0 2.0 3.0 3.0 │
│ 2.0 2.0 3.0 3.0 │
│ 2.0 2.0 3.0 3.0 │
└ ┘
iex> Matrex.reshape(1..6, 2, 3)
#Matrex[2×3]
┌ ┐
│ 1.0 2.0 3.0 │
│ 4.0 5.0 6.0 │
└ ┘
iex> Matrex.new("1 2 3; 4 5 6") |> Matrex.reshape(3, 2)
#Matrex[3×2]
┌ ┐
│ 1.0 2.0 │
│ 3.0 4.0 │
│ 5.0 6.0 │
└ ┘
Resize matrix by scaling its dimenson with scale
. NIF.
Examples
iex> m = Matrex.magic(3)
#Matrex[3×3]
┌ ┐
│ 8.0 1.0 6.0 │
│ 3.0 5.0 7.0 │
│ 4.0 9.0 2.0 │
└ ┘
iex(3)> Matrex.resize(m, 2)
#Matrex[6×6]
┌ ┐
│ 8.0 8.0 1.0 1.0 6.0 6.0 │
│ 8.0 8.0 1.0 1.0 6.0 6.0 │
│ 3.0 3.0 5.0 5.0 7.0 7.0 │
│ 3.0 3.0 5.0 5.0 7.0 7.0 │
│ 4.0 4.0 9.0 9.0 2.0 2.0 │
│ 4.0 4.0 9.0 9.0 2.0 2.0 │
└ ┘
iex(4)> m = Matrex.magic(5)
#Matrex[5×5]
┌ ┐
│ 16.0 23.0 5.0 7.0 14.0 │
│ 22.0 4.0 6.0 13.0 20.0 │
│ 3.0 10.0 12.0 19.0 21.0 │
│ 9.0 11.0 18.0 25.0 2.0 │
│ 15.0 17.0 24.0 1.0 8.0 │
└ ┘
iex(5)> Matrex.resize(m, 0.5)
#Matrex[3×3]
┌ ┐
│ 16.0 23.0 7.0 │
│ 22.0 4.0 13.0 │
│ 9.0 11.0 25.0 │
└ ┘
Get row of matrix as matrix (vector) in matrex form. One-based.
You can use shorter matrex[n]
syntax for the same result.
Example
iex> m = Matrex.magic(5)
#Matrex[5×5]
┌ ┐
│ 16.0 23.0 5.0 7.0 14.0 │
│ 22.0 4.0 6.0 13.0 20.0 │
│ 3.0 10.0 12.0 19.0 21.0 │
│ 9.0 11.0 18.0 25.0 2.0 │
│ 15.0 17.0 24.0 1.0 8.0 │
└ ┘
iex> Matrex.row(m, 4)
#Matrex[1×5]
┌ ┐
│ 9.0 11.0 18.0 25.0 2.0 │
└ ┘
iex> m[4]
#Matrex[1×5]
┌ ┐
│ 9.0 11.0 18.0 25.0 2.0 │
└ ┘
Return matrix row as list by one-based index.
Example
iex> m = Matrex.magic(5)
#Matrex[5×5]
┌ ┐
│ 16.0 23.0 5.0 7.0 14.0 │
│ 22.0 4.0 6.0 13.0 20.0 │
│ 3.0 10.0 12.0 19.0 21.0 │
│ 9.0 11.0 18.0 25.0 2.0 │
│ 15.0 17.0 24.0 1.0 8.0 │
└ ┘
iex> Matrex.row_to_list(m, 3)
[3.0, 10.0, 12.0, 19.0, 21.0]
Saves matrex into file.
Binary (.mtx) and CSV formats are supported currently.
Format is defined by the extension of the filename.
Example
iex> Matrex.random(5) |> Matrex.save("r.mtx")
:ok
Transfer one-element matrix to a scalar value.
Differently from first/1
will not match and throw an error,
if matrix contains more than one element.
Example
iex> Matrex.new([[1.234]]) |> Matrex.scalar()
1.234
iex> Matrex.new([[0]]) |> Matrex.divide(0) |> Matrex.scalar()
NaN
iex> Matrex.new([[1.234, 5.678]]) |> Matrex.scalar()
** (FunctionClauseError) no function clause matching in Matrex.scalar/1
Set element of matrix at the specified position (one-based) to new value.
Example
iex> m = Matrex.ones(3)
#Matrex[3×3]
┌ ┐
│ 1.0 1.0 1.0 │
│ 1.0 1.0 1.0 │
│ 1.0 1.0 1.0 │
└ ┘
iex> m = Matrex.set(m, 2, 2, 0)
#Matrex[3×3]
┌ ┐
│ 1.0 1.0 1.0 │
│ 1.0 0.0 1.0 │
│ 1.0 1.0 1.0 │
└ ┘
iex> m = Matrex.set(m, 3, 2, NegInf)
#Matrex[3×3]
┌ ┐
│ 1.0 1.0 1.0 │
│ 1.0 0.0 1.0 │
│ 1.0 1.0 1.0 │
└ ┘
Set column of a matrix to the values from the given 1-column matrix. NIF.
Example
iex> m = Matrex.reshape(1..6, 3, 2)
#Matrex[3×2]
┌ ┐
│ 1.0 2.0 │
│ 3.0 4.0 │
│ 5.0 6.0 │
└ ┘
iex> Matrex.set_column(m, 2, Matrex.new("7; 8; 9"))
#Matrex[3×2]
┌ ┐
│ 1.0 7.0 │
│ 3.0 8.0 │
│ 5.0 9.0 │
└ ┘
Return size of matrix as {rows, cols}
Example
iex> m = Matrex.random(2,3)
#Matrex[2×3]
┌ ┐
│ 0.69745 0.23668 0.36376 │
│ 0.63423 0.29651 0.22844 │
└ ┘
iex> Matrex.size(m)
{2, 3}
Produces element-wise squared matrix. NIF through multiply/4
.
Example
iex> m = Matrex.new("1 2 3; 4 5 6")
#Matrex[2×3]
┌ ┐
│ 1.0 2.0 3.0 │
│ 4.0 5.0 6.0 │
└ ┘
iex> Matrex.square(m)
#Matrex[2×3]
┌ ┐
│ 1.0 4.0 9.0 │
│ 16.0 25.0 36.0 │
└ ┘
Returns submatrix for a given matrix. NIF.
Rows and columns ranges are inclusive and one-based.
Example
iex> m = Matrex.new("1 2 3; 4 5 6; 7 8 9")
#Matrex[3×3]
┌ ┐
│ 1.0 2.0 3.0 │
│ 4.0 5.0 6.0 │
│ 7.0 8.0 9.0 │
└ ┘
iex> Matrex.submatrix(m, 2..3, 2..3)
#Matrex[2×2]
┌ ┐
│ 5.0 6.0 │
│ 8.0 9.0 │
└ ┘
Substracts two matrices or matrix from scalar element-wise. NIF.
Raises ErlangError
if matrices’ sizes do not match.
Examples
iex> Matrex.new([[1, 2, 3], [4, 5, 6]]) |>
...> Matrex.substract(Matrex.new([[5, 2, 1], [3, 4, 6]]))
#Matrex[2×3]
┌ ┐
│ -4.0 0.0 2.0 │
│ 1.0 1.0 0.0 │
└ ┘
iex> Matrex.substract(1, Matrex.new([[1, 2, 3], [4, 5, 6]]))
#Matrex[2×3]
┌ ┐
│ 0.0 -1.0 -2.0 │
│ -3.0 -4.0 -5.0 │
└ ┘
Substracts the second matrix from the first. Inlined.
Raises ErlangError
if matrices’ sizes do not match.
Example
iex> Matrex.new([[1, 2, 3], [4, 5, 6]]) |>
...> Matrex.substract_inverse(Matrex.new([[5, 2, 1], [3, 4, 6]]))
#Matrex[2×3]
┌ ┐
│ 4.0 0.0 -2.0 │
│ -1.0 -1.0 0.0 │
└ ┘
Sums all elements. NIF.
Can return special float values as atoms.
Example
iex> m = Matrex.magic(3)
#Matrex[3×3]
┌ ┐
│ 8.0 1.0 6.0 │
│ 3.0 5.0 7.0 │
│ 4.0 9.0 2.0 │
└ ┘
iex> Matrex.sum(m)
45.0
iex> m = Matrex.new("1 Inf; 2 3")
#Matrex[2×2]
┌ ┐
│ 1.0 ∞ │
│ 2.0 3.0 │
└ ┘
iex> sum(m)
Inf
Converts to flat list. NIF.
Example
iex> m = Matrex.magic(3)
#Matrex[3×3]
┌ ┐
│ 8.0 1.0 6.0 │
│ 3.0 5.0 7.0 │
│ 4.0 9.0 2.0 │
└ ┘
iex> Matrex.to_list(m)
[8.0, 1.0, 6.0, 3.0, 5.0, 7.0, 4.0, 9.0, 2.0]
Converts to list of lists. NIF.
Examples
iex> m = Matrex.magic(3)
#Matrex[3×3]
┌ ┐
│ 8.0 1.0 6.0 │
│ 3.0 5.0 7.0 │
│ 4.0 9.0 2.0 │
└ ┘
iex> Matrex.to_list_of_lists(m)
[[8.0, 1.0, 6.0], [3.0, 5.0, 7.0], [4.0, 9.0, 2.0]]
iex> r = Matrex.divide(Matrex.eye(3), Matrex.zeros(3))
#Matrex[3×3]
┌ ┐
│ ∞ NaN NaN │
│ NaN ∞ NaN │
│ NaN NaN ∞ │
└ ┘
iex> Matrex.to_list_of_lists(r)
[[Inf, NaN, NaN], [NaN, Inf, NaN], [NaN, NaN, Inf]]
Convert any matrix m×n to a row matrix 1×(m*n).
Example
iex> m = Matrex.magic(3)
#Matrex[3×3]
┌ ┐
│ 8.0 1.0 6.0 │
│ 3.0 5.0 7.0 │
│ 4.0 9.0 2.0 │
└ ┘
iex> Matrex.to_row(m)
#Matrex[1×9]
┌ ┐
│ 8.0 1.0 6.0 3.0 5.0 7.0 4.0 9.0 2.0 │
└ ┘
Transposes a matrix. NIF.
Example
iex> m = Matrex.new([[1,2,3],[4,5,6]])
#Matrex[2×3]
┌ ┐
│ 1.0 2.0 3.0 │
│ 4.0 5.0 6.0 │
└ ┘
iex> Matrex.transpose(m)
#Matrex[3×2]
┌ ┐
│ 1.0 4.0 │
│ 2.0 5.0 │
│ 3.0 6.0 │
└ ┘
Create square matrix of size size
rows × size
columns, filled with zeros. Inlined.
Example
iex> Matrex.zeros(3)
#Matrex[3×3]
┌ ┐
│ 0.0 0.0 0.0 │
│ 0.0 0.0 0.0 │
│ 0.0 0.0 0.0 │
└ ┘