[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: matrix library?
From: |
Damien Mattei |
Subject: |
Re: matrix library? |
Date: |
Fri, 6 Oct 2023 20:33:36 +0200 |
in maths there is a "philosophical" difference between a vector and
column-matrix.
for simplicity in my code i prefer to be able to multiply matrix and
vector directly as vector is a predefined type in scheme, not
matrix.And get as result a vector too.
but of course the solution is to convert the vector in matrix-column
and use the already defined and already overloaded multiplication of
two matrix:
(define-method (* (M <matrix>) (v <vector>)) ;; args: matrix ,vector ;
return vector
{Mc <+ (vector->matrix-column v)}
(matrix-column->vector {M * Mc}))
in fact i'm porting and testing a python code to scheme+ in Racket
(already done) and Guile :
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Matrix.py
The class Matrix.
Derived from:
exo_mat2.py
La classe Matrix : algèbre des matrices de format quelconque, sans numpy
"""
# D. Mattei
from multimethod import multimethod
from typing import Union,Callable
from collections.abc import Iterable
class MatError(Exception): # juste pour la lisibilité des exceptions
pass
Numeric = Union[float, int]
# m1=Matrix([[1,3],[-2,4],[0,-1]])
# m2=Matrix([[1],[2]])
# m3=Matrix([[1,3],[-2,4],[0,-1]])
# >>> m1*m2*m3
# Matrix.py : __mul__(Matrix,Matrix)
# # Matrix constructor Matrix (function,Numeric,Numeric) #
# Matrix.py : __mul__(Matrix,Matrix)
# # Matrix constructor Matrix (function,Numeric,Numeric) #
# 7.00 21.00
# 6.00 18.00
# -2.00 -6.00
# Matrix @ 0x7fca8d71edd0
class Matrix:
'''Construct an object Matrix.'''
# >>> m1=Matrix(2,3)
@multimethod
def __init__(self,n : Numeric,p : Numeric): # lines, columns
'''Construit un objet matrice de type Matrix, d'attributs le
format self.dim
et la liste architecturée en liste de listes de même longueur.
Exemples :
m = Matrix([[1,3],[-2,4],[0,-1]]) à 3 lignes et 2 colonnes
m = Matrix(lambda i,j: i+j,3,5) à 3 lignes et 5 colonnes'''
if __debug__:
print("# Matrix constructor Matrix (Numeric,Numeric) #")
__init__(lambda i,j: 0,n,p) # return a Zero matrix
@multimethod
def __init__(self,f : Callable,n : Numeric,p : Numeric):
if __debug__:
print("# Matrix constructor Matrix (function,Numeric,Numeric) #")
self.L = [[f(i,j) for j in range(p)] for i in range(n)]
@multimethod
def __init__(self,Lf : list):
if __debug__:
print("# Matrix constructor Matrix,list #")
if any(map(lambda x:type(x) != list,Lf)) :
raise MatError('Matrix : on attend une liste de listes !')
p = len(Lf[0])
if any(map(lambda x:len(x)!=p,Lf)) :
raise MatError('Matrix : on attend une liste de listes de
même longueur !')
self.L = Lf # la liste qui contient les éléments de matrice
def dim(self):
'''Retourne le format de la matrice courante.'''
n = len(self.L)
if n == 0:
raise MatError('Matrice vide !')
return (n,len(self.L[0]))
# m1=Matrix(lambda i,j : i+j, 5,2)
# # Matrix constructor Matrix (function,Numeric,Numeric) #
# m1
# 0.00 1.00
# 1.00 2.00
# 2.00 3.00
# 3.00 4.00
# 4.00 5.00
# Matrix @ 0x105ae03d0
# print(m1)
# 0.00 1.00
# 1.00 2.00
# 2.00 3.00
# 3.00 4.00
# 4.00 5.00
def __repr__(self):
'''Retourne une chaine formatée avec colonnes alignées représentant
la matrice m.'''
return self.__str__() + '\nMatrix @ {} \n'.format(hex(id(self)))
# >>> print(m)
def __str__(self):
'''Retourne une chaine formatée avec colonnes alignées représentant
la matrice m.'''
def texte(x):
return '{:10.2f}'.format(x) # précision limitée à l'affichage...
(n,p) = self.dim()
L = ['\t'.join(list(map(texte,self.L[i]))) for i in range(n)]
return '\n'.join(L)
def __getitem__(self,i): # pour pouvoir écrire m[i] pour la ligne i
return self.L[i] # et m[i][j] pour l'élément en
ligne i et colonne j
def __setitem__(self, i, data):
self.A[i] = data
def lig(self,i): # m.lig(i) <==> m[i]
'''Retourne la ligne i >= 0 de la matrice sous forme de liste plate.'''
return self.L[i]
def col(self,j):
'''Retourne la colonne j >= 0 de la matrice sous forme de
liste plate.'''
(n,_) = self.dim()
return [self.L[i][j] for i in range(n)]
def __add__(self,m2):
'''Retourne la somme de la matrice courante et d'une matrice m2
de même format.'''
(n,p) = self.dim()
if m2.dim() != (n,p):
raise MatError('mat_sum : Mauvais formats de matrices !')
L = self.L ; L2 = m2.L
return Matrix(lambda i,j : L[i][j] + L2[i][j],n,p)
def __sub__(self,m2):
'''Retourne la différence entre la matrice courante et une matrice
m2 de même format.'''
return self + m2.mul(-1)
def mul(self,k):
'''Retourne le produit externe du nombre k par la matrice m.'''
(n,p) = self.dim()
return Matrix(lambda i,j : k*self.L[i][j],n,p)
# R : multiplicand
# matrix multiplication by number
@multimethod
def __rmul__(self, m : Numeric): # self is at RIGHT of
multiplication operand : m * self
'''Retourne le produit externe du nombre par la matrice'''
if __debug__:
print("Matrix.py : __rmul__(Matrix,Numeric)")
return self.mul(m)
def app(self,v): # v = [a,b,c,d]
'''Retourne l'application de la matrice self au vecteur v vu
comme une liste
plate. Le résultat est aussi une liste plate.'''
if __debug__:
print("Matrix.py : app")
# transformation de la liste v en matrice uni-colonne
mv = Matrix(list(map(lambda x:[x],v))) # mv = [[a],[b],[c],[d]]
# l'application n'est autre qu'un produit de matrices
res = self * mv # objet de type Mat
#print("app : res =\n"); print(res)
res = res.L # objet de type list
# et on ré-aplatit la liste
return list(map(lambda L:L[0],res))
# R : multiplicand
# m1=Matrix(lambda i,j : i+j, 5,2)
# # Matrix constructor Matrix (function,Numeric,Numeric) #
# m1*(-2,-3.5)
# Matrix.py : __mul__(Matrix,Iterable)
# # Matrix constructor Matrix,list #
# Matrix.py : __mul__(Matrix,Matrix)
# # Matrix constructor Matrix (function,Numeric,Numeric) #
# [-3.5, -9.0, -14.5, -20.0, -25.5]
@multimethod
def __mul__(self, R : Iterable): # self is at LEFT of
multiplication operand : self * R = Matrix * R, R is at Right
if __debug__:
print("Matrix.py : __mul__(Matrix,Iterable)")
return self.app(R)
# R : multiplicand
# matrix multiplication
# m2=Matrix([[-2],[-3.5]])
# # Matrix constructor Matrix,list #
# m2
# -2.00
# -3.50
# Matrix @ 0x10127f490
# m1*m2
# Matrix.py : __mul__(Matrix,Matrix)
# # Matrix constructor Matrix (function,Numeric,Numeric) #
# -3.50
# -9.00
# -14.50
# -20.00
# -25.50
# Matrix @ 0x1012a7810
@multimethod
def __mul__(self, m2 : object): # self is at LEFT of
multiplication operand : self * m2 = Matrix * m2 = Matrix * Matrix, m2
is at Right of operator
if __debug__:
print("Matrix.py : __mul__(Matrix,Matrix)")
(n1,p1) = self.dim()
(n2,p2) = m2.dim()
if p1 != n2 : raise MatError('Produit de matrices impossible !')
def res(i,j) : # l'élément en ligne i et colonne
j du résultat
return sum(self.L[i][k] * m2.L[k][j] for k in range(p1))
# le produit aura pour format (n1,p2)
return Matrix(res,n1,p2)
On Fri, Oct 6, 2023 at 7:49 PM <tomas@tuxteam.de> wrote:
>
> On Fri, Oct 06, 2023 at 07:23:10PM +0200, Damien Mattei wrote:
> > and the rest of code for multiplying a matrix and a vector:
>
> [...]
>
> I haven't looked at all the details, but... isn't multiplying a
> matrix with a vector just a special case of matrix multiplication?
>
> Cheers
> --
> t
- matrix library?, Damien Mattei, 2023/10/04
- Re: matrix library?, tomas, 2023/10/04
- Re: matrix library?, Nala Ginrut, 2023/10/04
- Re: matrix library?, Damien Mattei, 2023/10/04
- Re: matrix library?, tomas, 2023/10/04
- Re: matrix library?, Damien Mattei, 2023/10/04
- Re: matrix library?, Damien Mattei, 2023/10/05
- Re: matrix library?, Damien Mattei, 2023/10/06
- Re: matrix library?, tomas, 2023/10/06
- Re: matrix library?,
Damien Mattei <=