Pure MicroPython Matrix (mathematics)

Discussion about programs, libraries and tools that work with MicroPython. Mostly these are provided by a third party.
Target audience: All users and developers of MicroPython.
Post Reply
User avatar
OlivierLenoir
Posts: 126
Joined: Fri Dec 13, 2019 7:10 pm
Location: Picardie, FR

Pure MicroPython Matrix (mathematics)

Post by OlivierLenoir » Thu Jan 21, 2021 8:32 pm

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]]
Last edited by OlivierLenoir on Sun Jul 11, 2021 4:41 pm, edited 2 times in total.

User avatar
rcolistete
Posts: 352
Joined: Thu Dec 31, 2015 3:12 pm
Location: Brazil
Contact:

Re: Pure MicroPython Matrix (mathematics)

Post by rcolistete » Thu Jan 21, 2021 10:19 pm

I suggest to use some MicroPython modules with matrix operations :
https://github.com/mcauser/awesome-micr ... #analytics
My "MicroPython Samples". My "MicroPython Firmwares" with many options (double precision, ulab, etc).

User avatar
pythoncoder
Posts: 5956
Joined: Fri Jul 18, 2014 8:01 am
Location: UK
Contact:

Re: Pure MicroPython Matrix (mathematics)

Post by pythoncoder » Fri Jan 22, 2021 9:29 am

There is also ulab but that requires compiling the firmware.
Peter Hinch
Index to my micropython libraries.

User avatar
OlivierLenoir
Posts: 126
Joined: Fri Dec 13, 2019 7:10 pm
Location: Picardie, FR

Re: Pure MicroPython Matrix (mathematics)

Post by OlivierLenoir » Fri Jan 22, 2021 5:11 pm

Thanks for your links.
Here is my on-going Matrix project.
https://gitlab.com/olivierlenoir/MicroPython-Matrix
Last edited by OlivierLenoir on Sun Jul 11, 2021 4:41 pm, edited 1 time in total.

User avatar
OlivierLenoir
Posts: 126
Joined: Fri Dec 13, 2019 7:10 pm
Location: Picardie, FR

Re: Pure MicroPython Matrix (mathematics)

Post by OlivierLenoir » Wed Feb 03, 2021 8:00 pm

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
Last edited by OlivierLenoir on Sun Jul 11, 2021 4:42 pm, edited 1 time in total.

User avatar
jimmo
Posts: 2754
Joined: Tue Aug 08, 2017 1:57 am
Location: Sydney, Australia
Contact:

Re: Pure MicroPython Matrix (mathematics)

Post by jimmo » Thu Feb 04, 2021 5:46 am

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?

User avatar
OlivierLenoir
Posts: 126
Joined: Fri Dec 13, 2019 7:10 pm
Location: Picardie, FR

Re: Pure MicroPython Matrix (mathematics)

Post by OlivierLenoir » Thu Feb 04, 2021 6:44 am

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?

User avatar
jimmo
Posts: 2754
Joined: Tue Aug 08, 2017 1:57 am
Location: Sydney, Australia
Contact:

Re: Pure MicroPython Matrix (mathematics)

Post by jimmo » Fri Feb 05, 2021 12:16 am

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?

User avatar
OlivierLenoir
Posts: 126
Joined: Fri Dec 13, 2019 7:10 pm
Location: Picardie, FR

Re: Pure MicroPython Matrix (mathematics)

Post by OlivierLenoir » Fri Feb 05, 2021 3:55 pm

Thanks Jimmo,
I've added a comment link to issue #5897. Lets wait and see.

Post Reply