Пример #1
0
 def test_distribute_operator(self):
     lattice_412 = qutip.Lattice1d(num_cell=4, boundary="periodic",
                                   cell_num_site=1, cell_site_dof=[2])
     op = qutip.Qobj(np.array([[0, 1], [1, 0]]))
     op_all = lattice_412.distribute_operator(op)
     sv_op_all = qutip.tensor(qutip.qeye(4), qutip.sigmax())
     assert op_all == sv_op_all
Пример #2
0
def _crow_lattice(coupling,
                  phase_delay,
                  cells=4,
                  boundary="periodic",
                  sites_per_cell=1,
                  freedom=[2]):
    r"""
    Return a `qutip.Lattice1d` of a "Coupled Resonator Optical Waveguide"
    (CROW) with the given coupling strength and phase delay.

    See for example: https://www.doi.org/10.1103/PhysRevB.99.224201
    where `coupling` is $J$ and `phase_delay` is $\eta$.
    """
    cell_hamiltonian = coupling * np.sin(phase_delay) * qutip.sigmax()
    phase_term = np.exp(1j * phase_delay)
    hopping = [
        0.5 * coupling *
        qutip.qdiags([phase_term, phase_term.conj()], 0),
        0.5 * coupling * qutip.sigmax(),
    ]
    return qutip.Lattice1d(num_cell=cells,
                           boundary=boundary,
                           cell_num_site=sites_per_cell,
                           cell_site_dof=freedom,
                           Hamiltonian_of_cell=cell_hamiltonian,
                           inter_hop=hopping)
Пример #3
0
 def test_basis(self):
     lattice_3242 = qutip.Lattice1d(num_cell=3, boundary="periodic",
                                    cell_num_site=2, cell_site_dof=[4, 2])
     psi0 = lattice_3242.basis(1, 0, [2, 1])
     psi0dag_a = np.zeros((1, 48), dtype=complex)
     psi0dag_a[0, 21] = 1
     psi0dag = qutip.Qobj(psi0dag_a, dims=[[1, 1, 1, 1], [3, 2, 4, 2]])
     assert psi0 == psi0dag.dag()
Пример #4
0
 def test_x(self):
     lattice_3223 = qutip.Lattice1d(num_cell=3,
                                    boundary="periodic",
                                    cell_num_site=2,
                                    cell_site_dof=[2, 3])
     test = lattice_3223.x().full()
     expected = np.diag([n for n in range(3) for _ in [None] * 12])
     np.testing.assert_allclose(test, expected, atol=1e-12)
Пример #5
0
 def test_hamiltonian(self, cells, periodic, sites_per_cell, freedom):
     """Test that the lattice model produces the expected Hamiltonians."""
     boundary = "periodic" if periodic else "aperiodic"
     lattice = qutip.Lattice1d(num_cell=cells, boundary=boundary,
                               cell_site_dof=freedom,
                               cell_num_site=sites_per_cell)
     expected = _hamiltonian_expected(cells, periodic, sites_per_cell,
                                      freedom)
     assert lattice.Hamiltonian() == expected
Пример #6
0
 def test_operator_at_cells(self):
     p_2222 = qutip.Lattice1d(num_cell=2, boundary="periodic",
                              cell_num_site=2, cell_site_dof=[2, 2])
     op_0 = qutip.projection(2, 0, 1)
     op_c = qutip.tensor(op_0, qutip.qeye([2, 2]))
     OP = p_2222.operator_between_cells(op_c, 1, 0)
     T = qutip.projection(2, 1, 0)
     QP = qutip.tensor(T, op_c)
     assert OP == QP
Пример #7
0
    def test_operator_between_cells(self):
        lattice_412 = qutip.Lattice1d(num_cell=4, boundary="periodic",
                                      cell_num_site=1, cell_site_dof=[2])
        op = qutip.sigmax()
        op_sp = lattice_412.operator_at_cells(op, cells=[1, 2])

        aop_sp = np.zeros((8, 8), dtype=complex)
        aop_sp[2:4, 2:4] = aop_sp[4:6, 4:6] = op.full()
        sv_op_sp = qutip.Qobj(aop_sp, dims=[[4, 2], [4, 2]])
        assert op_sp == sv_op_sp
