def test_qsd_codegen_operator_basis(): a = Destroy(1) a.space.dimension = 10 ad = a.dag() s = LocalSigma(2, 1, 0) s.space.dimension = 2 sd = s.dag() circuit = SLH(identity_matrix(0), [], a * ad + s + sd) codegen = QSDCodeGen(circuit) ob = codegen._operator_basis_lines(indent=0) assert dedent(ob).strip() == dedent(""" IdentityOperator Id0(0); IdentityOperator Id1(1); AnnihilationOperator A0(0); FieldTransitionOperator S1_0_1(0,1,1); FieldTransitionOperator S1_1_0(1,0,1); Operator Id = Id0*Id1; Operator Ad0 = A0.hc(); """).strip() circuit = SLH(identity_matrix(0), [], ad) codegen = QSDCodeGen(circuit) ob = codegen._operator_basis_lines(indent=0) assert dedent(ob).strip() == dedent(""" IdentityOperator Id0(0); AnnihilationOperator A0(0); Operator Id = Id0; Operator Ad0 = A0.hc(); """).strip()
def test_driven_tls(datadir): hs = local_space('tls', namespace='sys', basis=('g', 'e')) w = symbols(r'\omega', real=True) pi = sympy.pi cos = sympy.cos t, T, E0 = symbols('t, T, E_0', real=True) a = 0.16 blackman = 0.5 * (1 - a - cos(2 * pi * t / T) + a * cos(4 * pi * t / T)) H0 = Destroy(hs).dag() * Destroy(hs) H1 = LocalSigma(hs, 'g', 'e') + LocalSigma(hs, 'e', 'g') H = w * H0 + 0.5 * E0 * blackman * H1 circuit = SLH(identity_matrix(0), [], H) num_vals = {w: 1.0, T: 10.0, E0: 1.0 * 2 * np.pi} # test qutip conversion H_qutip, Ls = circuit.substitute(num_vals).HL_to_qutip(time_symbol=t) assert len(Ls) == 0 assert len(H_qutip) == 3 times = np.linspace(0, num_vals[T], 201) psi0 = qutip.basis(2, 1) states = qutip.mesolve(H_qutip, psi0, times, [], []).states pop0 = np.array(qutip_population(states, state=0)) pop1 = np.array(qutip_population(states, state=1)) datfile = os.path.join(datadir, 'pops.dat') #print("DATFILE: %s" % datfile) #np.savetxt(datfile, np.c_[times, pop0, pop1, pop0+pop1]) pop0_expect, pop1_expect = np.genfromtxt(datfile, unpack=True, usecols=(1, 2)) assert np.max(np.abs(pop0 - pop0_expect)) < 1e-12 assert np.max(np.abs(pop1 - pop1_expect)) < 1e-12 # Test QSD conversion codegen = QSDCodeGen(circuit, num_vals=num_vals, time_symbol=t) codegen.add_observable(LocalSigma(hs, 'e', 'e'), name='P_e') psi0 = BasisKet(hs, 'e') codegen.set_trajectories(psi_initial=psi0, stepper='AdaptiveStep', dt=0.01, nt_plot_step=5, n_plot_steps=200, n_trajectories=1) scode = codegen.generate_code() compile_cmd = _cmd_list_to_str( codegen._build_compile_cmd(qsd_lib='$HOME/local/lib/libqsd.a', qsd_headers='$HOME/local/include/qsd/', executable='test_driven_tls', path='$HOME/bin', compiler='mpiCC', compile_options='-g -O0')) print(compile_cmd) codefile = os.path.join(datadir, "test_driven_tls.cc") #print("CODEFILE: %s" % codefile) #with(open(codefile, 'w')) as out_fh: #out_fh.write(scode) #out_fh.write("\n") with open(codefile) as in_fh: scode_expected = in_fh.read() assert scode.strip() == scode_expected.strip()
def test_driven_tls(datadir): hs = local_space('tls', namespace='sys', basis=('g', 'e')) w = symbols(r'\omega', real=True) pi = sympy.pi cos = sympy.cos t, T, E0 = symbols('t, T, E_0', real=True) a = 0.16 blackman = 0.5 * (1 - a - cos(2*pi * t/T) + a*cos(4*pi*t/T)) H0 = Destroy(hs).dag() * Destroy(hs) H1 = LocalSigma(hs, 'g', 'e') + LocalSigma(hs, 'e', 'g') H = w*H0 + 0.5 * E0 * blackman * H1 circuit = SLH(identity_matrix(0), [], H) num_vals = {w: 1.0, T:10.0, E0:1.0*2*np.pi} # test qutip conversion H_qutip, Ls = circuit.substitute(num_vals).HL_to_qutip(time_symbol=t) assert len(Ls) == 0 assert len(H_qutip) == 3 times = np.linspace(0, num_vals[T], 201) psi0 = qutip.basis(2, 1) states = qutip.mesolve(H_qutip, psi0, times, [], []).states pop0 = np.array(qutip_population(states, state=0)) pop1 = np.array(qutip_population(states, state=1)) datfile = os.path.join(datadir, 'pops.dat') #print("DATFILE: %s" % datfile) #np.savetxt(datfile, np.c_[times, pop0, pop1, pop0+pop1]) pop0_expect, pop1_expect = np.genfromtxt(datfile, unpack=True, usecols=(1,2)) assert np.max(np.abs(pop0 - pop0_expect)) < 1e-12 assert np.max(np.abs(pop1 - pop1_expect)) < 1e-12 # Test QSD conversion codegen = QSDCodeGen(circuit, num_vals=num_vals, time_symbol=t) codegen.add_observable(LocalSigma(hs, 'e', 'e'), name='P_e') psi0 = BasisKet(hs, 'e') codegen.set_trajectories(psi_initial=psi0, stepper='AdaptiveStep', dt=0.01, nt_plot_step=5, n_plot_steps=200, n_trajectories=1) scode = codegen.generate_code() compile_cmd = _cmd_list_to_str(codegen._build_compile_cmd( qsd_lib='$HOME/local/lib/libqsd.a', qsd_headers='$HOME/local/include/qsd/', executable='test_driven_tls', path='$HOME/bin', compiler='mpiCC', compile_options='-g -O0')) print(compile_cmd) codefile = os.path.join(datadir, "test_driven_tls.cc") #print("CODEFILE: %s" % codefile) #with(open(codefile, 'w')) as out_fh: #out_fh.write(scode) #out_fh.write("\n") with open(codefile) as in_fh: scode_expected = in_fh.read() assert scode.strip() == scode_expected.strip()
def setup_qnet_sys(n_cavity, stark_shift=False, zero_phi=True, keep_delta=False, slh=True): """Return the effective SLH model (if `slh` is True) or a the symbolic circuit (if `slh` is False) for a two-node network, together with the symbols and operators in each node""" Sym1, Op1 = qnet_node_system('1', n_cavity, zero_phi=zero_phi, keep_delta=keep_delta) Sym2, Op2 = qnet_node_system('2', n_cavity, zero_phi=zero_phi, keep_delta=keep_delta) if slh: H1 = node_hamiltonian(Sym1, Op1, stark_shift=stark_shift, zero_phi=zero_phi, keep_delta=keep_delta) H2 = node_hamiltonian(Sym2, Op2, stark_shift=stark_shift, zero_phi=zero_phi, keep_delta=keep_delta) S = identity_matrix(1) κ = Sym1['kappa'] L1 = sympy.sqrt(2 * κ) * Op1['a'] κ = Sym2['kappa'] L2 = sympy.sqrt(2 * κ) * Op2['a'] SLH1 = SLH(S, [ L1, ], H1) SLH2 = SLH(S, [ L2, ], H2) Node1 = CircuitSymbol("Node1", cdim=1) Node2 = CircuitSymbol("Node2", cdim=1) components = [Node1, Node2] connections = [ ((Node1, 0), (Node2, 0)), ] circuit = connect(components, connections) if slh: network = circuit.substitute({Node1: SLH1, Node2: SLH2}) else: network = circuit return network, Sym1, Op1, Sym2, Op2
def _toSLH(self): S = Matrix([[Z(self.space)]]) L = Matrix([[0]]) H = self.Delta * LocalProjector(self.space, 'r') return SLH(S, L, H)
def test_qsd_codegen_parameters(): k = symbols(r'kappa', positive=True) x = symbols(r'chi', real=True) c = symbols("c") a = Destroy(1) H = x * (a * a + a.dag() * a.dag()) + (c * a.dag() + c.conjugate() * a) L = sqrt(k) * a slh = SLH(identity_matrix(1), [L], H) codegen = QSDCodeGen(circuit=slh, num_vals={x: 2., c: 1 + 2j, k: 2}) scode = codegen._parameters_lines(indent=0) assert dedent(scode).strip() == dedent(""" Complex I(0.0,1.0); Complex c(1,2); double chi = 2; double kappa = 2;""").strip() codegen.num_vals.update({c: 1}) scode = codegen._parameters_lines(indent=0) assert dedent(scode).strip() == dedent(""" Complex I(0.0,1.0); Complex c(1,0); double chi = 2; double kappa = 2;""").strip() del codegen.num_vals[c] with pytest.raises(KeyError) as excinfo: scode = codegen._parameters_lines(indent=0) assert "There is no value for symbol c" in str(excinfo.value)
def slh_Sec6(): """SHL for the model in Section 6 of the QSD paper""" E = symbols(r'E', positive=True) chi = symbols(r'\chi', real=True) omega = symbols(r'\omega', real=True) eta = symbols(r'\eta', real=True) gamma1 = symbols(r'\gamma_1', positive=True) gamma2 = symbols(r'\gamma_2', positive=True) kappa = symbols(r'\kappa', positive=True) A1 = Destroy(0) Ac1 = A1.dag() N1 = Ac1 * A1 Id1 = identity_matrix(0) A2 = Destroy(1) Ac2 = A2.dag() N2 = Ac2 * A2 Id2 = identity_matrix(1) Sp = LocalSigma(2, 1, 0) Sm = Sp.dag() Id3 = identity_matrix(3) BasisRegistry.set_basis(A1.space, range(50)) BasisRegistry.set_basis(A2.space, range(50)) BasisRegistry.set_basis(Sp.space, range(2)) H = E*I*(Ac1-A1) + 0.5*chi*I*(Ac1*Ac1*A2 - A1*A1*Ac2) \ + omega*Sp*Sm + eta*I*(A2*Sp-Ac2*Sm) Lindblads = [ sqrt(2 * gamma1) * A1, sqrt(2 * gamma2) * A2, sqrt(2 * kappa) * Sm ] return SLH(identity_matrix(3), Lindblads, H)
def _toSLH(self): Pi_g = LocalProjector(self.space, 'g') Pi_h = LocalProjector(self.space, 'h') S = Matrix([[Pi_g, -Pi_h ], [-Pi_h, Pi_g]]) return SLH(S, Matrix([[0]]*2), 0)
def test_operator_hilbert_space_check(): circuit = SLH(identity_matrix(0), [], 1) s = LocalSigma("sys", 'g', 'e') codegen = QSDCodeGen(circuit) with pytest.raises(ValueError) as exc_info: codegen._update_qsd_ops([ s, ]) assert "not in the circuit's Hilbert space" in str(exc_info.value)
def testABCD(self): a = Destroy(1) slh = SLH(identity_matrix(1), [a], 2 * a.dag() * a).coherent_input(3) A, B, C, D, a, c = getABCD(slh, doubled_up=True) self.assertEquals(A[0, 0], -sympyOne / 2 - 2 * I) self.assertEquals(A[1, 1], -sympyOne / 2 + 2 * I) self.assertEquals(B[0, 0], -1) self.assertEquals(C[0, 0], 1) self.assertEquals(D[0, 0], 1)
def _toSLH(self): sigma_p = LocalSigma(self.tls_space, 'h', 'g') sigma_m = sigma_p.adjoint() # vacuum coupling / spontaneous decay L = sqrt(self.gamma) * sigma_m return SLH(Matrix([[1]]), Matrix([[L]]), 0)
def _toSLH(self): Pi_g = LocalProjector(self.space, 'g') Pi_h = LocalProjector(self.space, 'h') sigma_gh = LocalSigma(self.space, 'g', 'h') sigma_hg = LocalSigma(self.space, 'h', 'g') S = Matrix([[Pi_g, - sigma_hg ], [-sigma_gh, Pi_h]]) return SLH(S, Matrix([[0]]*2), 0)
def _toSLH(self): S = identity_matrix(1) if self.sub_index == 1: L = sqrt(self.gamma) * Matrix([[LocalSigma(self.space, 'g', 'r')]]) elif self.sub_index == 2: L = sqrt(self.gamma) * Matrix([[LocalSigma(self.space, 'h', 'r')]]) else: raise Exception(str(self.sub_index)) return SLH(S, L, 0)
def _toSLH(self): a = Destroy(self.space) a_d = a.adjoint() S = identity_matrix(1) # Include the Hamiltonian only with the first port of the kerr cavity circuit object H = self.Delta * a_d * a + (I / 2) * (self.alpha * a_d * a_d - self.alpha.conjugate() * a * a) L = Matrix([[sqrt(self.kappa) * a]]) return SLH(S, L, H)
def test_labeled_basis_op(): """Check that in QSD code generation labeled basis states are translated into numbered basis states""" hs = local_space('tls', namespace='sys', basis=('g', 'e')) a = Destroy(hs) ad = a.dag() s = LocalSigma(hs, 'g', 'e') circuit = SLH(identity_matrix(0), [], a * ad) codegen = QSDCodeGen(circuit) codegen._update_qsd_ops([ s, ]) assert codegen._qsd_ops[s].instantiator == '(0,1,0)' != '(g,e,0)'
def _toSLH(self): a = Destroy(self.space) a_d = a.adjoint() S = identity_matrix(1) kappas = [self.kappa_1, self.kappa_2, self.kappa_3] kappa = kappas[self.sub_index] L = Matrix([[sqrt(kappa) * a]]) # Include the Hamiltonian only with the first port of the kerr cavity circuit object H = self.Delta * (a_d * a) + self.chi * ( a_d * a_d * a * a) if self.sub_index == 0 else 0 return SLH(S, L, H)
def _toSLH(self): sigma_p = LocalSigma(self.tls_space, 'h', 'g') sigma_m = sigma_p.adjoint() a = Destroy(self.fock_space) a_d = a.adjoint() #coupling to external mode L = sqrt(self.kappa) * a H = self.Delta_f * a_d * a + self.Delta_a * sigma_p * sigma_m + I * self.g * ( sigma_p * a - sigma_m * a_d) return SLH(Matrix([[1]]), Matrix([[L]]), H)
def _toSLH(self): a = Destroy(self.space) a_d = a.adjoint() S = identity_matrix(1) if self.sub_index == 0: # Include the Hamiltonian only with the first port of the kerr cavity circuit object H = self.Delta * (a_d * a) L = Matrix([[sqrt(self.kappa_1) * a]]) else: H = 0 L = Matrix([[sqrt(self.kappa_2) * a]]) return SLH(S, L, H)
def test_qsd_codegen_hamiltonian(): k = symbols(r'\kappa', positive=True) x = symbols(r'\chi', real=True) c = symbols("c", real=True) a = Destroy(1) H = x * (a * a + a.dag() * a.dag()) + (c * a.dag() + c.conjugate() * a) L = sqrt(k) * a slh = SLH(identity_matrix(1), [L], H) codegen = QSDCodeGen(circuit=slh, num_vals={x: 2., c: 1, k: 2}) codegen._operator_basis_lines(indent=0) scode = codegen._hamiltonian_lines(indent=0) assert scode.strip() == (r'Operator H = ((c) * (Ad0) + (c) * (A0) + (chi) ' r'* (((Ad0 * Ad0) + (A0 * A0))));')
def slh_map_2chan_chain(components, n_cavity): n_nodes = len(components) slh_map = {} for i in range(n_nodes): ind = i + 1 Sym, Op = qnet_node_system(node_index='%d' % ind, n_cavity=n_cavity) S = identity_matrix(2) kappa_l, kappa_r = symbols("kappa_%dl, kappa_%dr" % (ind, ind), positive=True) L = [ sympy.sqrt(2 * kappa_l) * Op['a'], sympy.sqrt(2 * kappa_r) * Op['a'] ] H = node_hamiltonian(Sym, Op) slh_map[components[i]] = SLH(S, L, H) return slh_map
def test_latex_symbols(slh_Sec6): """Test that if any of the symbols contain "special" characters such as backslashes (LaTeX code), we still get valid C++ code (basic ASCII words only).""" k = symbols("\kappa", positive=True) x = symbols(r'\chi^{(1)}_{\text{main}}', real=True) c = symbols("c") a = Destroy(1) H = x * (a * a + a.dag() * a.dag()) + (c * a.dag() + c.conjugate() * a) L = sqrt(k) * a slh = SLH(identity_matrix(1), [L], H) codegen = QSDCodeGen(circuit=slh, num_vals={x: 2., c: 1 + 2j, k: 2}) scode = codegen._parameters_lines(indent=0) assert dedent(scode).strip() == dedent(""" Complex I(0.0,1.0); Complex c(1,2); double chi_1_textmain = 2; double kappa = 2;""").strip()
def _toSLH(self): if self.sub_index == 0: sigma_p = LocalSigma(self.tls_space, 'h','g') sigma_m = sigma_p.adjoint() a = Destroy(self.fock_space) a_d = a.adjoint() #coupling to external mode L = sqrt(self.kappa_1) * a H = self.Delta_f * a_d * a + self.Delta_a * sigma_p * sigma_m + I * self.g * (sigma_p * a - sigma_m * a_d) elif self.sub_index == 1: a = Destroy(self.fock_space) L = sqrt(self.kappa_2) * a H = ZeroOperator return SLH(Matrix([[1]]), Matrix([[L]]), H)
def testDrawSLH(self): self.assertCanBeDrawn( SLH(identity_matrix(1), Matrix([[Create(1)]]), Create(1) * Destroy(1)))
def _toSLH(self): S = Matrix([[cos(self.theta), -sin(self.theta)], [sin(self.theta), cos(self.theta)]]) L = Matrix([[0], [0]]) return SLH(S, L, 0)
def _toSLH(self): S = Matrix([[exp(I * self.phi)]]) L = Matrix([[0]]) H = 0 return SLH(S, L, H)