Beispiel #1
0
def test_gap(backend, trotter, check_degenerate):
    original_backend = qibo.get_backend()
    qibo.set_backend(backend)
    from qibo import hamiltonians
    h0 = hamiltonians.X(4, trotter=trotter)
    if check_degenerate:
        # use h=0 to make this Hamiltonian degenerate
        h1 = hamiltonians.TFIM(4, h=0, trotter=trotter)
    else:
        h1 = hamiltonians.TFIM(4, h=1, trotter=trotter)

    ham = lambda t: (1 - t) * h0.matrix + t * h1.matrix
    targets = {"ground": [], "excited": [], "gap": []}
    for t in np.linspace(0, 1, 11):
        eigvals = np.linalg.eigvalsh(ham(t)).real
        targets["ground"].append(eigvals[0])
        targets["excited"].append(eigvals[1])
        targets["gap"].append(eigvals[1] - eigvals[0])
    if check_degenerate:
        targets["gap"][-1] = eigvals[3] - eigvals[0]

    gap = callbacks.Gap(check_degenerate=check_degenerate)
    ground = callbacks.Gap(0)
    excited = callbacks.Gap(1)
    evolution = AdiabaticEvolution(h0,
                                   h1,
                                   lambda t: t,
                                   dt=1e-1,
                                   callbacks=[gap, ground, excited])
    final_state = evolution(final_time=1.0)
    np.testing.assert_allclose(ground[:], targets["ground"])
    np.testing.assert_allclose(excited[:], targets["excited"])
    np.testing.assert_allclose(gap[:], targets["gap"])
    qibo.set_backend(original_backend)
Beispiel #2
0
def test_gap(backend, dense, check_degenerate):
    from qibo import hamiltonians
    h0 = hamiltonians.X(4, dense=dense)
    if check_degenerate:
        # use h=0 to make this Hamiltonian degenerate
        h1 = hamiltonians.TFIM(4, h=0, dense=dense)
    else:
        h1 = hamiltonians.TFIM(4, h=1, dense=dense)

    ham = lambda t: (1 - t) * h0.matrix + t * h1.matrix
    targets = {"ground": [], "excited": [], "gap": []}
    for t in np.linspace(0, 1, 11):
        eigvals = np.linalg.eigvalsh(ham(t)).real
        targets["ground"].append(eigvals[0])
        targets["excited"].append(eigvals[1])
        targets["gap"].append(eigvals[1] - eigvals[0])
    if check_degenerate:
        targets["gap"][-1] = eigvals[3] - eigvals[0]

    gap = callbacks.Gap(check_degenerate=check_degenerate)
    ground = callbacks.Gap(0)
    excited = callbacks.Gap(1)
    evolution = AdiabaticEvolution(h0, h1, lambda t: t, dt=1e-1,
                                   callbacks=[gap, ground, excited])
    final_state = evolution(final_time=1.0)
    targets = {k: K.stack(v) for k, v in targets.items()}
    K.assert_allclose(ground[:], targets["ground"])
    K.assert_allclose(excited[:], targets["excited"])
    K.assert_allclose(gap[:], targets["gap"])
Beispiel #3
0
def test_state_evolution_trotter_hamiltonian(backend, accelerators, nqubits,
                                             solver, dt, atol):
    if accelerators is not None and solver != "exp":
        pytest.skip("Distributed evolution is supported only with exp solver.")
    h = 1.0

    target_psi = [np.ones(2**nqubits) / np.sqrt(2**nqubits)]
    ham_matrix = K.to_numpy(hamiltonians.TFIM(nqubits, h=h).matrix)
    prop = expm(-1j * dt * ham_matrix)
    for n in range(int(1 / dt)):
        target_psi.append(prop.dot(target_psi[-1]))

    ham = hamiltonians.TFIM(nqubits, h=h, dense=False)
    checker = TimeStepChecker(target_psi, atol=atol)
    evolution = models.StateEvolution(ham,
                                      dt,
                                      solver=solver,
                                      callbacks=[checker],
                                      accelerators=accelerators)
    final_psi = evolution(final_time=1, initial_state=np.copy(target_psi[0]))

    # Change dt
    if solver == "exp":
        evolution = models.StateEvolution(ham,
                                          dt / 10,
                                          accelerators=accelerators)
        final_psi = evolution(final_time=1,
                              initial_state=np.copy(target_psi[0]))
        assert_states_equal(final_psi.tensor, target_psi[-1], atol=atol)
