Exemple #1
0
def test_RaisingOp():
    assert Dagger(ad) == a
    assert Commutator(ad, a).doit() == Integer(-1)
    assert Commutator(ad, N).doit() == Integer(-1) * ad
    assert qapply(ad * k) == (sqrt(k.n + 1) * SHOKet(k.n + 1)).expand()
    assert qapply(ad * kz) == (sqrt(kz.n + 1) * SHOKet(kz.n + 1)).expand()
    assert qapply(ad * kf) == (sqrt(kf.n + 1) * SHOKet(kf.n + 1)).expand()
    assert ad.rewrite('xp').doit() == \
        (Integer(1)/sqrt(Integer(2)*hbar*m*omega))*(Integer(-1)*I*Px + m*omega*X)
    assert ad.hilbert_space == ComplexSpace(S.Infinity)
    for i in range(ndim - 1):
        assert ad_rep_sympy[i + 1, i] == sqrt(i + 1)

    if not np:
        skip("numpy not installed.")

    ad_rep_numpy = represent(ad, basis=N, ndim=4, format='numpy')
    for i in range(ndim - 1):
        assert ad_rep_numpy[i + 1, i] == float(sqrt(i + 1))

    if not np:
        skip("numpy not installed.")
    if not scipy:
        skip("scipy not installed.")

    ad_rep_scipy = represent(ad,
                             basis=N,
                             ndim=4,
                             format='scipy.sparse',
                             spmatrix='lil')
    for i in range(ndim - 1):
        assert ad_rep_scipy[i + 1, i] == float(sqrt(i + 1))

    assert ad_rep_numpy.dtype == 'float64'
    assert ad_rep_scipy.dtype == 'float64'
Exemple #2
0
def test_NumberOp():
    assert Commutator(N, ad).doit() == ad
    assert Commutator(N, a).doit() == Integer(-1) * a
    assert Commutator(N, H).doit() == Integer(0)
    assert qapply(N * k) == (k.n * k).expand()
    assert N().rewrite('a').doit() == ad * a
    assert N().rewrite(
        'H').doit() == H / (hbar * omega) - Integer(1) / Integer(2)
Exemple #3
0
def test_LoweringOp():
    assert Dagger(a) == ad
    assert Commutator(a, ad).doit() == Integer(1)
    assert Commutator(a, N).doit() == a
    assert qapply(a * k) == (sqrt(k.n) * SHOKet(k.n - Integer(1))).expand()
    assert qapply(a * kz) == Integer(0)
    assert qapply(a * kf) == (sqrt(kf.n) * SHOKet(kf.n - Integer(1))).expand()
    assert a().rewrite('xp').doit() == \
        (Integer(1)/sqrt(Integer(2)*hbar*m*omega))*(I*Px + m*omega*X)
Exemple #4
0
def test_RaisingOp():
    assert Dagger(ad) == a
    assert Commutator(ad, a).doit() == Integer(-1)
    assert Commutator(ad, N).doit() == Integer(-1) * ad
    assert qapply(ad * k) == (sqrt(k.n + 1) * SHOKet(k.n + 1)).expand()
    assert qapply(ad * kz) == (sqrt(kz.n + 1) * SHOKet(kz.n + 1)).expand()
    assert qapply(ad * kf) == (sqrt(kf.n + 1) * SHOKet(kf.n + 1)).expand()
    assert ad().rewrite('xp').doit() == \
        (Integer(1)/sqrt(Integer(2)*hbar*m*omega))*(Integer(-1)*I*Px + m*omega*X)
    assert ad.hilbert_space == ComplexSpace(S.Infinity)
Exemple #5
0
def test_NumberOp():
    assert Commutator(N, ad).doit() == ad
    assert Commutator(N, a).doit() == Integer(-1)*a
    assert Commutator(N, H).doit() == Integer(0)
    assert qapply(N*k) == (k.n*k).expand()
    assert N.rewrite('a').doit() == ad*a
    assert N.rewrite('xp').doit() == (Integer(1)/(Integer(2)*m*hbar*omega))*(
        Px**2 + (m*omega*X)**2) - Integer(1)/Integer(2)
    assert N.rewrite('H').doit() == H/(hbar*omega) - Integer(1)/Integer(2)
    for i in range(ndim):
        assert N_rep[i,i] == i
    assert N_rep == ad_rep_sympy*a_rep
