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 = Experiment(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 test_setting_no_in_back_compat(): out_ops = _generate_random_paulis(n_qubits=4, n_terms=7) for oop in out_ops: expt = ExperimentSetting(TensorProductState(), oop) expt2 = ExperimentSetting.from_str(str(expt)) assert expt == expt2 assert expt2.in_operator == sI() assert expt2.out_operator == oop
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 = Experiment(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 _generate_random_states(n_qubits, n_terms): oneq_states = [ SIC0, SIC1, SIC2, SIC3, plusX, minusX, plusY, minusY, plusZ, minusZ ] all_s_inds = np.random.randint(len(oneq_states), size=(n_terms, n_qubits)) states = [] for s_inds in all_s_inds: state = functools.reduce(mul, (oneq_states[pi](i) for i, pi in enumerate(s_inds)), TensorProductState([])) states += [state] return states
def test_tomo_experiment(): expts = [ ExperimentSetting(TensorProductState(), sX(0) * sY(1)), ExperimentSetting(plusZ(0), sZ(0)), ] suite = Experiment(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 _max_weight_state( states: Iterable[TensorProductState] ) -> Union[None, TensorProductState]: """Construct a TensorProductState by taking the single-qubit state at each qubit position. This function will return ``None`` if the input states are not compatible For example, the max_weight_state of ["(+X, q0)", "(-Z, q1)"] is "(+X, q0; -Z q1)". Asking for the max weight state of something like ["(+X, q0)", "(+Z, q0)"] will return None. """ mapping = dict() # type: Dict[int, _OneQState] for state in states: for oneq_state in state.states: if oneq_state.qubit in mapping: if mapping[oneq_state.qubit] != oneq_state: return None else: mapping[oneq_state.qubit] = oneq_state return TensorProductState(list(mapping.values()))
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