Beispiel #4
0
def test_symbolic_hamiltonian_operator_add_and_sub(backend, nqubits, calcterms,
                                                   calcdense):
    """Test addition and subtraction between Trotter Hamiltonians."""
    local_ham1 = hamiltonians.SymbolicHamiltonian(symbolic_tfim(nqubits,
                                                                h=1.0))
    local_ham2 = hamiltonians.SymbolicHamiltonian(symbolic_tfim(nqubits,
                                                                h=0.5))
    if calcterms:
        _ = local_ham1.terms
        _ = local_ham2.terms
    if calcdense:
        _ = local_ham1.dense
        _ = local_ham2.dense
    local_ham = local_ham1 + local_ham2
    target_ham = (hamiltonians.TFIM(nqubits, h=1.0) +
                  hamiltonians.TFIM(nqubits, h=0.5))
    dense = local_ham.dense
    K.assert_allclose(dense.matrix, target_ham.matrix)

    local_ham1 = hamiltonians.SymbolicHamiltonian(symbolic_tfim(nqubits,
                                                                h=1.0))
    local_ham2 = hamiltonians.SymbolicHamiltonian(symbolic_tfim(nqubits,
                                                                h=0.5))
    if calcterms:
        _ = local_ham1.terms
        _ = local_ham2.terms
    if calcdense:
        _ = local_ham1.dense
        _ = local_ham2.dense
    local_ham = local_ham1 - local_ham2
    target_ham = (hamiltonians.TFIM(nqubits, h=1.0) -
                  hamiltonians.TFIM(nqubits, h=0.5))
    dense = local_ham.dense
    K.assert_allclose(dense.matrix, target_ham.matrix)
Beispiel #5
0
def test_trotter_hamiltonian_scalar_add(nqubits=4):
    """Test addition of Trotter Hamiltonian with scalar."""
    local_ham = hamiltonians.TFIM(nqubits, h=1.0, dense=False)
    target_ham = 2 + hamiltonians.TFIM(nqubits, h=1.0)
    local_dense = (2 + local_ham).dense
    K.assert_allclose(local_dense.matrix, target_ham.matrix)

    local_ham = hamiltonians.TFIM(nqubits, h=1.0, dense=False)
    local_dense = (local_ham + 2).dense
    K.assert_allclose(local_dense.matrix, target_ham.matrix)
Beispiel #6
0
def test_trotter_hamiltonian_scalar_mul(nqubits=3):
    """Test multiplication of Trotter Hamiltonian with scalar."""
    local_ham = hamiltonians.TFIM(nqubits, h=1.0, dense=False)
    target_ham = 2 * hamiltonians.TFIM(nqubits, h=1.0)
    local_dense = (2 * local_ham).dense
    K.assert_allclose(local_dense.matrix, target_ham.matrix)

    local_ham = hamiltonians.TFIM(nqubits, h=1.0, dense=False)
    local_dense = (local_ham * 2).dense
    K.assert_allclose(local_dense.matrix, target_ham.matrix)
Beispiel #7
0
def test_trotter_hamiltonian_scalar_sub(nqubits=3):
    """Test subtraction of Trotter Hamiltonian with scalar."""
    local_ham = hamiltonians.TFIM(nqubits, h=1.0, dense=False)
    target_ham = 2 - hamiltonians.TFIM(nqubits, h=1.0)
    local_dense = (2 - local_ham).dense
    K.assert_allclose(local_dense.matrix, target_ham.matrix)

    target_ham = hamiltonians.TFIM(nqubits, h=1.0) - 2
    local_ham = hamiltonians.TFIM(nqubits, h=1.0, dense=False)
    local_dense = (local_ham - 2).dense
    K.assert_allclose(local_dense.matrix, target_ham.matrix)
