Skip to content

tanguyl/numerl

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

NUMERL

NUMeric ERLang is an API for matrix operations in Erlang. All functions (except [eval/1, rnd_matrix/1]) are implemented in NIFs; some make use of BLAS and LAPACKE [inv/1, nrm2/1, vec_dot/2, dot/2] for even better performances.

1ms rule

This library does not yet take into account the 1ms rule of NIFs; DO NOT USE BIG MATRICES yet.
Work is in progress to make numerl's functions execute on chunks of matrices in parallel, solving this issue and improving performances.
This will be solved by the end of 2022's Q1.

Usage

This library is a rebar3 dependency (https://github.com/erlang/rebar3):

    {deps, [{numerl, {git, "https://github.com/tanguyl/numerl.git", {branch, "master"}}}]}.

A numerl example can be found at https://github.com/tanguyl/raytracer.

Installation

Openblas and lapacke are mandatory to use this library.

Ubuntu-like os'es:

    sudo apt-get install libopenblas-dev liblapacke-dev

macOS:
lapacke is included through the accelerate framework; only openblas is required.

    brew install openblas

Windows:
Tested on WSL :)

MAN

API

The following functions are available:

Constructors     = [matrix/1, rnd_matrix/1, eye/1, zeros/2].
Comparator       = [equals/2].
Accessors         = [mtfli/1, mtfl/1, get/3, at/2, row/2, col/2].
Element_wise_ops = [add/2, sub/2 ,mult/2, divide/2].
Ops              = [inv/1, nrm2/1, vec_dot/2, dot/2, transpose/1].

Matrices

Matrices are defined as follows:

-record(matrix,{n_rows, n_cols, bin}).

The bin field is a Binary, containing the represented matrices values stored as doubles.

Constructors

The following functions can be used to create matrices:

Constructors = [matrix/1, rnd_matrix/1, eye/1, zeros/2].

They can be used as follows:

% FCT                              INPUT(S)   OUTPUT    
numerl:matrix([[1, 2.0],[3, 4.0]]).% L    
numerl:rnd_matrix(2).              % N,     random   matrix of size NxN.
numerl:eye(2).                     % N,     identity matrix of size NxN.
numerl:zeros(2, 2).                % N,M    empty    matrix of size NxM.

The matrix/1 takes as input a list of rows.

Comparator

Matrices are stored as arrays of doubles, the granularity of which makes the ==/2 operator unadviced. Instead, numerl provides its own comparison operator:

Comparator = [equals/2].

It should be used as follows:

E = numerl:eye(2),                 %
Z = numerl:zeros(2,2),             %
%FCT                               INPUTS
Boolean = numerl:equals(E,Z).      % M1,M2: compared matrices.

Accessors

Matrices content can be extracted with the following functions:

Accessors = [mtfli/1, mtfl/1, row/2, col/2, get/3, at/2].

They are used as such:

M = numerl:matrix([[1,2,3]]),
P = numerl:matrix([[1]]),   
N = 1,                             
O = 1,                             
%Output         Fct                 Input
[1,2,3]       = numerl:mtfli(M),   % matrix M
[1.0,2.0,3.0] = numerl:mtfl(M),    % Matrix M
M             = numerl:row(M,N),   % N  in [1, M.n_rows], M
P             = numerl:col(M,N),   % N  in [1, M.n_cols], M
1.0           = numerl:get(M,N,O), % N in
1.0           = numerl:at(M,N).    % The N'th element of the matrix.

Element-wise operations

The following operations can be done element-wise on matrices:

Element_wise_ops = [add/2, sub/2 ,mult/2, divide/2].

They have the following usage:

%FCT                               INPUTS
op(Lval, Rval).                    % Lval: a matrix, Rval: a matrix || a number

For divide/2 op used with Rval either null or containing a null value, a badarg is thrown.

These ops can be combined with the eval/1 function:

M = numerl:rnd_matrix(2),
%FCT                               INPUTS
numerl:eval([M, add, 1,            % L: a list of V1,Op1,V2,OP2...
             divide, 2,
              mult, M]).

More functions

Ops = [inv/1, nrm2/1, vec_dot/2, dot/2, transpose/1].

Inv

Returns the inverse of input function.

M = numerl:rnd_matrix(2),
P = numerl:inv(M).

A badarg is thrown for input non-square matrix; and error "nif_inv: could not invert singular matrix." is thrown in case of input singular matrix.

Implementation is based upon a LAPACKE LU's decomposition/inversion.

nrm2

Returns the root square of the sum of the squared elements of input matrix.

P   = numerl:matrix([[-3]]),
3.0 = numerl:nrm2(P).

vec_dot

Returns the sum of element-wise multiplication of input matrices.

Q    = numerl:matrix([[1,2]]),
R    = numerl:matrix([[3,4]]),
11.0 = numerl:vec_dot(Q,R).

Input matrices need to contain the same number of elements; but their dimensions do not need to match.

dot

Returns the product of input matrices.

I    = numerl:eye(2),
I2   = numerl:mult(I,2),
M    = numerl:matrix([[1,2], [3,4]]),
R    = numerl:dot(M,I2).

transpose

Returns the transpose of input matrix.

I = numerl:eye(2),
It = numerl:transpose(I),
true = numerl:equals(I,It).

About

Small matrix library for Erlang.

Topics

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published