Exemple #6
0
def test_LoweringOp():
    assert Dagger(a) == ad
    assert Commutator(a, ad).doit() == Integer(1)
    assert Commutator(a, N).doit() == a
    assert qapply(a * k) == (sqrt(k.n) * SHOKet(k.n - Integer(1))).expand()
    assert qapply(a * kz) == Integer(0)
    assert qapply(a * kf) == (sqrt(kf.n) * SHOKet(kf.n - Integer(1))).expand()
    assert a.rewrite("xp").doit() == (
        Integer(1) / sqrt(Integer(2) * hbar * m * omega)
    ) * (I * Px + m * omega * X)
    for i in range(ndim - 1):
        assert a_rep[i, i + 1] == sqrt(i + 1)
def sympy_nested_commutator_recursive(level, a, b):
    """
    Compute nested commutator of type [[...[[A, B], B], ...], B]
    :param level: the level of nested commutator
    :param a: Operator A
    :param b: Operator B
    :return: commutator of type Add
    """
    if level <= 1:
        return Commutator(a, b)
    for i in range(level)[::-1]:
        return Commutator(sympy_nested_commutator_recursive(i, a, b), b)
Exemple #8
0
def recursive_commutator(a, b, n=1):
    """
    Generate a recursive commutator of order n:

    [a, b]_1 = [a, b]
    [a, b]_2 = [a, [a, b]]
    [a, b]_3 = [a, [a, b]_2] = [a, [a, [a, b]]]
    ...

    """
    if n == 1:
        return Commutator(a, b)
    else:
        return Commutator(a, recursive_commutator(a, b, n - 1))
Exemple #9
0
def test_x():
    assert X.hilbert_space == L2(Interval(S.NegativeInfinity, S.Infinity))
    assert Commutator(X, Px).doit() == I * hbar
    assert qapply(X * XKet(x)) == x * XKet(x)
    assert XKet(x).dual_class() == XBra
    assert XBra(x).dual_class() == XKet
    assert (Dagger(XKet(y)) * XKet(x)).doit() == DiracDelta(x - y)
    assert (PxBra(px)*XKet(x)).doit() == \
        exp(-I*x*px/hbar)/sqrt(2*pi*hbar)
    assert represent(XKet(x)) == DiracDelta(x - x_1)
    assert represent(XBra(x)) == DiracDelta(-x + x_1)
    assert XBra(x).position == x
    assert represent(XOp() * XKet()) == x * DiracDelta(x - x_2)
    assert represent(XOp()*XKet()*XBra('y')) == \
        x*DiracDelta(x - x_3)*DiracDelta(x_1 - y)
    assert represent(XBra("y") * XKet()) == DiracDelta(x - y)
    assert represent(XKet() *
                     XBra()) == DiracDelta(x - x_2) * DiracDelta(x_1 - x)

    rep_p = represent(XOp(), basis=PxOp)
    assert rep_p == hbar * I * DiracDelta(px_1 -
                                          px_2) * DifferentialOperator(px_1)
    assert rep_p == represent(XOp(), basis=PxOp())
    assert rep_p == represent(XOp(), basis=PxKet)
    assert rep_p == represent(XOp(), basis=PxKet())

    assert represent(XOp()*PxKet(), basis=PxKet) == \
        hbar*I*DiracDelta(px - px_2)*DifferentialOperator(px)
Exemple #10
0
def test_j2():
    j, m = symbols('j m')
    assert Commutator(J2, Jz).doit() == 0
    assert qapply(J2 * JzKet(1, 1)) == 2 * hbar**2 * JzKet(1, 1)
    assert qapply(J2 * JzKet(
        j, m)) == j**2 * hbar**2 * JzKet(j, m) + j * hbar**2 * JzKet(j, m)
    assert J2.matrix_element(1, 1, 1, 1) == 2 * hbar**2
Exemple #11
0
def test_jx():
    assert Commutator(Jx, Jz).doit() == -I * hbar * Jy
    assert qapply(Jx * JzKet(1, 1)) == sqrt(2) * hbar * JzKet(1, 0) / 2
    assert Jx.rewrite('plusminus') == (Jminus + Jplus) / 2
    assert represent(Jx, basis=Jz,
                     j=1) == (represent(Jplus, basis=Jz, j=1) +
                              represent(Jminus, basis=Jz, j=1)) / 2
