Example #1
0
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.0, 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()
    )
Example #2
0
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)
Example #3
0
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()
Example #4
0
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)
Example #5
0
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()
Example #6
0
 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)
Example #7
0
 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)
Example #8
0
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)"
Example #9
0
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)'
Example #10
0
def test_local_ops():
    psa = PseudoNAND()
    assert isinstance(psa, Circuit)
    l_ops = local_ops(psa)
    a = Destroy(psa.space)
    assert type(local_ops(a)) is set
    assert set([IdentityOperator, a, a.dag()]) == l_ops
    assert local_ops(a) == set([a])
    assert local_ops(a * a) == set([a])
    assert local_ops(a + a.dag()) == set([a, a.dag()])
    assert local_ops(10 * a) == set([a])
    with pytest.raises(TypeError):
        local_ops({})
Example #11
0
def test_local_ops():
    psa = PseudoNAND()
    assert isinstance(psa, Circuit)
    l_ops = local_ops(psa)
    a = Destroy(psa.space)
    assert type(local_ops(a)) is set
    assert set([IdentityOperator, a, a.dag()]) == l_ops
    assert local_ops(a) == set([a])
    assert local_ops(a * a) == set([a])
    assert local_ops(a + a.dag()) == set([a, a.dag()])
    assert local_ops(10 * a) == set([a])
    with pytest.raises(TypeError):
        local_ops({})
Example #12
0
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.0, 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))));")
Example #13
0
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))));')
Example #14
0
    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) + self.chi * (a_d * a_d * a * a)
            L = Matrix([[sqrt(self.kappa_1) * a]])
        else:
            H = 0
            L = Matrix([[sqrt(self.kappa_2) * a]])

        return SLH(S, L, H)
Example #15
0
    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) + self.chi * (a_d * a_d * a * a)
            L = Matrix([[sqrt(self.kappa_1) * a]])
        else:
            H = 0
            L = Matrix([[sqrt(self.kappa_2) * a]])
        
        return SLH(S, L, H)
Example #16
0
def test_find_kets():
    #                  hs n
    psi_A_0 = BasisKet(0, 0)
    psi_A_1 = BasisKet(0, 1)
    psi_B_0 = BasisKet(1, 0)
    psi_B_1 = BasisKet(1, 1)
    local_psi = [psi_A_0, psi_A_1, psi_B_0, psi_B_1]

    psi_00 = psi_A_0 * psi_B_0
    psi_01 = psi_A_0 * psi_B_1
    psi_10 = psi_A_1 * psi_B_0
    psi_11 = psi_A_1 * psi_B_1
    tensor_psi = [psi_00, psi_01, psi_10, psi_11]
    a1 = Destroy(psi_A_1.space)

    assert set((psi_A_0, )) == find_kets(psi_A_0, LocalKet)

    psi = 0.5 * (psi_00 + psi_01 + psi_10 + psi_11)
    assert set(local_psi) == find_kets(psi, LocalKet)
    assert set(tensor_psi) == find_kets(psi, TensorKet)

    psi = 0.5 * a1 * psi_10  # = 0.5 * psi_00
    assert set([psi_A_0, psi_B_0]) == find_kets(psi, LocalKet)
    assert set([
        psi_00,
    ]) == find_kets(psi, TensorKet)

    with pytest.raises(TypeError):
        find_kets({}, cls=LocalKet)
Example #17
0
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()
Example #18
0
def test_find_time_dependent_coeffs():
    E0, sigma, t, t0, a, b = sympy.symbols("E_0, sigma, t, t_0, a, b", real=True)
    op_a = Destroy(0)
    op_n = op_a.dag() * op_a
    gaussian = E0 * sympy.exp(-(t - t0) ** 2 / (2 * sigma ** 2))
    linear = a * t
    H = b * op_a.dag() + gaussian * op_n + linear * op_a
    coeffs = list(_find_time_dependent_coeffs(H, t))
    assert len(coeffs) == 2
    assert gaussian in coeffs
    assert linear in coeffs

    H = (gaussian * op_n) * (linear * op_a) + b
    coeffs = list(_find_time_dependent_coeffs(H, t))
    assert len(coeffs) == 1
    assert gaussian * linear in coeffs

    H = b * op_n
    coeffs = list(_find_time_dependent_coeffs(H, t))
    len(coeffs) == 9