Beispiel #8
0
def main(nqubits, hfield, T, save):
    """Compares exact with Trotterized state evolution.

    Plots the overlap between the exact final state and the state from the
    Trotterized evolution as a function of the number of time steps used for
    the discretization of time.
    The transverse field Ising model (TFIM) is used as a toy model for this
    experiment.

    Args:
        nqubits (int): Number of qubits in the system.
        hfield (float): Transverse field Ising model h-field h value.
        T (float): Total time of the adiabatic evolution.
        save (bool): Whether to save the plots.
    """
    dense_h = hamiltonians.TFIM(nqubits, h=hfield)
    trotter_h = hamiltonians.TFIM(nqubits, h=hfield, trotter=True)
    initial_state = np.ones(2 ** nqubits) / np.sqrt(2 ** nqubits)

    nsteps_list = np.arange(50, 550, 50)
    overlaps = []
    for nsteps in nsteps_list:
        exact_ev = models.StateEvolution(dense_h, dt=T/nsteps)
        trotter_ev = models.StateEvolution(trotter_h, dt=T/nsteps)
        exact_state = exact_ev(final_time=T, initial_state=np.copy(initial_state))
        trotter_state = trotter_ev(final_time=T, initial_state=np.copy(initial_state))
        overlaps.append(callbacks.Overlap(exact_state)(trotter_state).numpy())

    dt_list = T / nsteps_list
    overlaps = 1 - np.array(overlaps)

    exponent = int(linregress(np.log(dt_list), np.log(overlaps))[0])
    err = [overlaps[0] * (dt_list / dt_list[0])**(exponent - 1),
           overlaps[0] * (dt_list / dt_list[0])**exponent,
           overlaps[0] * (dt_list / dt_list[0])**(exponent + 1)]
    alphas = [1.0, 0.7, 0.4]
    labels = [r"$\delta t ^{}$".format(exponent - 1),
              r"$\delta t ^{}$".format(exponent),
              r"$\delta t ^{}$".format(exponent + 1)]

    plt.figure(figsize=(7, 4))
    plt.semilogy(nsteps_list, overlaps, marker="o", markersize=8, linewidth=2.0, label="Error")
    for e, a, l in zip(err, alphas, labels):
        plt.semilogy(nsteps_list, e, color="red", alpha=a, linestyle="--", linewidth=2.0, label=l)
    plt.xlabel("Number of steps")
    plt.ylabel("$1 -$ Overlap")
    plt.legend()

    if save:
        plt.savefig(f"images/trotter_error_n{nqubits}T{T}.png", bbox_inches="tight")
    else:
        plt.show()
Beispiel #9
0
def test_trotter_hamiltonian_t(nqubits, h=1.0, dt=1e-3):
    """Test using ``TrotterHamiltonian`` in adiabatic evolution model."""
    dense_h0 = hamiltonians.X(nqubits)
    dense_h1 = hamiltonians.TFIM(nqubits, h=h)
    dense_adev = models.AdiabaticEvolution(dense_h0, dense_h1, lambda t: t, dt)

    local_h0 = hamiltonians.X(nqubits, trotter=True)
    local_h1 = hamiltonians.TFIM(nqubits, h=h, trotter=True)
    local_adev = models.AdiabaticEvolution(local_h0, local_h1, lambda t: t, dt)

    for t in np.random.random(10):
        local_matrix = local_adev.hamiltonian(t, total_time=1).dense.matrix
        target_matrix = dense_adev.hamiltonian(t, total_time=1).matrix
        np.testing.assert_allclose(local_matrix, target_matrix)
Beispiel #10
0
def test_hamiltonian_matmul(backend, sparse_type):
    """Test matrix multiplication between Hamiltonians."""
    if sparse_type is None:
        nqubits = 3
        H1 = hamiltonians.TFIM(nqubits, h=1.0)
        H2 = hamiltonians.Y(nqubits)
    else:
        nqubits = 5
        nstates = 2 ** nqubits
        H1 = hamiltonians.Hamiltonian(nqubits, random_sparse_matrix(nstates, sparse_type))
        H2 = hamiltonians.Hamiltonian(nqubits, random_sparse_matrix(nstates, sparse_type))

    m1 = K.to_numpy(H1.matrix)
    m2 = K.to_numpy(H2.matrix)
    if K.name == "tensorflow" and sparse_type is not None:
        with pytest.raises(NotImplementedError):
            _ = H1 @ H2
    else:
        K.assert_allclose((H1 @ H2).matrix, m1 @ m2)
        K.assert_allclose((H2 @ H1).matrix, m2 @ m1)

    with pytest.raises(ValueError):
        H1 @ np.zeros(3 * (2 ** nqubits,), dtype=m1.dtype)
    with pytest.raises(NotImplementedError):
        H1 @ 2
Beispiel #11
0
def test_initial_state(accelerators):
    h = hamiltonians.TFIM(3, h=1.0, trotter=True)
    qaoa = models.QAOA(h, accelerators=accelerators)
    qaoa.set_parameters(np.random.random(4))
    target_state = np.ones(2 ** 3) / np.sqrt(2 ** 3)
    final_state = qaoa.get_initial_state()
    np.testing.assert_allclose(final_state, target_state)
