예제 #1
0
def test_simple_arithmetic():
    qubit = random.randint(0, 5)
    primitives = [paulis.X, paulis.Y, paulis.Z]
    assert (paulis.X(qubit).conjugate() == paulis.X(qubit))
    assert (paulis.Y(qubit).conjugate() == -1 * paulis.Y(qubit))
    assert (paulis.Z(qubit).conjugate() == paulis.Z(qubit))
    assert (paulis.X(qubit).transpose() == paulis.X(qubit))
    assert (paulis.Y(qubit).transpose() == -1 * paulis.Y(qubit))
    assert (paulis.Z(qubit).transpose() == paulis.Z(qubit))
    for P in primitives:
        assert (P(qubit) * P(qubit) == QubitHamiltonian(1.0))
        n = random.randint(0, 10)
        nP = QubitHamiltonian.zero()
        for i in range(n):
            nP += P(qubit)
        assert (n * P(qubit) == nP)

    for i, Pi in enumerate(primitives):
        i1 = (i + 1) % 3
        i2 = (i + 2) % 3
        assert (Pi(qubit) * primitives[i1](qubit) == 1j *
                primitives[i2](qubit))
        assert (primitives[i1](qubit) * Pi(qubit) == -1j *
                primitives[i2](qubit))

        for qubit2 in random.randint(6, 10, 5):
            if qubit2 == qubit: continue
            P = primitives[random.randint(0, 2)]
            assert (Pi(qubit) * primitives[i1](qubit) * P(qubit2) == 1j *
                    primitives[i2](qubit) * P(qubit2))
            assert (P(qubit2) * primitives[i1](qubit) * Pi(qubit) == -1j *
                    P(qubit2) * primitives[i2](qubit))
예제 #2
0
파일: qc_base.py 프로젝트: akpc/margarita
    def make_excitation_generator(
            self,
            indices: typing.Iterable[typing.Tuple[int,
                                                  int]]) -> QubitHamiltonian:
        """
        Notes
        ----------
        Creates the transformed hermitian generator of UCC type unitaries:
              M(a^\dagger_{a_0} a_{i_0} a^\dagger{a_1}a_{i_1} ... - h.c.)
              where the qubit map M depends is self.transformation

        Parameters
        ----------
        indices : typing.Iterable[typing.Tuple[int, int]] :
            List of tuples [(a_0, i_0), (a_1, i_1), ... ] - recommended format, in spin-orbital notation (alpha odd numbers, beta even numbers)
            can also be given as one big list: [a_0, i_0, a_1, i_1 ...]
        Returns
        -------
        type
            1j*Transformed qubit excitation operator, depends on self.transformation
        """
        # check indices and convert to list of tuples if necessary
        if len(indices) == 0:
            raise TequilaException(
                "make_excitation_operator: no indices given")
        elif not isinstance(indices[0], typing.Iterable):
            if len(indices) % 2 != 0:
                raise TequilaException(
                    "make_excitation_generator: unexpected input format of indices\n"
                    "use list of tuples as [(a_0, i_0),(a_1, i_1) ...]\n"
                    "or list as [a_0, i_0, a_1, i_1, ... ]\n"
                    "you gave: {}".format(indices))
            converted = [(indices[2 * i], indices[2 * i + 1])
                         for i in range(len(indices) // 2)]
        else:
            converted = indices

        # convert to openfermion input format
        ofi = []
        dag = []
        for pair in converted:
            assert (len(pair) == 2)
            ofi += [
                (int(pair[0]), 1), (int(pair[1]), 0)
            ]  # openfermion does not take other types of integers like numpy.int64
            dag += [(int(pair[0]), 0), (int(pair[1]), 1)]

        op = openfermion.FermionOperator(tuple(ofi),
                                         1.j)  # 1j makes it hermitian
        op += openfermion.FermionOperator(tuple(reversed(dag)), -1.j)
        qop = QubitHamiltonian(qubit_hamiltonian=self.transformation(op))

        # check if the operator is hermitian and cast coefficients to floats
        # in order to avoid trouble with the simulation backends
        assert qop.is_hermitian()
        for k, v in qop.qubit_operator.terms.items():
            qop.qubit_operator.terms[k] = to_float(v)

        qop = qop.simplify()
        return qop
예제 #3
0
파일: qc_base.py 프로젝트: akpc/margarita
    def make_hamiltonian(self,
                         occupied_indices=None,
                         active_indices=None) -> QubitHamiltonian:
        """ """
        if occupied_indices is None and self.active_space is not None:
            occupied_indices = self.active_space.frozen_reference_orbitals
        if active_indices is None and self.active_space is not None:
            active_indices = self.active_space.active_orbitals

        fop = openfermion.transforms.get_fermion_operator(
            self.molecule.get_molecular_hamiltonian(occupied_indices,
                                                    active_indices))
        return QubitHamiltonian(qubit_hamiltonian=self.transformation(fop))
예제 #4
0
def brute_force_transformation(H, old_basis, new_basis):
    def pair_unitary(a, b):
        '''
        Accepts a BinaryPauliString. 
        Return the paired unitary 1/sqrt(2) (a + b) in qubit hamiltonian. 
        '''
        a = QubitHamiltonian.from_paulistrings(a.to_pauli_strings())
        b = QubitHamiltonian.from_paulistrings(b.to_pauli_strings())
        return (1 / 2) ** (1 / 2) * (a + b)

    U = QubitHamiltonian(1)
    for i, i_basis in enumerate(old_basis):
        U *= pair_unitary(i_basis, new_basis[i])

    return U * H * U
예제 #5
0
파일: qc_base.py 프로젝트: akpc/margarita
    def reference_state(self,
                        reference_orbitals: list = None,
                        n_qubits: int = None) -> BitString:
        """Does a really lazy workaround ... but it works
        :return: Hartree-Fock Reference as binary-number

        Parameters
        ----------
        reference_orbitals: list:
            give list of doubly occupied orbitals
            default is None which leads to automatic list of the
            first n_electron/2 orbitals

        Returns
        -------

        """

        if reference_orbitals is None:
            reference_orbitals = [i for i in range(self.n_electrons // 2)]

        spin_orbitals = sorted([2 * i for i in reference_orbitals] +
                               [2 * i + 1 for i in reference_orbitals])

        if n_qubits is None:
            n_qubits = 2 * self.n_orbitals

        string = ""

        for i in spin_orbitals:
            string += str(i) + "^ "

        fop = openfermion.FermionOperator(string, 1.0)

        op = QubitHamiltonian(qubit_hamiltonian=self.transformation(fop))
        from tequila.wavefunction.qubit_wavefunction import QubitWaveFunction
        wfn = QubitWaveFunction.from_int(0, n_qubits=n_qubits)
        wfn = wfn.apply_qubitoperator(operator=op)
        assert (len(wfn.keys()) == 1)
        keys = [k for k in wfn.keys()]
        return keys[-1]
예제 #6
0
 def to_qubit_hamiltonian(self):
     qub_ham = QubitHamiltonian()
     for p in self.binary_terms:
         qub_ham += QubitHamiltonian.from_paulistrings(p.to_pauli_strings())
     return qub_ham