(e, **kw_args)
return e
Returns the normal ordered equivalent of an expression using Wicks Theorem.


    Examples
    ========

    >>> from sympy import symbols, Function, Dummy
    >>> from sympy.physics.secondquant import wicks, F, Fd, NO
    >>> p,q,r = symbols('p,q,r')
    >>> wicks(Fd(p)*F(q))  # doctest: +SKIP
    d(p, q)*d(q, _i) + NO(CreateFermion(p)*AnnihilateFermion(q))

    By default, the expression is expanded:

    >>> wicks(F(p)*(F(q)+F(r))) # doctest: +SKIP
    NO(AnnihilateFermion(p)*AnnihilateFermion(q)) + NO(
        AnnihilateFermion(p)*AnnihilateFermion(r))

    With the keyword 'keep_only_fully_contracted=True', only fully contracted
    terms are returned.

    By request, the result can be simplified in the following order:
     -- KroneckerDelta functions are evaluated
     -- Dummy variables are substituted consistently across terms

    >>> p, q, r = symbols('p q r', cls=Dummy)
    >>> wicks(Fd(p)*(F(q)+F(r)), keep_only_fully_contracted=True) # doctest: +SKIP
    KroneckerDelta(_i, _q)*KroneckerDelta(
        _p, _q) + KroneckerDelta(_i, _r)*KroneckerDelta(_p, _r)
Returns the normal ordered equivalent of an expression using Wicks Theorem.
Returns the normal ordered equivalent of an expression using Wicks Theorem .
def wicks(e, **kw_args):
    """
    Returns the normal ordered equivalent of an expression using Wicks Theorem.


    Examples
    ========

    >>> from sympy import symbols, Function, Dummy
    >>> from sympy.physics.secondquant import wicks, F, Fd, NO
    >>> p,q,r = symbols('p,q,r')
    >>> wicks(Fd(p)*F(q))  # doctest: +SKIP
    d(p, q)*d(q, _i) + NO(CreateFermion(p)*AnnihilateFermion(q))

    By default, the expression is expanded:

    >>> wicks(F(p)*(F(q)+F(r))) # doctest: +SKIP
    NO(AnnihilateFermion(p)*AnnihilateFermion(q)) + NO(
        AnnihilateFermion(p)*AnnihilateFermion(r))

    With the keyword 'keep_only_fully_contracted=True', only fully contracted
    terms are returned.

    By request, the result can be simplified in the following order:
     -- KroneckerDelta functions are evaluated
     -- Dummy variables are substituted consistently across terms

    >>> p, q, r = symbols('p q r', cls=Dummy)
    >>> wicks(Fd(p)*(F(q)+F(r)), keep_only_fully_contracted=True) # doctest: +SKIP
    KroneckerDelta(_i, _q)*KroneckerDelta(
        _p, _q) + KroneckerDelta(_i, _r)*KroneckerDelta(_p, _r)

    """

    if not e:
        return S.Zero

    opts = {
        'simplify_kronecker_deltas': False,
        'expand': True,
        'simplify_dummies': False,
        'keep_only_fully_contracted': False
    }
    opts.update(kw_args)

    # check if we are already normally ordered
    if isinstance(e, NO):
        if opts['keep_only_fully_contracted']:
            return S.Zero
        else:
            return e
    elif isinstance(e, FermionicOperator):
        if opts['keep_only_fully_contracted']:
            return S.Zero
        else:
            return e

    # break up any NO-objects, and evaluate commutators
    e = e.doit(wicks=True)

    # make sure we have only one term to consider
    e = e.expand()
    if isinstance(e, Add):
        if opts['simplify_dummies']:
            return substitute_dummies(Add(*[ wicks(term, **kw_args) for term in e.args]))
        else:
            return Add(*[ wicks(term, **kw_args) for term in e.args])

    # For Mul-objects we can actually do something
    if isinstance(e, Mul):

        # we dont want to mess around with commuting part of Mul
        # so we factorize it out before starting recursion
        c_part = []
        string1 = []
        for factor in e.args:
            if factor.is_commutative:
                c_part.append(factor)
            else:
                string1.append(factor)
        n = len(string1)

        # catch trivial cases
        if n == 0:
            result = e
        elif n == 1:
            if opts['keep_only_fully_contracted']:
                return S.Zero
            else:
                result = e

        else:  # non-trivial

            if isinstance(string1[0], BosonicOperator):
                raise NotImplementedError

            string1 = tuple(string1)

            # recursion over higher order contractions
            result = _get_contractions(string1,
                keep_only_fully_contracted=opts['keep_only_fully_contracted'] )
            result = Mul(*c_part)*result

        if opts['expand']:
            result = result.expand()
        if opts['simplify_kronecker_deltas']:
            result = evaluate_deltas(result)

        return result

    # there was nothing to do
    return e
def wicks ( e , * * kw_args ) : if not e : return S . Zero opts = { 'simplify_kronecker_deltas' : False , 'expand' : True , 'simplify_dummies' : False , 'keep_only_fully_contracted' : False } opts . update ( kw_args ) # check if we are already normally ordered if isinstance ( e , NO ) : if opts [ 'keep_only_fully_contracted' ] : return S . Zero else : return e elif isinstance ( e , FermionicOperator ) : if opts [ 'keep_only_fully_contracted' ] : return S . Zero else : return e # break up any NO-objects, and evaluate commutators e = e . doit ( wicks = True ) # make sure we have only one term to consider e = e . expand ( ) if isinstance ( e , Add ) : if opts [ 'simplify_dummies' ] : return substitute_dummies ( Add ( * [ wicks ( term , * * kw_args ) for term in e . args ] ) ) else : return Add ( * [ wicks ( term , * * kw_args ) for term in e . args ] ) # For Mul-objects we can actually do something if isinstance ( e , Mul ) : # we dont want to mess around with commuting part of Mul # so we factorize it out before starting recursion c_part = [ ] string1 = [ ] for factor in e . args : if factor . is_commutative : c_part . append ( factor ) else : string1 . append ( factor ) n = len ( string1 ) # catch trivial cases if n == 0 : result = e elif n == 1 : if opts [ 'keep_only_fully_contracted' ] : return S . Zero else : result = e else : # non-trivial if isinstance ( string1 [ 0 ] , BosonicOperator ) : raise NotImplementedError string1 = tuple ( string1 ) # recursion over higher order contractions result = _get_contractions ( string1 , keep_only_fully_contracted = opts [ 'keep_only_fully_contracted' ] ) result = Mul ( * c_part ) * result if opts [ 'expand' ] : result = result . expand ( ) if opts [ 'simplify_kronecker_deltas' ] : result = evaluate_deltas ( result ) return result # there was nothing to do return e