Beispiel #1
0
    def test_bk_jw_majoranas(self):
        # Check if the Majorana operators have the same spectrum
        # irrespectively of the transform.
        n_qubits = 7

        a = FermionOperator(((1, 0), ))
        a_dag = FermionOperator(((1, 1), ))

        c = a + a_dag
        d = 1j * (a_dag - a)

        c_spins = [jordan_wigner(c), bravyi_kitaev(c)]
        d_spins = [jordan_wigner(d), bravyi_kitaev(d)]

        c_sparse = [
            get_sparse_operator(c_spins[0]),
            get_sparse_operator(c_spins[1])
        ]
        d_sparse = [
            get_sparse_operator(d_spins[0]),
            get_sparse_operator(d_spins[1])
        ]

        c_spectrum = [eigenspectrum(c_spins[0]), eigenspectrum(c_spins[1])]
        d_spectrum = [eigenspectrum(d_spins[0]), eigenspectrum(d_spins[1])]

        self.assertAlmostEqual(
            0., numpy.amax(numpy.absolute(d_spectrum[0] - d_spectrum[1])))
Beispiel #2
0
    def __init__(self, qubit_1, qubit_2, system_n_qubits=None, encoding='jw'):
        self.spin_complement = True

        self.qubits = [[qubit_1], [qubit_2]]
        self.complement_qubits = [
            self.spin_complement_orbitals([qubit_1]),
            self.spin_complement_orbitals([qubit_2])
        ]

        fermi_operator_1 = FermionOperator('[{1}^ {0}] - [{0}^ {1}]'.format(
            qubit_2, qubit_1))

        if encoding == 'jw':
            excitations_generators = [jordan_wigner(fermi_operator_1)]
        else:
            assert encoding == 'bk'
            excitations_generators = [bravyi_kitaev(fermi_operator_1)]

        if {*self.qubits[0], *self.qubits[1]} != {*self.complement_qubits[0], *self.complement_qubits[1]} and \
           {*self.qubits[0], *self.qubits[1]} != {*self.complement_qubits[1], *self.complement_qubits[0]}:

            fermi_operator_2 = FermionOperator(
                '[{1}^ {0}] - [{0}^ {1}]'.format(self.complement_qubits[1][0],
                                                 self.complement_qubits[0][0]))
            if encoding == 'jw':
                excitations_generators = [jordan_wigner(fermi_operator_2)]
            else:
                assert encoding == 'bk'
                excitations_generators = [bravyi_kitaev(fermi_operator_2)]

        super(SpinCompSFExc, self).\
            __init__(element='spin_s_f_exc_{}_{}'.format(qubit_2, qubit_1), order=1, n_var_parameters=1,
                     excitations_generators=excitations_generators, system_n_qubits=system_n_qubits)
Beispiel #3
0
    def test_bravyi_kitaev_transform(self):
        # Check that the QubitOperators are two-term.
        lowering = bravyi_kitaev(FermionOperator(((3, 0),)))
        raising = bravyi_kitaev(FermionOperator(((3, 1),)))
        self.assertEqual(len(raising.terms), 2)
        self.assertEqual(len(lowering.terms), 2)

        #  Test the locality invariant for N=2^d qubits
        # (c_j majorana is always log2N+1 local on qubits)
        n_qubits = 16
        invariant = numpy.log2(n_qubits) + 1
        for index in range(n_qubits):
            operator = bravyi_kitaev(FermionOperator(((index, 0),)), n_qubits)
            qubit_terms = operator.terms.items()  # Get the majorana terms.

            for item in qubit_terms:
                coeff = item[1]

                #  Identify the c majorana terms by real
                #  coefficients and check their length.
                if not isinstance(coeff, complex):
                    self.assertEqual(len(item[0]), invariant)

        #  Hardcoded coefficient test on 16 qubits
        lowering = bravyi_kitaev(FermionOperator(((9, 0),)), n_qubits)
        raising = bravyi_kitaev(FermionOperator(((9, 1),)), n_qubits)

        correct_operators_c = ((7, 'Z'), (8, 'Z'), (9, 'X'),
                               (11, 'X'), (15, 'X'))
        correct_operators_d = ((7, 'Z'), (9, 'Y'), (11, 'X'), (15, 'X'))

        self.assertEqual(lowering.terms[correct_operators_c], 0.5)
        self.assertEqual(lowering.terms[correct_operators_d], 0.5j)
        self.assertEqual(raising.terms[correct_operators_d], -0.5j)
        self.assertEqual(raising.terms[correct_operators_c], 0.5)
    def test_hermitian_conjugated_qubit_op_consistency(self):
        """Some consistency checks for conjugating QubitOperators."""
        ferm_op = (FermionOperator('1^ 2') + FermionOperator('2 3 4') +
                   FermionOperator('2^ 7 9 11^'))

        # Check that hermitian conjugation commutes with transforms
        self.assertEqual(jordan_wigner(hermitian_conjugated(ferm_op)),
                         hermitian_conjugated(jordan_wigner(ferm_op)))
        self.assertEqual(bravyi_kitaev(hermitian_conjugated(ferm_op)),
                         hermitian_conjugated(bravyi_kitaev(ferm_op)))
