(self, t)
Evaluate the trace of a single gamma matrix line inside a ``TensExpr``.

        Notes
        =====

        If there are ``DiracSpinorIndex.auto_left`` and ``DiracSpinorIndex.auto_right``
        indices trace over them; otherwise traces are not implied (explain)


        Examples
        ========

        >>> from sympy.physics.hep.gamma_matrices import GammaMatrix as G
        >>> from sympy.tensor.tensor import tensor_indices, tensorhead
        >>> p = tensorhead('p', [G.LorentzIndex], [[1]])
        >>> i0,i1,i2,i3,i4,i5 = tensor_indices('i0:6', G.LorentzIndex)
        >>> G._trace_single_line(G(i0)*G(i1))
        4*metric(i0, i1)
        >>> G._trace_single_line(G(i0)*p(-i0)*G(i1)*p(-i1)) - 4*p(i0)*p(-i0)
        0
Evaluate the trace of a single gamma matrix line inside a ``TensExpr``.
Evaluate the trace of a single gamma matrix line inside a TensExpr .
def _trace_single_line(self, t):
        """
        Evaluate the trace of a single gamma matrix line inside a ``TensExpr``.

        Notes
        =====

        If there are ``DiracSpinorIndex.auto_left`` and ``DiracSpinorIndex.auto_right``
        indices trace over them; otherwise traces are not implied (explain)


        Examples
        ========

        >>> from sympy.physics.hep.gamma_matrices import GammaMatrix as G
        >>> from sympy.tensor.tensor import tensor_indices, tensorhead
        >>> p = tensorhead('p', [G.LorentzIndex], [[1]])
        >>> i0,i1,i2,i3,i4,i5 = tensor_indices('i0:6', G.LorentzIndex)
        >>> G._trace_single_line(G(i0)*G(i1))
        4*metric(i0, i1)
        >>> G._trace_single_line(G(i0)*p(-i0)*G(i1)*p(-i1)) - 4*p(i0)*p(-i0)
        0

        """
        def _trace_single_line1(t):
            t = t.sorted_components()
            components = t.components
            ncomps = len(components)
            g = self.LorentzIndex.metric
            sg = DiracSpinorIndex.delta
            # gamma matirices are in a[i:j]
            hit = 0
            for i in range(ncomps):
                if isinstance(components[i], GammaMatrixHead):
                    hit = 1
                    break

            for j in range(i + hit, ncomps):
                if not isinstance(components[j], GammaMatrixHead):
                    break
            else:
                j = ncomps
            numG = j - i
            if numG == 0:
                spinor_free = [_[0] for _ in t._tids.free if _[0].tensortype is DiracSpinorIndex]
                tcoeff = t.coeff
                if spinor_free == [DiracSpinorIndex.auto_left, -DiracSpinorIndex.auto_right]:
                    t = t*DiracSpinorIndex.delta(-DiracSpinorIndex.auto_left, DiracSpinorIndex.auto_right)
                    t = t.contract_metric(sg)
                    return t/tcoeff if tcoeff else t
                else:
                    return t/tcoeff if tcoeff else t
            if numG % 2 == 1:
                return TensMul.from_data(S.Zero, [], [], [])
            elif numG > 4:
                t = t.substitute_indices((-DiracSpinorIndex.auto_right, -DiracSpinorIndex.auto_index), (DiracSpinorIndex.auto_left, DiracSpinorIndex.auto_index))
                a = t.split()
                ind1, lind1, rind1 = a[i].args[-1]
                ind2, lind2, rind2 = a[i + 1].args[-1]
                aa = a[:i] + a[i + 2:]
                t1 = tensor_mul(*aa)*g(ind1, ind2)*sg(lind1, rind1)*sg(lind2, rind2)
                t1 = t1.contract_metric(g)
                t1 = t1.contract_metric(sg)
                args = [t1]
                sign = 1
                for k in range(i + 2, j):
                    sign = -sign
                    ind2, lind2, rind2 = a[k].args[-1]
                    aa = a[:i] + a[i + 1:k] + a[k + 1:]
                    t2 = sign*tensor_mul(*aa)*g(ind1, ind2)*sg(lind1, rind1)*sg(lind2, rind2)
                    t2 = t2.contract_metric(g)
                    t2 = t2.contract_metric(sg)

                    t2 = GammaMatrixHead.simplify_gpgp(t2, False)
                    args.append(t2)
                t3 = TensAdd(*args)

                #aa = _tensorlist_contract_metric(aa, g(ind1, ind2))
                #t3 = t3.canon_bp()
                t3 = self._trace_single_line(t3)
                return t3
            else:
                a = t.split()
                if len(t.components) == 1:
                    if t.components[0] is DiracSpinorIndex.delta:
                        return 4  # FIXME only for D=4
                t1 = self._gamma_trace1(*a[i:j])
                a2 = a[:i] + a[j:]
                t2 = tensor_mul(*a2)
                t3 = t1*t2
                if not t3:
                    return t3
                t3 = t3.contract_metric(g)
                return t3

        if isinstance(t, TensAdd):
            a = [x.coeff*_trace_single_line1(x) for x in t.args]
            return TensAdd(*a)
        elif isinstance(t, TensMul):
            r = t.coeff*_trace_single_line1(t)
            return r
        else:
            return t