Exemple #12
0
def test_pauli_operators_commutator_with_labels():

    assert Commutator(sx1, sy1).doit() == 2 * I * sz1
    assert Commutator(sy1, sz1).doit() == 2 * I * sx1
    assert Commutator(sz1, sx1).doit() == 2 * I * sy1

    assert Commutator(sx2, sy2).doit() == 2 * I * sz2
    assert Commutator(sy2, sz2).doit() == 2 * I * sx2
    assert Commutator(sz2, sx2).doit() == 2 * I * sy2

    assert Commutator(sx1, sy2).doit() == 0
    assert Commutator(sy1, sz2).doit() == 0
    assert Commutator(sz1, sx2).doit() == 0
Exemple #13
0
    def _eval_commutator_OperatorFunction(self, other, **hints):
        from sympy.physics.quantum import Commutator

        if self.operator.args[0] == other.operator.args[0]:
            if str(self.variable) == str(other.variable):
                return Commutator(self.operator, other.operator).doit()

        return None
def test_bosonoperator():
    a = BosonOp('a')
    b = BosonOp('b')

    assert isinstance(a, BosonOp)
    assert isinstance(Dagger(a), BosonOp)

    assert a.is_annihilation
    assert not Dagger(a).is_annihilation

    assert BosonOp("a") == BosonOp("a", True)
    assert BosonOp("a") != BosonOp("c")
    assert BosonOp("a", True) != BosonOp("a", False)

    assert Commutator(a, Dagger(a)).doit() == 1

    assert Commutator(a, Dagger(b)).doit() == a * Dagger(b) - Dagger(b) * a
Exemple #15
0
def test_Hamiltonian():
    assert Commutator(H, N).doit() == Integer(0)
    assert qapply(H*k) == ((hbar*omega*(k.n + Integer(1)/Integer(2)))*k).expand()
    assert H.rewrite('a').doit() == hbar*omega*(ad*a + Integer(1)/Integer(2))
    assert H.rewrite('xp').doit() == \
        (Integer(1)/(Integer(2)*m))*(Px**2 + (m*omega*X)**2)
    assert H.rewrite('N').doit() == hbar*omega*(N + Integer(1)/Integer(2))
    for i in range(ndim):
        assert H_rep[i,i] == hbar*omega*(i + Integer(1)/Integer(2))
Exemple #16
0
def operator_master_equation(op_t, t, H, a_ops, use_eq=True):
    """
    Adjoint master equation
    """
    lhs = diff(op_t, t)
    rhs = (I * Commutator(H, op_t) +
           sum([operator_lindblad_dissipator(a, op_t) for a in a_ops]))

    return Eq(lhs, rhs) if use_eq else (lhs, rhs)
Exemple #17
0
def master_equation(rho_t, t, H, a_ops, use_eq=True):
    """
    Lindblad master equation
    """
    lhs = diff(rho_t, t)
    rhs = (-I * Commutator(H, rho_t) +
           sum([lindblad_dissipator(a, rho_t) for a in a_ops]))

    return Eq(lhs, rhs) if use_eq else (lhs, rhs)
Exemple #18
0
def test_x():
    assert X.hilbert_space == L2(Interval(S.NegativeInfinity, S.Infinity))
    assert Commutator(X, Px).doit() == I*hbar
    assert apply_operators(X*XKet(x)) == x*XKet(x)
    assert XKet(x).dual_class == XBra
    assert XBra(x).dual_class == XKet
    assert (Dagger(XKet(y))*XKet(x)).doit() == DiracDelta(x-y)
    assert (PxBra(px)*XKet(x)).doit() ==\
        exp(-I*x*px/hbar)/sqrt(2*pi*hbar)
    assert represent(XKet(x)) == x
    assert XBra(x).position == x
Exemple #19
0
def master_equation(rho_t, t, H, a_ops, use_eq=True):
    """
    Lindblad master equation
    """
    #t = [s for s in rho_t.free_symbols if isinstance(s, Symbol)][0]

    rhs = diff(rho_t, t)
    lhs = (-I * Commutator(H, rho_t) +
           sum([lindblad_dissipator(a, rho_t) for a in a_ops]))

    return Eq(rhs, lhs) if use_eq else (rhs, lhs)