Beispiel #12
0
def test_qaoa_execution(solver, trotter, accelerators):
    h = hamiltonians.TFIM(4, h=1.0, trotter=trotter)
    m = hamiltonians.X(4, trotter=trotter)
    # Trotter and RK require small p's!
    params = 0.01 * (1 - 2 * np.random.random(4))
    state = utils.random_numpy_state(4)
    # set absolute test tolerance according to solver
    if "rk" in solver:
        atol = 1e-2
    elif trotter:
        atol = 1e-5
    else:
        atol = 0

    target_state = np.copy(state)
    h_matrix = h.matrix.numpy()
    m_matrix = m.matrix.numpy()
    for i, p in enumerate(params):
        if i % 2:
            u = expm(-1j * p * m_matrix)
        else:
            u = expm(-1j * p * h_matrix)
        target_state = u @ target_state

    qaoa = models.QAOA(h, mixer=m, solver=solver, accelerators=accelerators)
    qaoa.set_parameters(params)
    final_state = qaoa(np.copy(state))
    np.testing.assert_allclose(final_state, target_state, atol=atol)
Beispiel #13
0
def main(nqubits_list, dt, solver, trotter=False, accelerators=None):
    """Performs adiabatic evolution with critical TFIM as the "hard" Hamiltonian."""
    if accelerators is not None:
        trotter = True
        solver = "exp"

    print(f"Using {solver} solver and dt = {dt}.")
    print(f"Accelerators: {accelerators}")

    for nqubits in nqubits_list:
        start_time = time.time()
        h0 = hamiltonians.X(nqubits, trotter=trotter)
        h1 = hamiltonians.TFIM(nqubits, h=1.0, trotter=trotter)
        ham_creation_time = time.time() - start_time
        print(f"\nnqubits = {nqubits}, solver = {solver}")
        print(f"trotter = {trotter}, accelerators = {accelerators}")
        print("Hamiltonians created in:", ham_creation_time)

        start_time = time.time()
        evolution = models.AdiabaticEvolution(h0,
                                              h1,
                                              lambda t: t,
                                              dt=dt,
                                              solver=solver,
                                              accelerators=accelerators)
        creation_time = time.time() - start_time
        print("Evolution model created in:", creation_time)

        start_time = time.time()
        final_psi = evolution(final_time=1.0)
        simulation_time = time.time() - start_time
        print("Simulation time:", simulation_time)
def test_gap(trotter):
    """Check gap callback for adiabatic evolution model."""
    from qibo import hamiltonians
    h0 = hamiltonians.X(3, trotter=trotter)
    h1 = hamiltonians.TFIM(3, h=1.0, trotter=trotter)

    ham = lambda t: ((1 - t) * h0.matrix + t * h1.matrix).numpy()
    targets = {"ground": [], "excited": [], "gap": []}
    for t in np.linspace(0, 1, 11):
        eigvals = np.linalg.eigvalsh(ham(t)).real
        targets["ground"].append(eigvals[0])
        targets["excited"].append(eigvals[1])
        targets["gap"].append(eigvals[1] - eigvals[0])

    gap = callbacks.Gap()
    ground = callbacks.Gap(0)
    excited = callbacks.Gap(1)
    evolution = AdiabaticEvolution(h0,
                                   h1,
                                   lambda t: t,
                                   dt=1e-1,
                                   callbacks=[gap, ground, excited])
    final_state = evolution(final_time=1.0)

    np.testing.assert_allclose(ground[:], targets["ground"])
    np.testing.assert_allclose(excited[:], targets["excited"])
    np.testing.assert_allclose(gap[:], targets["gap"])
    # check not implemented for density matrices
    with pytest.raises(NotImplementedError):
        gap(np.zeros(8), is_density_matrix=True)
