def test_get_qubit_wise(): ''' Testing whether the get_qubit_wise methods correctly gives the all-Z form of the hamiltonian ''' H, _, _, _ = prepare_test_hamiltonian() H = BinaryHamiltonian.init_from_qubit_hamiltonian(H) qwc, qwc_U = H.get_qubit_wise() # Check qwc has all z for term, val in qwc.items(): for qub in term: assert qub[1] == 'Z' # Checking the expectation values are the same U = tq.gates.ExpPauli(angle="a", paulistring=tq.PauliString.from_string('X(0)Y(1)')) variables = {"a": np.random.rand(1) * 2 * np.pi} e_ori = tq.ExpectationValue(H=H.to_qubit_hamiltonian(), U=U) e_qwc = tq.ExpectationValue(H=qwc, U=U + qwc_U) e_integrated = tq.ExpectationValue(H=H.to_qubit_hamiltonian(), U=U, optimize_measurements=True) result_ori = tq.simulate(e_ori, variables) result_qwc = tq.simulate(e_qwc, variables) result_integrated = tq.simulate(e_qwc, variables) assert np.isclose(result_ori, result_qwc) assert np.isclose(result_ori, result_integrated) # Checking the optimized expectation values are the same initial_values = {k: np.random.uniform(0.0, 6.0, 1) for k in e_ori.extract_variables()} sol1 = tq.minimize(method='bfgs', objective=e_ori, initial_values=initial_values) sol2 = tq.minimize(method='bfgs', objective=e_qwc, initial_values=initial_values) sol3 = tq.minimize(method='bfgs', objective=e_integrated, initial_values=initial_values) assert np.isclose(sol1.energy, sol2.energy) assert np.isclose(sol1.energy, sol3.energy)
def run_ising_circuits(n_qubits, g=1.0, *args, **kwargs): H = simplified_ising(n_qubits=n_qubits, g=g) if n_qubits < 10: exact_gs = numpy.linalg.eigvalsh(H.to_matrix())[0] else: exact_gs = None # orquestra workaround if "generators" in kwargs: kwargs["generators"] = json.loads(kwargs["generators"]) if "fix_angles" in kwargs: kwargs["fix_angles"] = yaml.load(kwargs["fix_angles"], Loader=yaml.SafeLoader) if "connectivity" in kwargs: kwargs["connectivity"] = yaml.load(kwargs["connectivity"], Loader=yaml.SafeLoader) # initial mean-field like state n_qubits = H.n_qubits UMF = sum([tq.gates.Ry(angle=("a", q), target=q) for q in range(n_qubits)],tq.QCircuit()) # encoder to save circuits as string encoder = CircuitGenEncoder() # solve "mean field" EMF = tq.ExpectationValue(H=H, U=UMF) result = tq.minimize(EMF) result_dict = {"schema":"schema"} result_dict["data"] = test_circuits(H=H, UMF=UMF, mf_variables=result.variables, *args, **kwargs) result_dict["kwargs"]=kwargs result_dict["g"]=g result_dict["exact_ground_state"]=exact_gs result_dict["mean_field_energy"]=float(result.energy) with open("isingdata.json", "w") as f: f.write(json.dumps(result_dict, indent=2))
def test_method_convergence(simulator,method): U = tq.gates.Trotterized(angles=["a"], steps=1, generators=[tq.paulis.Y(0)]) H = tq.paulis.X(0) O = tq.ExpectationValue(U=U, H=H) samples=None angles={'a':numpy.pi/3} result = tq.minimize(objective=O, method=method,initial_values=angles, samples=samples, lr=0.1,stop_count=40, maxiter=200, backend=simulator) assert (numpy.isclose(result.energy, -1.0,atol=3.e-2))
def test_hcb(trafo): geomstring = "Be 0.0 0.0 0.0\n H 0.0 0.0 1.6\n H 0.0 0.0 -1.6" mol1 = tq.Molecule(geometry=geomstring, active_orbitals=[1,2,3,4,5,6], basis_set="sto-3g", transformation="ReorderedJordanWigner") H = mol1.make_hardcore_boson_hamiltonian() U = mol1.make_upccgsd_ansatz(name="HCB-UpCCGD") E = tq.ExpectationValue(H=H, U=U) energy1 = tq.minimize(E).energy assert numpy.isclose(energy1, -15.527740838656282, atol=1.e-3) mol2 = tq.Molecule(geometry=geomstring, active_orbitals=[1,2,3,4,5,6], basis_set="sto-3g", transformation=trafo) H = mol2.make_hamiltonian() U = mol2.make_upccgsd_ansatz(name="UpCCGD", use_hcb=False) E = tq.ExpectationValue(H=H, U=U) energy2 = tq.minimize(E).energy assert numpy.isclose(energy1, energy2)
def test_circuits(H, UMF, mf_variables, n_circuits=1, n_trials=1, n_samples=1000, g=1.0, connectivity="local_line", generators=["Y", "XY", "YZ"], depth=None, fix_mean_field=True, only_samples=False, draw_from_normal_distribution=False, **kwargs): # initial mean-field like state n_qubits = H.n_qubits # encoder to save circuits as string encoder = CircuitGenEncoder() if fix_mean_field: fixed_variables = mf_variables else: fixed_variables = {} generator = CircuitGenerator(n_qubits=n_qubits, connectivity=connectivity, depth=depth, generators=generators, **kwargs) print(generator) data = [] for i in range(n_circuits): circuit = UMF + generator() E = tq.ExpectationValue(H=H, U=circuit) E = tq.compile(E, backend="qulacs") sampled_energies = [] sampled_variables = [] for sample in range(n_samples): if draw_from_normal_distribution: variables = {k:numpy.random.normal(loc=1.0, scale=1.0)*numpy.pi for k in circuit.extract_variables()} else: variables = {k:numpy.random.uniform(0.0,4.0,1)[0]*numpy.pi for k in circuit.extract_variables()} variables = {**variables, **fixed_variables} sampled_energies.append(E(variables=variables)) sampled_variables.append(variables) best_variables = sorted( [(sampled_energies[i],sampled_variables[i]) for i in range(n_samples)] , key=lambda x:x[0] ) best_variables = [best_variables[i][1] for i in range(n_trials)] starting_points = best_variables starting_points = [{k:0.0 for k in circuit.extract_variables()}] + starting_points starting_points = [{k:numpy.random.uniform(-0.1,0.1,1)[0]*numpy.pi for k in circuit.extract_variables()}] + starting_points ev_samples = [] encoded_circuit = encoder(circuit, variables=fixed_variables) if not only_samples: for j,variables in enumerate(starting_points): print("step {} from {} in circuit {} from {}\n".format(j, len(starting_points), i ,n_circuits)) variables = {**variables, **fixed_variables} active_variables = [x for x in E.extract_variables() if x not in fixed_variables.keys()] E = tq.ExpectationValue(H=H, U=circuit) result = tq.minimize(E, initial_values=variables, variables=active_variables) variables = result.variables energy = result.energy ev_samples.append({"energy":energy, "variables":{str(k):v for k,v in variables.items()} }) energy_samples={"circuit":encoded_circuit, "vqe_energies": sorted(ev_samples, key=lambda x: x["energy"]), "random_energies":sampled_energies} data.append(energy_samples) data = sorted(data, key=lambda x: x["vqe_energies"][0]["energy"]) else: zeroes={k:0.0 for k in E.extract_variables()} energy_samples={"circuit":encoded_circuit, "vqe_energies": [{"energy":tq.simulate(E, variables=zeroes), "variables":{str(k):v for k,v in zeroes.items()}}], "random_energies":sampled_energies} data.append(energy_samples) print("finished test_circuits") return data
def test_one_qubit_wfn(simulator, method): U = tq.gates.Trotterized(angles=["a"], steps=1, generators=[tq.paulis.Y(0)]) H = tq.paulis.X(0) O = tq.ExpectationValue(U=U, H=H) result = tq.minimize(objective=O, maxiter=8, backend=simulator, method=method) assert (numpy.isclose(result.energy, -1.0, atol=1.e-2))
def test_one_qubit_shot(simulator): U = tq.gates.Trotterized(angles=["a"], steps=1, generators=[tq.paulis.Y(0)]) H = tq.paulis.X(0) O = tq.ExpectationValue(U=U, H=H) result = tq.minimize(method="phoenics", objective=O, maxiter=3, backend=simulator, samples=10000) assert (numpy.isclose(result.energy, -1.0, atol=1.e-1))
def test_madness_he_data(): # relies that he_xtensor.npy are present (x=g,h) geomstring = "He 0.0 0.0 0.0" molecule = tq.Molecule(name="he", geometry=geomstring) H = molecule.make_hamiltonian() UHF = molecule.prepare_reference() EHF = tq.simulate(tq.ExpectationValue(H=H, U=UHF)) assert (numpy.isclose(-2.861522e+00, EHF, atol=1.e-5)) U = molecule.make_upccgsd_ansatz() E = tq.ExpectationValue(H=H, U=U) result = tq.minimize(method="bfgs", objective=E, initial_values=0.0, silent=True) print(result.energy) assert (numpy.isclose(-2.87761809, result.energy, atol=1.e-5))
def test_madness_full_be(): # relies on madness being compiled and MAD_ROOT_DIR exported # or pno_integrals in the path geomstring = "Be 0.0 0.0 0.0" molecule = tq.Molecule(name="be", geometry=geomstring, n_pno=3, frozen_core=True) H = molecule.make_hamiltonian() UHF = molecule.prepare_reference() EHF = tq.simulate(tq.ExpectationValue(H=H, U=UHF)) assert (numpy.isclose(-14.57269300, EHF, atol=1.e-5)) U = molecule.make_upccgsd_ansatz() E = tq.ExpectationValue(H=H, U=U) result = tq.minimize(method="bfgs", objective=E, initial_values=0.0, silent=True) assert (numpy.isclose(-14.614662051580321, result.energy, atol=1.e-3))
def test_one_qubit_wfn_really_works(simulator): U = tq.gates.Trotterized(angles=["a"], steps=1, generators=[tq.paulis.Y(0)]) H = tq.paulis.X(0) O = tq.ExpectationValue(U=U, H=H) result = tq.minimize(method="lbfgs", objective=O, maxiter=8, backend=simulator) assert (numpy.isclose(result.energy, -1.0, atol=1.e-2)) assert (numpy.isclose(result.energy, simulate(objective=O, variables=result.angles)))
def test_madness_full_he(): # relies on madness being compiled and MAD_ROOT_DIR exported # or pno_integrals in the path geomstring = "He 0.0 0.0 0.0" molecule = tq.Molecule(geometry=geomstring, n_pno=1) H = molecule.make_hamiltonian() UHF = molecule.prepare_reference() EHF = tq.simulate(tq.ExpectationValue(H=H, U=UHF)) assert (numpy.isclose(-2.861522e+00, EHF, atol=1.e-5)) U = molecule.make_upccgsd_ansatz() E = tq.ExpectationValue(H=H, U=U) result = tq.minimize(method="bfgs", objective=E, initial_values=0.0, silent=True) assert (numpy.isclose(-2.87761809, result.energy, atol=1.e-5))
def do_test_upccgsd(molecule, *args, **kwargs): U = molecule.make_upccgsd_ansatz(*args, **kwargs) H = molecule.make_hamiltonian() E = tq.ExpectationValue(U=U, H=H) result = tq.minimize(objective=E, initial_values=0.0, gradient="2-point", method="bfgs", method_options={ "finite_diff_rel_step": 1.e-4, "eps": 1.e-4 }) return result.energy
def minimize_E(objective, method, initial_values, tol, samples): sample_energies = np.zeros(samples) for t in range(samples): result = minimize(objective=objective, method=method, initial_values=initial_values, tol=tol, silent=True) E_t = result.energy sample_energies[t] = E_t return min(samples_energies)
def test_madness_full_li_plus(): # relies on madness being compiled and MAD_ROOT_DIR exported # or pno_integrals in the path geomstring = "Li 0.0 0.0 0.0" molecule = tq.Molecule(name="li+", geometry=geomstring, n_pno=1, charge=1, frozen_core=False) # need to deactivate frozen_core, otherwise there is no active orbital H = molecule.make_hamiltonian() UHF = molecule.prepare_reference() EHF = tq.simulate(tq.ExpectationValue(H=H, U=UHF)) assert (numpy.isclose(-7.236247e+00, EHF, atol=1.e-5)) U = molecule.make_upccgsd_ansatz() E = tq.ExpectationValue(H=H, U=U) result = tq.minimize(method="bfgs", objective=E, initial_values=0.0, silent=True) assert (numpy.isclose(-7.251177798, result.energy, atol=1.e-5))
def test_execution(simulator,method): U = tq.gates.Rz(angle="a", target=0) \ + tq.gates.X(target=2) \ + tq.gates.Ry(angle="b", target=1, control=2) \ + tq.gates.Trotterized(angles=["c", "d"], generators=[-0.25 * tq.paulis.Z(1), tq.paulis.X(0) + tq.paulis.Y(1)], steps=2) \ + tq.gates.Trotterized(angles=[1.0, 2.0], generators=[-0.25 * tq.paulis.Z(1), tq.paulis.X(0) + tq.paulis.Y(1)], steps=2) \ + tq.gates.ExpPauli(angle="a", paulistring="X(0)Y(1)Z(2)") H = 1.0 * tq.paulis.X(0) + 2.0 * tq.paulis.Y(1) + 3.0 * tq.paulis.Z(2) O = tq.ExpectationValue(U=U, H=H) result = tq.minimize(objective=O,method=method, maxiter=1, backend=simulator)
def test_one_qubit_shot(simulator): U = tq.gates.Trotterized(angles=["a"], steps=1, generators=[tq.paulis.Y(0)]) H = tq.paulis.X(0) O = tq.ExpectationValue(U=U, H=H) samples = 1000 result = tq.minimize(objective=O, method="cobyla", backend=simulator, samples=samples, silent=True, initial_values=-0.5) assert (numpy.isclose(result.energy, -1.0, atol=1.e-1))
def get_eigvals(mat=[]): """Get eigenvalues for Hermitianmatrix.""" herm = HermitianSolver(mat) matrix = herm.mat H = tq.paulis.Zero() rows = matrix.shape[0] columns = matrix.shape[0] n_qubits = herm.n_qubits() print("true values", np.linalg.eigh(matrix)[0]) for i in range(rows): for j in range(columns): H += matrix[i, j] * tq.paulis.KetBra( ket=i, bra=j, n_qubits=n_qubits) hermitian, anti = H.split() eigenValues, eigenVectors = numpy.linalg.eigh(hermitian.to_matrix()) # print(tq.QubitWaveFunction(eigenVectors[:, 2])) circuits = [] energies = [] factor = 22 # TODO: replace factor with reverse VQE value opt_variables = {} for i in range(rows): U = tq.gates.Ry(angle=(0, i), target=0) U += tq.gates.Ry(angle=(1, i), target=1) U += tq.gates.Ry(angle=(2, i), target=2) active_variables = U.extract_variables() E = tq.ExpectationValue(H=hermitian, U=U) ex_objective = E P1 = tq.paulis.Projector("1.0*|000>") for k in range(i): S = tq.ExpectationValue(H=P1, U=U + circuits[k].dagger()) ex_objective += factor * abs(energies[k]) * S opt_variables = { **opt_variables, **{k: 1.0e-3 for k in active_variables}, } result = tq.minimize( objective=ex_objective, method="bfgs", variables=active_variables, initial_values=opt_variables, ) circuits.append(U) energies.append(result.energy) opt_variables = {**opt_variables, **result.variables} return energies
def test_methods_qng(simulator, method): ### please note! I am finely tuned to always pass! don't get cocky and change lr, maxiter, etc. H = tq.paulis.Y(0) U = tq.gates.Ry(numpy.pi/4,0) +tq.gates.Ry(numpy.pi/3,1)+tq.gates.Ry(numpy.pi/7,2) U += tq.gates.Rz('a',0)+tq.gates.Rz('b',1) U += tq.gates.CNOT(control=0,target=1)+tq.gates.CNOT(control=1,target=2) U += tq.gates.Ry('c',1) +tq.gates.Rx('d',2) U += tq.gates.CNOT(control=0,target=1)+tq.gates.CNOT(control=1,target=2) E = tq.ExpectationValue(H=H, U=U) # just equal to the original circuit, but i'm checking that all the sub-division works O=E # need to improve starting points for some of the optimizations initial_values = {"a": 0.432, "b": -0.123, 'c':0.543,'d':0.233} result = tq.minimize(objective=-O,qng=True,backend=simulator, method=method, maxiter=200,lr=0.1,stop_count=50, initial_values=initial_values, silent=False) assert(numpy.isclose(result.energy, -0.612, atol=2.e-2))
def minimize_E_random_guesses(objective, method, tol, n): sample_energies = np.zeros(n) vars = objective.extract_variables() for t in range(n): initial_values = {v: np.random.uniform(0, 2 * np.pi) for v in vars} result = minimize(objective=objective, method=method, initial_values=initial_values, tol=tol, silent=True) E_t = result.energy sample_energies[t] = E_t return min(sample_energies)
def test_execution_shot(simulator): U = tq.gates.Rz(angle="a", target=0) \ + tq.gates.X(target=2) \ + tq.gates.Ry(angle="b", target=1, control=2) \ + tq.gates.Trotterized(angles=["c","d"], generators=[-0.25 * tq.paulis.Z(1), tq.paulis.X(0) + tq.paulis.Y(1)], steps=2) \ + tq.gates.Trotterized(angles=[1.0, 2.0], generators=[-0.25 * tq.paulis.Z(1), tq.paulis.X(0) + tq.paulis.Y(1)], steps=2) \ + tq.gates.ExpPauli(angle="a", paulistring="X(0)Y(1)Z(2)") H = 1.0 * tq.paulis.X(0) + 2.0 * tq.paulis.Y(1) + 3.0 * tq.paulis.Z(2) O = tq.ExpectationValue(U=U, H=H) mi = 2 result = tq.minimize(method="lbfgs", objective=O, maxiter=mi, backend=simulator, samples=1024) print(result.history.energies)
def run_example(): U = tq.gates.Ry(angle="a", target=0) H = tq.paulis.X(0) E = tq.ExpectationValue(U=U, H=H) result = tq.minimize(method="bfgs", objective=E, gradient="2-point") message = "Small demo calculation" message_dict = {} message_dict["message"] = message message_dict["schema"] = "message" message_dict["energy"] = result.energy message_dict["iterations"] = len(result.history.extract_energies()) message_dict["angles"] = {k.name: v for k, v in result.variables.items()} with open("result.json", 'w') as f: f.write( json.dumps(message_dict, indent=2) ) # Write message to file as this will serve as output artifact
def compute_energy(self, method, *args, **kwargs): """ Call classical methods over PySCF (needs to be installed) or use as a shortcut to calculate quantum energies (see make_upccgsd_ansatz) Parameters ---------- method: method name classical: HF, MP2, CCSD, CCSD(T), FCI quantum: SPA-GASD (SPA can be dropped as well as letters in GASD) examples: GSD is the same as UpCCGSD, SPA alone is equivalent to SPA-D see make_upccgsd_ansatz of the this class for more information args kwargs Returns ------- """ if any([x in method.upper() for x in ["U", "SPA", "PNO", "HCB"]]): # simulate entirely in HCB representation if no singles are involved if "S" not in method.upper().split("-")[-1] and "HCB" not in method.upper(): method = "HCB-"+method U = self.make_upccgsd_ansatz(name=method) if "hcb" in method.lower(): H = self.make_hardcore_boson_hamiltonian() else: H = self.make_hamiltonian() E = ExpectationValue(H=H, U=U) from tequila import minimize return minimize(objective=E, *args, **kwargs).energy else: from tequila.quantumchemistry import INSTALLED_QCHEMISTRY_BACKENDS if "pyscf" not in INSTALLED_QCHEMISTRY_BACKENDS: raise TequilaMadnessException("PySCF needs to be installed to compute {}/MRA-PNO".format(method)) else: from tequila.quantumchemistry import QuantumChemistryPySCF molx = QuantumChemistryPySCF.from_tequila(self) return molx.compute_energy(method=method)
# No encoding: total_U += tq.gates.Rx(target=q, angle=theta) + tq.gates.Rz(target=q, angle=phi) Obj += tq.ExpectationValue(H=Ham, U=total_U) # Number of optimization variables print("Meta-VQE training: ", len(Obj.extract_variables()), file=file_data_varcount) variables = Obj.extract_variables() variables = sorted(variables, key=lambda x: x.name) # Random initialization of variables th0 = {key: random.uniform(0, np.pi) for key in variables} initial_values = th0 metaVQE = tq.minimize(objective=Obj, adaptive = True, lr=lr, method_options=mthd_opt, method=methods, gradient=grad_methods, samples=None, initial_values=initial_values, backend=backend, noise=None, device=None, silent=True) file_name = os.path.join(data_dir, "metaVQE_seed_{}{}.txt".format(seeds[s], extra_mes)) file_data = open(file_name, "w") print(metaVQE, file=file_data) file_data.close() # Results training x_train = arg_train y_train_ex = [] y_train_metaVQE = [] error_train_metaVQE = [] file_name = os.path.join(data_dir, "metaVQE_train_seed_{}{}.txt".format(seeds[s], extra_mes)) file_data = open(file_name, "w") for i in range(n_train):
print("Optimimal Angles: ", variables) print("E0=", tq.simulate(E0, variables)) print("E1=", tq.simulate(E1, variables)) print("F=-E0/E1=", -F) # initialize starting conditions you want to have # this one here is not unrealistic and will lead to convergence # starting conditions are better than in the paper in order to speed up the demo here # We recommend having qulacs installed for this optimization # you can pass: backend="qulacs" to minimize in order to make sure qulacs is used # if it is installed tequila should pick it automatically # see the tequila tutorials for more values = {'t': 0.5, 'angle0': 0.5, 'angle1': -0.5} result = tq.minimize(tol=1.e-3, initial_values=values, objective=O, method="BFGS", silent=False) # lets keep the history with open("optimize.pickle", "wb") as f: pickle.dump(result.history, f, pickle.HIGHEST_PROTOCOL) # some illustration how to get data from the tequila history object print("energies\n", result.history.extract_energies()) print("angle0\n", result.history.extract_angles(angle0)) print("angle1\n", result.history.extract_angles(angle1)) print("t\n", result.history.extract_angles(param_dove)) print("grad_0\n", result.history.extract_gradients(angle0)) print("grad_1\n", result.history.extract_gradients(angle1)) print("grad_t\n", result.history.extract_gradients(param_dove))
def test_madness_upccgsd(trafo): n_pno = 2 if os.path.isfile('balanced_be_gtensor.npy'): n_pno = None mol = tq.Molecule(name="balanced_be", frozen_core=False, geometry="Be 0.0 0.0 0.0", n_pno=n_pno, pno={"diagonal": True, "maxrank": 1}, transformation=trafo) H = mol.make_hardcore_boson_hamiltonian() oigawert=numpy.linalg.eigvalsh(H.to_matrix())[0] U = mol.make_upccgsd_ansatz(name="HCB-UpCCGD", direct_compiling=True) E = tq.ExpectationValue(H=H, U=U) assert (len(E.extract_variables()) == 6) result = tq.minimize(E) assert numpy.isclose(result.energy, oigawert, atol=1.e-3) U = mol.make_upccgsd_ansatz(name="HCB-PNO-UpCCD") E = tq.ExpectationValue(H=H, U=U) assert (len(E.extract_variables()) == 2) result = tq.minimize(E) assert numpy.isclose(result.energy, oigawert, atol=1.e-3) H = mol.make_hamiltonian() oigawert2=numpy.linalg.eigvalsh(H.to_matrix())[0] U = mol.make_upccgsd_ansatz(name="SPA-D") E = tq.ExpectationValue(H=H, U=U) assert (len(E.extract_variables()) == 2) variables = result.variables if "bravyi" in trafo.lower(): # signs of angles change in BK compared to JW-like HCB variables = {k: -v for k, v in variables.items()} energy = tq.simulate(E, variables) result = tq.minimize(E) assert numpy.isclose(result.energy, oigawert, atol=1.e-3) assert numpy.isclose(energy, oigawert, atol=1.e-3) e3 = mol.compute_energy(method="SPA") assert numpy.isclose(result.energy, e3) e3 = mol.compute_energy(method="HCB-SPA") assert numpy.isclose(result.energy, e3) e3 = mol.compute_energy(method="SPA-UpCCD") assert numpy.isclose(result.energy, e3) U = mol.make_upccgsd_ansatz(name="SPA-UpCCSD") E = tq.ExpectationValue(H=H, U=U) assert (len(E.extract_variables()) == 4) result = tq.minimize(E) assert numpy.isclose(result.energy, -14.60266198, atol=1.e-3) U = mol.make_upccgsd_ansatz(name="SPA-UpCCGSD") # in this case no difference to SPA-UpCCSD E = tq.ExpectationValue(H=H, U=U) assert (len(E.extract_variables()) == 4) result = tq.minimize(E) assert numpy.isclose(result.energy, -14.60266198, atol=1.e-3) U = mol.make_upccgsd_ansatz(name="UpCCSD") E = tq.ExpectationValue(H=H, U=U) print(U) assert (len(E.extract_variables()) == 8) result = tq.minimize(E) assert numpy.isclose(result.energy, oigawert, atol=1.e-3) U = mol.make_upccgsd_ansatz(name="UpCCGSD") E = tq.ExpectationValue(H=H, U=U) assert (len(E.extract_variables()) == 12) result = tq.minimize(E) assert numpy.isclose(result.energy, oigawert, atol=1.e-3) U = mol.make_upccgsd_ansatz(name="UpCCGSD", direct_compiling=False) E = tq.ExpectationValue(H=H, U=U) assert (len(E.extract_variables()) == 12) result = tq.minimize(E) assert numpy.isclose(result.energy, oigawert, atol=1.e-3)
C = E2 print("Some Testing:\n") print("Parameter region where all parameters are the same value") print("{:15} | {:25} | {:15} | {:25}".format("Parameter" ,"Normalized Fidelity", "Count Rate","Fidelity without PS")) for x in [i/steps*2.0*numpy.pi for i in range(steps)]: variables={k:x for k in E1.extract_variables()} print("{:15} | {:25} | {:15} | {:25}".format(x, tq.simulate(F, variables=variables),tq.simulate(C, variables=variables), tq.simulate(Ex, variables=variables))) # if the parameters vary the non-normalized fidelity is not the same as the count rate # meaning now we have also valid states (one photon each path) that are not basis states of the state we are looking for print("Some Testing:\n") print("random parameters") print("Parameter | Normalized Fidelity | Count Rate | Fidelity without PS\n") for x in [i/steps*2.0*numpy.pi for i in range(steps)]: variables={k:numpy.random.uniform(0.0, 2.0*numpy.pi,1)[0] for k in E1.extract_variables()} print(x, " ", tq.simulate(F, variables=variables), " ", tq.simulate(C, variables=variables), tq.simulate(Ex, variables=variables)) # This is the actual optimization print("lets optimize") initial_values={k:0.4*numpy.pi for k in E1.extract_variables()} result = tq.minimize(objective=1-F + (1-C), method="bfgs", initial_values=initial_values) variables=result.angles print("Optimization Result") print("non-normalized Fidelity: ", tq.simulate(E1, variables=variables)) print("count rate : ", tq.simulate(E2, variables=variables)) print("normalized Fidelity : ", tq.simulate(E1/E2, variables=variables))
def __call__(self, static_variables = None, mp_pool=None, label=None, variables=None, *args, **kwargs): print("Starting Adaptive Solver") print(self) # count resources screening_cycles = 0 objective_expval_evaluations = 0 gradient_expval_evaluations = 0 histories = [] if static_variables is None: static_variables = {} if variables is None: variables = {**static_variables} else: variables = {**variables, **static_variables} U = QCircuit() initial_objective = self.make_objective(U, variables = variables) for k in initial_objective.extract_variables(): if k not in variables: warnings.warn("variable {} of initial objective not given, setting to 0.0 and activate optimization".format(k), TequilaWarning) variables[k] = 0.0 energy = simulate(initial_objective, variables=variables) for iter in range(self.parameters.maxiter): current_label = (iter,0) if label is not None: current_label = (iter, label) gradients = self.screen_gradients(U=U, variables=variables, mp_pool=mp_pool) grad_values = numpy.asarray(list(gradients.values())) max_grad = max(grad_values) grad_norm = numpy.linalg.norm(grad_values) if grad_norm < self.parameters.gradient_convergence: print("pool gradient norm is {:+2.8f}, convergence criterion met".format(grad_norm)) break if numpy.abs(max_grad) < self.parameters.max_gradient_convergence: print("max pool gradient is {:+2.8f}, convergence criterion |max(grad)|<{} met".format(max_grad, self.parameters.max_gradient_convergence)) break batch_size = self.parameters.batch_size # detect degeneracies degeneracies = [k for k in range(batch_size, len(grad_values)) if numpy.isclose(grad_values[batch_size-1],grad_values[k], rtol=self.parameters.degeneracy_threshold) ] if len(degeneracies) > 0: batch_size += len(degeneracies) print("detected degeneracies: increasing batch size temporarily from {} to {}".format(self.parameters.batch_size, batch_size)) count = 0 for k,v in gradients.items(): Ux = self.operator_pool.make_unitary(k, label=current_label) U += Ux count += 1 if count >= batch_size: break variables = {**variables, **{k:0.0 for k in U.extract_variables() if k not in variables}} active_variables = [k for k in variables if k not in static_variables] objective = self.make_objective(U, variables=variables) result = minimize(objective=objective, variables=active_variables, initial_values=variables, **self.parameters.compile_args, **self.parameters.optimizer_args) diff = energy - result.energy energy = result.energy variables = result.variables print("-------------------------------------") print("Finished iteration {}".format(iter)) print("current energy : {:+2.8f}".format(energy)) print("difference : {:+2.8f}".format(diff)) print("grad_norm : {:+2.8f}".format(grad_norm)) print("max_grad : {:+2.8f}".format(max_grad)) print("circuit size : {}".format(len(U.gates))) screening_cycles += 1 mini_iter=len(result.history.extract_energies()) gradient_expval = sum([v.count_expectationvalues() for k, v in grad(objective).items()]) objective_expval_evaluations += mini_iter*objective.count_expectationvalues() gradient_expval_evaluations += mini_iter*gradient_expval histories.append(result.history) if self.parameters.energy_convergence is not None and numpy.abs(diff) < self.parameters.energy_convergence: print("energy difference is {:+2.8f}, convergence criterion met".format(diff)) break if iter == self.parameters.maxiter - 1: print("reached maximum number of iterations") break @dataclasses.dataclass class AdaptReturn: U:QCircuit=None objective_factory:ObjectiveFactoryBase=None variables:dict=None energy: float = None histories: list = None screening_cycles: int = None objective_expval_evaluations: int =None gradient_expval_evaluations: int =None return AdaptReturn(U=U, variables=variables, objective_factory=self.objective_factory, energy=energy, histories=histories, screening_cycles = screening_cycles, objective_expval_evaluations=objective_expval_evaluations, gradient_expval_evaluations=gradient_expval_evaluations)