[Haskell-cafe] Hatlab: My attempt to make a library inspired by Matlab and NumPy

TeraTux teratux.mail at gmail.com
Sun Mar 27 17:13:40 UTC 2022

```Greetings!

I made a library which implements functions similar to those in Matlab or
NumPy. The code is not much clean yet, you can see it at
https://gitlab.com/Hume2/hatlab . The functions with comments are intended
to be used. I want to know if it is a good start or I just wasted time.

The matrices can have arbitrary dimensions, starting from 0D matrices,
which are basically scalars. Operations like + - * / are element-wise. I
also implemented broadcasting of these operations.

I also implemented indexing. Some examples:

a = matrix2D [[1,2,3],[4,5,6],[7,8,9]]
a !# [2,2] -- element at index [2,2]
a !\$ [At 1, All] -- 1st row
a !\$ [To (-1), All] -- all rows except the last one
a !\$ [Where \$ a ># 5] -- all elements bigger than 5 (The ># operator
returns a matrix of bools, I will come to that later.)

It is also possible to update a matrix. These operations do not copy all
the elements from the original matrix, they just make another matrix which
points to the original matrix at places where it was not changed. Some
examples:

a = eye 5
b = matrix2D [[1,2,3],[4,5,6],[7,8,9]]
a !:[FromTo 1 4, FromTo 1 4]:= b -- replace the middle square by a
different matrix
a !:[FromTo 1 4, FromTo 1 4]:= 1 -- set all values in the middle square to 1
a !:[FromTo 1 4, FromTo 1 4]:+= 1 -- add one to all values in the middle
square
a !:[FromTo 1 4, FromTo 1 4]:\$= cos -- replace all values in the middle
square by their cosine

Operators are broadcasted the same way as in Matlab or NumPy. If one
operand has size 1 and the other one has size N or vice-versa in given
dimension, the operator acts as if the thinner matrix was repeated in the
given dimension N times. Example:

a = matrix1D [10, 20, 30] -- row vector
b = matrix2D [[1], [2], [3]] -- column vector
a + b -- returns [[11, 21, 31], [12, 22, 32], [13, 23, 33]]

There is a function "scalar" which creates a 0D matrix out of any value, so
we can do:

a + (scalar 5) -- returns [15, 25, 35]
a * (scalar 2) -- returns [20, 40, 60]

If a type is in the class Num, Fractional or Floating, the matrix of the
given type is also in the given class. Conversions are performed using the
function "scalar", so we can write:

a + 5
a * 2

because the "5" and "2" are then interpreted as 0D matrices.

Operator * is interpreted as element-wise multiplication. To do matrix
multiplication, use the × operator. It can be also used to multiply
matrices with vectors. Examples:

v = matrix1D [1,2,3]
m = matrix2D [[1,0,1],[2,-1,1],[0,1,-1]]
v × m -- multiply row vector v with matrix m
m × v -- multiply matrix m with column vector v
m × m -- multiply matrix m by itself

There are also functions for element-wise boolean operations. They work
similarly and they have the # suffix. Examples:

a = matrix2D [[True, True], [False, False]]
b = matrix2D [[True, False], [True, False]]
a &# b -- element-wise and
a |# b -- element-wise or

There are also element-wise comparison functions in a similar fashion.
Examples:

a = eye 3
b = ones [3,3]
a ==# b -- returns a matrix of bools saying where the element of matrix a
is equal to the corresponding element in matrix b.
a <# b -- similar as above except that it tests for being less than instead
of equality.
a ==# 1 -- Broadcasting works for these operators too, so this syntax is
valid also.

There are also other functions not described in this mail. I will not
describe them here because this mail is already too long. Don't worry
asking me if you don't understand the meaning of any function from my

I did not implement any algorithms for linear equation solving, not even
any other matrix algorithms yet. If this library has any potential, I may
do that in the future.

Please, let me know if this library has any potential or it was just a
waste of time.

Hume2
-------------- next part --------------
An HTML attachment was scrubbed...