Example #19
0
def test_find_time_dependent_coeffs():
    E0, sigma, t, t0, a, b = sympy.symbols('E_0, sigma, t, t_0, a, b',
                                           real=True)
    op_a = Destroy(0)
    op_n = op_a.dag() * op_a
    gaussian = E0 * sympy.exp(-(t - t0)**2 / (2 * sigma**2))
    linear = a * t
    H = b * op_a.dag() + gaussian * op_n + linear * op_a
    coeffs = list(_find_time_dependent_coeffs(H, t))
    assert len(coeffs) == 2
    assert gaussian in coeffs
    assert linear in coeffs

    H = (gaussian * op_n) * (linear * op_a) + b
    coeffs = list(_find_time_dependent_coeffs(H, t))
    assert len(coeffs) == 1
    assert gaussian * linear in coeffs

    H = b * op_n
    coeffs = list(_find_time_dependent_coeffs(H, t))
    len(coeffs) == 9
Example #20
0
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.0, 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)
Example #21
0
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 transmon_hamiltonian(n_qubit,
                         n_cavity,
                         non_herm=False,
                         non_linear_decay=False):
    """Return the Transmon symbolic drift and control Hamiltonians. If
    `non_herm` is True, the drift Hamiltonian will include non-Hermitian decay
    terms for the spontaneous decay for the qubits and the cavity. This will be
    the "standard" decay with a linear decay rate, or with an independent decay
    rate for each level in the transmon and cavity if `non_linear_decay` is
    True.
    """
    HilQ1 = LocalSpace('1', dimension=n_qubit)
    HilQ2 = LocalSpace('2', dimension=n_qubit)
    HilCav = LocalSpace('c', dimension=n_cavity)
    b1 = Destroy(identifier='b_1', hs=HilQ1)
    b1_dag = b1.adjoint()
    b2 = Destroy(identifier='b_2', hs=HilQ2)
    b2_dag = b2.adjoint()
    a = Destroy(hs=HilCav)
    a_dag = a.adjoint()
    δ1, δ2, Δ, α1, α2, g1, g2 = sympy.symbols(
        r'delta_1, delta_2, Delta, alpha_1, alpha_2, g_1, g_2', real=True)
    H0 = (δ1 * b1_dag * b1 + (α1 / 2) * b1_dag * b1_dag * b1 * b1 + g1 *
          (b1_dag * a + b1 * a_dag) + δ2 * b2_dag * b2 +
          (α2 / 2) * b2_dag * b2_dag * b2 * b2 + g2 *
          (b2_dag * a + b2 * a_dag) + Δ * a_dag * a)
    if non_herm:
        if non_linear_decay:
            for i in range(1, n_qubit):
                γ = sympy.symbols(r'gamma_%d' % i, real=True)
                H0 = H0 - sympy.I * γ * LocalSigma(i, i, hs=HilQ1) / 2
            for j in range(1, n_qubit):
                γ = sympy.symbols(r'gamma_%d' % j, real=True)
                H0 = H0 - sympy.I * γ * LocalSigma(j, j, hs=HilQ2) / 2
            for n in range(1, n_cavity):
                κ = sympy.symbols(r'kappa_%d' % n, real=True)
                H0 = H0 - sympy.I * κ * LocalSigma(n, n, hs=HilCav) / 2
        else:
            γ, κ = sympy.symbols(r'gamma, kappa', real=True)
            H0 = H0 - sympy.I * γ * b1_dag * b1 / 2
            H0 = H0 - sympy.I * γ * b2_dag * b2 / 2
            H0 = H0 - sympy.I * κ * a_dag * a / 2
    H1 = a / 2  # factor 2 to account for RWA
    return H0, H1
Example #23
0
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()
    )
Example #24
0
def Sec6_codegen(slh_Sec6, slh_Sec6_vals):
    codegen = QSDCodeGen(circuit=slh_Sec6, num_vals=slh_Sec6_vals)
    A2 = Destroy(1)
    Sp = LocalSigma(2, 1, 0)
    Sm = Sp.dag()
    codegen.add_observable(Sp * A2 * Sm * Sp, name="X1")
    codegen.add_observable(Sm * Sp * A2 * Sm, name="X2")
    codegen.add_observable(A2, name="A2")
    psi0 = BasisKet(0, 0)
    psi1 = BasisKet(1, 0)
    psi2 = BasisKet(2, 0)
    codegen.set_trajectories(psi_initial=psi0 * psi1 * psi2,
                             stepper='AdaptiveStep',
                             dt=0.01,
                             nt_plot_step=100,
                             n_plot_steps=5,
                             n_trajectories=1,
                             traj_save=10)
    return codegen