Beispiel #15
0
def test_hamiltonian_matmul():
    """Test matrix multiplication between Hamiltonians and state vectors."""
    H1 = hamiltonians.TFIM(nqubits=3, h=1.0)
    H2 = hamiltonians.Y(nqubits=3)
    m1 = K.to_numpy(H1.matrix)
    m2 = K.to_numpy(H2.matrix)

    K.assert_allclose((H1 @ H2).matrix, m1 @ m2)
    K.assert_allclose((H2 @ H1).matrix, m2 @ m1)

    v = random_complex(8, dtype=m1.dtype)
    m = random_complex((8, 8), dtype=m1.dtype)
    H1v = H1 @ K.cast(v)
    H1m = H1 @ K.cast(m)
    K.assert_allclose(H1v, m1.dot(v))
    K.assert_allclose(H1m, m1 @ m)

    from qibo.core.states import VectorState
    H1state = H1 @ VectorState.from_tensor(K.cast(v))
    K.assert_allclose(H1state, m1.dot(v))

    with pytest.raises(ValueError):
        H1 @ np.zeros((8, 8, 8), dtype=m1.dtype)
    with pytest.raises(NotImplementedError):
        H1 @ 2
def test_initial_state(backend, accelerators):
    h = hamiltonians.TFIM(5, h=1.0, dense=False)
    qaoa = models.QAOA(h, accelerators=accelerators)
    qaoa.set_parameters(np.random.random(4))
    target_state = np.ones(2**5) / np.sqrt(2**5)
    final_state = qaoa.get_initial_state()
    K.assert_allclose(final_state, target_state)
def test_qaoa_execution(backend, solver, dense, accel=None):
    h = hamiltonians.TFIM(6, h=1.0, dense=dense)
    m = hamiltonians.X(6, dense=dense)
    # Trotter and RK require small p's!
    params = 0.01 * (1 - 2 * np.random.random(4))
    state = random_state(6)
    # set absolute test tolerance according to solver
    if "rk" in solver:
        atol = 1e-2
    elif not dense:
        atol = 1e-5
    else:
        atol = 0

    target_state = np.copy(state)
    h_matrix = K.to_numpy(h.matrix)
    m_matrix = K.to_numpy(m.matrix)
    for i, p in enumerate(params):
        if i % 2:
            u = expm(-1j * p * m_matrix)
        else:
            u = expm(-1j * p * h_matrix)
        target_state = u @ target_state

    qaoa = models.QAOA(h, mixer=m, solver=solver, accelerators=accel)
    qaoa.set_parameters(params)
    final_state = qaoa(np.copy(state))
    K.assert_allclose(final_state, target_state, atol=atol)
def test_tfim_hamiltonian_from_symbols(nqubits, hamtype, calcterms):
    """Check creating TFIM Hamiltonian using sympy."""
    if hamtype == "symbolic":
        from qibo.symbols import X, Z
        h = 0.5
        symham = sum(Z(i) * Z(i + 1) for i in range(nqubits - 1))
        symham += Z(0) * Z(nqubits - 1)
        symham += h * sum(X(i) for i in range(nqubits))
        ham = hamiltonians.SymbolicHamiltonian(-symham)
    else:
        h = 0.5
        z_symbols = sympy.symbols(" ".join((f"Z{i}" for i in range(nqubits))))
        x_symbols = sympy.symbols(" ".join((f"X{i}" for i in range(nqubits))))

        symham = sum(z_symbols[i] * z_symbols[i + 1] for i in range(nqubits - 1))
        symham += z_symbols[0] * z_symbols[-1]
        symham += h * sum(x_symbols)
        symmap = {z: (i, matrices.Z) for i, z in enumerate(z_symbols)}
        symmap.update({x: (i, matrices.X) for i, x in enumerate(x_symbols)})
        ham = hamiltonians.Hamiltonian.from_symbolic(-symham, symmap)

    if calcterms:
        _ = ham.terms
    final_matrix = ham.matrix
    target_matrix = hamiltonians.TFIM(nqubits, h=h).matrix
    K.assert_allclose(final_matrix, target_matrix)
Beispiel #19
0
def test_adiabatic_evolution_errors():
    """Test errors of ``AdiabaticEvolution`` model."""
    # Hamiltonians of bad type
    h0 = hamiltonians.X(3)
    s = lambda t: t
    with pytest.raises(TypeError):
        adev = models.AdiabaticEvolution(h0, lambda t: h0, s, dt=1e-2)
    h1 = hamiltonians.TFIM(2)
    with pytest.raises(TypeError):
        adev = models.AdiabaticEvolution(lambda t: h1, h1, s, dt=1e-2)
    # Hamiltonians with different number of qubits
    with pytest.raises(ValueError):
        adev = models.AdiabaticEvolution(h0, h1, s, dt=1e-2)
    # s with three arguments
    h0 = hamiltonians.X(2)
    s = lambda t, a, b: t + a + b
    with pytest.raises(ValueError):
        adev = models.AdiabaticEvolution(h0, h1, s, dt=1e-2)
    # s(0) != 0
    with pytest.raises(ValueError):
        adev = models.AdiabaticEvolution(h0, h1, lambda t: t + 1, dt=1e-2)
    # s(T) != 0
    with pytest.raises(ValueError):
        adev = models.AdiabaticEvolution(h0, h1, lambda t: t / 2, dt=1e-2)
    # Non-zero ``start_time``
    adev = models.AdiabaticEvolution(h0, h1, lambda t: t, dt=1e-2)
    with pytest.raises(NotImplementedError):
        final_state = adev(final_time=2, start_time=1)
    # execute without specifying variational parameters
    sp = lambda t, p: (1 - p) * np.sqrt(t) + p * t
    adevp = models.AdiabaticEvolution(h0, h1, sp, dt=1e-1)
    with pytest.raises(ValueError):
        final_state = adevp(final_time=1)