def get_qubit_hamiltonian(mol,
                          geometry,
                          basis,
                          charge=0,
                          multiplicity=1,
                          qubit_transf='bk'):
    '''
    Generating qubit hamiltonina of the given molecules with specified geometry, basis sets, charge and multiplicity
    Give its qubit form using specified transformation
    '''
    g = get_molecular_data(mol, geometry)
    mol = MolecularData(g, basis, multiplicity, charge)
    mol = run_pyscf(mol)

    ham = mol.get_molecular_hamiltonian()
    hamf = get_fermion_operator(ham)

    if qubit_transf == 'bk':
        hamq = bravyi_kitaev(hamf)
    elif qubit_transf == 'jw':
        hamq = jordan_wigner(hamf)
    else:
        raise (ValueError(qubit_transf, 'Unknown transformation specified'))

    return hamq
Beispiel #6
0
def decompose_hamiltonian(mol_name,
                          hf_data,
                          mapping="jordan_wigner",
                          docc_mo_indices=None,
                          active_mo_indices=None):
    r"""Decomposes the electronic Hamiltonian into a linear combination of Pauli operators using
    OpenFermion tools.

    **Example usage:**

    >>> decompose_hamiltonian('h2', './pyscf/sto-3g/', mapping='bravyi_kitaev')
    (-0.04207897696293986+0j) [] + (0.04475014401986122+0j) [X0 Z1 X2] +
    (0.04475014401986122+0j) [X0 Z1 X2 Z3] +(0.04475014401986122+0j) [Y0 Z1 Y2] +
    (0.04475014401986122+0j) [Y0 Z1 Y2 Z3] +(0.17771287459806262+0j) [Z0] +
    (0.17771287459806265+0j) [Z0 Z1] +(0.1676831945625423+0j) [Z0 Z1 Z2] +
    (0.1676831945625423+0j) [Z0 Z1 Z2 Z3] +(0.12293305054268105+0j) [Z0 Z2] +
    (0.12293305054268105+0j) [Z0 Z2 Z3] +(0.1705973832722409+0j) [Z1] +
    (-0.2427428049645989+0j) [Z1 Z2 Z3] +(0.1762764080276107+0j) [Z1 Z3] +
    (-0.2427428049645989+0j) [Z2]

    Args:
        mol_name (str): name of the molecule
        hf_data (str): path to the directory containing the file with the Hartree-Fock
            electronic structure
        mapping (str): optional argument to specify the fermion-to-qubit mapping
            Input values can be ``'jordan_wigner'`` or ``'bravyi_kitaev'``
        docc_mo_indices (list): indices of doubly-occupied molecular orbitals, i.e.,
            the orbitals that are not correlated in the many-body wave function
        active_mo_indices (list): indices of active molecular orbitals, i.e., the orbitals used to
            build the correlated many-body wave function

    Returns:
        transformed_operator: instance of the QubitOperator class representing the electronic
        Hamiltonian
    """

    # loading HF data from a hdf5 file
    molecule = MolecularData(
        filename=os.path.join(hf_data.strip(), mol_name.strip()))

    # getting the terms entering the second-quantized Hamiltonian
    terms_molecular_hamiltonian = molecule.get_molecular_hamiltonian(
        occupied_indices=docc_mo_indices, active_indices=active_mo_indices)

    # generating the fermionic Hamiltonian
    fermionic_hamiltonian = get_fermion_operator(terms_molecular_hamiltonian)

    mapping = mapping.strip().lower()

    if mapping not in ("jordan_wigner", "bravyi_kitaev"):
        raise TypeError(
            "The '{}' transformation is not available. \n "
            "Please set 'mapping' to 'jordan_wigner' or 'bravyi_kitaev'.".
            format(mapping))

    # fermionic-to-qubit transformation of the Hamiltonian
    if mapping == "bravyi_kitaev":
        return bravyi_kitaev(fermionic_hamiltonian)

    return jordan_wigner(fermionic_hamiltonian)
