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])))
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)
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
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)
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)
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)
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
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)
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)
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
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)))
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)))
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)
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)))
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)))
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)
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
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)))
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)
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
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
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)
def test_bk_identity(self): self.assertTrue(bravyi_kitaev(FermionOperator(())) == QubitOperator(()))
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))
def test_bk_bad_type(self): with self.assertRaises(TypeError): bravyi_kitaev(QubitOperator())