Beispiel #20
0
def test_energy_callback(solver, dt, atol):
    """Test using energy callback in adiabatic evolution."""
    h0 = hamiltonians.X(2)
    h1 = hamiltonians.TFIM(2)
    energy = callbacks.Energy(h1)
    adev = models.AdiabaticEvolution(h0,
                                     h1,
                                     lambda t: t,
                                     dt=dt,
                                     callbacks=[energy],
                                     solver=solver)
    final_psi = adev(final_time=1)

    target_psi = np.ones(4) / 2
    calc_energy = lambda psi: psi.conj().dot(K.to_numpy(h1.matrix).dot(psi))
    target_energies = [calc_energy(target_psi)]
    ham = lambda t: h0 * (1 - t) + h1 * t
    for n in range(int(1 / dt)):
        prop = K.to_numpy(ham(n * dt).exp(dt))
        target_psi = prop.dot(target_psi)
        target_energies.append(calc_energy(target_psi))

    assert_states_equal(final_psi, target_psi, atol=atol)
    target_energies = K.cast(target_energies)
    K.assert_allclose(energy[:], target_energies, atol=atol)
Beispiel #21
0
def test_adiabatic_evolution_hamiltonian(backend, dense):
    """Test adiabatic evolution hamiltonian as a function of time."""
    h0 = hamiltonians.X(2, dense=dense)
    h1 = hamiltonians.TFIM(2, dense=dense)
    adev = models.AdiabaticEvolution(h0, h1, lambda t: t, dt=1e-2)
    # try accessing hamiltonian before setting it
    with pytest.raises(RuntimeError):
        adev.hamiltonian(0.1)

    m1 = np.array([[0, 1, 1, 0], [1, 0, 0, 1], [1, 0, 0, 1], [0, 1, 1, 0]])
    m2 = np.diag([2, -2, -2, 2])
    ham = lambda t, T: -(1 - t / T) * m1 - (t / T) * m2

    adev.hamiltonian.total_time = 1
    for t in [0, 0.3, 0.7, 1.0]:
        if dense:
            matrix = adev.hamiltonian(t).matrix
        else:
            matrix = adev.hamiltonian(t).dense.matrix
        K.assert_allclose(matrix, ham(t, 1))

    #try using a different total time
    adev.hamiltonian.total_time = 2
    for t in [0, 0.3, 0.7, 1.0]:
        if dense:
            matrix = adev.hamiltonian(t).matrix
        else:
            matrix = adev.hamiltonian(t).dense.matrix
        K.assert_allclose(matrix, ham(t, 2))
Beispiel #22
0
def test_initial_state():
    """Test that adiabatic evolution initial state is the ground state of H0."""
    h0 = hamiltonians.X(3)
    h1 = hamiltonians.TFIM(3)
    adev = models.AdiabaticEvolution(h0, h1, lambda t: t, dt=1e-2)
    target_psi = np.ones(8) / np.sqrt(8)
    init_psi = adev.get_initial_state()
    assert_states_equal(init_psi, target_psi)
Beispiel #23
0
def test_symbolic_hamiltonian_hamiltonianmatmul(backend, nqubits, calcterms,
                                                calcdense):
    local_ham1 = hamiltonians.SymbolicHamiltonian(symbolic_tfim(nqubits,
                                                                h=1.0))
    local_ham2 = hamiltonians.SymbolicHamiltonian(symbolic_tfim(nqubits,
                                                                h=0.5))
    dense_ham1 = hamiltonians.TFIM(nqubits, h=1.0)
    dense_ham2 = hamiltonians.TFIM(nqubits, h=0.5)
    if calcterms:
        _ = local_ham1.terms
        _ = local_ham2.terms
    if calcdense:
        _ = local_ham1.dense
        _ = local_ham2.dense
    local_matmul = local_ham1 @ local_ham2
    target_matmul = dense_ham1 @ dense_ham2
    K.assert_allclose(local_matmul.matrix, target_matmul.matrix)