def qnet_node_system(node_index, n_cavity, zero_phi=True, keep_delta=False):
    """Define symbols and operators for a single node"""
    from sympy import symbols
    HilAtom = LocalSpace('q%d' % int(node_index), basis=('g', 'e'))
    HilCavity = LocalSpace('c%d' % int(node_index), dimension=n_cavity)
    Sym = {}
    Sym['Delta'] = symbols(r'Delta_%s' % node_index, real=True)
    Sym['g'] = symbols(r'g_%s' % node_index, positive=True)
    Sym['Omega'] = symbols(r'Omega_%s' % node_index)
    Sym['I'] = sympy.I
    Sym['kappa'] = sympy.symbols(r'kappa', positive=True)
    if not zero_phi:
        Sym['phi'] = sympy.symbols(r'phi_%s' % node_index, real=True)
        Sym['exp'] = sympy.exp
    if keep_delta:
        Sym['delta'] = symbols(r'delta_%s' % node_index, real=True)
    Op = {}
    Op['a'] = Destroy(hs=HilCavity)
    Op['|g><g|'] = LocalSigma('g', 'g', hs=HilAtom)
    Op['|e><e|'] = LocalSigma('e', 'e', hs=HilAtom)
    Op['|e><g|'] = LocalSigma('e', 'g', hs=HilAtom)
    return Sym, Op
