def test_build_experiment_setting_memory_map(): p = Program() s = ExperimentSetting(in_state=sX(0), out_operator=sZ(0) * sY(1)) e = TomographyExperiment(settings=[s], program=p) memory_map = e.build_setting_memory_map(s) assert memory_map == { 'preparation_alpha': [0.0], 'preparation_beta': [np.pi / 2], 'preparation_gamma': [0.0], 'measurement_alpha': [0.0, np.pi / 2], 'measurement_beta': [0.0, np.pi / 2], 'measurement_gamma': [0.0, -np.pi / 2] }
def test_build_symmetrization_memory_maps(): p = Program() s = ExperimentSetting(in_state=sZ(0) * sZ(1), out_operator=sZ(0) * sZ(1)) e = TomographyExperiment(settings=[s], program=p) memory_maps = [{ 'symmetrization': [0.0, 0.0] }, { 'symmetrization': [0.0, np.pi] }, { 'symmetrization': [np.pi, 0.0] }, { 'symmetrization': [np.pi, np.pi] }] assert e.build_symmetrization_memory_maps([0, 1]) == memory_maps
def test_for_negative_probabilities(): # trivial program to do state tomography on prog = Program(I(0)) # make TomographyExperiment expt_settings = [ExperimentSetting(zeros_state([0]), pt) for pt in [sI(0), sX(0), sY(0), sZ(0)]] experiment_1q = TomographyExperiment(settings=expt_settings, program=prog) # make a quantum computer object device = NxDevice(nx.complete_graph(1)) qc_density = QuantumComputer( name="testy!", qam=PyQVM(n_qubits=1, quantum_simulator_type=ReferenceDensitySimulator), device=device, compiler=DummyCompiler(), ) # initialize with a pure state initial_density = np.array([[1.0, 0.0], [0.0, 0.0]]) qc_density.qam.wf_simulator.density = initial_density try: list(measure_observables(qc=qc_density, tomo_experiment=experiment_1q, n_shots=3000)) except ValueError as e: # the error is from np.random.choice by way of self.rs.choice in ReferenceDensitySimulator assert str(e) != "probabilities are not non-negative" # initialize with a mixed state initial_density = np.array([[0.9, 0.0], [0.0, 0.1]]) qc_density.qam.wf_simulator.density = initial_density try: list(measure_observables(qc=qc_density, tomo_experiment=experiment_1q, n_shots=3000)) except ValueError as e: assert str(e) != "probabilities are not non-negative"
def group_experiments_greedy(tomo_expt: TomographyExperiment): """ Greedy method to group ExperimentSettings in a given TomographyExperiment :param tomo_expt: TomographyExperiment to group ExperimentSettings within :return: TomographyExperiment, with grouped ExperimentSettings according to whether it consists of PauliTerms diagonal in the same tensor product basis """ diag_sets = _max_tpb_overlap(tomo_expt) grouped_expt_settings_list = list(diag_sets.values()) grouped_tomo_expt = TomographyExperiment(grouped_expt_settings_list, program=tomo_expt.program) return grouped_tomo_expt
def test_tomo_experiment(): expts = [ ExperimentSetting(TensorProductState(), sX(0) * sY(1)), ExperimentSetting(plusZ(0), sZ(0)), ] suite = TomographyExperiment(settings=expts, program=Program(X(0), Y(1))) assert len(suite) == 2 for e1, e2 in zip(expts, suite): # experiment suite puts in groups of length 1 assert len(e2) == 1 e2 = e2[0] assert e1 == e2 prog_str = str(suite).splitlines()[3:5] assert prog_str == EXPERIMENT_REPR.splitlines()[4:6]
def test_qc_expectation_larger_lattice(forest): device = NxDevice(nx.complete_graph(4)) qc = QuantumComputer(name='testy!', qam=QVM(connection=forest), device=device, compiler=DummyCompiler()) q0 = 2 q1 = 3 # bell state program p = Program() p += RESET() p += H(q0) p += CNOT(q0, q1) p.wrap_in_numshots_loop(10) # XX, YY, ZZ experiment sx = ExperimentSetting(in_state=sZ(q0) * sZ(q1), out_operator=sX(q0) * sX(q1)) sy = ExperimentSetting(in_state=sZ(q0) * sZ(q1), out_operator=sY(q0) * sY(q1)) sz = ExperimentSetting(in_state=sZ(q0) * sZ(q1), out_operator=sZ(q0) * sZ(q1)) e = TomographyExperiment(settings=[sx, sy, sz], program=p) results = qc.experiment(e) # XX expectation value for bell state |00> + |11> is 1 assert np.isclose(results[0].expectation, 1) assert np.isclose(results[0].std_err, 0) assert results[0].total_counts == 40 # YY expectation value for bell state |00> + |11> is -1 assert np.isclose(results[1].expectation, -1) assert np.isclose(results[1].std_err, 0) assert results[1].total_counts == 40 # ZZ expectation value for bell state |00> + |11> is 1 assert np.isclose(results[2].expectation, 1) assert np.isclose(results[2].std_err, 0) assert results[2].total_counts == 40
def test_experiment_deser(tmpdir): expts = [ [ ExperimentSetting(TensorProductState(), sX(0) * sI(1)), ExperimentSetting(TensorProductState(), sI(0) * sX(1)) ], [ ExperimentSetting(TensorProductState(), sZ(0) * sI(1)), ExperimentSetting(TensorProductState(), sI(0) * sZ(1)) ], ] suite = TomographyExperiment(settings=expts, program=Program(X(0), Y(1))) to_json(f'{tmpdir}/suite.json', suite) suite2 = read_json(f'{tmpdir}/suite.json') assert suite == suite2
def group_experiments_clique_removal( experiments: TomographyExperiment) -> TomographyExperiment: """ Group experiments that are diagonal in a shared tensor product basis (TPB) to minimize number of QPU runs, using a graph clique removal algorithm. :param experiments: a tomography experiment :return: a tomography experiment with all the same settings, just grouped according to shared TPBs. """ g = construct_tpb_graph(experiments) _, cliqs = clique_removal(g) new_cliqs = [] for cliq in cliqs: new_cliq = [] for expt in cliq: # duplicate `count` times new_cliq += [expt] * g.nodes[expt]["count"] new_cliqs += [new_cliq] return TomographyExperiment(new_cliqs, program=experiments.program)
def test_tomo_experiment_pre_grouped(): expts = [ [ ExperimentSetting(TensorProductState(), sX(0) * sI(1)), ExperimentSetting(TensorProductState(), sI(0) * sX(1)) ], [ ExperimentSetting(TensorProductState(), sZ(0) * sI(1)), ExperimentSetting(TensorProductState(), sI(0) * sZ(1)) ], ] suite = TomographyExperiment(settings=expts, program=Program(X(0), Y(1))) assert len(suite) == 2 # number of groups for es1, es2 in zip(expts, suite): for e1, e2 in zip(es1, es2): assert e1 == e2 prog_str = str(suite).splitlines()[3:5] assert prog_str == EXPERIMENT_REPR.splitlines()[4:6]
def simulate(self, amplitudes): """Perform the simulation for the molecule. Args: amplitudes (list): The initial amplitudes (float64). Returns: float64: The total energy (energy). Raise: ValueError: If the dimension of the amplitude list is incorrect. """ if len(amplitudes) != self.amplitude_dimension: raise ValueError("Incorrect dimension for amplitude list.") #Anti-hermitian operator and its qubit form generator = uccsd_singlet_generator(amplitudes, self.of_mole.n_qubits, self.of_mole.n_electrons) jw_generator = jordan_wigner(generator) pyquil_generator = qubitop_to_pyquilpauli(jw_generator) p = Program(Pragma('INITIAL_REWIRING', ['"GREEDY"'])) # Set initial wavefunction (Hartree-Fock) for i in range(self.of_mole.n_electrons): p.inst(X(i)) # Trotterization (unitary for UCCSD state preparation) for term in pyquil_generator.terms: term.coefficient = np.imag(term.coefficient) p += exponentiate(term) p.wrap_in_numshots_loop(self.backend_options["n_shots"]) # Do not simulate if no operator was passed if len(self.qubit_hamiltonian.terms) == 0: return 0. else: # Run computation using the right backend if isinstance(self.backend_options["backend"], WavefunctionSimulator): energy = self.backend_options["backend"].expectation( prep_prog=p, pauli_terms=self.forest_qubit_hamiltonian) else: # Set up experiment, each setting corresponds to a particular measurement basis settings = [ ExperimentSetting(in_state=TensorProductState(), out_operator=forest_term) for forest_term in self.forest_qubit_hamiltonian.terms ] experiment = TomographyExperiment(settings=settings, program=p) print(experiment, "\n") results = self.backend_options["backend"].experiment( experiment) energy = 0. coefficients = [ forest_term.coefficient for forest_term in self.forest_qubit_hamiltonian.terms ] for i in range(len(results)): energy += results[i].expectation * coefficients[i] energy = np.real(energy) # Save the amplitudes so we have the optimal ones for RDM calculation self.optimized_amplitudes = amplitudes return energy
def test_tomo_experiment_empty(): suite = TomographyExperiment([], program=Program(X(0))) assert len(suite) == 0 assert str(suite.program) == 'X 0\n'
def test_generate_experiment_program(): # simplest example p = Program() s = ExperimentSetting(in_state=sZ(0), out_operator=sZ(0)) e = TomographyExperiment(settings=[s], program=p, symmetrization=0) exp = e.generate_experiment_program() test_exp = Program() ro = test_exp.declare('ro', 'BIT') test_exp += MEASURE(0, ro[0]) assert exp.out() == test_exp.out() assert exp.num_shots == 1 # 2Q exhaustive symmetrization p = Program() s = ExperimentSetting(in_state=sZ(0) * sZ(1), out_operator=sZ(0) * sZ(1)) e = TomographyExperiment(settings=[s], program=p) exp = e.generate_experiment_program() test_exp = Program() test_exp += parameterized_readout_symmetrization([0, 1]) ro = test_exp.declare('ro', 'BIT', 2) test_exp += MEASURE(0, ro[0]) test_exp += MEASURE(1, ro[1]) assert exp.out() == test_exp.out() assert exp.num_shots == 1 # add shots p = Program() p.wrap_in_numshots_loop(1000) s = ExperimentSetting(in_state=sZ(0), out_operator=sZ(0)) e = TomographyExperiment(settings=[s], program=p, symmetrization=0) exp = e.generate_experiment_program() test_exp = Program() ro = test_exp.declare('ro', 'BIT') test_exp += MEASURE(0, ro[0]) assert exp.out() == test_exp.out() assert exp.num_shots == 1000 # active reset p = Program() p += RESET() s = ExperimentSetting(in_state=sZ(0), out_operator=sZ(0)) e = TomographyExperiment(settings=[s], program=p, symmetrization=0) exp = e.generate_experiment_program() test_exp = Program() test_exp += RESET() ro = test_exp.declare('ro', 'BIT') test_exp += MEASURE(0, ro[0]) assert exp.out() == test_exp.out() assert exp.num_shots == 1 # state preparation and measurement p = Program() s = ExperimentSetting(in_state=sY(0), out_operator=sX(0)) e = TomographyExperiment(settings=[s], program=p, symmetrization=0) exp = e.generate_experiment_program() test_exp = Program() test_exp += parameterized_single_qubit_state_preparation([0]) test_exp += parameterized_single_qubit_measurement_basis([0]) ro = test_exp.declare('ro', 'BIT') test_exp += MEASURE(0, ro[0]) assert exp.out() == test_exp.out() assert exp.num_shots == 1 # multi-qubit state preparation and measurement p = Program() s = ExperimentSetting(in_state=sZ(0) * sY(1), out_operator=sZ(0) * sX(1)) e = TomographyExperiment(settings=[s], program=p, symmetrization=0) exp = e.generate_experiment_program() test_exp = Program() test_exp += parameterized_single_qubit_state_preparation([0, 1]) test_exp += parameterized_single_qubit_measurement_basis([0, 1]) ro = test_exp.declare('ro', 'BIT', 2) test_exp += MEASURE(0, ro[0]) test_exp += MEASURE(1, ro[1]) assert exp.out() == test_exp.out() assert exp.num_shots == 1