Exemple #20
0
def bch_special_closed_form(X, Y, independent=False):
    """
    Return the exact solution to exp(X)*Y*exp(-X) in the special case that 
    [X, Y] = uX + vY + cI otherwise returns exp(X)*Y*exp(-X)
    
    See https://arxiv.org/abs/1501.02506v2 for derivation of this special-case 
    closed form to the Baker–Campbell–Hausdorff formula.
    """
    if not isinstance(Y, Operator):
        raise ValueError("Y must be an Operator")
    if debug: print("bch_special_closed_form()\nX =", X, "\nY =", Y)

    comm = Commutator(X, Y)
    while True:  # this should be implemented in Commutator class
        expr = comm.expand(commutator=True)
        if comm == expr: break
        else: comm = expr

    comm = simplify(comm.doit(independent=independent)).expand()
    if debug: print("comm: ", comm)
    if comm == 0: return Y

    # this will fail for X or Y if they are Adds, need better collect
    collected = collect_by_nc(comm, evaluate=False)
    u = collected[X] if X in collected else S.Zero
    v = collected[Y] if Y in collected else S.Zero
    c = collected[S.One] if S.One in collected else S.Zero

    if debug: print("u: ", u, "v: ", v, "c: ", c)
    if simplify((u * X + v * Y + c - comm).expand()) == 0:
        e = Y + comm * ((exp(v) - S.One) / v)  # Eq. 52 in above paper
        if v == 0:
            return Y + u * X + c  # instead of NaN
            #else: return e.expand()
        else:
            return exp(v) * Y + (u * X + c) * (1 - exp(v)) / v
    else:
        print("warning: special closed form doesn't apply...")
        return exp(X) * Y * exp(-X)
Exemple #21
0
def llegir_base(txt, opA, opB):
    f = open(txt, "r")
    linies = f.readlines()
    E = []
    E.append([0])
    i = 1
    for lin in linies:
        E.append([0])
        ls = lin.replace("\n", "").split(" ")[:-1]
        for j in range(0, len(ls)):
            item = ls[j].replace("[", "").replace("]", "")
            item_rev = item[::-1]
            com = opA
            if item_rev[0] == "B":
                com = opB
            for k in range(1, len(item_rev)):
                if item_rev[k] == "A":
                    com = Commutator(opA, com)
                else:
                    com = Commutator(opB, com)
            E[i].append(com)
        i += 1
    return E
Exemple #22
0
def comm_1(commutator_1, commutator_2, aux):
    """
    This function is not used directly, it is only used in the comm() function below. 

    Args:
        commutator_1: The first operator in the commutator
        commutator_2: The second operator in the commutator
        aux: The auxiliary function. This is defined below, as F(x).

    Returns:
        The commutator of commutator_1 and commutator_2 with respect to the auxiliary function.

    """

    return expand((Commutator(Operator(commutator_1), Operator(commutator_2)) *
                   aux).doit())
Exemple #23
0
def comm_steps(commutator_1, commutator_2, aux):
    """
    Args:    
        commutator_1: the first operator
        commutator_2: the second operator
        aux: the auxiliary function
    
    Returns:    
        Three main steps used to solve a commutator. The first is the printed commutator in brackets, the second is the expansion, and the 
        third output will be the answer. Please note that as of now, the code does not understand the 
        addition/subtraction/multiplication/division of commutators, and so if there are multiple commutators in a line (ex: 
        comm_steps(comm(A, B) - comm(C, D))) the code will not process this and therefore each individual commutator needs to have its own 
        line.
        
    """

    return display(Commutator(Operator(commutator_1), Operator(commutator_2))*aux),\
                    display(comm_1(Operator(commutator_1), Operator(commutator_2), aux)),\
                            display(expression_replace(comm_1(Operator(commutator_1), Operator(commutator_2), aux), find_variable(aux)))
Exemple #24
0
def test_pauli_operators_commutator():

    assert Commutator(sx, sy).doit() == 2 * I * sz
    assert Commutator(sy, sz).doit() == 2 * I * sx
    assert Commutator(sz, sx).doit() == 2 * I * sy