Beispiel #7
0
    def __init__(self,
                 qubit_pair_1,
                 qubit_pair_2,
                 system_n_qubits=None,
                 encoding='jw'):
        self.spin_complement = False

        qubit_pair_1.sort()
        qubit_pair_2.sort()

        assert len(qubit_pair_1) == 2
        assert len(qubit_pair_2) == 2
        self.qubits = [qubit_pair_1, qubit_pair_2]

        fermi_operator = FermionOperator(
            '[{2}^ {3}^ {0} {1}] - [{0}^ {1}^ {2} {3}]'.format(
                self.qubits[0][0], self.qubits[0][1], self.qubits[1][0],
                self.qubits[1][1]))
        if encoding == 'jw':
            excitation_generator = jordan_wigner(fermi_operator)
        else:
            assert encoding == 'bk'
            excitation_generator = bravyi_kitaev(fermi_operator)

        super(DFExc, self).\
            __init__(element='d_f_exc_{}_{}'.format(qubit_pair_1, qubit_pair_2), order=2, n_var_parameters=1,
                     excitations_generators=[excitation_generator], system_n_qubits=system_n_qubits)
Beispiel #8
0
def decompose(hf_file, mapping="jordan_wigner", core=None, active=None):
    r"""Decomposes the molecular Hamiltonian into a linear combination of Pauli operators using
    OpenFermion tools.

    This function uses OpenFermion functions to build the second-quantized electronic Hamiltonian
    of the molecule and map it to the Pauli basis using the Jordan-Wigner or Bravyi-Kitaev
    transformation.

    Args:
        hf_file (str): absolute path to the hdf5-formatted file with the
            Hartree-Fock electronic structure
        mapping (str): Specifies the transformation to map the fermionic Hamiltonian to the
            Pauli basis. Input values can be ``'jordan_wigner'`` or ``'bravyi_kitaev'``.
        core (list): indices of core orbitals, i.e., the orbitals that are
            not correlated in the many-body wave function
        active (list): indices of active orbitals, i.e., the orbitals used to
            build the correlated many-body wave function

    Returns:
        QubitOperator: an instance of OpenFermion's ``QubitOperator``

    **Example**

    >>> decompose('./pyscf/sto-3g/h2', mapping='bravyi_kitaev')
    (-0.04207897696293986+0j) [] + (0.04475014401986122+0j) [X0 Z1 X2] +
    (0.04475014401986122+0j) [X0 Z1 X2 Z3] +(0.04475014401986122+0j) [Y0 Z1 Y2] +
    (0.04475014401986122+0j) [Y0 Z1 Y2 Z3] +(0.17771287459806262+0j) [Z0] +
    (0.17771287459806265+0j) [Z0 Z1] +(0.1676831945625423+0j) [Z0 Z1 Z2] +
    (0.1676831945625423+0j) [Z0 Z1 Z2 Z3] +(0.12293305054268105+0j) [Z0 Z2] +
    (0.12293305054268105+0j) [Z0 Z2 Z3] +(0.1705973832722409+0j) [Z1] +
    (-0.2427428049645989+0j) [Z1 Z2 Z3] +(0.1762764080276107+0j) [Z1 Z3] +
    (-0.2427428049645989+0j) [Z2]
    """

    # loading HF data from the hdf5 file
    molecule = MolecularData(filename=hf_file.strip())

    # getting the terms entering the second-quantized Hamiltonian
    terms_molecular_hamiltonian = molecule.get_molecular_hamiltonian(
        occupied_indices=core, active_indices=active
    )

    # generating the fermionic Hamiltonian
    fermionic_hamiltonian = get_fermion_operator(terms_molecular_hamiltonian)

    mapping = mapping.strip().lower()

    if mapping not in ("jordan_wigner", "bravyi_kitaev"):
        raise TypeError(
            "The '{}' transformation is not available. \n "
            "Please set 'mapping' to 'jordan_wigner' or 'bravyi_kitaev'.".format(mapping)
        )

    # fermionic-to-qubit transformation of the Hamiltonian
    if mapping == "bravyi_kitaev":
        return bravyi_kitaev(fermionic_hamiltonian)

    return jordan_wigner(fermionic_hamiltonian)
