Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Devel matrices #147

Open
wants to merge 21 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 11 commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
a6e4faa
add Matrix object
ratnania Feb 19, 2024
9f84773
add Vector class
ratnania Feb 19, 2024
b9fe24e
mv matrices to core
ratnania Feb 19, 2024
572011d
TerminalExpr for sympde objects: Matrix and Vector
ratnania Feb 19, 2024
3a658bc
add __eq__ to vector and matrix
ratnania Feb 21, 2024
d02fd51
add new tests for matrices and vectors
ratnania Feb 21, 2024
760fdd1
add to_tympy method that converts Matrix/Vector to ImmutableDenseMatr…
ratnania Feb 21, 2024
e51563c
fixing test_norm_2d_2 test, for Norm
ratnania Feb 21, 2024
d9bcba7
convert Norm expression Matrix/Vector to sympy
ratnania Feb 21, 2024
d1928b4
fix evaluation of Vector in TerminalExpr
ratnania Feb 21, 2024
bdfe6eb
update mapping and derivatives to use Vector as input instead of Tupl…
ratnania Feb 22, 2024
369e295
we should only name a variable as _ if it is a local variable which i…
ratnania Mar 2, 2024
0ffdf16
rm commented line
ratnania Mar 2, 2024
4a7d8c4
fix exception for codacy
ratnania Mar 2, 2024
20e8c31
we should only name a variable as _ if it is a local variable which i…
ratnania Mar 2, 2024
fb0c1e6
rm try/except from __getitem__
ratnania Mar 2, 2024
46b97b8
clean declaration of test functions
ratnania Mar 2, 2024
93815b6
improve test equality between two Matrices or Vectors + add tests
ratnania Mar 2, 2024
7f83e33
improve Vector & Matrix class constructors
ratnania Mar 2, 2024
74e7475
Check equality of Cross arguments after simplifications
ratnania Mar 2, 2024
67d4e00
Clean some white spaces in test_expr.py
yguclu Mar 2, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
1 change: 0 additions & 1 deletion sympde/calculus/__init__.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,2 @@
from .core import *
from .errors import *
from .matrices import *
1 change: 1 addition & 0 deletions sympde/core/__init__.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
from .algebra import *
from .basic import *
from .utils import *
from .matrices import *
122 changes: 122 additions & 0 deletions sympde/calculus/matrices.py → sympde/core/matrices.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,13 @@
from sympy import Expr, S
from sympy import Add, Mul, Pow
from sympy import Tuple
from sympy import sympify
from sympy.core.decorators import call_highest_priority
from sympde.core.basic import _coeffs_registery, Basic

from sympy import ImmutableDenseMatrix


class MatrixSymbolicExpr(Expr):
is_commutative = False
_op_priority = 20.0
Expand Down Expand Up @@ -289,6 +293,124 @@ def _sympystr(self, printer):
sstr = printer.doprint
return '{}[{}]'.format(sstr(self.args[0]),sstr(self.args[1]))

class Matrix(MatrixSymbolicExpr):

def __new__(cls, *args, **options):
name = options.pop('name')
if name is None:
raise ValueError('Expecting a name keyword.')

if not( len(args) == 1 ):
raise ValueError('Expecting one argument.')

_args = args[0]
if not isinstance(_args, list):
raise TypeError('Expecting a list.')

for _ in _args:
if not isinstance(_, list):
raise TypeError('args components must be a list.')

sizes = [len(_) for _ in _args]
if not( len(set(sizes)) == 1):
raise ValueError('Wrong matrix size')

# make _args a Tuple of Tuples
newargs = []
for _ in _args:
a = Tuple(*_)
newargs.append(a)
_args = Tuple(*newargs)

args = (_args, args[1:])

obj = Expr.__new__(cls, *args)
obj._name = name

return obj
ratnania marked this conversation as resolved.
Show resolved Hide resolved
ratnania marked this conversation as resolved.
Show resolved Hide resolved

