I think I am going to rewrite GA the code is much simpler (and shorter)
and better use the abilities of python and sympy. Below is an exercise
to get started. I define a simple vector class that inherits from the
sympy Expr (expression) class. Then I can define fuctions of vectors in
the class such as dot (2 vector arguments) and triple (3 vector
arguments). For the purpose of the exercise both return scalars (sympy
symbols). The problem is that the linear combination of vectors is a
sympy Mul or Add type and dot and triple doesn't know what to do with
them as an arguments. The trick is in the function
multilinear_function. It accepts argument of type Type (in our example
vector). Performs the multilinear expansion and applies the correct
arguments to the function Fct (in out example vector.dot or
vector.triple). I think this is really neat!!!
What I need to do is define __or__ and __and__ operators (as bilinear
operators) for sympy expressions. Is there a way I can do this without
changing the core code of sympy?
from sympy import *
import itertools as it
import sys
def multilinear_function(*args,**kwargs):
"""
function Fct of dim arguments of type Type
"""
Fct = kwargs['Fct']
Type = kwargs['Type']
dim = kwargs['dim']
if dim != len(args):
err_str = str(Type)+'.'+str(Fct.__name__)+' does not have
'+str(dim)+' args\n'
sys.stderr.write(err_str)
sys.exit(1)
vlst = []
for v in args:
vlst.append(expand(v))
v = tuple(vlst)
vlst = []
for x in v:
vlst.append(x._args)
sum_range = tuple(it.product(*(tuple(vlst))))
f = 0
for x in sum_range:
scalar = 1
args = []
for v in x:
if len(v._args) == 2:
if isinstance(v,Mul):
scalar *= v._args[0]
args.append(v._args[1])
if isinstance(v,Type):
args.append(v._args[0])
else:
if isinstance(v,Type):
args.append(v)
args = tuple(args)
f += scalar*Fct(*args)
return(f)
class vector(Expr):
is_commutative = False
def __new__(cls, label, shape=None, **kw_args):
label = sympify(label)
obj = Expr.__new__(cls, label, **kw_args)
obj.label = label
return obj
@staticmethod
def dot(v1,v2):
v_lst = [str(v1.label),str(v2.label)]
v_lst.sort()
return(Symbol(v_lst[0]+'.'+v_lst[1]))
@staticmethod
def triple(v1,v2,v3):
v_lst = [str(v1.label),str(v2.label),str(v3.label)]
v_lst.sort()
return(Symbol(v_lst[0]+'.'+v_lst[1]+'.'+v_lst[2]))
def _sympystr(self, p):
return p.doprint(self.label)
def dot(x,y):
return(multilinear_function(x,y,Fct=vector.dot,Type=vector,dim=2))
def triple(x,y,z):
return(multilinear_function(x,y,z,Fct=vector.triple,Type=vector,dim=3))
v1 = vector('v1')
v2 = vector('v2')
V1 = v1+v2
V2 = 3*v1+v2
V3 = 2*v1-3*v2
print dot(V1,V2)
#3*v1.v1 + 4*v1.v2 + v2.v2
print triple(V1,V2,V3)
#6*v1.v1.v1 - v1.v1.v2 - 10*v1.v2.v2 - 3*v2.v2.v2
--
You received this message because you are subscribed to the Google Groups
"sympy" group.
To post to this group, send email to sympy@googlegroups.com.
To unsubscribe from this group, send email to
sympy+unsubscr...@googlegroups.com.
For more options, visit this group at
http://groups.google.com/group/sympy?hl=en.