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.

Reply via email to