Example #26
0
def transmon_model(n_qubit, n_cavity, w1, w2, wc, wd, alpha1, alpha2, g,
        gamma, kappa, lambda_a, pulse, dissipation_model='dissipator',
        gate=None, J_T='sm', iter_stop=1000, ens_pulse_scale=None):
    """Return a QDYN model for propagation and oct of a 2-transmon system

    Args:
        n_qubit (int): number of levels after which transmon is truncated
        n_cavity (int): number of levels after which cavity is truncated
        w1 (float): frequency of qubit 1 (MHz)
        w2 (float): frequency of qubit 2 (MHz)
        wc (float): frequency of cavity (MHz)
        wd (float): frequency of rotating frame (MHz)
        alpha1 (float): anharmonicity of transmon 1 (MHz)
        alpha2 (float): anharmonicity of transmon 2 (MHz)
        g (float): transmon-cavity coupling (MHz)
        gamma (float): decay rate of transmon (MHz). May be a list of values of
            size ``n_qubit - 1`` for non-linear decay, for
            ``dissipation_mode='non_Hermitian' only``
        kappa (float): decay rate of cavity (MHz). May be a list of value of
            size ``n_cavity - 1`` for non-linear decay, for
            ``dissipation_mode='non_Hermitian' only``. Note that `gamma` and
            `kappa` must either both be floats or both be lists.
        lambda_a (float): Krotov scaling parameter
        pulse (QDYN.pulse.Pulse): control pulse
        dissipation_model (str): one of 'dissipator' (density matrix
            propagation), 'non-Hermitian' (Hilbert space propagation with
            non-Hermitian Hamiltonian)
        gate (Gate2Q): an optional two-qubit target gate. If present, it will
            be stored in a custom `gate` attribute. Also, the config file will
            have have a userdefined string parameter 'gate' with value
            'target_gate.dat'. When writing the model to the runfolder,
            `model.gate` must be written to this file.
        J_T (str): The functional to be used for optimization. Must be in
            ['sm', 're', 'LI', 'PE']. Only used if `gate` is given.
        iter_stop: Maximum number of OCT iterations


    The returned model has custom `rwa_vector` and `gate` attributes
    """
    δ1, δ2, Δ, α1, α2, g1, g2 = sympy.symbols(
        r'delta_1, delta_2, Delta, alpha_1, alpha_2, g_1, g_2', real=True)
    num_vals = {  # numeric values in the RWA
            δ1: w1 - wd, δ2: w2 - wd, Δ: wc - wd,
            α1: alpha1, α2: alpha2, g1: g, g2: g}
    nt = len(pulse.tgrid) + 1
    t0 = pulse.t0
    T = pulse.T
    assert J_T in ['sm', 're', 'LI', 'PE']
    if dissipation_model == 'non-Hermitian':
        non_herm = True
        assert isinstance(gamma, type(kappa))
        if isinstance(gamma, float):
            non_linear_decay = False
            γ, κ = sympy.symbols('gamma, kappa', real=True)
            num_vals[γ] = gamma
            num_vals[κ] = kappa
        else:
            non_linear_decay = True
            assert len(gamma) == n_qubit - 1
            assert len(kappa) == n_cavity - 1
            for i in range(1, n_qubit):
                γ = sympy.symbols(r'gamma_%d' % i, real=True)
                num_vals[γ] = gamma[i-1]
            for n in range(1, n_cavity):
                κ = sympy.symbols(r'kappa_%d' % n, real=True)
                num_vals[κ] = kappa[n-1]
    else:
        non_herm = False
        non_linear_decay = False
        # non-linear decay rates are not allowed
        assert isinstance(gamma, float)
        assert isinstance(kappa, float)

    H0, H1 = transmon_hamiltonian(n_qubit, n_cavity, non_herm=non_herm,
                                  non_linear_decay=non_linear_decay)
    hs = H0.space
    H0_num = convert_to_qutip(H0.substitute(num_vals), full_space=hs)
    H1_num = convert_to_qutip(H1, full_space=H0.space)

    model = QDYN.model.LevelModel()

    # dissipation model
    if dissipation_model == 'dissipator':
        # Use a dissipator (density matrix propagation); linear decay
        decay_ops = {ls.label: Destroy(hs=ls) for ls in H0.space.local_factors}
        L1 = np.sqrt(gamma) * convert_to_qutip(decay_ops['1'], full_space=hs)
        L2 = np.sqrt(gamma) * convert_to_qutip(decay_ops['2'], full_space=hs)
        Lc = np.sqrt(kappa) * convert_to_qutip(decay_ops['c'], full_space=hs)
        lindblad_ops = [L1, L2, Lc]
        D = lindblad_ops_to_dissipator(
                [coo_matrix(L.data) for L in lindblad_ops])
        model.set_dissipator(D, op_unit='MHz')
    elif dissipation_model == 'non-Hermitian':
        # the decay term is already included in H0 and H0_num
        pass
    else:
        raise ValueError("Unknown dissipatoin_model: %s" % dissipation_model)

    # Hamiltonian
    model.add_ham(H0_num, op_unit='MHz', op_type='potential')
    model.add_ham(H1_num, pulse=pulse, op_unit='dimensionless',
                  op_type='dipole', sparsity_model='indexed')
    model.add_ham(H1_num.dag(), pulse=pulse, op_unit='dimensionless',
                  op_type='dipole', conjg_pulse=True, sparsity_model='indexed')
    if ens_pulse_scale is not None:
        pulse.config_attribs['label'] = ''
        ens_labels = []
        for i, f in enumerate(ens_pulse_scale):
            ens_label = 'gen%d' % (i+1)
            model.add_ham(H0_num, op_unit='MHz', op_type='potential',
                          label=ens_label)
            model.add_ham(f*H1_num, pulse=pulse, op_unit='dimensionless',
                          op_type='dipole', sparsity_model='indexed',
                          label=ens_label)
            model.add_ham(f*H1_num.dag(), pulse=pulse, op_unit='dimensionless',
                          op_type='dipole', conjg_pulse=True,
                          sparsity_model='indexed', label=ens_label)
            ens_labels.append(ens_label)
        model.user_data['ensemble_gens'] = ",".join(ens_labels)


    model.set_propagation(T=T, nt=nt, t0=t0, time_unit='ns',
                          prop_method='newton')

    # RWA vector
    model.rwa_vector = wd * np.array(
            [sum(ijn) for ijn in itertools.product(
                *[list(range(n)) for n in H0_num.dims[0]])])

    # States
    bare_00 = state(H0.space, 0, 0, 0, fmt='qutip')
    bare_01 = state(H0.space, 0, 1, 0, fmt='qutip')
    bare_10 = state(H0.space, 1, 0, 0, fmt='qutip')
    bare_11 = state(H0.space, 1, 1, 0, fmt='qutip')
    bare_basis = [bare_00, bare_01, bare_10, bare_11]
    dressed_basis = pick_logical_basis(H0_num, bare_basis)
    dressed_00, dressed_01, dressed_10, dressed_11 = dressed_basis
    model.add_state(dressed_00, label='00')
    model.add_state(dressed_01, label='01')
    model.add_state(dressed_10, label='10')
    model.add_state(dressed_11, label='11')

    model.user_data['time_unit'] = 'ns'
    if wd > 0:
        model.user_data['rwa_vector'] = 'rwa_vector.dat'
    if dissipation_model == 'non-Hermitian':
        model.user_data['write_gate'] = 'U_over_t.dat'
    model.user_data['basis'] = '00,01,10,11'
    if gate is not None:
        model.user_data['gate'] = 'target_gate.dat'
        assert isinstance(gate, QDYN.gate2q.Gate2Q)
        model.gate = gate
        model.user_data['J_T'] = 'J_T_%s' % J_T
        model.user_data['write_optimized_gate'] = True
    if J_T in ['PE', 'LI']:
        model.user_data['w_unitary'] = 0.9
    return model
