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)
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"])
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)
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)
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)
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)
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)
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()
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)
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
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)
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)
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)
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)
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)
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)
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))
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)
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)
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()
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)
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)
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)
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)
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)
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)