Beispiel #9
0
 def test_bravyi_kitaev(self):
     hamiltonian, gs_energy = lih_hamiltonian()
     code = bravyi_kitaev_code(4)
     qubit_hamiltonian = binary_code_transform(hamiltonian, code)
     self.assertAlmostEqual(gs_energy, eigenspectrum(qubit_hamiltonian)[0])
     qubit_spectrum = eigenspectrum(qubit_hamiltonian)
     fenwick_spectrum = eigenspectrum(bravyi_kitaev(hamiltonian))
     for eigen_idx, eigenvalue in enumerate(qubit_spectrum):
         self.assertAlmostEqual(eigenvalue, fenwick_spectrum[eigen_idx])
def get_BK_ham(distance, basis="sto-3g", multiplicity=1, charge=1):
    geometry = [["He", [0, 0, 0]], ["H", [0, 0, distance]]]
    description = str(distance)
    molecule = MolecularData(geometry, basis, multiplicity, charge,
                             description)
    molecule = run_pyscf(molecule, run_fci=1)
    bk_hamiltonian = get_sparse_operator(
        bravyi_kitaev(
            get_fermion_operator(molecule.get_molecular_hamiltonian())))
    return bk_hamiltonian
Beispiel #11
0
def get_ground_energy(interaction_hamil, numLayer):
    fermionop_hamil = FermionOperator()
    for key in interaction_hamil:
        value = interaction_hamil[key]
        fermionop_hamil += FermionOperator(term=key, coefficient=value)

    qubitop_hamil = bravyi_kitaev(fermionop_hamil)
    pauliop_hamil = qubitop_to_pyquilpauli(qubitop_hamil)

    return solve_vqe(pauliop_hamil, numLayer)
Beispiel #12
0
    def __init__(self,
                 qubit_pair_1,
                 qubit_pair_2,
                 system_n_qubits=None,
                 encoding='jw'):
        self.spin_complement = True

        assert len(qubit_pair_1) == 2
        assert len(qubit_pair_2) == 2
        self.qubits = [qubit_pair_1, qubit_pair_2]
        self.complement_qubits = [
            self.spin_complement_orbitals(qubit_pair_1),
            self.spin_complement_orbitals(qubit_pair_2)
        ]

        fermi_operator_1 = FermionOperator(
            '[{2}^ {3}^ {0} {1}] - [{0}^ {1}^ {2} {3}]'.format(
                *self.qubits[0], *self.qubits[1]))

        if encoding == 'jw':
            excitations_generators = [jordan_wigner(fermi_operator_1)]
        else:
            assert encoding == 'bk'
            excitations_generators = [bravyi_kitaev(fermi_operator_1)]

        if [set(self.qubits[0]), set(self.qubits[1])] != [set(self.complement_qubits[0]), set(self.complement_qubits[1])] and \
           [set(self.qubits[0]), set(self.qubits[1])] != [set(self.complement_qubits[1]), set(self.complement_qubits[0])]:

            fermi_operator_2 = FermionOperator(
                '[{2}^ {3}^ {0} {1}] - [{0}^ {1}^ {2} {3}]'.format(
                    *self.complement_qubits[0], *self.complement_qubits[1]))

            if encoding == 'jw':
                excitations_generators = [jordan_wigner(fermi_operator_2)]
            else:
                assert encoding == 'bk'
                excitations_generators = [bravyi_kitaev(fermi_operator_2)]

        super(SpinCompDFExc, self).\
            __init__(element='spin_d_f_exc_{}_{}'.format(qubit_pair_1, qubit_pair_2), order=2, n_var_parameters=1,
                     system_n_qubits=system_n_qubits, excitations_generators=excitations_generators)