Example #27
0
def test_qsd_codegen_traj(slh_Sec6):
    A2 = Destroy(1)
    Sp = LocalSigma(2, 1, 0)
    Sm = Sp.dag()
    codegen = QSDCodeGen(circuit=slh_Sec6)
    codegen.add_observable(Sp * A2 * Sm * Sp, name="X1")
    codegen.add_observable(Sm * Sp * A2 * Sm, name="X2")
    codegen.add_observable(A2, name="A2")

    with pytest.raises(QSDCodeGenError) as excinfo:
        scode = codegen._trajectory_lines(indent=0)
    assert "No trajectories set up" in str(excinfo.value)

    codegen.set_trajectories(psi_initial=None,
                             stepper='AdaptiveStep',
                             dt=0.01,
                             nt_plot_step=100,
                             n_plot_steps=5,
                             n_trajectories=1,
                             traj_save=10)
    scode = codegen._trajectory_lines(indent=0)
    assert dedent(scode).strip() == dedent(r'''
    ACG gen(rndSeed); // random number generator
    ComplexNormal rndm(&gen); // Complex Gaussian random numbers

    double dt = 0.01;
    int dtsperStep = 100;
    int nOfSteps = 5;
    int nTrajSave = 10;
    int nTrajectory = 1;
    int ReadFile = 0;

    AdaptiveStep stepper(psiIni, H, nL, L);
    Trajectory traj(psiIni, dt, stepper, &rndm);

    traj.sumExp(nOfOut, outlist, flist , dtsperStep, nOfSteps,
                nTrajectory, nTrajSave, ReadFile);
    ''').strip()

    with pytest.raises(ValueError) as excinfo:
        codegen.set_moving_basis(move_dofs=0,
                                 delta=0.01,
                                 width=2,
                                 move_eps=0.01)
    assert "move_dofs must be an integer >0" in str(excinfo.value)
    with pytest.raises(ValueError) as excinfo:
        codegen.set_moving_basis(move_dofs=4,
                                 delta=0.01,
                                 width=2,
                                 move_eps=0.01)
    assert "move_dofs must not be larger" in str(excinfo.value)
    with pytest.raises(QSDCodeGenError) as excinfo:
        codegen.set_moving_basis(move_dofs=3,
                                 delta=0.01,
                                 width=2,
                                 move_eps=0.01)
    assert "A moving basis cannot be used" in str(excinfo.value)
    codegen.set_moving_basis(move_dofs=2, delta=0.01, width=2, move_eps=0.01)
    scode = codegen._trajectory_lines(indent=0)
    assert dedent(scode).strip() == dedent(r'''
    ACG gen(rndSeed); // random number generator
    ComplexNormal rndm(&gen); // Complex Gaussian random numbers

    double dt = 0.01;
    int dtsperStep = 100;
    int nOfSteps = 5;
    int nTrajSave = 10;
    int nTrajectory = 1;
    int ReadFile = 0;

    AdaptiveStep stepper(psiIni, H, nL, L);
    Trajectory traj(psiIni, dt, stepper, &rndm);

    int move = 2;
    double delta = 0.01;
    int width = 2;
    double moveEps = 0.01;

    traj.sumExp(nOfOut, outlist, flist , dtsperStep, nOfSteps,
                nTrajectory, nTrajSave, ReadFile, move,
                delta, width, moveEps);
    ''').strip()
