def test_symbol(): expN = OperatorSymbol("expN", hs=1) hs1 = LocalSpace("sym1", dimension=10) hs2 = LocalSpace("sym2", dimension=5) N = Create(hs=hs1) * Destroy(hs=hs1) M = Create(hs=hs2) * Destroy(hs=hs2) converter1 = {expN: convert_to_qutip(N).expm()} expNq = convert_to_qutip(expN, mapping=converter1) assert (np.linalg.norm(expNq.data.toarray() - (convert_to_qutip(N).expm().data.toarray())) < 1e-8) expNMq = convert_to_qutip(expN * M, mapping=converter1) assert (np.linalg.norm(expNMq.data.toarray() - (qutip.tensor( convert_to_qutip(N).expm(), convert_to_qutip(M)).data.toarray())) < 1e-8) converter2 = {expN: lambda expr: convert_to_qutip(N).expm()} expNq = convert_to_qutip(expN, mapping=converter2) assert (np.linalg.norm(expNq.data.toarray() - (convert_to_qutip(N).expm().data.toarray())) < 1e-8) expNMq = convert_to_qutip(expN * M, mapping=converter1) assert (np.linalg.norm(expNMq.data.toarray() - (qutip.tensor( convert_to_qutip(N).expm(), convert_to_qutip(M)).data.toarray())) < 1e-8)
def test_custom_localspace_identifier_hash(): """Test hashes for expressions with different local_identifiers for their Hilbert spaces have different hashes""" hs1 = LocalSpace(1) hs1_custom = LocalSpace(1, local_identifiers={'Destroy': 'b'}) assert hash(hs1) != hash(hs1_custom) a = Destroy(hs=hs1) b = Destroy(hs=hs1_custom) assert hash(a) != hash(b)
def test_basis_change(): """Test that we can change the basis of an Expression's Hilbert space through substitution""" a = Destroy(hs=1) assert a.space == LocalSpace('1') assert not a.space.has_basis subs = {LocalSpace('1'): LocalSpace('1', basis=(-1, 0, 1))} b = a.substitute(subs) assert str(a) == str(b) assert a != b assert b.space.dimension == 3 assert b.space.basis_labels == ('-1', '0', '1')
def test_op_product_space(): """Test that a product of operators has the correct Hilbert space""" a = Destroy(hs=1) b = Destroy(hs=2) p = a * b assert p.space == ProductSpace(LocalSpace(1), LocalSpace(2)) assert not p.space.has_basis hs1 = LocalSpace(1, dimension=3) a = a.substitute({LocalSpace(1): hs1}) p = a * b assert p.space == ProductSpace(hs1, LocalSpace(2)) assert not p.space.has_basis hs2 = LocalSpace(2, dimension=2) b = b.substitute({LocalSpace(2): hs2}) p = a * b ps = ProductSpace(hs1, hs2) assert p.space == ps assert p.space.dimension == 6 assert p.space.basis_labels == ('0,0', '0,1', '1,0', '1,1', '2,0', '2,1') hs1_2 = LocalSpace(1, basis=('g', 'e')) hs2_2 = LocalSpace(2, basis=('g', 'e')) p = p.substitute({hs1: hs1_2, hs2: hs2_2}) assert p.space.dimension == 4 assert p.space.basis_labels == ('g,g', 'g,e', 'e,g', 'e,e') b = b.substitute({hs2: hs1}) p = a * b assert p.space == hs1 assert p.space.dimension == 3 assert p.space.basis_labels == ('0', '1', '2')
def _diff(self, sym): from qalgebra.library.fock_operators import Create, Destroy hs = self.space if sym in hs.free_symbols: return StateDerivative(self, derivs={sym: 1}) else: return (self._ampl * Create(hs=hs) - self._ampl.conjugate() * Destroy(hs=hs)).diff(sym) * self
def test_commutator_oder(): """Test anti-commutativity of commutators""" hs = LocalSpace("0") A = OperatorSymbol('A', hs=hs) B = OperatorSymbol('B', hs=hs) assert Commutator.create(B, A) == -Commutator(A, B) a = Destroy(hs=hs) a_dag = Create(hs=hs) assert Commutator.create(a, a_dag) == -Commutator.create(a_dag, a)
def test_scalar_coeff_cc(): """Test that we can find complex conjugates in a sum of ScalarTimesOperator""" hs_1 = LocalSpace('q1', basis=('g', 'e')) hs_2 = LocalSpace('q2', basis=('g', 'e')) kappa = Symbol('kappa', real=True) a1 = Destroy(hs=hs_1) a2 = Destroy(hs=hs_2) jc_expr = (I / 2 * (2 * kappa * (a1.dag() * a2) - 2 * kappa * (a1 * a2.dag()))) simplified = rewrite_with_operator_pm_cc(jc_expr) assert simplified == I * kappa * OperatorPlusMinusCC(a1.dag() * a2, sign=-1) expanded = simplified.doit() assert expanded == I * kappa * (a1.dag() * a2 - a1 * a2.dag())
def test_substitute_sub_expr(H_JC): """Test that we can replace non-atomic sub-expressions""" hil_a = LocalSpace('A') hil_b = LocalSpace('B') omega_a, omega_b, g = symbols('omega_a, omega_b, g') a = Destroy(hs=hil_a) a_dag = a.dag() b = Destroy(hs=hil_b) b_dag = b.dag() n_op_a = OperatorSymbol('n', hs=hil_a) n_op_b = OperatorSymbol('n', hs=hil_b) x_op = OperatorSymbol('x', hs=H_JC.space) mapping = { a_dag * a: n_op_a, b_dag * b: n_op_b, (a_dag * b + b_dag * a): x_op + x_op.dag(), } H2_expected = (omega_a * n_op_a + omega_b * n_op_b + 2 * g * (x_op + x_op.dag())) H2 = H_JC.substitute(mapping) assert H2 == H2_expected H2 = substitute(H_JC, mapping) assert H2 == H2_expected
def H_JC(): hil_a = LocalSpace('A') hil_b = LocalSpace('B') a = Destroy(hs=hil_a) a_dag = a.dag() b = Destroy(hs=hil_b) b_dag = b.dag() omega_a, omega_b, g = symbols('omega_a, omega_b, g') H = (omega_a * a_dag * a + omega_b * b_dag * b + 2 * g * (a_dag * b + b_dag * a)) return H
def test_equal_hash(): """Test that expressions with and equal hash or not equal, and that they can be used as dictionary keys""" a = Destroy(hs="0") expr1 = -a expr2 = -2 * a h1 = hash(expr1) h2 = hash(expr2) # expr1 and expr2 just happen to have a hash collision for the current # implementation of the the hash function. This does not mean that they # are not distinguishable! assert h1 == h2 # this is the point of the test assert expr1 != expr2 d = {} d[expr1] = 1 d[expr2] = 2 assert d[expr1] == 1 assert d[expr2] == 2
def test_simple_cc(): """Test that we can find complex conjugates in a sum directly""" hs_c = LocalSpace('c', dimension=3) hs_q = LocalSpace('q1', basis=('g', 'e')) Delta_1 = Symbol('Delta_1') Omega_1 = Symbol('Omega_1') g_1 = Symbol('g_1') a = Destroy(hs=hs_c) a_dag = Create(hs=hs_c) sig_p = LocalSigma('e', 'g', hs=hs_q) sig_m = LocalSigma('g', 'e', hs=hs_q) coeff = (-I / 2) * (Omega_1 * g_1 / Delta_1) jc_expr = coeff * (a * sig_p - a_dag * sig_m) simplified = rewrite_with_operator_pm_cc(jc_expr) assert simplified == coeff * OperatorPlusMinusCC(a * sig_p, sign=-1) assert (srepr(simplified.term) == "OperatorPlusMinusCC(OperatorTimes(Destroy(hs=LocalSpace('c', " "dimension=3)), LocalSigma('e', 'g', hs=LocalSpace('q1', " "basis=('g', 'e')))), sign=-1)") expanded = simplified.doit() assert expanded == jc_expr
def test_known_commutators(): """Test that well-known commutators are recognized""" fock = LocalSpace("0") spin = SpinSpace("0", spin=1) a = Destroy(hs=fock) a_dag = Create(hs=fock) assert Commutator.create(a, a_dag) == IdentityOperator assert Commutator.create(a_dag, a) == -IdentityOperator assert Commutator.create(LocalSigma(1, 0, hs=fock), LocalSigma(0, 1, hs=fock)) == LocalProjector( 1, hs=fock) - LocalProjector(0, hs=fock) assert Commutator.create(LocalSigma(1, 0, hs=fock), LocalProjector( 1, hs=fock)) == (-1 * LocalSigma(1, 0, hs=fock)) assert Commutator.create(LocalSigma(1, 0, hs=fock), LocalProjector(0, hs=fock)) == LocalSigma(1, 0, hs=fock) assert Commutator.create(LocalSigma(1, 0, hs=fock), Create(hs=fock)) == (-sqrt(2) * LocalSigma(2, 0, hs=fock)) assert Commutator.create(Jplus(hs=spin), Jz(hs=spin)) == -Jplus(hs=spin)
def test_substitute_sympy_formula(H_JC): """Test that we can replace sympy symbols with other sympy formulas""" omega_a, omega_b, g = symbols('omega_a, omega_b, g') Delta_a, Delta_b, delta, kappa = symbols('Delta_a, Delta_b, delta, kappa') hil_a = LocalSpace('A') hil_b = LocalSpace('B') a = Destroy(hs=hil_a) a_dag = a.dag() b = Destroy(hs=hil_b) b_dag = b.dag() mapping = {omega_a: Delta_a, omega_b: Delta_b, g: kappa / (2 * delta)} H2_expected = (Delta_a * a_dag * a + Delta_b * b_dag * b + (kappa / delta) * (a_dag * b + b_dag * a)) H2 = H_JC.substitute(mapping) assert H2 == H2_expected H2 = substitute(H_JC, mapping) assert H2 == H2_expected
def test_substitute_numvals(H_JC): """Test that we can substitute in numbers for scalar coefficients""" omega_a, omega_b, g = symbols('omega_a, omega_b, g') num_vals = { omega_a: 0.2, omega_b: 0, g: 1, } hil_a = LocalSpace('A') hil_b = LocalSpace('B') a = Destroy(hs=hil_a) a_dag = a.dag() b = Destroy(hs=hil_b) b_dag = b.dag() H2_expected = 0.2 * a_dag * a + 2 * (a_dag * b + b_dag * a) H2 = H_JC.substitute(num_vals) assert H2 == H2_expected H2 = substitute(H_JC, num_vals) assert H2 == H2_expected