def get_qubit_hamiltonian(g, basis, charge=0, spin=1, qubit_transf='jw'):

    ## Create OpenFermion molecule
    #mol = gto.Mole()
    #mol.atom = g
    #mol.basis = basis
    #mol.spin = spin
    #mol.charge = charge
    #mol.symmetry = False
    ##mol.max_memory = 1024
    #mol.build()

    multiplicity = spin + 1  # spin here is 2S ?
    mol = MolecularData(g, basis, multiplicity, charge)
    #mol.load()

    # Convert to PySCF molecule and run SCF
    print("Running run_pyscf...")
    print(f"Time: {time()}")
    print("=" * 20)
    mol = run_pyscf(mol)

    # Freeze some orbitals?
    occupied_indices = range(183)
    active_indices = range(183, 183+5)

    # Get Hamiltonian
    print("Running get_molecular_hamiltonian...")
    print(f"Time: {time()}")
    print("=" * 20)
    ham = mol.get_molecular_hamiltonian(
            occupied_indices=occupied_indices,
            active_indices=active_indices)

    import pdb; pdb.set_trace()

    print("Running get_fermion_operator...")
    print(f"Time: {time()}")
    print("=" * 20)
    hamf = get_fermion_operator(ham)

    print(f"Running {qubit_transf}...")
    print(f"Time: {time()}")
    print("=" * 20)

    if qubit_transf == 'bk':
        hamq = bravyi_kitaev(hamf)
    elif qubit_transf == 'jw':
        hamq = jordan_wigner(hamf)
    else:
        raise(ValueError(qubit_transf, 'Unknown transformation specified'))

    return remove_complex(hamq)
Beispiel #14
0
def full_ham_terms(spacing,dead_space = range(1),active_space = range(1,4)):
    molecule=molecule_data(spacing)

    molecular_hamiltonian = molecule.get_molecular_hamiltonian(
    occupied_indices=dead_space,
    active_indices=active_space)

    fermion_hamiltonian = get_fermion_operator(molecular_hamiltonian)
    qubit_hamiltonian = bravyi_kitaev(fermion_hamiltonian)
    qubit_hamiltonian.compress()
    terms_dict=qubit_hamiltonian.terms
    return terms_dict
Beispiel #15
0
    def test_bk_jw_hopping_operator(self):
        # Check if the spectrum fits for a single hoppping operator
        ho = FermionOperator(((1, 1), (4, 0))) + FermionOperator(
            ((4, 1), (1, 0)))
        jw_ho = jordan_wigner(ho)
        bk_ho = bravyi_kitaev(ho)

        # Diagonalize and make sure the spectra are the same.
        jw_spectrum = eigenspectrum(jw_ho)
        bk_spectrum = eigenspectrum(bk_ho)

        self.assertAlmostEqual(0., numpy.amax(
                               numpy.absolute(jw_spectrum - bk_spectrum)))
Beispiel #16
0
    def test_bk_jw_number_operator(self):
        # Check if number operator has the same spectrum in both
        # BK and JW representations
        n = number_operator(1, 0)
        jw_n = jordan_wigner(n)
        bk_n = bravyi_kitaev(n)

        # Diagonalize and make sure the spectra are the same.
        jw_spectrum = eigenspectrum(jw_n)
        bk_spectrum = eigenspectrum(bk_n)

        self.assertAlmostEqual(0., numpy.amax(
            numpy.absolute(jw_spectrum - bk_spectrum)))