Exemple #25
0
def _normal_ordered_form_factor(product,
                                independent=False,
                                recursive_limit=10,
                                _recursive_depth=0):
    """
    Helper function for normal_ordered_form_factor: Write multiplication
    expression with bosonic or fermionic operators on normally ordered form,
    using the bosonic and fermionic commutation relations. The resulting
    operator expression is equivalent to the argument, but will in general be
    a sum of operator products instead of a simple product.
    """

    factors = _expand_powers(product)

    new_factors = []
    n = 0
    while n < len(factors) - 1:

        if isinstance(factors[n], BosonOp):
            # boson
            if not isinstance(factors[n + 1], BosonOp):
                new_factors.append(factors[n])

            elif factors[n].is_annihilation == factors[n + 1].is_annihilation:
                if (independent
                        and str(factors[n].name) > str(factors[n + 1].name)):
                    new_factors.append(factors[n + 1])
                    new_factors.append(factors[n])
                    n += 1
                else:
                    new_factors.append(factors[n])

            elif not factors[n].is_annihilation:
                new_factors.append(factors[n])

            else:
                if factors[n + 1].is_annihilation:
                    new_factors.append(factors[n])
                else:
                    if factors[n].args[0] != factors[n + 1].args[0]:
                        if independent:
                            c = 0
                        else:
                            c = Commutator(factors[n], factors[n + 1])
                        new_factors.append(factors[n + 1] * factors[n] + c)
                    else:
                        c = Commutator(factors[n], factors[n + 1])
                        new_factors.append(factors[n + 1] * factors[n] +
                                           c.doit())
                    n += 1

        elif isinstance(factors[n], FermionOp):
            # fermion
            if not isinstance(factors[n + 1], FermionOp):
                new_factors.append(factors[n])

            elif factors[n].is_annihilation == factors[n + 1].is_annihilation:
                if (independent
                        and str(factors[n].name) > str(factors[n + 1].name)):
                    new_factors.append(factors[n + 1])
                    new_factors.append(factors[n])
                    n += 1
                else:
                    new_factors.append(factors[n])

            elif not factors[n].is_annihilation:
                new_factors.append(factors[n])

            else:
                if factors[n + 1].is_annihilation:
                    new_factors.append(factors[n])
                else:
                    if factors[n].args[0] != factors[n + 1].args[0]:
                        if independent:
                            c = 0
                        else:
                            c = AntiCommutator(factors[n], factors[n + 1])
                        new_factors.append(-factors[n + 1] * factors[n] + c)
                    else:
                        c = AntiCommutator(factors[n], factors[n + 1])
                        new_factors.append(-factors[n + 1] * factors[n] +
                                           c.doit())
                    n += 1

        elif isinstance(factors[n], Operator):

            if isinstance(factors[n + 1], (BosonOp, FermionOp)):
                new_factors.append(factors[n + 1])
                new_factors.append(factors[n])
                n += 1
            else:
                new_factors.append(factors[n])

        else:
            new_factors.append(factors[n])

        n += 1

    if n == len(factors) - 1:
        new_factors.append(factors[-1])

    if new_factors == factors:
        return product
    else:
        expr = Mul(*new_factors).expand()
        return normal_ordered_form(expr,
                                   recursive_limit=recursive_limit,
                                   _recursive_depth=_recursive_depth + 1,
                                   independent=independent)
Exemple #26
0
def test_jz():
    assert Commutator(Jz, Jminus).doit() == -hbar * Jminus
    assert qapply(Jz * JzKet(2, 1)) == hbar * JzKet(2, 1)
    assert Jz.rewrite('plusminus')
Exemple #27
0
def test_jy():
    assert Commutator(Jy, Jz).doit() == I * hbar * Jx
    assert qapply(Jy * JzKet(1, 1)) == I * sqrt(2) * hbar * JzKet(1, 0) / 2
    assert Jy.rewrite('plusminus') == (Jplus - Jminus) / (2 * I)
    assert represent(Jy, basis=Jz) == (represent(Jplus, basis=Jz) -
                                       represent(Jminus, basis=Jz)) / (2 * I)
Exemple #28
0
def test_jplus():
    assert Commutator(Jplus, Jminus).doit() == 2 * hbar * Jz
    assert qapply(Jplus * JzKet(1, 1)) == 0
    assert Jplus.matrix_element(1, 1, 1, 1) == 0
    assert Jplus.rewrite('xyz') == Jx + I * Jy
Exemple #29
0
    ord_bch = len(rl.tamZ) + 1
    for i in range(1, ord_bch):
        for j in range(1, rl.tamZ[i - 1] + 1):
            for k in range(1, ord_bch):
                for l in range(1, rl.tamZ[k - 1] + 1):
                    if rl.relZ[i][j][k][l][0][0] != 0:
                        res = rl.relZ[i][j][k][l]
                        cad = "[Z" + str(i) + str(j) + ", Z" + str(k) + str(
                            l) + "] - ("
                        primer = True
                        resq = sp.S(0)
                        for m in res:
                            resq += sp.Rational(m[0], m[1]) * Z[m[2]][m[3]]
                            if m[0] > 0 and primer == False:
                                cad += "+ "
                            elif m[0] < 0:
                                cad += "- "
                            primer = False
                            if abs(m[0]) > 1:
                                cad += str(abs(m[0])) + "*"
                            cad += "Z" + str(m[2]) + str(m[3]) + ""
                            if m[1] != 1:
                                cad += "/" + str(m[1])
                            cad += " "
                        cad = cad[:-1] + ") ="
                        r = (Commutator(Z[i][j], Z[k][l]) -
                             resq).doit().expand()
                        if (r != 0):
                            print(cad, r)