Пример #8
0
def _ssh_lattice(intra, inter,
                 cells=5, boundary="periodic", sites_per_cell=2,
                 freedom=[1]):
    part_hamiltonian = qutip.Qobj(np.array([[0, intra], [intra, 0]]))
    free_identity = qutip.qeye(freedom)
    hamiltonian = qutip.tensor(part_hamiltonian, free_identity)
    hopping = qutip.tensor(qutip.Qobj(np.array([[0, 0], [inter, 0]])),
                           free_identity)
    return qutip.Lattice1d(num_cell=cells, boundary=boundary,
                           cell_num_site=sites_per_cell,
                           cell_site_dof=freedom,
                           Hamiltonian_of_cell=hamiltonian,
                           inter_hop=hopping)
Пример #9
0
 def test_k(self):
     L = 7
     lattice_L123 = qutip.Lattice1d(num_cell=L, boundary="periodic",
                                    cell_num_site=1, cell_site_dof=[2, 3])
     kq = lattice_L123.k()
     kop = np.zeros((L, L), dtype=complex)
     for row in range(L):
         for col in range(L):
             if row == col:
                 kop[row, col] = (L-1)/2
             else:
                 kop[row, col] = 1 / (np.exp(2j * np.pi * (row - col)/L)-1)
     kt = np.kron(kop * 2 * np.pi / L, np.eye(6))
     dim_H = [[L, 2, 3], [L, 2, 3]]
     kt = qutip.Qobj(kt, dims=dim_H)
     k_q = kq.eigenstates()[0]
     k_t = kt.eigenstates()[0]
     k_tC = k_t - (2*np.pi/L) * ((L-1) // 2)
     np.testing.assert_allclose(k_tC, k_q, atol=1e-12)
Пример #10
0
class TestLattice1d:
    @pytest.mark.parametrize("cells", [1, 2, 3])
    @pytest.mark.parametrize("periodic", [True, False],
                             ids=["periodic", "aperiodic"])
    @pytest.mark.parametrize("sites_per_cell", [1, 2])
    @pytest.mark.parametrize("freedom", [[1], [2, 3]],
                             ids=["simple chain", "onsite freedom"])
    def test_hamiltonian(self, cells, periodic, sites_per_cell, freedom):
        """Test that the lattice model produces the expected Hamiltonians."""
        boundary = "periodic" if periodic else "aperiodic"
        lattice = qutip.Lattice1d(num_cell=cells, boundary=boundary,
                                  cell_site_dof=freedom,
                                  cell_num_site=sites_per_cell)
        expected = _hamiltonian_expected(cells, periodic, sites_per_cell,
                                         freedom)
        assert lattice.Hamiltonian() == expected

    def test_cell_structures(self):
        val_s = ['site0', 'site1']
        val_t = [' orb0', 'orb1']
        H_cell_form, inter_cell_T_form, H_cell, inter_cell_T =\
            qutip.cell_structures(val_s, val_t)
        c_H_form = [['<site0 orb0 H site0 orb0>',
                     '<site0 orb0 H site0orb1>',
                     '<site0 orb0 H site1 orb0>',
                     '<site0 orb0 H site1orb1>'],
                    ['<site0orb1 H site0 orb0>',
                     '<site0orb1 H site0orb1>',
                     '<site0orb1 H site1 orb0>',
                     '<site0orb1 H site1orb1>'],
                    ['<site1 orb0 H site0 orb0>',
                     '<site1 orb0 H site0orb1>',
                     '<site1 orb0 H site1 orb0>',
                     '<site1 orb0 H site1orb1>'],
                    ['<site1orb1 H site0 orb0>',
                     '<site1orb1 H site0orb1>',
                     '<site1orb1 H site1 orb0>',
                     '<site1orb1 H site1orb1>']]

        i_cell_T_form = [['<cell(i):site0 orb0 H site0 orb0:cell(i+1) >',
                          '<cell(i):site0 orb0 H site0orb1:cell(i+1) >',
                          '<cell(i):site0 orb0 H site1 orb0:cell(i+1) >',
                          '<cell(i):site0 orb0 H site1orb1:cell(i+1) >'],
                         ['<cell(i):site0orb1 H site0 orb0:cell(i+1) >',
                          '<cell(i):site0orb1 H site0orb1:cell(i+1) >',
                          '<cell(i):site0orb1 H site1 orb0:cell(i+1) >',
                          '<cell(i):site0orb1 H site1orb1:cell(i+1) >'],
                         ['<cell(i):site1 orb0 H site0 orb0:cell(i+1) >',
                          '<cell(i):site1 orb0 H site0orb1:cell(i+1) >',
                          '<cell(i):site1 orb0 H site1 orb0:cell(i+1) >',
                          '<cell(i):site1 orb0 H site1orb1:cell(i+1) >'],
                         ['<cell(i):site1orb1 H site0 orb0:cell(i+1) >',
                          '<cell(i):site1orb1 H site0orb1:cell(i+1) >',
                          '<cell(i):site1orb1 H site1 orb0:cell(i+1) >',
                          '<cell(i):site1orb1 H site1orb1:cell(i+1) >']]
        c_H = np.zeros((4, 4), dtype=complex)
        i_cell_T = np.zeros((4, 4), dtype=complex)
        assert H_cell_form == c_H_form
        assert inter_cell_T_form == i_cell_T_form
        assert (H_cell == c_H).all()
        assert (inter_cell_T == i_cell_T).all()

    def test_basis(self):
        lattice_3242 = qutip.Lattice1d(num_cell=3, boundary="periodic",
                                       cell_num_site=2, cell_site_dof=[4, 2])
        psi0 = lattice_3242.basis(1, 0, [2, 1])
        psi0dag_a = np.zeros((1, 48), dtype=complex)
        psi0dag_a[0, 21] = 1
        psi0dag = qutip.Qobj(psi0dag_a, dims=[[1, 1, 1, 1], [3, 2, 4, 2]])
        assert psi0 == psi0dag.dag()

    def test_distribute_operator(self):
        lattice_412 = qutip.Lattice1d(num_cell=4, boundary="periodic",
                                      cell_num_site=1, cell_site_dof=[2])
        op = qutip.Qobj(np.array([[0, 1], [1, 0]]))
        op_all = lattice_412.distribute_operator(op)
        sv_op_all = qutip.tensor(qutip.qeye(4), qutip.sigmax())
        assert op_all == sv_op_all

    def test_operator_at_cells(self):
        p_2222 = qutip.Lattice1d(num_cell=2, boundary="periodic",
                                 cell_num_site=2, cell_site_dof=[2, 2])
        op_0 = qutip.projection(2, 0, 1)
        op_c = qutip.tensor(op_0, qutip.qeye([2, 2]))
        OP = p_2222.operator_between_cells(op_c, 1, 0)
        T = qutip.projection(2, 1, 0)
        QP = qutip.tensor(T, op_c)
        assert OP == QP

    def test_operator_between_cells(self):
        lattice_412 = qutip.Lattice1d(num_cell=4, boundary="periodic",
                                      cell_num_site=1, cell_site_dof=[2])
        op = qutip.sigmax()
        op_sp = lattice_412.operator_at_cells(op, cells=[1, 2])

        aop_sp = np.zeros((8, 8), dtype=complex)
        aop_sp[2:4, 2:4] = aop_sp[4:6, 4:6] = op.full()
        sv_op_sp = qutip.Qobj(aop_sp, dims=[[4, 2], [4, 2]])
        assert op_sp == sv_op_sp

    def test_x(self):
        lattice_3223 = qutip.Lattice1d(num_cell=3, boundary="periodic",
                                       cell_num_site=2, cell_site_dof=[2, 3])
        test = lattice_3223.x().full()
        expected = np.diag([n for n in range(3) for _ in [None]*12])
        np.testing.assert_allclose(test, expected, atol=1e-12)

    def test_k(self):
        L = 7
        lattice_L123 = qutip.Lattice1d(num_cell=L, boundary="periodic",
                                       cell_num_site=1, cell_site_dof=[2, 3])
        kq = lattice_L123.k()
        kop = np.zeros((L, L), dtype=complex)
        for row in range(L):
            for col in range(L):
                if row == col:
                    kop[row, col] = (L-1)/2
                else:
                    kop[row, col] = 1 / (np.exp(2j * np.pi * (row - col)/L)-1)
        kt = np.kron(kop * 2 * np.pi / L, np.eye(6))
        dim_H = [[L, 2, 3], [L, 2, 3]]
        kt = qutip.Qobj(kt, dims=dim_H)
        k_q = kq.eigenstates()[0]
        k_t = kt.eigenstates()[0]
        k_tC = k_t - (2*np.pi/L) * ((L-1) // 2)
        np.testing.assert_allclose(k_tC, k_q, atol=1e-12)

    @pytest.mark.parametrize([
        "lattice_func", "k_expected", "energies_expected",
    ], [
        pytest.param(lambda: qutip.Lattice1d(num_cell=8),
                     _k_expected(8),
                     np.array([[2, np.sqrt(2), 0, -np.sqrt(2), -2,
                                -np.sqrt(2), 0, np.sqrt(2)]]),
                     id="atom chain"),
        pytest.param(lambda: _ssh_lattice(
                        -0.5, -0.6, cells=6, sites_per_cell=2, freedom=[2, 2]),
                     _k_expected(6),
                     np.array([-_ssh_energies]*4 + [_ssh_energies]*4),
                     id="ssh model")
    ])
    def test_get_dispersion(self, lattice_func, k_expected, energies_expected):
        lattice = lattice_func()
        k_test, energies_test = lattice.get_dispersion()
        _assert_angles_close(k_test, k_expected, atol=1e-8)
        np.testing.assert_allclose(energies_test, energies_expected, atol=1e-8)

    def test_cell_periodic_parts(self):
        lattice = _crow_lattice(2, np.pi/4)
        eigensystems = zip(lattice.get_dispersion()[1].T,
                           lattice.cell_periodic_parts()[1])
        hamiltonians = lattice.bulk_Hamiltonians()[1]
        for hamiltonian, system in zip(hamiltonians, eigensystems):
            for eigenvalue, eigenstate in zip(*system):
                eigenstate = qutip.Qobj(eigenstate)
                np.testing.assert_allclose((hamiltonian * eigenstate).full(),
                                           (eigenvalue * eigenstate).full(),
                                           atol=1e-12)

    def test_bulk_Hamiltonians(self):
        test = _crow_lattice(2, np.pi/2).bulk_Hamiltonians()[1]
        expected = [[[0, 0], [0, 0]],
                    [[2, 2], [2, -2]],
                    [[0, 4], [4, 0]],
                    [[-2, 2], [2, 2]]]
        for test_hamiltonian, expected_hamiltonian in zip(test, expected):
            np.testing.assert_allclose(test_hamiltonian.full(),
                                       expected_hamiltonian,
                                       atol=1e-12)

    def test_bloch_wave_functions(self):
        lattice = _crow_lattice(2, np.pi/2)
        hamiltonian = lattice.Hamiltonian()
        expected = np.array([[0,    2,   1j,  1,   0,   0,  -1j,  1],
                             [2,    0,   1,  -1j,  0,   0,   1,   1j],
                             [-1j,  1,   0,   2,   1j,  1,   0,   0],
                             [1,    1j,  2,   0,   1,  -1j,  0,   0],
                             [0,    0,  -1j,  1,   0,   2,   1j,  1],
                             [0,    0,   1,   1j,  2,   0,   1,  -1j],
                             [1j,   1,   0,   0,  -1j,  1,   0,   2],
                             [1,   -1j,  0,   0,   1,   1j,  2,   0]])
        np.testing.assert_allclose(hamiltonian.full(), expected, atol=1e-8)
        for eigenvalue, eigenstate in lattice.bloch_wave_functions():
            np.testing.assert_allclose((hamiltonian * eigenstate).full(),
                                       (eigenvalue * eigenstate).full(),
                                       atol=1e-12)