Example #28
0
def test_qsd_codegen_initial_state(slh_Sec6):

    A2 = Destroy(1)
    Sp = LocalSigma(2, 1, 0)
    Sm = Sp.dag()
    psi_cav1 = lambda n: BasisKet(0, n)
    psi_cav2 = lambda n: BasisKet(1, n)
    psi_spin = lambda n: BasisKet(2, n)
    psi_tot = lambda n, m, l: psi_cav1(n) * psi_cav2(m) * psi_spin(l)

    BasisRegistry.registry = {}  # reset
    psi_cav1(0).space.dimension = 10
    psi_cav2(0).space.dimension = 10
    psi_spin(0).space.dimension = 2

    codegen = QSDCodeGen(circuit=slh_Sec6)
    codegen.add_observable(Sp * A2 * Sm * Sp, "X1.out")
    codegen.add_observable(Sm * Sp * A2 * Sm, "X2.out")
    codegen.add_observable(A2, "A2.out")

    psi = (((psi_cav1(0) + psi_cav1(1)) / sympy.sqrt(2)) *
           ((psi_cav2(0) + psi_cav2(1)) / sympy.sqrt(2)) * psi_spin(0))
    codegen.set_trajectories(psi_initial=psi,
                             stepper='AdaptiveStep',
                             dt=0.01,
                             nt_plot_step=100,
                             n_plot_steps=5,
                             n_trajectories=1,
                             traj_save=10)

    scode = codegen._initial_state_lines(indent=0)
    assert scode == dedent(r'''
    State phiL0(10,0,FIELD); // HS 0
    State phiL1(10,0,FIELD); // HS 1
    State phiL2(2,0,FIELD); // HS 2
    State phiL3(10,1,FIELD); // HS 0
    State phiL4(10,1,FIELD); // HS 1
    State phiT0List[3] = {(phiL0 + phiL3), (phiL1 + phiL4), phiL2};
    State phiT0(3, phiT0List); // HS 0 * HS 1 * HS 2

    State psiIni = (1.0L/2.0L) * (phiT0);
    psiIni.normalize();
    ''').strip()

    alpha = symbols('alpha')
    psi = CoherentStateKet(0, alpha) * psi_cav2(0) * psi_spin(0)
    codegen.set_trajectories(psi_initial=psi,
                             stepper='AdaptiveStep',
                             dt=0.01,
                             nt_plot_step=100,
                             n_plot_steps=5,
                             n_trajectories=1,
                             traj_save=10)
    scode = codegen._initial_state_lines(indent=0)
    assert scode == dedent(r'''
    State phiL0(10,0,FIELD); // HS 1
    State phiL1(2,0,FIELD); // HS 2
    State phiL2(10,alpha,FIELD); // HS 0
    State phiT0List[3] = {phiL2, phiL0, phiL1};
    State phiT0(3, phiT0List); // HS 0 * HS 1 * HS 2

    State psiIni = phiT0;
    psiIni.normalize();
    ''').strip()

    psi = (psi_tot(1, 0, 0) + psi_tot(0, 1, 0)) / sympy.sqrt(2)
    codegen.set_trajectories(psi_initial=psi,
                             stepper='AdaptiveStep',
                             dt=0.01,
                             nt_plot_step=100,
                             n_plot_steps=5,
                             n_trajectories=1,
                             traj_save=10)
    scode = codegen._initial_state_lines(indent=0)
    assert scode == dedent(r'''
    State phiL0(10,0,FIELD); // HS 0
    State phiL1(10,0,FIELD); // HS 1
    State phiL2(2,0,FIELD); // HS 2
    State phiL3(10,1,FIELD); // HS 0
    State phiL4(10,1,FIELD); // HS 1
    State phiT0List[3] = {phiL0, phiL4, phiL2};
    State phiT0(3, phiT0List); // HS 0 * HS 1 * HS 2
    State phiT1List[3] = {phiL3, phiL1, phiL2};
    State phiT1(3, phiT1List); // HS 0 * HS 1 * HS 2

    State psiIni = ((1.0L/2.0L)*sqrt(2)) * ((phiT0 + phiT1));
    psiIni.normalize();
    ''').strip()
Example #29
0
 def testDrawSLH(self):
     self.assertCanBeDrawn(
         SLH(identity_matrix(1), Matrix([[Create(1)]]),
             Create(1) * Destroy(1)))
