Page 1 of 1

Pure MicroPython Matrix (mathematics)

Posted: Thu Jan 21, 2021 8:32 pm
by OlivierLenoir
https://gitlab.com/olivierlenoir/MicroPython-Matrix

I wrote the following code to do basic matrix operations. It works for me, but I'm not sure it's the best way to do it.
Do you have recommendation?
Is it the right way when I use return Matrix(...)?

Code: Select all

def add(a, b):
    return a + b


def sub(a, b):
    return a - b


def mul(a, b):
    return a * b


class Matrix(object):

    def __init__(self, mat):
        self.mat = mat

    def __repr__(self):
        return self.mat

    def __add__(self, b):
        return Matrix([list(map(add, *ab)) for ab in zip(self.mat, b.mat)])

    def __sub__(self, b):
        return Matrix([list(map(sub, *ab)) for ab in zip(self.mat, b.mat)])

    def __matmul__(self, b):
        return Matrix([[sum(map(mul, _a, _b)) for _b in zip(*b.mat)] for _a in self.mat])

Code: Select all

>>> a = Matrix([[1, 2, 3], [4, 5, 6]])
>>> b = Matrix([[10, 11], [20, 21], [30, 31]])
>>> c = Matrix([[-23, 3, 8], [-13, 17, -21]])
>>> d = Matrix([[32, 17], [-3, 11]])
>>> a @ b
[[140, 146], [320, 335]]
>>> a + c
[[-22, 5, 11], [-9, 22, -15]]
>>> a - c
[[24, -1, -5], [17, -12, 27]]
>>> a @ b + d
[[172, 163], [317, 346]]

Re: Pure MicroPython Matrix (mathematics)

Posted: Thu Jan 21, 2021 10:19 pm
by rcolistete
I suggest to use some MicroPython modules with matrix operations :
https://github.com/mcauser/awesome-micr ... #analytics

Re: Pure MicroPython Matrix (mathematics)

Posted: Fri Jan 22, 2021 9:29 am
by pythoncoder
There is also ulab but that requires compiling the firmware.

Re: Pure MicroPython Matrix (mathematics)

Posted: Fri Jan 22, 2021 5:11 pm
by OlivierLenoir
Thanks for your links.
Here is my on-going Matrix project.
https://gitlab.com/olivierlenoir/MicroPython-Matrix

Re: Pure MicroPython Matrix (mathematics)

Posted: Wed Feb 03, 2021 8:00 pm
by OlivierLenoir
I'm getting this error TypeError: unsupported types for __add__: 'int', 'Matrix'. It seem to be link to def __radd__(self, other): but I need help. In fact my class Matrix works well with python 3.7.3 but not with micropython v1.13 or v1.14.

Code: Select all

def add(a, b):
    return a + b


def sub(a, b):
    return a - b


def mul(a, b):
    return a * b


def square(a):
    return a * a


def eq(a, b):
    return a == b


class Matrix(object):

    def __init__(self, mat):
        """Matrix A, list of list"""
        self.mat = mat

    def dim(self):
        """Matrix dimension m rows by n cols"""
        return len(self.mat), len(self.mat[0])

    def map(self, func):
        """Map function to all elements of the matrix"""
        return Matrix([list(map(func, m)) for m in self.mat])

    def sumsquare(self):
        """Sum square of elements"""
        return sum(sum(m) for m in self.actfunc(square).mat)

    def meansquare(self):
        """Mean square of elements"""
        return self.sumsquare() / mul(*self.dim())

    def t(self):
        """Matrix transpose"""
        return Matrix(list(zip(*self.mat)))

    def __str__(self):
        return '{}'.format(self.mat)

    def __repr__(self):
        return '{}'.format(self.mat)

    def __neg__(self):
        """- A"""
        return self.map(lambda e: -e)

    def __pos__(self):
        """+ A"""
        return self.map(lambda e: e)

    def __add__(self, other):
        """A + B"""
        if not isinstance(other, Matrix):
            return Matrix([[_n + other for _n in _m] for _m in self.mat])
        return Matrix([list(map(add, *ab)) for ab in zip(self.mat, other.mat)])

    def __radd__(self, other):
        """B + A"""
        return self.__add__(other)

    def __iadd__(self, other):
        """A += B"""
        self.mat = self + other
        return self.mat
 # ....

Code: Select all

from matrix import Matrix

a = Matrix([[1, 2, 3], [4, 5, 6]])
b = Matrix([[10, 11], [20, 21], [30, 31]])
c = Matrix([[-23, 3, 8], [-13, 17, -21]])
d = Matrix([[32, 17], [-3, 11]])
e = Matrix([[9, 8, 7], [6, 5, 4]])

print('a + c =', a + c)
print('a - c =', a - c)

print('a + 2 =', a + 2)
print('2 + a =', 2 + a)  # TypeError: unsupported types for __add__: 'int', 'Matrix'
Do you have an explanation?
Full project is available https://gitlab.com/olivierlenoir/MicroPython-Matrix

Re: Pure MicroPython Matrix (mathematics)

Posted: Thu Feb 04, 2021 5:46 am
by jimmo
OlivierLenoir wrote:
Wed Feb 03, 2021 8:00 pm
It seem to be link to def __radd__(self, other):
Which board are you using?

For __radd__ etc, you need MICROPY_PY_REVERSE_SPECIAL_METHODS to be enabled (which I think is only STM32/pyboard, Unix, and Windows)

If you're on ESP32 then you'll need to do a custom build. Or perhaps raise an issue on github to suggest getting them enabled by default for ESP32?

Re: Pure MicroPython Matrix (mathematics)

Posted: Thu Feb 04, 2021 6:44 am
by OlivierLenoir
I'm using ESP32 board without SPIRAM and I plan to use the recent RPi PICO.
At that stage I don't feel confident to custom build my own version.
It would be a good idea to enable, __radd__(), __rsub__(), __rmul__()...
Can you help to raise an issue?

Re: Pure MicroPython Matrix (mathematics)

Posted: Fri Feb 05, 2021 12:16 am
by jimmo
OlivierLenoir wrote:
Thu Feb 04, 2021 6:44 am
Can you help to raise an issue?
I found https://github.com/micropython/micropyt ... -614417107

Maybe could you reply to that and suggest pico also?

Re: Pure MicroPython Matrix (mathematics)

Posted: Fri Feb 05, 2021 3:55 pm
by OlivierLenoir
Thanks Jimmo,
I've added a comment link to issue #5897. Lets wait and see.