def test_rz_phase_flip_1(simulator, p, angle): U = gates.X(target=0) + gates.H(1) + gates.CRz( control=0, target=1, angle=Variable('a')) + gates.H(1) H = paulis.Z(1) * paulis.I(0) O = ExpectationValue(U, H) NM = PhaseFlip(p, 2) E = simulate(O, backend=simulator, variables={'a': angle}, samples=1, noise=NM) print(E)
def test_sampling(backend): U = tq.gates.Ry(angle=0.0, target=0) H = tq.paulis.X(0) E = tq.ExpectationValue(H=H, U=U) for i in range(10): e = tq.simulate(E, samples=1000, backend=backend) assert numpy.isclose(e, 0.0, atol=2.e-1) E = tq.compile(E, backend=backend, samples=1000) for i in range(10): e = E(samples=1000) assert numpy.isclose(e, 0.0, atol=2.e-1)
def test_rx_bit_flip_0(simulator, p, angle): U = gates.Rx(target=0, angle=Variable('a')) H = paulis.Z(0) NM = BitFlip(p, 1) O = ExpectationValue(U=U, H=H) E = simulate(O, backend=simulator, samples=1, variables={'a': angle}, noise=NM)
def test_depolarizing_error(simulator, p, controlled): cq = 1 qubit = 0 H = paulis.Z(0) if controlled: U = gates.X(target=cq) + gates.X(target=qubit, control=cq) NM = DepolarizingError(p, 2) else: U = gates.X(target=qubit) NM = DepolarizingError(p, 1) O = ExpectationValue(U=U, H=H) E = simulate(O, backend=simulator, samples=1, noise=NM)
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_rotations(simulator, angle): U1 = tq.gates.X(target=1) + tq.gates.X(target=0, control=1) + tq.gates.Rx( angle=angle, target=0) U2 = tq.gates.X(target=1) + tq.gates.X( target=0, control=1) + tq.gates.ExpPauli(angle=angle, paulistring="X(0)") wfn1 = tequila.simulators.simulator_api.simulate(U1, backend=None) wfn2 = tequila.simulators.simulator_api.simulate(U2, backend=None) wfn3 = tequila.simulators.simulator_api.simulate(U2, backend=simulator) wfn4 = tequila.simulators.simulator_api.simulate(U2, backend=simulator) assert (numpy.isclose(numpy.abs(wfn1.inner(wfn2))**2, 1.0, atol=1.e-4)) assert (numpy.isclose(numpy.abs(wfn3.inner(wfn4))**2, 1.0, atol=1.e-4)) assert (numpy.isclose(numpy.abs(wfn1.inner(wfn3))**2, 1.0, atol=1.e-4)) U = tq.gates.X(target=1) + tq.gates.X( target=0, control=1) + tq.gates.ExpPauli(angle=angle, paulistring="X(0)Y(3)") wfn1 = tq.simulate(U2, backend=None) wfn2 = tq.simulate(U2, backend=simulator) assert (numpy.isclose(numpy.abs(wfn1.inner(wfn2))**2, 1.0, atol=1.e-4))
def test_rz_phase_flip_0(simulator, p, angle): qubit = 0 H = paulis.Y(qubit) U = gates.H(target=qubit) + gates.Rz(angle=Variable('a'), target=qubit) + gates.H(target=qubit) O = ExpectationValue(U=U, H=H) NM = PhaseFlip(p, 1) E = simulate(O, backend=simulator, variables={'a': angle}, samples=1, noise=NM) print(E)
def test_parametrized_interface(backend, samples): if samples is not None and backend not in INSTALLED_SAMPLERS: pytest.skip("sampling not yet supported for backend={}".format(backend)) H = tq.paulis.X(0) U = tq.gates.Ry(angle="a", target=0) variables = {"a": numpy.pi / 2} CU = tq.compile(objective=U, backend=backend, samples=None) a = tq.simulate(objective=U, backend=backend, variables=variables, samples=None) aa = CU(variables=variables, samples=None) aaa = tq.compile_to_function(objective=U, backend=backend, samples=samples)(variables["a"], samples=None) assert (isinstance(a, tq.QubitWaveFunction)) assert (aa.isclose(a)) assert (aaa.isclose(a)) E = tq.ExpectationValue(H=H, U=U) CE = tq.compile(objective=E, backend=backend, samples=samples) a = tq.simulate(objective=E, backend=backend, variables=variables, samples=samples) aa = CE(variables=variables, samples=samples) aaa = tq.compile_to_function(objective=E, backend=backend)(variables["a"], samples=samples) assert (isinstance(a, numbers.Number)) assert numpy.isclose(aa, a, 1.e-1) assert numpy.isclose(aaa, a, 1.e-1)
def test_sampling_expvals(backend): U = tq.gates.X([0, 1, 2]) H = tq.paulis.Z(0) E1 = tq.simulate(tq.ExpectationValue(H=H, U=U), backend=backend, samples=1000) assert numpy.isclose(E1, -1.0) H = tq.paulis.Z([0, 1]) E1 = tq.simulate(tq.ExpectationValue(H=H, U=U), backend=backend, samples=1000) assert numpy.isclose(E1, 1.0) H = tq.paulis.Z([0, 1, 2]) E1 = tq.simulate(tq.ExpectationValue(H=H, U=U), backend=backend, samples=1000) assert numpy.isclose(E1, -1.0) U = tq.gates.H([0, 1, 2]) H = tq.paulis.X(0) E1 = tq.simulate(tq.ExpectationValue(H=H, U=U), backend=backend, samples=1000) assert numpy.isclose(E1, 1.0) H = tq.paulis.X([0, 1]) E1 = tq.simulate(tq.ExpectationValue(H=H, U=U), backend=backend, samples=1000) assert numpy.isclose(E1, 1.0) H = tq.paulis.X([0, 1, 2]) E1 = tq.simulate(tq.ExpectationValue(H=H, U=U), backend=backend, samples=1000) assert numpy.isclose(E1, 1.0) U = tq.gates.H([0, 1, 2]) H = tq.paulis.Zero() E1 = tq.simulate(tq.ExpectationValue(H=H, U=U), backend=backend, samples=1000) assert numpy.isclose(E1, 0.0) U = tq.gates.H([0, 1, 2]) H = tq.paulis.X(3) + 1.234 * tq.paulis.I() E1 = tq.simulate(tq.ExpectationValue(H=H, U=U), backend=backend, samples=1000) assert numpy.isclose(E1, 1.234)
def test_total_type_jumble( simulator, value1=(numpy.random.randint(0, 1000) / 1000.0 * (numpy.pi / 2.0)), value2=(numpy.random.randint(0, 1000) / 1000.0 * (numpy.pi / 2.0))): a = Variable('a') b = Variable('b') values = {a: value1, b: value2} H1 = tq.paulis.X(0) H2 = tq.paulis.Y(0) U1 = tq.gates.Ry(angle=a, target=0) U2 = tq.gates.Rx(angle=b, target=0) e1 = ExpectationValue(U1, H1) e2 = ExpectationValue(U2, H2) stacked = tq.objective.vectorize([e1, e2]) stacked = stacked * a * e2 out = simulate(stacked, variables=values, backend=simulator) v1 = out[0] v2 = out[1] appendage = a(values) * -np.sin(b(values)) an1 = np.sin(a(values)) * appendage an2 = -np.sin(b(values)) * appendage assert np.isclose(v1 + v2, an1 + an2) # not gonna contract, lets make gradient do some real work ga = grad(stacked, a) gb = grad(stacked, b) la = [tq.simulate(x, variables=values) for x in ga] print(la) lb = [tq.simulate(x, variables=values) for x in gb] print(lb) tota = np.sum(np.array(la)) totb = np.sum(np.array(lb)) gan1 = np.cos(a(values)) * appendage + ( np.sin(a(values)) * -np.sin(b(values))) - (np.sin(b(values)) * -np.sin(b(values))) gan2 = np.sin(a(values)) * a(values) * -np.cos(b(values)) + 2 * ( -np.cos(b(values)) * appendage) assert np.isclose(tota + totb, gan1 + gan2)
def test_fermionic_gates(assume_real, trafo): mol = tq.chemistry.Molecule(geometry="H 0.0 0.0 0.7\nLi 0.0 0.0 0.0", basis_set="sto-3g") U1 = mol.prepare_reference() U2 = mol.prepare_reference() variable_count = {} for i in [0,1,0]: for a in numpy.random.randint(2, 5, 3): idx = [(2 * i, 2 * a), (2 * i + 1, 2 * a + 1)] U1 += mol.make_excitation_gate(indices=idx, angle=(i, a), assume_real=assume_real) g = mol.make_excitation_generator(indices=idx) U2 += tq.gates.Trotterized(generator=g, angle=(i, a), steps=1) if (i,a) in variable_count: variable_count[(i,a)] += 1 else: variable_count[(i,a)] = 1 a = numpy.random.choice(U1.extract_variables(), 1)[0] H = mol.make_hamiltonian() E = tq.ExpectationValue(H=H, U=U1) dE = tq.grad(E, a) if not assume_real: assert dE.count_expectationvalues() == 4*variable_count[a.name] else: assert dE.count_expectationvalues() == 2*variable_count[a.name] E2 = tq.ExpectationValue(H=H, U=U2) dE2 = tq.grad(E2, a) variables = {k:numpy.random.uniform(0.0, 2.0*numpy.pi, 1)[0] for k in E.extract_variables()} test1=tq.simulate(E, variables=variables) test1x=tq.simulate(E2, variables=variables) test2=tq.simulate(dE, variables=variables) test2x=tq.simulate(dE2, variables=variables) assert numpy.isclose(test1, test1x, atol=1.e-6) assert numpy.isclose(test2, test2x, atol=1.e-6)
def test_bit_flip(simulator, p, controlled): qubit = 0 if controlled: U = gates.X(target=1) + gates.CX(1, 0) H = paulis.Qm(0) NM = BitFlip(p, 2) else: U = gates.X(target=0) NM = BitFlip(p, 1) H = paulis.Qm(qubit) O = ExpectationValue(U=U, H=H) E = simulate(O, backend=simulator, samples=1, noise=NM)
def test_bit_flip(simulator, p, controlled): qubit = 0 if controlled: U = gates.X(target=1) + gates.CX(1, 0) H = paulis.Qm(0) NM = BitFlip(p, 2) else: U = gates.X(target=0) NM = BitFlip(p, 1) H = paulis.Qm(qubit) O = ExpectationValue(U=U, H=H) E = simulate(O, backend=simulator, samples=1000, noise=NM) assert (numpy.isclose(E, 1.0 - p, atol=1.e-1))
def do_screening(self, arg): Ux = self.operator_pool.make_unitary(k=arg["k"], label="tmp") Utmp = arg["U"] + Ux variables = {**arg["variables"]} objective = self.make_objective(Utmp, screening=True, variables=variables) dEs = [] for k in Ux.extract_variables(): variables[k] = 0.0 dEs.append(grad(objective, k)) gradients=[numpy.abs(simulate(objective=dE, variables=variables, **self.parameters.compile_args)) for dE in dEs] return arg["k"], sum(gradients)
def test_rx_bit_flip_1(simulator, p, angle): qubit = 1 U = gates.X(target=0) + gates.CRx(control=0, target=1, angle=Variable('a')) H = paulis.Z(1) * paulis.I(0) NM = BitFlip(p, 2) O = ExpectationValue(U=U, H=H) E = simulate(O, backend=simulator, samples=1, variables={'a': angle}, noise=NM) print(E) print(p + numpy.cos(angle) - p * numpy.cos(angle))
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) 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 simulate_wavefunction(self, initial_state: [str, PhotonicStateVector] = None, simulator=None) -> PhotonicStateVector: if isinstance(initial_state, str): initial_state = PhotonicStateVector.from_string( paths=self.paths, string=initial_state) if initial_state is None: initial_state = 0 else: initial_state = initial_state.state simresult = tq.simulate(self.setup, backend=simulator, initial_state=initial_state) return PhotonicStateVector(paths=self.paths, state=simresult)
def test_qubit_excitations(backend): if backend == "symbolic": return U1 = tq.gates.X(0) + tq.gates.QubitExcitation(angle=numpy.pi / 2, target=[0, 1]) U2 = tq.gates.H(0) + tq.gates.X(1) + tq.gates.CNOT(0, 1) wfn1 = tq.simulate(U1, backend=backend) wfn2 = tq.simulate(U2, backend=backend) F = numpy.abs(wfn1.inner(wfn2))**2 assert numpy.isclose(F, 1.0, 1.e-4) U1 = tq.gates.X([0, 1]) + tq.gates.QubitExcitation(angle=numpy.pi / 2, target=[0, 2, 1, 3]) U2 = tq.gates.H(0) + tq.gates.X([2, 3]) + tq.gates.CNOT( 0, 1) + tq.gates.CNOT(0, 2) + tq.gates.CNOT(0, 3) wfn1 = tq.simulate(U1, backend=backend) wfn2 = tq.simulate(U2, backend=backend) F = numpy.abs(wfn1.inner(wfn2))**2 assert numpy.isclose(F, 1.0, 1.e-4) U1 = tq.gates.X([0, 1, 2, 3]) + tq.gates.QubitExcitation( angle=numpy.pi / 2, target=[0, 4, 1, 5, 2, 6, 3, 7]) U2 = tq.gates.H(0) + tq.gates.X([4, 5, 6, 7]) + tq.gates.X( [1, 2, 3], 0) + tq.gates.X([4, 5, 6, 7], 0) wfn1 = tq.simulate(U1, backend=backend) wfn2 = tq.simulate(U2, backend=backend) F = numpy.abs(wfn1.inner(wfn2))**2 assert numpy.isclose(F, 1.0, 1.e-4) q = [5, 3, 7, 8, 2, 9, 2, 4] U1 = tq.gates.X([q[0], q[1], q[2]]) + tq.gates.QubitExcitation( angle=numpy.pi / 2, target=[q[0], q[3], q[1], q[4], q[2], q[5]]) U2 = tq.gates.H(q[0]) + tq.gates.X([q[3], q[4], q[5]]) + tq.gates.X( [q[1], q[2]], q[0]) + tq.gates.X([q[3], q[4], q[5]], q[0]) wfn1 = tq.simulate(U1, backend=backend) wfn2 = tq.simulate(U2, backend=backend) F = numpy.abs(wfn1.inner(wfn2))**2 assert numpy.isclose(F, 1.0, 1.e-4)
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-5))
def test_array_contraction(backend, shape): def contraction(array): bra = numpy.asarray([1.0, 1.0, 1.0, -1.0]).reshape(shape) return numpy.trace(bra.dot(array)) expected = numpy.asarray([1.0, 0.0, 0.0, -1.0]).reshape(shape) U = tq.gates.X(target=0) hamiltonians = [ tq.paulis.I(), tq.paulis.X(0), tq.paulis.Y(0), tq.paulis.Z(0) ] E = tq.ExpectationValue(H=hamiltonians, U=U, shape=shape, contraction=contraction) result = tq.simulate(E, backend=backend) assert result == contraction(expected)
def sample(self, samples: int = 1, initial_state: str = None, simulator=None): iprep = tq.gates.QCircuit() if initial_state is not None: state = self.initialize_state(state=initial_state) # can only do product states right now, alltough more general ones are possible assert (len(state.state) == 1) key = [k for k in state.state.keys()][0] for i, q in enumerate(key.array): if q == 1: iprep += tq.gates.X(target=i) self._add_measurements() # those are the qubit counts given back by tequila qcounts = tq.simulate(iprep + self.setup, samples=samples) # those are the qubit counts re-interpreted as photonic counts pcounts = PhotonicStateVector(paths=self.paths, state=qcounts) return pcounts
threads=threads, guess_wfn=guess_wfn, options=options, active_orbitals=active) guess_wfn = mol.ref_wfn for m in ref_methods: print("computing ", m) try: ref_energies[m] += [ mol.compute_energy(method=m, guess_wfn=mol.ref_wfn) ] except: ref_energies[m] += [None] H = mol.make_hamiltonian() Uhf = mol.prepare_reference() # stupid excuse for an vqe, but it tests consistency # just evaluates the hartree fock energy U = Uhf hf = tq.simulate(tq.ExpectationValue(U=U, H=H)) energies += [hf] plt.plot(energies, label="QHF", marker="o", linestyle="--") for m in ref_methods: values = ref_energies[m] plt.plot(values, label=str(m)) plt.legend() plt.show()
file_data = open(file_name, "w") for i in range(n_train): Ham = Htrans(arg_train[i]) total_U = ans4(n_qub, n_lay[0], arg_train[i], True) + ans4(n_qub, n_lay[1], arg_train[i], False) if original == False: # last layer of single-qubit gates for q in range(n_qub): theta = tq.Variable(name="th2_{}".format(q)) phi = tq.Variable(name="ph2_{}".format(q)) # No encoding: total_U += tq.gates.Rx(target=q, angle=theta) + tq.gates.Rz(target=q, angle=phi) exp_val = tq.ExpectationValue(H=Ham, U=total_U) res = tq.simulate(exp_val, variables=metaVQE.angles) res_ex = Htrans_exact(Ham) print(arg_train[i], res_ex, res, abs(res-res_ex), file=file_data) y_train_ex.append(res_ex) y_train_metaVQE.append(res) error_train_metaVQE.append(abs(res-res_ex)) file_data.close() # TEST print("MetaVQE test running") # Results test
import photonic import numpy import tequila as tq setup = photonic.PhotonicSetup(pathnames=['a', 'b', 'c', 'd'], S=1, qpm=1) setup.add_edge('a', 'b', -1, -1, ('a','b',-1,-1)) setup.add_edge('c', 'd', -1, -1, ('c','d',-1,-1)) setup.add_edge('a', 'c', 0, 0, ('a','c',0,0)) setup.add_edge('b', 'd', 0, 0, ('b','d',0,0)) U = setup.setup variables = {k:numpy.pi/2 for k in U.extract_variables()} wfn = tq.simulate(U, variables=variables) ph_wfn = photonic.PhotonicStateVector(setup.paths, wfn) print(ph_wfn) asd=str(ph_wfn) dsa=asd.split("+") for i in dsa: print(i) def prepare_ghz_state(phase=None): U = tq.gates.H(0) U+= tq.gates.CNOT(0,3) U+= tq.gates.CNOT(3,6) U+= tq.gates.CNOT(6,9) U+= tq.gates.X(0) U+= tq.gates.CNOT(0,1) U+= tq.gates.CNOT(1,4) U+= tq.gates.CNOT(4,7)
def test_return_type(): U = tq.gates.H(0) H = tq.paulis.X(0) E = tq.ExpectationValue(H=H,U=U) result = tq.simulate(E) assert isinstance(result, numbers.Number)
result += "{:30} : {}\n".format(k, v) return result if __name__ == "__main__": U = tq.gates.X(0) + tq.gates.H(0) + tq.gates.Ry(target=1, angle="a") encoder = CircuitGenEncoder() UX = encoder.prune_circuit(U, variables={"a": 4.0 * numpy.pi}) print(UX) result = encoder(U) print(result) U2 = encoder.decode(result) print(U2) U3 = encoder.decode(result, variables={"a": 1.0}) print(U3) encoder.export_to(circuit=U, filename="before.pdf") encoder.export_to(circuit=U2, filename="after.pdf") generator = CircuitGenerator(depth=10, connectivity="local_line", n_qubits=4, generators=["Y", "XY"], fix_angles={"XY": numpy.pi / 2}) print(generator) Urand = generator() encoded = encoder(Urand) print(encoded) encoder.export_to(Urand, filename="random.pdf") U = tq.gates.ExpPauli(paulistring="X({})Y({})".format(0, 1), angle=numpy.pi / 2) print(tq.simulate(U))
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)
P1 = tq.paulis.Qp(qubit=p1_qubits) # form the abstract expectation values E0 = tq.ExpectationValue(H=P0 * H * P1, U=U) E1 = tq.ExpectationValue(H=P0 * P1, U=U) # form the objective to optimize O = E0 / E1 print(O) # (in case you do not want to do the optimization) # Since we already know the real minimum we can test it here # In case you're beeing curious: E0 gives you information about the countrate of your setup # So in prinicple that can be optimized as well variables = {'t': 1.0, 'angle0': 0.5, 'angle1': -1.0} F = tq.simulate(O, variables) 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,
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)
setup = PhotonicSetup(pathnames=['a', 'b'], S=S, qpm=qpm) # the beam splitter is parametrized as phi=i*pi*t setup.add_beamsplitter(path_a='a', path_b='b', t=t, steps=trotter_steps) # need explicit circuit for initial state state = setup.initialize_state(state=initial_state) # can only do product states right now, alltough more general ones are possible # with code adaption Ui = tq.QCircuit() assert (len(state.state) == 1) key = [k for k in state.state.keys()][0] for i, q in enumerate(key.array): if q == 1: Ui += tq.gates.X(target=i) # full circuit (initial state plus mapped HOM setup) U = Ui + setup.setup + tq.gates.Measurement(target=[0, 1, 2, 3]) print(U) # those are the qubit counts given back by tequila qcounts = tq.simulate(U, samples=samples) # those are the qubit counts re-interpreted as photonic counts pcounts = PhotonicStateVector(paths=setup.paths, state=qcounts) print("qubit counts:\n", qcounts) print("photon counts:\n", pcounts) pcounts.plot(title="HOM-Counts for initial state " + initial_state)