Example #30
0
def test_qsd_codegen_observables(caplog, slh_Sec6, slh_Sec6_vals):
    A2 = Destroy(1)
    Sp = LocalSigma(2, 1, 0)
    Sm = Sp.dag()
    codegen = QSDCodeGen(circuit=slh_Sec6, num_vals=slh_Sec6_vals)

    with pytest.raises(QSDCodeGenError) as excinfo:
        scode = codegen._observables_lines(indent=0)
    assert "Must register at least one observable" in str(excinfo.value)

    codegen.add_observable(Sp * A2 * Sm * Sp)
    name = 'a_1 sigma_10^[2]'
    filename = codegen._observables[name][1]
    assert filename == 'a_1_sigma_10_2.out'
    codegen.add_observable(Sp * A2 * Sm * Sp)
    assert 'Overwriting existing operator' in caplog.text()

    with pytest.raises(ValueError) as exc_info:
        codegen.add_observable(Sp * A2 * A2 * Sm * Sp)
    assert "longer than limit" in str(exc_info.value)
    name = 'A2^2'
    codegen.add_observable(Sp * A2 * A2 * Sm * Sp, name=name)
    assert name in codegen._observables
    filename = codegen._observables[name][1]
    assert filename == 'A2_2.out'

    with pytest.raises(ValueError) as exc_info:
        codegen.add_observable(A2, name='A2_2')
    assert "Cannot generate unique filename" in str(exc_info.value)

    with pytest.raises(ValueError) as exc_info:
        codegen.add_observable(A2, name="A2\t2")
    assert "invalid characters" in str(exc_info.value)

    with pytest.raises(ValueError) as exc_info:
        codegen.add_observable(A2, name="A" * 100)
    assert "longer than limit" in str(exc_info.value)

    with pytest.raises(ValueError) as exc_info:
        codegen.add_observable(A2, name="()")
    assert "Cannot generate filename" in str(exc_info.value)

    codegen = QSDCodeGen(circuit=slh_Sec6, num_vals=slh_Sec6_vals)
    codegen.add_observable(Sp * A2 * Sm * Sp, name="X1")
    codegen.add_observable(Sm * Sp * A2 * Sm, name="X2")
    assert codegen._observables["X2"] == (Sm * Sp * A2 * Sm, 'X2.out')
    codegen.add_observable(A2, name="A2")
    assert codegen._observables["A2"] == (A2, 'A2.out')
    scode = codegen._observables_lines(indent=0)
    assert dedent(scode).strip() == dedent(r'''
    const int nOfOut = 3;
    Operator outlist[nOfOut] = {
      (A1 * S2_1_0),
      (A1 * S2_0_1),
      A1
    };
    char *flist[nOfOut] = {"X1.out", "X2.out", "A2.out"};
    int pipe[4] = {1,2,3,4};
    ''').strip()
    # Note how the observables have been simplified
    assert Sp * A2 * Sm * Sp == Sp * A2
    assert codegen._operator_str(Sp * A2) == '(A1 * S2_1_0)'
    assert Sm * Sp * A2 * Sm == Sm * A2
    assert codegen._operator_str(Sm * A2) == '(A1 * S2_0_1)'
    # If the oberservables introduce new operators or symbols, these should
    # extend the existing ones
    P1 = LocalSigma(2, 1, 1)
    zeta = symbols("zeta", real=True)
    codegen.add_observable(zeta * P1, name="P1")
    assert P1 in codegen._local_ops
    assert str(codegen._qsd_ops[P1]) == 'S2_1_1'
    assert zeta in codegen.syms
    codegen.num_vals.update({zeta: 1.0})
    assert 'zeta' in codegen._parameters_lines(indent=0)
    assert str(codegen._qsd_ops[P1]) in codegen._operator_basis_lines(indent=0)
    assert Sp * A2 in set(codegen.observables)
    assert Sm * A2 in set(codegen.observables)
    assert zeta * P1 in set(codegen.observables)
    assert list(codegen.observable_names) == ['X1', 'X2', 'A2', 'P1']
    assert codegen.get_observable('X1') == Sp * A2 * Sm * Sp
Example #31
0
def test_operator_str(Sec6_codegen):
    gamma1 = symbols(r'\gamma_1', positive=True)
    A0 = Destroy(0)
    Op = sqrt(gamma1) * A0
    assert Sec6_codegen._operator_str(Op) == '(sqrt(gamma_1)) * (A0)'