@property
def name(self):
return self._name
ratnania marked this conversation as resolved.
Show resolved Hide resolved

def __getitem__(self, key):
try:
i,j = key
return self.args[0][i][j]
except:
return MatrixElement(self, key)
ratnania marked this conversation as resolved.
Show resolved Hide resolved

def _sympystr(self, printer):
sstr = printer.doprint
return '{}'.format(sstr(self.name))

def __hash__(self):
return hash((self.name, self.args))

def __eq__(self, a):
if isinstance(a, Matrix):
eq = self.name == a.name
return eq
return False

def to_sympy(self):
return ImmutableDenseMatrix(self.args[0])


class Vector(MatrixSymbolicExpr):

def __new__(cls, *args, **options):
name = options.pop('name')
if name is None:
raise ValueError('Expecting a name keyword.')

if not( len(args) == 1 ):
raise ValueError('Expecting one argument.')

_args = args[0]
if not isinstance(_args, list):
raise TypeError('Expecting a list.')

# make _args a Tuple
_args = Tuple(*_args)

args = (_args, args[1:])

obj = Expr.__new__(cls, *args)
obj._name = name

return obj

@property
def name(self):
return self._name

def __getitem__(self, key):
try:
i = key
return self.args[0][i]
except:
# TODO ARA do we keep returning a MatrixElement?
return MatrixElement(self, key)
ratnania marked this conversation as resolved.
Show resolved Hide resolved

def _sympystr(self, printer):
sstr = printer.doprint
return '{}'.format(sstr(self.name))

def __hash__(self):
return hash((self.name, self.args))

def __eq__(self, a):
if isinstance(a, Matrix):
eq = self.name == a.name
return eq
return False
ratnania marked this conversation as resolved.
Show resolved Hide resolved

def to_sympy(self):
_args = [[_] for _ in self.args[0]]
return ImmutableDenseMatrix(_args)
ratnania marked this conversation as resolved.
Show resolved Hide resolved


Basic._constructor_postprocessor_mapping[MatrixSymbolicExpr] = {
"Mul": [lambda x: MatSymbolicMul(*x.args)],
"Add": [lambda x: MatSymbolicAdd(*x.args)]
Expand Down
13 changes: 11 additions & 2 deletions sympde/expr/evaluation.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,12 +20,14 @@
Dot_2d, Inner_2d, Cross_2d,
Dot_3d, Inner_3d, Cross_3d)
from sympde.core.utils import random_string
from sympde.core.matrices import SymbolicDeterminant, Inverse, Transpose
from sympde.core.matrices import MatSymbolicPow, MatrixElement, SymbolicTrace
from sympde.core.matrices import Matrix as SympdeMatrix
from sympde.core.matrices import Vector as SympdeVector

from sympde.calculus import jump, avg, minus, plus
from sympde.calculus import Jump, is_zero
from sympde.calculus.core import _generic_ops, _diff_ops
from sympde.calculus.matrices import SymbolicDeterminant, Inverse, Transpose
from sympde.calculus.matrices import MatSymbolicPow, MatrixElement, SymbolicTrace

from sympde.topology.basic import BasicDomain, Union, Interval
from sympde.topology.basic import Boundary, Interface
Expand Down Expand Up @@ -614,6 +616,13 @@ def eval(cls, expr, domain):
elif isinstance(expr, Inverse):
return cls.eval(expr.arg, domain=domain).inv()

elif isinstance(expr, SympdeMatrix):
return expr.to_sympy()

elif isinstance(expr, SympdeVector):
# return ImmutableDenseMatrix([expr.args[0]])
return expr.to_sympy()
ratnania marked this conversation as resolved.
Show resolved Hide resolved

elif isinstance(expr, ScalarFunction):
return expr

Expand Down
16 changes: 12 additions & 4 deletions sympde/expr/expr.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@
from sympde.topology.space import ScalarFunction
from sympde.topology.space import VectorFunction
from sympde.topology.space import Trace, trace_0, trace_1
from sympde.core.matrices import Matrix as SympdeMatrix
from sympde.core.matrices import Vector