Beispiel #24
0
def main(nqubits, hfield, T, dt, solver, save):
    """Performs adiabatic evolution with critical TFIM as the "hard" Hamiltonian.

    Plots how the <H1> energy and the overlap with the actual ground state
    changes during the evolution.
    Linear scheduling is used.

    Args:
        nqubits (int): Number of qubits in the system.
        hfield (float): Transverse field Ising model h-field h value.
        T (float): Total time of the adiabatic evolution.
        dt (float): Time step used for integration.
        solver (str): Solver used for integration.
        save (bool): Whether to save the plots.
    """
    h0 = hamiltonians.X(nqubits)
    h1 = hamiltonians.TFIM(nqubits, h=hfield)

    # Calculate target values (H1 ground state)
    target_state = h1.ground_state()
    target_energy = h1.eigenvalues()[0].numpy().real

    # Check ground state
    state_energy = callbacks.Energy(h1)(target_state).numpy()
    np.testing.assert_allclose(state_energy.real, target_energy)

    energy = callbacks.Energy(h1)
    overlap = callbacks.Overlap(target_state)
    evolution = models.AdiabaticEvolution(h0,
                                          h1,
                                          lambda t: t,
                                          dt=dt,
                                          solver=solver,
                                          callbacks=[energy, overlap])
    final_psi = evolution(final_time=T)

    # Plots
    tt = np.linspace(0, T, int(T / dt) + 1)
    plt.figure(figsize=(12, 4))
    plt.subplot(121)
    plt.plot(tt, energy[:], linewidth=2.0, label="Evolved state")
    plt.axhline(y=target_energy,
                color="red",
                linewidth=2.0,
                label="Ground state")
    plt.xlabel("$t$")
    plt.ylabel("$H_1$")
    plt.legend()

    plt.subplot(122)
    plt.plot(tt, overlap[:], linewidth=2.0)
    plt.xlabel("$t$")
    plt.ylabel("Overlap")

    if save:
        plt.savefig(f"images/dynamics_n{nqubits}T{T}.png", bbox_inches="tight")
    else:
        plt.show()
Beispiel #25
0
def main(nqubits, layers, compress, lambdas):
    def cost_function(params, count):
        """Evaluates the cost function to be minimized.

        Args:
            params (array or list): values of the parameters.

        Returns:
            Value of the cost function.
        """
        circuit = models.Circuit(nqubits)
        for l in range(layers):
            for q in range(nqubits):
                circuit.add(gates.RY(q, theta=0))
            for q in range(0, nqubits - 1, 2):
                circuit.add(gates.CZ(q, q + 1))
            for q in range(nqubits):
                circuit.add(gates.RY(q, theta=0))
            for q in range(1, nqubits - 2, 2):
                circuit.add(gates.CZ(q, q + 1))
            circuit.add(gates.CZ(0, nqubits - 1))
        for q in range(nqubits):
            circuit.add(gates.RY(q, theta=0))

        cost = 0
        circuit.set_parameters(
            params)  # this will change all thetas to the appropriate values
        for i in range(len(ising_groundstates)):
            final_state = circuit(np.copy(ising_groundstates[i]))
            cost += encoder.expectation(final_state).numpy().real

        if count[0] % 50 == 0:
            print(count[0], cost / len(ising_groundstates))
        count[0] += 1

        return cost / len(ising_groundstates)

    nparams = 2 * nqubits * layers + nqubits
    initial_params = np.random.uniform(0, 2 * np.pi, nparams)
    encoder = 0.5 * (compress + hamiltonians.Z(nqubits))

    ising_groundstates = []
    for lamb in lambdas:
        ising_ham = -1 * hamiltonians.TFIM(nqubits, h=lamb)
        ising_groundstates.append(ising_ham.eigenvectors()[0])

    count = [0]
    result = minimize(lambda p: cost_function(p, count),
                      initial_params,
                      method='L-BFGS-B',
                      options={
                          'maxiter': 2.0e3,
                          'maxfun': 2.0e3
                      })

    print('Final parameters: ', result.x)
    print('Final cost function: ', result.fun)
