On 02/12/2012 05:59 PM, Alan Bromborsky wrote:
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
Please disregard my question. I figured out the correct way to do what
I want with inheritance.
--
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.