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))
def _eval_anticommutator_MultiBosonOp(self, other, **hints): if 'independent' in hints and hints['independent']: # {a, b} = 2 * a * b, because [a, b] = 0 return 2 * self * other else: return 2 * self * other - Commutator(self, other) return None
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)
def operator_master_equation(op_t, t, H, a_ops, use_eq=True): """ Adjoint master equation """ rhs = diff(op_t, t) lhs = (I * Commutator(H, op_t) + sum([operator_lindblad_dissipator(a, op_t) for a in a_ops])) if use_eq: return Eq(rhs, lhs) else: return rhs, lhs
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 assert Commutator(sz1, sx2).doit() == 0 assert Commutator(sz1, sx2).doit() == 0 assert Commutator(sz1, sx2).doit() == 0 assert Commutator(sm1, sz2).doit() == 0 assert Commutator(sm1, sp2).doit() == 0 assert Commutator(sm1, sm2).doit() == 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
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], OperatorFunction) and isinstance(factors[n].operator, BosonOp)): # boson if (not isinstance(factors[n + 1], OperatorFunction) or (isinstance(factors[n + 1], OperatorFunction) and not isinstance(factors[n + 1].operator, BosonOp))): new_factors.append(factors[n]) elif factors[n].operator.is_annihilation == factors[n + 1].operator.is_annihilation: if (independent and str(factors[n].operator.name) > str(factors[n + 1].operator.name)): new_factors.append(factors[n + 1]) new_factors.append(factors[n]) n += 1 else: new_factors.append(factors[n]) elif not factors[n].operator.is_annihilation: new_factors.append(factors[n]) else: if factors[n + 1].operator.is_annihilation: new_factors.append(factors[n]) else: if factors[n].operator.args[0] != factors[n + 1].operator.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], Expectation): factor = Expectation(normal_ordered_form(factors[n].args[0]), factors[n].is_normal_order) new_factors.append(factor) elif 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], SigmaOpBase): if isinstance(factors[n + 1], BosonOp): new_factors.append(factors[n + 1]) new_factors.append(factors[n]) n += 1 elif (isinstance(factors[n + 1], OperatorFunction) and isinstance(factors[n + 1].operator, BosonOp)): new_factors.append(factors[n + 1]) new_factors.append(factors[n]) n += 1 else: new_factors.append(factors[n]) elif isinstance(factors[n], Operator): if isinstance(factors[n], (BosonOp, FermionOp)): if isinstance(factors[n + 1], (BosonOp, FermionOp)): new_factors.append(factors[n + 1]) new_factors.append(factors[n]) n += 1 elif (isinstance(factors[n + 1], OperatorFunction) and isinstance(factors[n + 1].operator, (BosonOp, FermionOp))): new_factors.append(factors[n + 1]) new_factors.append(factors[n]) n += 1 else: new_factors.append(factors[n]) elif isinstance(factors[n], OperatorFunction): if isinstance(factors[n].operator, (BosonOp, FermionOp)): if isinstance(factors[n + 1], (BosonOp, FermionOp)): new_factors.append(factors[n + 1]) new_factors.append(factors[n]) n += 1 elif (isinstance(factors[n + 1], OperatorFunction) and isinstance(factors[n + 1].operator, (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(normal_ordered_form(factors[n], recursive_limit=recursive_limit, _recursive_depth=_recursive_depth + 1, independent=independent)) n += 1 if n == len(factors) - 1: new_factors.append(normal_ordered_form(factors[-1], recursive_limit=recursive_limit, _recursive_depth=_recursive_depth + 1, independent=independent)) 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)