There are not these routines yet.  In the attached file there is a function 
to eliminate a scalar from
a tensor product (not much tested)

```
>>> Lorentz = TensorIndexType('Lorentz', dummy_fmt='L')
>>> i0,i1,i2,i3,i4 = tensor_indices('i0:5', Lorentz)
>>> p1, p2, p3, p4 = tensorhead('p1:5', [Lorentz], [[1]])
>>> t = 2*p1(i0)*p2(-i0)*p1(i1)*p3(-i1)*p1(i2)
>>> t = t.canon_bp()
>>> s = (p1(i2)*p3(-i2)).canon_bp()
>>> mul_eliminate_scalar(t, s)
2*p1(i2)*p1(L_0)*p2(-L_0)
```

To substitute a scalar with another expression eliminate the scalar, then 
multiply by the other
expression.
I think that in general to apply some transformation rule one can do the 
matching examining
the graph-like data structure of TensMul, while to apply a rule one can use 
``a = t.split()``, 
do the modifications to ``a`` and then reconstruct the new tensor with 
``Mul(*a)``.

This strategy is used in PR 1699 to manipulate gamma matrices and to 
compute group factors.

On Tuesday, April 30, 2013 2:20:51 PM UTC+2, Stefan Krastanov wrote:
>
> Hi all, 
>
> I would like to know what is the correct way to pattern match and 
> substitute expressions in the new tensor canonicalization module. 
>
> For instance: 
>
> >>> Lorentz = TensorIndexType('Lorentz') 
> >>> i0,i1 = tensor_indices('i0:1', Lorentz) 
> >>> A = tensorhead('A', [Lorentz], [[1]]) 
> >>> B = tensorhead('B', [Lorentz], [[1]]) 
>
> I need something that will match any of these: 
>
> A(i0)*B(-i0) 
> B(-i0)*A(i0) 
> A(i1)*B(-i1) 
>
> Any suggestions? 
>
>
> Thanks 
>

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


from sympy import *
from sympy.tensor.tensor import *

def mul_match_scalar(t, s):
    """
    find a scalar ``s=A(i)*B(-i)`` in a TensMul ``t``, both in canonical form
    Returns the position of ``s`` in ``t._dum`` or ``None`` 
    """
    assert t._is_canon_bp and s._is_canon_bp
    t_comps = t._components
    s_comps = s._components
    if not (len(s_comps) == 2 and not s._free and len(s._dum) == 1):
        raise ValueError
    if set(s_comps) & set(t_comps) != set(s_comps):
        return None
    sc1, sc2 = s_comps
    for i, (ipos1, ipos2, cpos1, cpos2) in enumerate(t._dum):
        if ipos1 == 0 and ipos2 == 0 and \
           t_comps[cpos1] == sc1 and t_comps[cpos2] == sc2:
           return i
    return None

def mul_eliminate_scalar(t, s):
    """
    eliminate a scalar ``s=A(i)*B(-i) `` in a TensMul ``t``, 
    both in canonical form, with ``A`` and ``B`` commuting.
    """
    # TODO add check that the components of s are commutind
    # or make changes for the case in which they are not
    m = mul_match_scalar(t, s)
    if m is None:
        return t
    a = t.split()
    _, _, i, j = t._dum[m]
    # the coefficient of the tensor goes with the first component tensor
    ct = t._coeff if i == 0 else S.One
    a1 = a[:i] + a[i+1:j] + a[j+1:]
    t1 = ct*tensor_mul(*a1)
    return t1


def test1():
    Lorentz = TensorIndexType('Lorentz', dummy_fmt='L')
    i0,i1,i2,i3,i4 = tensor_indices('i0:5', Lorentz)
    p1, p2, p3, p4 = tensorhead('p1:5', [Lorentz], [[1]])
    t = 2*p1(i0)*p2(-i0)*p1(i1)*p3(-i1)*p1(i2)
    s = p1(i2)*p3(-i2)
    t = t.canon_bp()
    s = s.canon_bp()
    m = mul_match_scalar(t, s)
    assert m == 1
    s = (p1(i2)*p2(-i2)).canon_bp()
    m = mul_match_scalar(t, s)
    assert m == 0
    s = (p1(i2)*p1(-i2)).canon_bp()
    m = mul_match_scalar(t, s)
    assert m is None
    a = t.split()
    s = (p1(i2)*p3(-i2)).canon_bp()
    t1 = mul_eliminate_scalar(t, s)
    assert t1 ==  2*p1(i0)*p2(-i0)*p1(i2)
    s = (p1(i2)*p1(-i2)).canon_bp()
    t1 = mul_eliminate_scalar(t, s)
    assert t1 == t


test1()

Reply via email to