from .errors import UnconsistentLinearExpressionError
from .basic import BasicForm
Expand Down Expand Up @@ -538,9 +540,12 @@ def __new__(cls, expr, domain, kind='l2', evaluate=True, **options):
# ...

# ...
is_vector = isinstance(expr, (Matrix, ImmutableDenseMatrix, Tuple, list, tuple))
is_vector = isinstance(expr, (Vector, SympdeMatrix, Matrix, ImmutableDenseMatrix, Tuple, list, tuple))
if is_vector:
expr = ImmutableDenseMatrix(expr)
if isinstance(expr, (Vector, SympdeMatrix)):
expr = expr.to_sympy()
else:
expr = ImmutableDenseMatrix(expr)
# ...

# ...
Expand Down Expand Up @@ -610,9 +615,12 @@ def __new__(cls, expr, domain, kind='l2', evaluate=True, **options):
# ...

# ...
is_vector = isinstance(expr, (Matrix, ImmutableDenseMatrix, Tuple, list, tuple))
is_vector = isinstance(expr, (Vector, SympdeMatrix, Matrix, ImmutableDenseMatrix, Tuple, list, tuple))
if is_vector:
expr = ImmutableDenseMatrix(expr)
if isinstance(expr, (Vector, SympdeMatrix)):
expr = expr.to_sympy()
else:
expr = ImmutableDenseMatrix(expr)
# ...

# ...
Expand Down
13 changes: 6 additions & 7 deletions sympde/expr/tests/test_equation_2d.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@

#import pytest

from sympy.core.containers import Tuple
from sympy import pi, cos, sin
from sympy import ImmutableDenseMatrix as Matrix

Expand Down Expand Up @@ -48,7 +47,7 @@ def test_equation_2d_1():
int_0 = lambda expr: integral(domain , expr)
int_1 = lambda expr: integral(B1, expr)
int_2 = lambda expr: integral(B2, expr)

# ... bilinear/linear forms
expr = dot(grad(v), grad(u))
a1 = BilinearForm((v,u), int_0(expr))
Expand Down Expand Up @@ -169,7 +168,7 @@ def test_equation_2d_2():
alpha = Constant('alpha', real=True)

int_0 = lambda expr: integral(domain , expr)

s = BilinearForm((tau,sigma), int_0(dot(grad(tau), grad(sigma))))
m = BilinearForm((tau,sigma), int_0(tau*sigma))
b1 = BilinearForm((tau,dw), int_0(bracket(pn, dw) * tau))
Expand Down Expand Up @@ -202,7 +201,7 @@ def test_equation_2d_3():
x,y = domain.coordinates

B1 = Boundary(r'\Gamma_1', domain)

int_0 = lambda expr: integral(domain , expr)
int_1 = lambda expr: integral(B1, expr)

Expand Down Expand Up @@ -235,7 +234,7 @@ def test_equation_2d_4():
x,y = domain.coordinates

B1 = Boundary(r'\Gamma_1', domain)

int_0 = lambda expr: integral(domain , expr)
int_1 = lambda expr: integral(B1, expr)

Expand Down Expand Up @@ -283,7 +282,7 @@ def test_equation_2d_5():
p,q = [element_of(V, name=i) for i in ['p', 'q']]

int_0 = lambda expr: integral(domain , expr)

a0 = BilinearForm((v,u), int_0(inner(grad(v), grad(u))))
print(' a0 done.')
a1 = BilinearForm((q,p), int_0(p*q))
Expand Down Expand Up @@ -335,7 +334,7 @@ def test_equation_2d_6():
u,v = [element_of(V, name=i) for i in ['u', 'v']]

int_0 = lambda expr: integral(domain , expr)

# ...
expr = kappa * dot(grad(u), grad(v)) + dot(b, grad(u)) * v
a = BilinearForm((v,u), int_0(expr))
Expand Down