Beispiel #17
0
    def test_bravyi_kitaev_transform_sympy(self):
        # Check that the QubitOperators are two-term.
        coeff = sympy.Symbol('x')

        #  Hardcoded coefficient test on 16 qubits
        n_qubits = 16
        lowering = bravyi_kitaev(FermionOperator(((9, 0), )) * coeff, n_qubits)
        raising = bravyi_kitaev(FermionOperator(((9, 1), )) * coeff, n_qubits)
        sum_lr = bravyi_kitaev(
            FermionOperator(((9, 0), )) * coeff + FermionOperator(
                ((9, 1), )) * coeff, n_qubits)

        correct_operators_c = ((7, 'Z'), (8, 'Z'), (9, 'X'), (11, 'X'), (15,
                                                                         'X'))
        correct_operators_d = ((7, 'Z'), (9, 'Y'), (11, 'X'), (15, 'X'))

        self.assertEqual(lowering.terms[correct_operators_c], 0.5 * coeff)
        self.assertEqual(lowering.terms[correct_operators_d], 0.5j * coeff)
        self.assertEqual(raising.terms[correct_operators_d], -0.5j * coeff)
        self.assertEqual(raising.terms[correct_operators_c], 0.5 * coeff)
        self.assertEqual(len(sum_lr.terms), 1)
        sum_lr_correct = QubitOperator(correct_operators_c, coeff)
        self.assertEqual(sum_lr, sum_lr_correct)
Beispiel #18
0
    def test_bk_jw_number_operator_scaled(self):
        # Check if number operator has the same spectrum in both
        # JW and BK representations
        n_qubits = 1
        n = number_operator(n_qubits, 0, coefficient=2)  # eigenspectrum (0,2)
        jw_n = jordan_wigner(n)
        bk_n = bravyi_kitaev(n)

        # Diagonalize and make sure the spectra are the same.
        jw_spectrum = eigenspectrum(jw_n)
        bk_spectrum = eigenspectrum(bk_n)

        self.assertAlmostEqual(0., numpy.amax(
                               numpy.absolute(jw_spectrum - bk_spectrum)))
Beispiel #19
0
    def test_bk_jw_integration(self):
        # This is a legacy test, which was a minimal failing example when
        # optimization for hermitian operators was used.

        # Minimal failing example:
        fo = FermionOperator(((3, 1),))

        jw = jordan_wigner(fo)
        bk = bravyi_kitaev(fo)

        jw_spectrum = eigenspectrum(jw)
        bk_spectrum = eigenspectrum(bk)

        self.assertAlmostEqual(0., numpy.amax(numpy.absolute(jw_spectrum -
                                                             bk_spectrum)))
Beispiel #20
0
    def __init__(self, qubit_1, qubit_2, system_n_qubits=None, encoding='jw'):
        self.spin_complement = False

        self.qubits = [[qubit_1], [qubit_2]]

        fermi_operator = FermionOperator('[{1}^ {0}] - [{0}^ {1}]'.format(
            self.qubits[1][0], self.qubits[0][0]))
        if encoding == 'jw':
            excitation_generator = jordan_wigner(fermi_operator)
        else:
            assert encoding == 'bk'
            excitation_generator = bravyi_kitaev(fermi_operator)

        super(SFExc, self).\
            __init__(element='s_f_exc_{}_{}'.format(qubit_1, qubit_2), order=1, n_var_parameters=1,
                     excitations_generators=[excitation_generator], system_n_qubits=system_n_qubits)