Beispiel #26
0
def test_initial_state(backend, accelerators):
    original_backend = qibo.get_backend()
    qibo.set_backend(backend)
    h = hamiltonians.TFIM(5, h=1.0, trotter=True)
    qaoa = models.QAOA(h, accelerators=accelerators)
    qaoa.set_parameters(np.random.random(4))
    target_state = np.ones(2**5) / np.sqrt(2**5)
    final_state = qaoa.get_initial_state()
    np.testing.assert_allclose(final_state, target_state)
    qibo.set_backend(original_backend)
Beispiel #27
0
def test_trotterized_evolution(nqubits, accelerators, dt, h=1.0):
    """Test state evolution using trotterization of ``TrotterHamiltonian``."""
    target_psi = [np.ones(2**nqubits) / np.sqrt(2**nqubits)]
    ham_matrix = np.array(hamiltonians.TFIM(nqubits, h=h).matrix)
    prop = expm(-1j * dt * ham_matrix)
    for n in range(int(1 / dt)):
        target_psi.append(prop.dot(target_psi[-1]))

    ham = hamiltonians.TFIM(nqubits, h=h, trotter=True)
    checker = TimeStepChecker(target_psi, atol=1e-4)
    evolution = models.StateEvolution(ham,
                                      dt,
                                      callbacks=[checker],
                                      accelerators=accelerators)
    final_psi = evolution(final_time=1, initial_state=np.copy(target_psi[0]))

    # Change dt
    evolution = models.StateEvolution(ham, dt / 10, accelerators=accelerators)
    final_psi = evolution(final_time=1, initial_state=np.copy(target_psi[0]))
    assert_states_equal(final_psi, target_psi[-1], atol=1e-4)
Beispiel #28
0
def test_symbolic_hamiltonian_scalar_sub(backend, nqubits, calcterms,
                                         calcdense):
    """Test subtraction of Trotter Hamiltonian with scalar."""
    local_ham = hamiltonians.SymbolicHamiltonian(symbolic_tfim(nqubits, h=1.0))
    target_ham = 2 - hamiltonians.TFIM(nqubits, h=1.0)
    if calcterms:
        _ = local_ham.terms
    if calcdense:
        _ = local_ham.dense
    local_dense = (2 - local_ham).dense
    K.assert_allclose(local_dense.matrix, target_ham.matrix)

    target_ham = hamiltonians.TFIM(nqubits, h=1.0) - 2
    local_ham = hamiltonians.SymbolicHamiltonian(symbolic_tfim(nqubits, h=1.0))
    if calcterms:
        _ = local_ham.terms
    if calcdense:
        _ = local_ham.dense
    local_dense = (local_ham - 2).dense
    K.assert_allclose(local_dense.matrix, target_ham.matrix)
Beispiel #29
0
def test_trotter_hamiltonian_matmul(nqubits, normalize):
    """Test Trotter Hamiltonian expectation value."""
    local_ham = hamiltonians.TFIM(nqubits, h=1.0, dense=False)
    dense_ham = hamiltonians.TFIM(nqubits, h=1.0)

    state = K.cast(random_complex((2 ** nqubits,)))
    trotter_ev = local_ham.expectation(state, normalize)
    target_ev = dense_ham.expectation(state, normalize)
    K.assert_allclose(trotter_ev, target_ev)

    state = random_complex((2 ** nqubits,))
    trotter_ev = local_ham.expectation(state, normalize)
    target_ev = dense_ham.expectation(state, normalize)
    K.assert_allclose(trotter_ev, target_ev)

    from qibo.core.states import VectorState
    state = VectorState.from_tensor(state)
    trotter_matmul = local_ham @ state
    target_matmul = dense_ham @ state
    K.assert_allclose(trotter_matmul, target_matmul)
Beispiel #30
0
def test_scheduling_optimization(method, options, messages, trotter, filename):
    """Test optimization of s(t)."""
    h0 = hamiltonians.X(3, trotter=trotter)
    h1 = hamiltonians.TFIM(3, trotter=trotter)
    sp = lambda t, p: (1 - p) * np.sqrt(t) + p * t
    adevp = models.AdiabaticEvolution(h0, h1, sp, dt=1e-1)
    best, params = adevp.minimize([0.5, 1],
                                  method=method,
                                  options=options,
                                  messages=messages)
    if filename is not None:
        utils.assert_regression_fixture(params, filename)