(cls, *args)
Construct a Trace object.

        Parameters
        ==========
        args = sympy expression
        indices = tuple/list if indices, optional
Construct a Trace object.
Construct a Trace object .
def __new__(cls, *args):
        """ Construct a Trace object.

        Parameters
        ==========
        args = sympy expression
        indices = tuple/list if indices, optional

        """

        # expect no indices,int or a tuple/list/Tuple
        if (len(args) == 2):
            if not isinstance(args[1], (list, Tuple, tuple)):
                indices = Tuple(args[1])
            else:
                indices = Tuple(*args[1])

            expr = args[0]
        elif (len(args) == 1):
            indices = Tuple()
            expr = args[0]
        else:
            raise ValueError("Arguments to Tr should be of form "
                             "(expr[, [indices]])")

        if isinstance(expr, Matrix):
            return expr.trace()
        elif hasattr(expr, 'trace') and callable(expr.trace):
            #for any objects that have trace() defined e.g numpy
            return expr.trace()
        elif isinstance(expr, Add):
            return Add(*[Tr(arg, indices) for arg in expr.args])
        elif isinstance(expr, Mul):
            c_part, nc_part = expr.args_cnc()
            if len(nc_part) == 0:
                return Mul(*c_part)
            else:
                obj = Expr.__new__(cls, Mul(*nc_part), indices )
                #this check is needed to prevent cached instances
                #being returned even if len(c_part)==0
                return Mul(*c_part)*obj if len(c_part) > 0 else obj
        elif isinstance(expr, Pow):
            if (_is_scalar(expr.args[0]) and
                    _is_scalar(expr.args[1])):
                return expr
            else:
                return Expr.__new__(cls, expr, indices)
        else:
            if (_is_scalar(expr)):
                return expr

            return Expr.__new__(cls, expr, indices)
def __new__ ( cls , * args ) : # expect no indices,int or a tuple/list/Tuple if ( len ( args ) == 2 ) : if not isinstance ( args [ 1 ] , ( list , Tuple , tuple ) ) : indices = Tuple ( args [ 1 ] ) else : indices = Tuple ( * args [ 1 ] ) expr = args [ 0 ] elif ( len ( args ) == 1 ) : indices = Tuple ( ) expr = args [ 0 ] else : raise ValueError ( "Arguments to Tr should be of form " "(expr[, [indices]])" ) if isinstance ( expr , Matrix ) : return expr . trace ( ) elif hasattr ( expr , 'trace' ) and callable ( expr . trace ) : #for any objects that have trace() defined e.g numpy return expr . trace ( ) elif isinstance ( expr , Add ) : return Add ( * [ Tr ( arg , indices ) for arg in expr . args ] ) elif isinstance ( expr , Mul ) : c_part , nc_part = expr . args_cnc ( ) if len ( nc_part ) == 0 : return Mul ( * c_part ) else : obj = Expr . __new__ ( cls , Mul ( * nc_part ) , indices ) #this check is needed to prevent cached instances #being returned even if len(c_part)==0 return Mul ( * c_part ) * obj if len ( c_part ) > 0 else obj elif isinstance ( expr , Pow ) : if ( _is_scalar ( expr . args [ 0 ] ) and _is_scalar ( expr . args [ 1 ] ) ) : return expr else : return Expr . __new__ ( cls , expr , indices ) else : if ( _is_scalar ( expr ) ) : return expr return Expr . __new__ ( cls , expr , indices )