def _trace_single_line ( self , t ) : def _trace_single_line1 ( t ) : t = t . sorted_components ( ) components = t . components ncomps = len ( components ) g = self . LorentzIndex . metric sg = DiracSpinorIndex . delta # gamma matirices are in a[i:j] hit = 0 for i in range ( ncomps ) : if isinstance ( components [ i ] , GammaMatrixHead ) : hit = 1 break for j in range ( i + hit , ncomps ) : if not isinstance ( components [ j ] , GammaMatrixHead ) : break else : j = ncomps numG = j - i if numG == 0 : spinor_free = [ _ [ 0 ] for _ in t . _tids . free if _ [ 0 ] . tensortype is DiracSpinorIndex ] tcoeff = t . coeff if spinor_free == [ DiracSpinorIndex . auto_left , - DiracSpinorIndex . auto_right ] : t = t * DiracSpinorIndex . delta ( - DiracSpinorIndex . auto_left , DiracSpinorIndex . auto_right ) t = t . contract_metric ( sg ) return t / tcoeff if tcoeff else t else : return t / tcoeff if tcoeff else t if numG % 2 == 1 : return TensMul . from_data ( S . Zero , [ ] , [ ] , [ ] ) elif numG > 4 : t = t . substitute_indices ( ( - DiracSpinorIndex . auto_right , - DiracSpinorIndex . auto_index ) , ( DiracSpinorIndex . auto_left , DiracSpinorIndex . auto_index ) ) a = t . split ( ) ind1 , lind1 , rind1 = a [ i ] . args [ - 1 ] ind2 , lind2 , rind2 = a [ i + 1 ] . args [ - 1 ] aa = a [ : i ] + a [ i + 2 : ] t1 = tensor_mul ( * aa ) * g ( ind1 , ind2 ) * sg ( lind1 , rind1 ) * sg ( lind2 , rind2 ) t1 = t1 . contract_metric ( g ) t1 = t1 . contract_metric ( sg ) args = [ t1 ] sign = 1 for k in range ( i + 2 , j ) : sign = - sign ind2 , lind2 , rind2 = a [ k ] . args [ - 1 ] aa = a [ : i ] + a [ i + 1 : k ] + a [ k + 1 : ] t2 = sign * tensor_mul ( * aa ) * g ( ind1 , ind2 ) * sg ( lind1 , rind1 ) * sg ( lind2 , rind2 ) t2 = t2 . contract_metric ( g ) t2 = t2 . contract_metric ( sg ) t2 = GammaMatrixHead . simplify_gpgp ( t2 , False ) args . append ( t2 ) t3 = TensAdd ( * args ) #aa = _tensorlist_contract_metric(aa, g(ind1, ind2)) #t3 = t3.canon_bp() t3 = self . _trace_single_line ( t3 ) return t3 else : a = t . split ( ) if len ( t . components ) == 1 : if t . components [ 0 ] is DiracSpinorIndex . delta : return 4 # FIXME only for D=4 t1 = self . _gamma_trace1 ( * a [ i : j ] ) a2 = a [ : i ] + a [ j : ] t2 = tensor_mul ( * a2 ) t3 = t1 * t2 if not t3 : return t3 t3 = t3 . contract_metric ( g ) return t3 if isinstance ( t , TensAdd ) : a = [ x . coeff * _trace_single_line1 ( x ) for x in t . args ] return TensAdd ( * a ) elif isinstance ( t , TensMul ) : r = t . coeff * _trace_single_line1 ( t ) return r else : return t