Exemple #30
0
    Y.append([0])
    for i in range(n_max + 1):
        Y.append(Operator("Y_{%d}" % (i + 1)))

    Z = []
    Z.append([0])

    Z.append([0])
    Z[1].append(Y[1])

    Z.append([0])
    Z[2].append(Y[2])

    Z.append([0])
    Z[3].append(Y[3])
    Z[3].append(Commutator(Z[1][1], Z[2][1]))

    for n in range(4, n_max + 1):
        Z.append([0])
        Z[n].append(Y[n])
        llistes = []
        for i in range(1, (n // 2) + 1):
            llistes.append([i, n - i])
        for ind in (llistes):
            i, k = ind
            for j, l in itertools.product(range(1, len(Z[i])),
                                          range(1, len(Z[k]))):
                if not (i == k and j >= l):
                    can = Commutator(Z[i][j], Z[k][l])
                    if not escl(can, Z[n]):
                        Z[n].append(can)
Exemple #31
0
def _normal_ordered_form_factor(product, independent=False, recursive_limit=10,
                                _recursive_depth=0):
    """
    Helper function for normal_ordered_form_factor: Write multiplication
    expression with bosonic or fermionic operators on normally ordered form,
    using the bosonic and fermionic commutation relations. The resulting
    operator expression is equivalent to the argument, but will in general be
    a sum of operator products instead of a simple product.
    """

    factors = _expand_powers(product)

    new_factors = []
    n = 0
    while n < len(factors) - 1:

        if isinstance(factors[n], BosonOp):
            # boson
            if not isinstance(factors[n + 1], BosonOp):
                new_factors.append(factors[n])

            elif factors[n].is_annihilation == factors[n + 1].is_annihilation:
                if (independent and
                        str(factors[n].name) > str(factors[n + 1].name)):
                    new_factors.append(factors[n + 1])
                    new_factors.append(factors[n])
                    n += 1
                else:
                    new_factors.append(factors[n])

            elif not factors[n].is_annihilation:
                new_factors.append(factors[n])

            else:
                if factors[n + 1].is_annihilation:
                    new_factors.append(factors[n])
                else:
                    if factors[n].args[0] != factors[n + 1].args[0]:
                        if independent:
                            c = 0
                        else:
                            c = Commutator(factors[n], factors[n + 1])
                        new_factors.append(factors[n + 1] * factors[n] + c)
                    else:
                        c = Commutator(factors[n], factors[n + 1])
                        new_factors.append(
                            factors[n + 1] * factors[n] + c.doit())
                    n += 1

        elif isinstance(factors[n], FermionOp):
            # fermion
            if not isinstance(factors[n + 1], FermionOp):
                new_factors.append(factors[n])

            elif factors[n].is_annihilation == factors[n + 1].is_annihilation:
                if (independent and
                        str(factors[n].name) > str(factors[n + 1].name)):
                    new_factors.append(factors[n + 1])
                    new_factors.append(factors[n])
                    n += 1
                else:
                    new_factors.append(factors[n])

            elif not factors[n].is_annihilation:
                new_factors.append(factors[n])

            else:
                if factors[n + 1].is_annihilation:
                    new_factors.append(factors[n])
                else:
                    if factors[n].args[0] != factors[n + 1].args[0]:
                        if independent:
                            c = 0
                        else:
                            c = AntiCommutator(factors[n], factors[n + 1])
                        new_factors.append(-factors[n + 1] * factors[n] + c)
                    else:
                        c = AntiCommutator(factors[n], factors[n + 1])
                        new_factors.append(
                            -factors[n + 1] * factors[n] + c.doit())
                    n += 1

        else:
            new_factors.append(factors[n])

        n += 1

    if n == len(factors) - 1:
        new_factors.append(factors[-1])

    if new_factors == factors:
        return product
    else:
        expr = Mul(*new_factors).expand()
        return normal_ordered_form(expr,
                                   recursive_limit=recursive_limit,
                                   _recursive_depth=_recursive_depth + 1,
                                   independent=independent)