Beispiel #21
0
def load_and_transform(filename, orbitals, transform):
    # Load data
    print('--- loading molecule ---')
    molecule = MolecularData(filename=filename)

    print('filename: {}'.format(molecule.filename))
    #print('n_atoms: {}'.format(molecule.n_atoms))
    #print('n_electrons: {}'.format(molecule.n_electrons))
    #print('n_orbitals: {}'.format(molecule.n_orbitals))
    #print('Canonical Orbitals: {}'.format(molecule.canonical_orbitals))
    #print('n_qubits: {}'.format(molecule.n_qubits))

    # get the Hamiltonian for a specific choice of active space
    # set the Hamiltonian parameters
    occupied_orbitals, active_orbitals = orbitals

    molecular_hamiltonian = molecule.get_molecular_hamiltonian(
        occupied_indices=range(occupied_orbitals),
        active_indices=range(active_orbitals))

    # map the operator to fermions and then qubits
    fermion_hamiltonian = get_fermion_operator(molecular_hamiltonian)

    # get interaction operator
    interaction_hamiltonian = get_interaction_operator(fermion_hamiltonian)

    if transform is 'JW':
        qubit_h = jordan_wigner(fermion_hamiltonian)
        qubit_h.compress()
    elif transform is 'BK':
        qubit_h = bravyi_kitaev(fermion_hamiltonian)
        qubit_h.compress()
    elif transform is 'BKSF':
        qubit_h = bravyi_kitaev_fast(interaction_hamiltonian)
        qubit_h.compress()
    elif transform is 'BKT':
        qubit_h = bravyi_kitaev_tree(fermion_hamiltonian)
        qubit_h.compress()
    elif transform is 'PC':
        qubit_h = binary_code_transform(fermion_hamiltonian,
                                        parity_code(2 * active_orbitals))
        qubit_h.compress()
    else:
        print('ERROR: Unrecognized qubit transformation: {}'.format(transform))
        sys.exit(2)

    return qubit_h
Beispiel #22
0
    def test_bk_jw_number_operators(self):
        # Check if a number operator has the same spectrum in both
        # JW and BK representations
        n_qubits = 2
        n1 = number_operator(n_qubits, 0)
        n2 = number_operator(n_qubits, 1)
        n = n1 + n2

        jw_n = jordan_wigner(n)
        bk_n = bravyi_kitaev(n)

        # Diagonalize and make sure the spectra are the same.
        jw_spectrum = eigenspectrum(jw_n)
        bk_spectrum = eigenspectrum(bk_n)

        self.assertAlmostEqual(0., numpy.amax(
            numpy.absolute(jw_spectrum - bk_spectrum)))
Beispiel #23
0
    def test_bk_jw_integration_original(self):
        # This is a legacy test, which was an example proposed by Ryan,
        # failing when optimization for hermitian operators was used.
        fermion_operator = FermionOperator(((3, 1), (2, 1), (1, 0), (0, 0)),
                                           -4.3)
        fermion_operator += FermionOperator(((3, 1), (1, 0)), 8.17)
        fermion_operator += 3.2 * FermionOperator()

        # Map to qubits and compare matrix versions.
        jw_qubit_operator = jordan_wigner(fermion_operator)
        bk_qubit_operator = bravyi_kitaev(fermion_operator)

        # Diagonalize and make sure the spectra are the same.
        jw_spectrum = eigenspectrum(jw_qubit_operator)
        bk_spectrum = eigenspectrum(bk_qubit_operator)
        self.assertAlmostEqual(0., numpy.amax(numpy.absolute(jw_spectrum -
                                              bk_spectrum)), places=5)
Beispiel #24
0
def get_molecular_Hamiltonian(geometry=[('H', (0.0, 0.0, 0.0)),
                                        ('H', (0.0, 0.0, 0.7414))],
                              basis='sto-3g',
                              multiplicity=1,
                              charge=0):
    # Perform electronic structure calculations and obtain Hamiltonian as an InteractionOperator
    hamiltonian = ofpyscf.generate_molecular_hamiltonian(
        geometry, basis, multiplicity, charge)

    # Convert to a FermionOperator
    hamiltonian_ferm_op = of.get_fermion_operator(hamiltonian)

    mol_qubit_hamiltonianBK = bravyi_kitaev(
        hamiltonian_ferm_op
    )  # JW is exponential in the maximum locality of the original FermionOperator.
    mol_matrix = get_sparse_operator(mol_qubit_hamiltonianBK).todense()
    return mol_matrix
