def main(nqubits, nlayers, varlayer=False, method="Powell", maxiter=None): """Performs a VQE circuit minimization test.""" print("Number of qubits:", nqubits) print("Number of layers:", nlayers) start_time = time.time() if varlayer: circuit = varlayer_circuit(nqubits, nlayers) else: circuit = standard_circuit(nqubits, nlayers) hamiltonian = hamiltonians.XXZ(nqubits=nqubits) vqe = models.VQE(circuit, hamiltonian) creation_time = time.time() - start_time target = np.real(np.min(hamiltonian.eigenvalues().numpy())) print("\nTarget state =", target) np.random.seed(0) nparams = 2 * nqubits * nlayers + nqubits initial_parameters = np.random.uniform(0, 2 * np.pi, nparams) start_time = time.time() options = {'disp': True, 'maxiter': maxiter} best, params, _ = vqe.minimize(initial_parameters, method=method, options=options, compile=False) minimization_time = time.time() - start_time epsilon = np.log10(1/np.abs(best-target)) print("Found state =", best) print("Final eps =", epsilon) print("\nCreation time =", creation_time) print("Minimization time =", minimization_time) print("Total time =", minimization_time + creation_time)
def test_vqe_custom_gates_errors(): """Check that ``RuntimeError``s is raised when using custom gates.""" if "qibotf" not in qibo.K.available_backends: # pragma: no cover pytest.skip("Custom backend not available.") original_backend = qibo.get_backend() qibo.set_backend("qibotf") nqubits = 6 circuit = models.Circuit(nqubits) 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)) hamiltonian = hamiltonians.XXZ(nqubits=nqubits) initial_parameters = np.random.uniform(0, 2 * np.pi, 2 * nqubits + nqubits) v = models.VQE(circuit, hamiltonian) # compile with custom gates with pytest.raises(RuntimeError): best, params, _ = v.minimize(initial_parameters, method="BFGS", options={'maxiter': 1}, compile=True) # use SGD with custom gates with pytest.raises(RuntimeError): best, params, _ = v.minimize(initial_parameters, method="sgd", compile=False) qibo.set_backend(original_backend)
def minimize(self, params, method="BFGS", jac=None, hess=None, hessp=None, bounds=None, constraints=(), tol=None, options=None, compile=False, processes=None): """ Performs minimization to find the ground state of the problem Hamiltonian. Args: params (np.ndarray or list): initial guess for the parameters of the variational circuit. method (str): optimizer to employ. jac (dict): Method for computing the gradient vector for scipy optimizers. hess (dict): Method for computing the hessian matrix for scipy optimizers. hessp (callable): Hessian of objective function times an arbitrary vector for scipy optimizers. bounds (sequence or Bounds): Bounds on variables for scipy optimizers. constraints (dict): Constraints definition for scipy optimizers. tol (float): Tolerance of termination for scipy optimizers. options (dict): a dictionary with options for the different optimizers. compile (bool): whether the TensorFlow graph should be compiled. processes (int): number of processes when using the parallel BFGS method. """ from qibo import models t = 0. while (t-self._t_max)<=self.ATOL_TIME: H = self.hamiltonian(t) vqe = models.VQE(self._circuit, H) best, params, _ = vqe.minimize(params, method=method, jac=jac, hess=hess, hessp=hessp, bounds=bounds, constraints=constraints, tol=tol, options=options, compile=compile, processes=processes) t += self._dt return best, params
def main(nqubits, nlayers, backend, varlayer=False, method="Powell", maxiter=None, filename=None): """Performs a VQE circuit minimization test.""" qibo.set_backend(backend) logs = BenchmarkLogger(filename) logs.append({ "nqubits": nqubits, "nlayers": nlayers, "varlayer": varlayer, "backend": qibo.get_backend(), "precision": qibo.get_precision(), "device": qibo.get_device(), "threads": qibo.get_threads(), "method": method, "maxiter": maxiter }) print("Number of qubits:", nqubits) print("Number of layers:", nlayers) print("Backend:", logs[-1]["backend"]) start_time = time.time() if varlayer: circuit = varlayer_circuit(nqubits, nlayers) else: circuit = standard_circuit(nqubits, nlayers) hamiltonian = hamiltonians.XXZ(nqubits=nqubits) vqe = models.VQE(circuit, hamiltonian) logs[-1]["creation_time"] = time.time() - start_time target = np.real(np.min(K.to_numpy(hamiltonian.eigenvalues()))) print("\nTarget state =", target) np.random.seed(0) nparams = 2 * nqubits * nlayers + nqubits initial_parameters = np.random.uniform(0, 2 * np.pi, nparams) start_time = time.time() options = {'disp': False, 'maxiter': maxiter} best, params, _ = vqe.minimize(initial_parameters, method=method, options=options, compile=False) logs[-1]["minimization_time"] = time.time() - start_time epsilon = np.log10(1 / np.abs(best - target)) print("Found state =", best) print("Final eps =", epsilon) logs[-1]["best_energy"] = float(best) logs[-1]["epsilon_energy"] = float(epsilon) print("\nCreation time =", logs[-1]["creation_time"]) print("Minimization time =", logs[-1]["minimization_time"]) print("Total time =", logs[-1]["minimization_time"] + logs[-1]["creation_time"]) logs.dump()
def test_vqe(backend, method, options, compile, filename): """Performs a VQE circuit minimization test.""" original_backend = qibo.get_backend() original_threads = qibo.get_threads() if (method == "sgd" or compile) and backend != "matmuleinsum": pytest.skip("Skipping SGD test for unsupported backend.") qibo.set_backend(backend) if method == 'parallel_L-BFGS-B': device = qibo.get_device() if device is not None and "GPU" in device: # pragma: no cover pytest.skip("unsupported configuration") import os if os.name == 'nt': # pragma: no cover pytest.skip("Parallel L-BFGS-B not supported on Windows.") qibo.set_threads(1) nqubits = 6 layers = 4 circuit = models.Circuit(nqubits) for l in range(layers): for q in range(nqubits): circuit.add(gates.RY(q, theta=1.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=1.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=1.0)) hamiltonian = hamiltonians.XXZ(nqubits=nqubits) np.random.seed(0) initial_parameters = np.random.uniform(0, 2 * np.pi, 2 * nqubits * layers + nqubits) v = models.VQE(circuit, hamiltonian) best, params, _ = v.minimize(initial_parameters, method=method, options=options, compile=compile) if method == "cma": # remove `outcmaes` folder import shutil shutil.rmtree("outcmaes") if filename is not None: assert_regression_fixture(params, filename) qibo.set_backend(original_backend) qibo.set_threads(original_threads)
def test_vqe(backend, method, options, compile, filename, skip_parallel): """Performs a VQE circuit minimization test.""" original_threads = qibo.get_threads() if (method == "sgd" or compile) and qibo.get_backend() != "tensorflow": pytest.skip("Skipping SGD test for unsupported backend.") if method == 'parallel_L-BFGS-B': # pragma: no cover if skip_parallel: pytest.skip("Skipping parallel test.") from qibo.tests.test_parallel import is_parallel_supported backend_name = qibo.get_backend() if not is_parallel_supported(backend_name): pytest.skip( "Skipping parallel test due to unsupported configuration.") qibo.set_threads(1) nqubits = 6 layers = 4 circuit = models.Circuit(nqubits) for l in range(layers): for q in range(nqubits): circuit.add(gates.RY(q, theta=1.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=1.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=1.0)) hamiltonian = hamiltonians.XXZ(nqubits=nqubits) np.random.seed(0) initial_parameters = np.random.uniform(0, 2 * np.pi, 2 * nqubits * layers + nqubits) v = models.VQE(circuit, hamiltonian) best, params, _ = v.minimize(initial_parameters, method=method, options=options, compile=compile) if method == "cma": # remove `outcmaes` folder import shutil shutil.rmtree("outcmaes") if filename is not None: assert_regression_fixture(params, filename) qibo.set_threads(original_threads)
def AAVQE(nqubits, layers, maxsteps, T_max, initial_parameters, easy_hamiltonian, problem_hamiltonian): """Implements the Adiabatically Assisted Variational Quantum Eigensolver (AAVQE). Args: nqubits (int): number of quantum bits. layers (int): number of ansatz layers. maxsteps (int): number of maximum iterations on each adiabatic step. T_max (int): number of maximum adiabatic steps. initial_parameters (array or list): values of the initial parameters. easy_hamiltonian (qibo.hamiltonians.Hamiltonian): initial Hamiltonian object. problem_hamiltonian (qibo.hamiltonians.Hamiltonian): problem Hamiltonian object. Returns: Groundstate energy of the problem Hamiltonian and best set of parameters. """ # Create variational circuit pairs = list((i, i + 1) for i in range(0, nqubits - 1, 2)) circuit = models.Circuit(nqubits) for l in range(layers): circuit.add( gates.VariationalLayer(range(nqubits), pairs, gates.RY, gates.CZ, np.zeros(nqubits), np.zeros(nqubits))) circuit.add((gates.CZ(i, i + 1) for i in range(1, nqubits - 2, 2))) circuit.add(gates.CZ(0, nqubits - 1)) circuit.add((gates.RY(i, theta=0) for i in range(nqubits))) for t in range(T_max + 1): s = t / T_max print('s =', s) hamiltonian = (1 - s) * easy_hamiltonian + s * problem_hamiltonian vqe = models.VQE(circuit, hamiltonian) energy, params = vqe.minimize(initial_parameters, method='Nelder-Mead', options={'maxfev': maxsteps}, compile=False) initial_parameters = params return energy, params