Does this work?

    def linear_expand(e):
        from sympy.utilities.iterables import sift
        d = sift(Add.make_args(e), lambda i: i.is_commutative)
        t0 = (Add._from_args(d[True]),)
        n0 = (S.One,)
        e = d[False]
        if not e:
            return t0, n0
        h, t = zip(*[[Mul._from_args(i) for i in t.args_cnc()]
            for t in e])
        return t0 + h, n0 + t

    def projection(h, t, *sym):
        assert len(h) == len(t)
        rv = []
        for i in range(len(h)):
            if t[i].has(*sym):
                rv.append((h[i], t[i]))
        rv = tuple(zip(*rv))
        if not rv:
            rv = ((), ())
        return rv

    >>> linear_expand(1+a*A+3*b*B)
    ((1, a, 3*b), (1, A, B))
    >>> c,nc=_
    >>> projection(c,nc,A)
    ((a,), (A,))
    >>> scalar = c[0]; scalar
    1
    >>> linear_expand(3*b*B)
    ((0, 3*b), (1, B))
    >>> c,nc=_
    >>> projection(c,nc,A)
    ((), ())
    >>> scalar = c[0]; scalar
    0

Something like this could probably go in exprtools. There is already a
class Term in there for """Efficient representation of
``coeff*(numer/denom)``. """ So you might have a class Linear that
implements the expand, projection and scalar methods.

/c

-- 
You received this message because you are subscribed to the Google Groups 
"sympy" group.
To post to this group, send email to [email protected].
To unsubscribe from this group, send email to 
[email protected].
For more options, visit this group at 
http://groups.google.com/group/sympy?hl=en.

Reply via email to