def majorana_to_pauli_dict(majorana_list, qubit_mapping='jw'):
    """
    Generates a dictionary from Majorana operator indices (ordered tuples) to
    its Pauli string representation under a given fermion-to-qubit mapping.
    Does not keep track of phases in front of the operators, since we always
    assume the convention
    
    Majorana operator = (-i)^k * \gamma_1 ... \gamma_{2k}.

    Parameters
    ----------
    majorana_list : iterable
        An iterable of Majorana tuples.
    qubit_mapping : str, optional
        The chosen fermion-to-qubit mapping, Jordan-Wigner ('jw') or Bravyi-
        Kitaev ('bk'). The default is 'jw'.

    Raises
    ------
    NotImplementedError
        If mappings other than Jordan-Wigner or Bravyi-Kitaev are specified.

    Returns
    -------
    majorana_to_pauli : dict
        Dictionary which maps between the Majorana and Pauli representations.

    """

    majorana_to_pauli = {}

    for majorana in majorana_list:

        if qubit_mapping == 'jw':
            op = jordan_wigner(MajoranaOperator(mu))
        elif qubit_mapping == 'bk':
            op = bravyi_kitaev(MajoranaOperator(mu))
        else:
            raise NotImplementedError(
                'Only jw and bk mappings currently supported.')

        majorana_to_pauli[majorana] = next(iter(op.terms))

    return majorana_to_pauli
Beispiel #26
0
def load_and_transform(filename, orbitals, transform):
    # Load data
    print('--- Loading molecule ---')
    molecule = MolecularData(filename=filename)
    molecule.load()

    print('filename: {}'.format(molecule.filename))
    print('n_atoms: {}'.format(molecule.n_atoms))
    print('n_electrons: {}'.format(molecule.n_electrons))
    print('n_orbitals: {}'.format(molecule.n_orbitals))
    #print('Canonical Orbitals: {}'.format(molecule.canonical_orbitals))
    print('n_qubits: {}'.format(molecule.n_qubits))

    # Get the Hamiltonian in an active space.
    # Set Hamiltonian parameters.
    occupied_orbitals, active_orbitals = orbitals

    molecular_hamiltonian = molecule.get_molecular_hamiltonian(
        occupied_indices=range(occupied_orbitals),
        active_indices=range(active_orbitals))

    # Map operator to fermions and qubits.
    fermion_hamiltonian = get_fermion_operator(molecular_hamiltonian)
    #print('Fermionic Hamiltonian is:\n{}'.format(fermion_hamiltonian))

    if transform is 'JW':
        qubit_h = jordan_wigner(fermion_hamiltonian)
        qubit_h.compress()
        print('\nJordan-Wigner Hamiltonian:\n{}'.format(qubit_h))
    elif transform is 'BK':
        qubit_h = bravyi_kitaev(fermion_hamiltonian)
        qubit_h.compress()
        print('\nBravyi-Kitaev Hamiltonian is:\n{}'.format(qubit_h))
    else:
        print('ERROR: Unrecognized qubit transformation: {}'.format(transform))
        sys.exit(2)

    return qubit_h
Beispiel #27
0
 def test_bk_n_qubits_too_small(self):
     with self.assertRaises(ValueError):
         bravyi_kitaev(FermionOperator('2^ 3^ 5 0'), n_qubits=4)
     with self.assertRaises(ValueError):
         bravyi_kitaev(MajoranaOperator((2, 3, 9, 0)), n_qubits=4)
Beispiel #28
0
 def test_bk_identity(self):
     self.assertTrue(bravyi_kitaev(FermionOperator(())) ==
                     QubitOperator(()))
Beispiel #29
0
def test_bravyi_kitaev_majorana_op_consistent():
    op = (MajoranaOperator((1, 3, 4), 0.5)
          + MajoranaOperator((3, 7, 8, 9, 10, 12), 1.8)
          + MajoranaOperator((0, 4)))
    assert bravyi_kitaev(op) == bravyi_kitaev(get_fermion_operator(op))
Beispiel #30
0
 def test_bk_bad_type(self):
     with self.assertRaises(TypeError):
         bravyi_kitaev(QubitOperator())