Ejemplo n.º 1
0
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
Ejemplo n.º 2
0
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
Ejemplo n.º 3
0
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]
Ejemplo n.º 4
0
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
Ejemplo n.º 5
0
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]
Ejemplo n.º 6
0
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()))
Ejemplo n.º 7
0
    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