### Install OpenFermion Source: https://github.com/quantumlib/openfermion/blob/main/docs/tutorials/binary_code_transforms.ipynb Installs the OpenFermion package if it is not already present. This is a common setup step for using the library. ```python try: import openfermion except ImportError: !pip install git+https://github.com/quantumlib/OpenFermion.git@main#egg=openfermion ``` -------------------------------- ### Install OpenFermion-FQE Source: https://github.com/quantumlib/openfermion/blob/main/docs/fqe/guide/introduction.ipynb Installs the fqe library quietly if it's not already imported. Use this to ensure the library is available before proceeding. ```python try: import fqe except ImportError: !pip install fqe --quiet ``` -------------------------------- ### Install FQE library Source: https://github.com/quantumlib/openfermion/blob/main/docs/fqe/tutorials/fermi_hubbard.ipynb Installs the FQE library if it's not already available. This is a prerequisite for using FQE functionalities. ```python try: import fqe except ImportError: # TODO: Change to `pip install fqe --quiet` when FQE>0.1.0 is released. !pip install git+https://github.com/quantumlib/OpenFermion-FQE --quiet ``` -------------------------------- ### Install Resource Estimation Dependencies Source: https://github.com/quantumlib/openfermion/blob/main/src/openfermion/resource_estimates/pbc/README.md Command to install the necessary dependencies for resource estimation. ```bash pip install openfermion[resources] ``` -------------------------------- ### Install OpenFermion and OpenFermion-PySCF Source: https://github.com/quantumlib/openfermion/blob/main/docs/tutorials/intro_workshop_exercises.ipynb Installs the necessary OpenFermion and OpenFermion-PySCF libraries if they are not already present. Use this at the beginning of your session. ```python try: import openfermion as of import openfermionpyscf as ofpyscf except ImportError: print("Installing OpenFermion and OpenFermion-PySCF...") !pip install openfermion openfermionpyscf --quiet ``` -------------------------------- ### Install OpenFermion as a library Source: https://github.com/quantumlib/openfermion/blob/main/docs/install.md Use this command to install the latest stable PyPI release of OpenFermion in user mode. ```bash python3 -m pip install --user openfermion ``` -------------------------------- ### Install OpenFermion (Developer) Source: https://github.com/quantumlib/openfermion/blob/main/README.md Installs the latest version of OpenFermion in development mode. This requires cloning the repository and then installing the package in editable mode. ```shell git clone https://github.com/quantumlib/OpenFermion cd OpenFermion python -m pip install -e . ``` -------------------------------- ### Install tensorflow-docs generator Source: https://github.com/quantumlib/openfermion/blob/main/docs/install.md Install the tensorflow-docs package to enable the generation of API documentation from docstrings. ```bash python3 -m pip install -U --user git+https://github.com/tensorflow/docs ``` -------------------------------- ### Install OpenFermion in development mode Source: https://github.com/quantumlib/openfermion/blob/main/docs/install.md Use this command to install the latest version of OpenFermion from a local clone for development purposes. ```bash git clone https://github.com/quantumlib/OpenFermion cd OpenFermion python3 -m pip install -e . ``` -------------------------------- ### Install OpenFermion (User) Source: https://github.com/quantumlib/openfermion/blob/main/README.md Installs the latest PyPI release of OpenFermion for the current user, avoiding modifications to system Python packages. Ensure pip is up-to-date. ```shell python -m pip install --user openfermion ``` -------------------------------- ### Construct a Bose-Hubbard Hamiltonian Source: https://github.com/quantumlib/openfermion/blob/main/docs/tutorials/bosonic_operators.ipynb Example of creating a Bose-Hubbard Hamiltonian instance. ```python from openfermion.hamiltonians import bose_hubbard, fermi_hubbard bose_hubbard(2, 2, 1, 1) ``` -------------------------------- ### Initialize and Run PySCF Calculation Source: https://github.com/quantumlib/openfermion/blob/main/src/openfermion/resource_estimates/README.md This Python snippet demonstrates how to set up a molecule using PySCF and run a Restricted Open-shell Hartree-Fock (ROHF) calculation. Ensure PySCF is installed. ```python from pyscf import gto, scf # input is just like any other PySCF script mol = gto.M( atom = '''O 0.000000 -0.075791844 0.000000 H 0.866811829 0.601435779 0.000000 H -0.866811829 0.601435779 0.000000 ''', basis = 'augccpvtz', symmetry = False, charge = 1, spin = 1 ) mf = scf.ROHF(mol) mf.verbose = 4 mf.kernel() # run the SCF ``` -------------------------------- ### Run OpenFermion Docker Container Source: https://github.com/quantumlib/openfermion/blob/main/docker/README.md Runs the OpenFermion Docker container interactively. This command launches a new Ubuntu-like environment with OpenFermion and accessories installed. ```bash docker run -it openfermion_docker ``` -------------------------------- ### Start Jupyter Notebook within Docker Source: https://github.com/quantumlib/openfermion/blob/main/docker/README.md Starts a Jupyter notebook server inside the Docker container, accessible from the host browser. Ensure the port matches the one used in the 'docker run' command. ```bash jupyter-notebook --allow-root --no-browser --port 8888 --ip=0.0.0.0 ``` -------------------------------- ### Jordan-Wigner Transform Examples Source: https://github.com/quantumlib/openfermion/blob/main/docs/tutorials/intro_workshop_exercises.ipynb Illustrates the Jordan-Wigner transform on various FermionOperator combinations, including single operators, products, and linear combinations with complex coefficients. ```python a2 = of.FermionOperator("2") print(of.jordan_wigner(a2)) print() a2dag = of.FermionOperator("2^") print(of.jordan_wigner(a2dag * a2)) print() a7 = of.FermionOperator("7") a7dag = of.FermionOperator("7^") print(of.jordan_wigner((1 + 2j) * (a2dag * a7) + (1 - 2j) * (a7dag * a2))) ``` -------------------------------- ### Initialize and set random wavefunction Source: https://github.com/quantumlib/openfermion/blob/main/docs/fqe/tutorials/fermi_hubbard.ipynb Initializes an FQE wavefunction for a specific number of particles and spin sector, then sets its state randomly. This is used to start the time evolution simulation. ```python nele, sz = 2, 0 init_wfn = fqe.Wavefunction([[nele, sz, nsites]]) init_wfn.set_wfn(strategy="random") ``` -------------------------------- ### Initialize environment and imports Source: https://github.com/quantumlib/openfermion/blob/main/docs/fqe/tutorials/hamiltonian_time_evolution_and_expectation_estimation.ipynb Configures numpy settings and imports necessary OpenFermion and FQE modules. ```python Print = True from openfermion import FermionOperator, MolecularData from openfermion.utils import hermitian_conjugated import numpy import fqe numpy.set_printoptions(floatmode='fixed', precision=6, linewidth=80, suppress=True) numpy.random.seed(seed=409) ``` -------------------------------- ### Initialize FQE Wavefunction Source: https://github.com/quantumlib/openfermion/blob/main/docs/fqe/tutorials/fqe_vs_openfermion_quadratic_hamiltonians.ipynb Sets up the FQE wavefunction and prints the initial state. ```python # initialize the FQE wavefunction [n-elec, sz, norbs] fqe_wfn = fqe.Wavefunction([[norbs // 2, norbs//2, norbs]]) hf_wf = np.zeros((int(binom(norbs, norbs // 2)), 1), dtype=np.complex128) hf_wf[0, 0] = 1 # right most bit is zero orbital. fqe_wfn.set_wfn(strategy='from_data', raw_data={(norbs//2, norbs//2): hf_wf}) fqe_wfn.print_wfn() ``` -------------------------------- ### Build OpenFermion API documentation Source: https://github.com/quantumlib/openfermion/blob/main/docs/install.md Execute the build script to generate Markdown API documentation files from the local repository. ```bash python3 dev_tools/docs/build_api_docs.py --output_dir=docs/api_docs ``` -------------------------------- ### Initialize PySCF Periodic System Source: https://github.com/quantumlib/openfermion/blob/main/src/openfermion/resource_estimates/pbc/README.md Sets up a periodic carbon diamond system using PySCF for subsequent resource estimation. ```python from pyscf.pbc import gto, scf cell = gto.Cell() cell.atom = ''' C 0.000000000000 0.000000000000 0.000000000000 C 1.685068664391 1.685068664391 1.685068664391 ''' cell.basis = 'gth-szv' cell.pseudo = 'gth-hf-rev' cell.a = ''' 0.000000000, 3.370137329, 3.370137329 3.370137329, 0.000000000, 3.370137329 3.370137329, 3.370137329, 0.000000000''' cell.unit = 'B' cell.verbose = 0 cell.build() kmesh = [1, 1, 3] kpts = cell.make_kpts(kmesh) nkpts = len(kpts) mf = scf.KRHF(cell, kpts).rs_density_fit() mf.kernel() ``` -------------------------------- ### Get Sparse Charge-Charge Operator Source: https://github.com/quantumlib/openfermion/blob/main/docs/fqe/tutorials/fermi_hubbard.ipynb Retrieves the sparse operator for the charge-charge interaction term. This is a precursor to exponentiating the matrix for time evolution. ```python # Get the 2^n x 2^n matrix (as a sparse operator). sparse_charge_charge_matrix = of.get_sparse_operator(sum(two_body_terms)) ``` -------------------------------- ### Initialize LiH molecular data and Hamiltonian parameters Source: https://github.com/quantumlib/openfermion/blob/main/docs/tutorials/intro_to_openfermion.ipynb Sets up the initial parameters for a LiH molecule calculation, including geometry and active space definitions. ```python from openfermion.chem import MolecularData from openfermion.transforms import get_fermion_operator, jordan_wigner from openfermion.linalg import get_ground_state, get_sparse_operator import numpy import scipy import scipy.linalg # Load saved file for LiH. diatomic_bond_length = 1.45 geometry = [('Li', (0., 0., 0.)), ('H', (0., 0., diatomic_bond_length))] basis = 'sto-3g' multiplicity = 1 # Set Hamiltonian parameters. active_space_start = 1 active_space_stop = 3 ``` -------------------------------- ### Access Wavefunction Coefficients by Sector Source: https://github.com/quantumlib/openfermion/blob/main/docs/fqe/guide/introduction.ipynb Retrieve the coefficients for a specific sector of the wavefunction using `get_coeff`. This example accesses the sector for n=2 and sz=-2. ```python interesting_states = wfn_fqe.get_coeff((2, -2)) print(interesting_states) ``` -------------------------------- ### Initialize a MolecularData instance Source: https://github.com/quantumlib/openfermion/blob/main/docs/tutorials/intro_to_openfermion.ipynb Demonstrates creating a MolecularData object with specific geometry, basis, and charge parameters without performing electronic structure calculations. ```python from openfermion.chem import MolecularData # Set parameters to make a simple molecule. diatomic_bond_length = .7414 geometry = [('H', (0., 0., 0.)), ('H', (0., 0., diatomic_bond_length))] basis = 'sto-3g' multiplicity = 1 charge = 0 description = str(diatomic_bond_length) # Make molecule and print out a few interesting facts about it. molecule = MolecularData(geometry, basis, multiplicity, charge, description) print('Molecule has automatically generated name {}'.format( molecule.name)) print('Information about this molecule would be saved at:\n{}\n'.format( molecule.filename)) print('This molecule has {} atoms and {} electrons.'.format( molecule.n_atoms, molecule.n_electrons)) for atom, atomic_number in zip(molecule.atoms, molecule.protons): print('Contains {} atom, which has {} protons.'.format( atom, atomic_number)) ``` -------------------------------- ### Get Molecular Hamiltonian in Active Space Source: https://github.com/quantumlib/openfermion/blob/main/docs/tutorials/intro_to_openfermion.ipynb Extracts the molecular Hamiltonian for a specified active space, defining occupied and active orbital indices. ```python molecular_hamiltonian = molecule.get_molecular_hamiltonian( occupied_indices=range(active_space_start), active_indices=range(active_space_start, active_space_stop)) ``` -------------------------------- ### Initialize Random Wavefunction Source: https://github.com/quantumlib/openfermion/blob/main/docs/fqe/tutorials/diagonal_coulomb_evolution.ipynb Sets up a random wavefunction for a system with 6 orbitals and 4 electrons. ```python norbs = 6 tedim = norbs * (norbs + 1) // 2 if (norbs // 2) % 2 == 0: n_elec = norbs // 2 else: n_elec = (norbs // 2) + 1 sz = 0 fqe_wfn = fqe.Wavefunction([[n_elec, sz, norbs]]) fqe_wfn.set_wfn(strategy='random') initial_coeffs = fqe_wfn.get_coeff((n_elec, sz)).copy() print("Random initial wavefunction") fqe_wfn.print_wfn() ``` -------------------------------- ### Import Necessary Libraries Source: https://github.com/quantumlib/openfermion/blob/main/docs/fqe/tutorials/diagonal_coulomb_evolution.ipynb Imports essential libraries for quantum chemistry calculations, including FQE, NumPy, OpenFermion, and SciPy's exponential function. ```python from itertools import product import fqe from fqe.hamiltonians.diagonal_coulomb import DiagonalCoulomb import numpy as np import openfermion as of from scipy.linalg import expm ``` -------------------------------- ### Get Sparse Hamiltonian and Energy in Rotated Basis Source: https://github.com/quantumlib/openfermion/blob/main/docs/tutorials/intro_to_openfermion.ipynb Obtains the sparse representation of the qubit Hamiltonian in the rotated basis and computes its ground state energy. ```python # Get sparse Hamiltonian and energy in rotated basis. sparse_hamiltonian = get_sparse_operator(qubit_hamiltonian) energy, state = get_ground_state(sparse_hamiltonian) print('Ground state energy after rotation is {} Hartree.'.format(energy)) ``` -------------------------------- ### Get Qubit Hamiltonian in Rotated Basis Source: https://github.com/quantumlib/openfermion/blob/main/docs/tutorials/intro_to_openfermion.ipynb Recalculates the qubit Hamiltonian using the Jordan-Wigner transformation after the molecular Hamiltonian's basis has been rotated. The Hamiltonian is then compressed. ```python # Get qubit Hamiltonian in rotated basis. qubit_hamiltonian = jordan_wigner(molecular_hamiltonian) qubit_hamiltonian.compress() print('The Jordan-Wigner Hamiltonian in rotated basis follows:\n{}'.format(qubit_hamiltonian)) ``` -------------------------------- ### Prepare Fermi-Hubbard Initial State Source: https://github.com/quantumlib/openfermion/blob/main/docs/fqe/tutorials/fermi_hubbard.ipynb Sets up the initial state for the Fermi-Hubbard experiment by defining parameters and constructing the spin-up and spin-down Hamiltonians. These Hamiltonians represent non-interacting systems with specific onsite potentials. ```python # Parameters used in the Fermi-Hubbard experiment. nsites = 8 l_up = 4 m_up = 4.5 sigma_up = 1 # For convenience. site_index = np.arange(1, nsites + 1) # Creating the spin-up and spin-down Hamiltonians. spin_up_ham = np.diag([-1.] * (nsites - 1), k=1) + np.diag([-1.] * (nsites - 1), k=-1) spin_up_ham += np.diag(-l_up * np.exp(-0.5 * (site_index - m_up)**2) / sigma_up**2) spin_down_ham = np.diag([-1.] * (nsites - 1), k=1) + np.diag([-1.] * (nsites - 1), k=-1) ``` -------------------------------- ### Initialize and Manipulate QubitOperators Source: https://github.com/quantumlib/openfermion/blob/main/docs/tutorials/intro_to_openfermion.ipynb Demonstrates initializing QubitOperator objects and performing basic arithmetic operations. ```python from openfermion.ops import QubitOperator my_first_qubit_operator = QubitOperator('X1 Y2 Z3') print(my_first_qubit_operator) print(my_first_qubit_operator.terms) operator_2 = QubitOperator('X3 Z4', 3.17) operator_2 -= 77. * my_first_qubit_operator print('') print(operator_2) ``` -------------------------------- ### Get Sparse Operator and Ground State Energy Source: https://github.com/quantumlib/openfermion/blob/main/docs/tutorials/intro_to_openfermion.ipynb Obtains the sparse representation of a qubit Hamiltonian and calculates its ground state energy and corresponding state vector. ```python sparse_hamiltonian = get_sparse_operator(qubit_hamiltonian) energy, state = get_ground_state(sparse_hamiltonian) print('Ground state energy before rotation is {} Hartree.\n'.format(energy)) ``` -------------------------------- ### Initialize Hilbert Space Wavefunction Source: https://github.com/quantumlib/openfermion/blob/main/docs/fqe/tutorials/fqe_vs_openfermion_quadratic_hamiltonians.ipynb Sets up the initial Hartree-Fock state in the full Hilbert space. ```python # set up initial full Hilbert space wavefunction wfn = np.zeros((2**(norbs), 1), dtype=np.complex128) wfn[int("".join([str(x) for x in [1] * (norbs//2) + [0] * (norbs//2)]), 2), 0] = 1 # alpha1-alpha2 Hartree-Fock state ``` -------------------------------- ### Build OpenFermion Docker Image Source: https://github.com/quantumlib/openfermion/blob/main/docker/README.md Builds the Docker image for OpenFermion and its plugins. This command should be run from the directory containing the Dockerfile. ```bash docker build -t openfermion_docker . ``` -------------------------------- ### Map Wavefunction to Cirq and Get OPDM Source: https://github.com/quantumlib/openfermion/blob/main/docs/fqe/tutorials/fqe_vs_openfermion_quadratic_hamiltonians.ipynb Convert a FermionQuantumField (FQE) wavefunction to a Cirq wavefunction, reshape it, and then compute the one-particle density matrix (OPDM). This is useful for analyzing quantum states in a Cirq-compatible format. ```python crq_wfn = fqe.to_cirq(fqe_wfn).reshape((-1, 1)) crq_opdm = get_opdm(crq_wfn, 2 * norbs) print(crq_opdm[::2, ::2]) ``` -------------------------------- ### Import necessary libraries Source: https://github.com/quantumlib/openfermion/blob/main/docs/fqe/tutorials/fermi_hubbard.ipynb Imports all required libraries for the simulation, including OpenFermion, FQE, NumPy, Matplotlib, SciPy, and others. ```python import copy from itertools import product import matplotlib.pyplot as plt import numpy as np from scipy import sparse from scipy.linalg import expm import openfermion as of import fqe ``` -------------------------------- ### Import SF Costing Module Source: https://github.com/quantumlib/openfermion/blob/main/src/openfermion/resource_estimates/README.md This Python snippet shows how to import the Single Factorization (SF) costing module from OpenFermion's resource estimates. ```python from openfermion.resource_estimates import sf ``` -------------------------------- ### Initialize Periodic SCF Calculation Source: https://github.com/quantumlib/openfermion/blob/main/src/openfermion/resource_estimates/pbc/notebooks/isdf.ipynb Sets up a diamond carbon cell and performs a KRHF calculation using PySCF. ```python import os import numpy as np from ase.build import bulk from pyscf.pbc import gto, scf from pyscf.pbc.tools import pyscf_ase from pyscf.pbc.mp import KMP2 ase_atom = bulk("C", "diamond", a=3.5) cell = gto.Cell() cell.atom = pyscf_ase.ase_atoms_to_pyscf(ase_atom) cell.a = ase_atom.cell[:].copy() cell.basis = "gth-szv" cell.pseudo = "gth-hf-rev" # Use a smaller value of Ng that would otherwise be suggested (~ 26^3) for # expediency + to allow exact ISDF factorization for comparison. cell.mesh = [11]*3 cell.verbose = 0 cell.build() kmesh = [1, 1, 3] kpts = cell.make_kpts(kmesh) num_kpts = len(kpts) mf = scf.KRHF(cell, kpts) mf.kernel() print("SCF energy: ", mf.e_tot) # converged SCF energy with appropriate Ng = -10.388904514046914, mesh = 28^3 ``` -------------------------------- ### Import Required Libraries Source: https://github.com/quantumlib/openfermion/blob/main/docs/fqe/tutorials/fqe_vs_openfermion_quadratic_hamiltonians.ipynb Imports necessary modules for FQE, OpenFermion, Cirq, and SciPy. ```python from typing import Union from itertools import product import fqe from fqe.hamiltonians.restricted_hamiltonian import RestrictedHamiltonian import numpy as np import cirq import openfermion as of from openfermion.testing.testing_utils import random_quadratic_hamiltonian from openfermion.ops import QuadraticHamiltonian from openfermion.linalg.givens_rotations import givens_decomposition_square from openfermion.circuits.primitives import optimal_givens_decomposition from scipy.sparse import csc_matrix from scipy.linalg import expm from scipy.special import binom import scipy as sp ``` -------------------------------- ### Factorization Methods Source: https://github.com/quantumlib/openfermion/blob/main/src/openfermion/resource_estimates/README.md Demonstrates switching between different factorization schemes (SF, DF, THC) by calling their respective factorize methods. This allows for flexibility in processing molecular integrals. ```python sf.factorize() df.factorize() thc.factorize() ``` -------------------------------- ### Initialize BosonOperator with Coefficient Source: https://github.com/quantumlib/openfermion/blob/main/docs/tutorials/bosonic_operators.ipynb Shows the preferred method for initializing a BosonOperator with a coefficient, and contrasts it with a less efficient method involving multiplication. Also demonstrates initialization of identity and zero operators. ```python good_way_to_initialize = BosonOperator('3^ 1', -1.7) print(good_way_to_initialize) bad_way_to_initialize = -1.7 * BosonOperator('3^ 1') print(bad_way_to_initialize) identity = BosonOperator('') print(identity == BosonOperator.identity()) print(identity) zero_operator = BosonOperator() print(zero_operator == BosonOperator.zero()) print(zero_operator) ``` -------------------------------- ### Import QuadOperator Utilities Source: https://github.com/quantumlib/openfermion/blob/main/docs/tutorials/bosonic_operators.ipynb Import necessary functions for manipulating QuadOperators. ```python from openfermion.utils import hermitian_conjugated, is_hermitian ``` -------------------------------- ### Generate Circuit for Preparing Ground State of Quadratic Hamiltonian Source: https://github.com/quantumlib/openfermion/blob/main/docs/tutorials/intro_to_openfermion.ipynb Obtains a circuit description for preparing the ground state of a quadratic Hamiltonian and the initial state configuration. This circuit can be used on a quantum computer. ```python from openfermion.circuits import gaussian_state_preparation_circuit circuit_description, start_orbitals = gaussian_state_preparation_circuit(quadratic_hamiltonian) for parallel_ops in circuit_description: print(parallel_ops) print('') print(start_orbitals) ``` -------------------------------- ### Construct and Print Phase Estimation Circuit Source: https://github.com/quantumlib/openfermion/blob/main/docs/tutorials/circuits_2_diagonal_coulomb_trotter.ipynb Uses OpenFermion's Trotter simulation to create a controlled unitary and wraps it in a phase estimation circuit. The circuit is then optimized by dropping negligible operations before printing. ```python time = 2 * numpy.pi / bound control = cirq.LineQubit(-1) controlled_unitary = openfermion.simulate_trotter( qubits, hamiltonian, time, n_steps=1, order=1, algorithm=trotter.LINEAR_SWAP_NETWORK, control_qubit=control) circuit = cirq.Circuit( measure_bit_of_phase( qubits, control, controlled_unitary)) # Print the circuit. circuit=cirq.drop_negligible_operations(circuit) print(circuit.to_text_diagram(transpose=True)) ``` -------------------------------- ### Import necessary libraries for OpenFermion and Cirq Source: https://github.com/quantumlib/openfermion/blob/main/docs/tutorials/intro_workshop_exercises.ipynb Imports core libraries including numpy, scipy.sparse, cirq, openfermion, and openfermionpyscf. Ensure these are imported before use. ```python import numpy as np from scipy.sparse import linalg import cirq import openfermion as of import openfermionpyscf as ofpyscf ``` -------------------------------- ### Initialize Hartree-Fock Wavefunction Source: https://github.com/quantumlib/openfermion/blob/main/docs/fqe/tutorials/diagonal_coulomb_evolution.ipynb Sets up a Hartree-Fock wavefunction for a system with 4 orbitals and 2 electrons, with Sz=0. This is a prerequisite for diagonal Coulomb evolution. ```python norbs = 4 tedim = norbs * (norbs + 1) // 2 if (norbs // 2) % 2 == 0: n_elec = norbs // 2 else: n_elec = (norbs // 2) + 1 sz = 0 fqe_wfn = fqe.Wavefunction([[n_elec, sz, norbs]]) fci_data = fqe_wfn.sector((n_elec, sz)) fci_graph = fci_data.get_fcigraph() # This line is not used in the snippet but is present in the source. hf_wf = np.zeros((fci_data.lena(), fci_data.lenb()), dtype=np.complex128) hf_wf[0, 0] = 1 # right most bit is zero orbital. fqe_wfn.set_wfn(strategy='from_data', raw_data={(n_elec, sz): hf_wf}) fqe_wfn.print_wfn() ``` -------------------------------- ### Create and print a QubitOperator Source: https://github.com/quantumlib/openfermion/blob/main/docs/tutorials/intro_workshop_exercises.ipynb Demonstrates the creation of a QubitOperator using tuples for Pauli operators (X, Y, Z) and their corresponding qubit indices, and also using string notation. The print output shows the combined operator. ```python op = of.QubitOperator(((1, "X"), (2, "Y"), (3, "Z"))) op += of.QubitOperator("X3 Z4", 3.0) print(op) ``` -------------------------------- ### Build Quantum Circuit with Basis Transformations and Rotations Source: https://github.com/quantumlib/openfermion/blob/main/docs/tutorials/circuits_1_basis_change.ipynb This code constructs a quantum circuit by first applying an inverse Bogoliubov transform, followed by diagonal RZ phase rotations based on eigenvalues, and finally applying the forward Bogoliubov transform. Requires 'openfermion', 'cirq', 'n_qubits', 'basis_transformation_matrix', 'eigenvalues', and 'simulation_time'. ```python import openfermion import cirq # Initialize the qubit register. qubits = cirq.LineQubit.range(n_qubits) # Start circuit with the inverse basis rotation, print out this step. inverse_basis_rotation = cirq.inverse(openfermion.bogoliubov_transform(qubits, basis_transformation_matrix)) circuit = cirq.Circuit(inverse_basis_rotation) print(circuit) # Add diagonal phase rotations to circuit. for k, eigenvalue in enumerate(eigenvalues): phase = -eigenvalue * simulation_time circuit.append(cirq.rz(rads=phase).on(qubits[k])) # Finally, restore basis. basis_rotation = openfermion.bogoliubov_transform(qubits, basis_transformation_matrix) circuit.append(basis_rotation) ``` -------------------------------- ### Import BosonOperator Utilities Source: https://github.com/quantumlib/openfermion/blob/main/docs/tutorials/bosonic_operators.ipynb Import necessary functions for manipulating BosonOperators. ```python from openfermion.utils import hermitian_conjugated, is_hermitian from openfermion.transforms import normal_ordered ``` -------------------------------- ### Initialize FQE Wavefunction Directly Source: https://github.com/quantumlib/openfermion/blob/main/docs/fqe/guide/introduction.ipynb Initialize an FQE wavefunction by directly calling the constructor with initial coefficients. The 'broken' parameter can be set to None. ```python wfn_fqe = fqe.Wavefunction([[2, -2, 4]], broken=None) ``` -------------------------------- ### Build LiH wavefunction and Hamiltonian Source: https://github.com/quantumlib/openfermion/blob/main/docs/fqe/tutorials/hamiltonian_time_evolution_and_expectation_estimation.ipynb Constructs the LiH Hamiltonian and initializes the wavefunction from data. ```python h1e, h2e, wfn = build_lih_data.build_lih_data('energy') lih_hamiltonian = fqe.get_restricted_hamiltonian(([h1e, h2e])) lihwfn = fqe.Wavefunction([[4, 0, 6]]) lihwfn.set_wfn(strategy='from_data', raw_data={(4, 0): wfn}) if Print: lihwfn.print_wfn() ``` -------------------------------- ### Import sparse bosonic operator utilities Source: https://github.com/quantumlib/openfermion/blob/main/docs/tutorials/bosonic_operators.ipynb Import the function required to represent bosonic operators as sparse matrices. ```python from openfermion.linalg import boson_operator_sparse ``` -------------------------------- ### Initialize and Configure FQE Wavefunction Source: https://github.com/quantumlib/openfermion/blob/main/docs/fqe/tutorials/fqe_vs_openfermion_quadratic_hamiltonians.ipynb Initializes an FQE wavefunction and sets the Hartree-Fock state from raw data. ```python fqe_wfn = fqe.Wavefunction([[norbs // 2, norbs//2, norbs]]) hf_wf = np.zeros((int(binom(norbs, norbs // 2)), 1), dtype=np.complex128) hf_wf[0, 0] = 1 # right most bit is zero orbital. 2-alpha electron HF is 0011. This is the first element of our particle conserved Hilbert space fqe_wfn.set_wfn(strategy='from_data', raw_data={(norbs//2, norbs//2): hf_wf}) fqe_wfn.print_wfn() # OpenFermion indexes from the left as zero. The RHF state is 1100 wfn[int("".join([str(x) for x in [1] * (norbs//2) + [0] * (norbs//2)]), 2), 0] = 1 print("\nHF-Vector-OpenFermion ", bin(int("".join([str(x) for x in [1] * (norbs//2) + [0] * (norbs//2)]), 2))) ``` -------------------------------- ### Create and Manipulate QuadOperator Source: https://github.com/quantumlib/openfermion/blob/main/docs/tutorials/bosonic_operators.ipynb Demonstrates the creation and manipulation of QuadOperator objects. ```python from openfermion.ops import QuadOperator H = QuadOperator('q0 p1 q3') print(H) print(H.terms) H2 = QuadOperator('q3 p4', 3.17) H2 -= 77. * H print('') print(H2) ``` -------------------------------- ### License Header Source: https://github.com/quantumlib/openfermion/blob/main/docs/fqe/tutorials/fqe_vs_openfermion_quadratic_hamiltonians.ipynb Apache License 2.0 header for the project. ```python #@title Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # https://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. ``` -------------------------------- ### Create BinaryCode Object Source: https://github.com/quantumlib/openfermion/blob/main/docs/tutorials/binary_code_transforms.ipynb Shows how to initialize a BinaryCode object, which bundles an encoder matrix and a decoder (list of BinaryPolynomials). This class represents a binary code for encoding and decoding. ```python from openfermion.ops import BinaryCode code_1 = BinaryCode([[1, 0, 0], [0, 1, 0]], ['w0', 'w1', 'w0 + w1 + 1' ]) print(code_1) print('number of qubits: ', code_1.n_qubits, ' number of Fermion modes: ', code_1.n_modes ) print('encoding matrix: \n', code_1.encoder.toarray()) print('decoder: ', code_1.decoder) ``` -------------------------------- ### Import OpenFermion-FQE and NumPy Source: https://github.com/quantumlib/openfermion/blob/main/docs/fqe/guide/introduction.ipynb Imports the necessary fqe library and the numpy library for numerical operations. These imports are standard for using OpenFermion-FQE. ```python import fqe import numpy as np ``` -------------------------------- ### Initialize BosonOperator Source: https://github.com/quantumlib/openfermion/blob/main/docs/tutorials/bosonic_operators.ipynb Demonstrates two ways to initialize a BosonOperator: using a tuple of tuples for terms and using a string representation. Note that the printed order may differ due to commutativity. ```python from openfermion.ops import BosonOperator my_term = BosonOperator(((3, 1), (5, 0), (4, 1), (1, 0))) print(my_term) my_term = BosonOperator('3^ 5 4^ 1') print(my_term) ``` -------------------------------- ### Import OpenFermion Library Source: https://github.com/quantumlib/openfermion/blob/main/docs/tutorials/circuits_2_diagonal_coulomb_trotter.ipynb Imports the OpenFermion library for use in subsequent operations. ```python import openfermion ``` -------------------------------- ### Construct Circuit with LINEAR_SWAP_NETWORK Trotter Step Source: https://github.com/quantumlib/openfermion/blob/main/docs/tutorials/circuits_2_diagonal_coulomb_trotter.ipynb Constructs a quantum circuit for Hamiltonian simulation using the LINEAR_SWAP_NETWORK algorithm. Requires specifying time, number of steps, and order. Uses cirq.InsertStrategy.EARLIEST for compact output. ```python from openfermion.circuits import trotter # Set algorithm parameters. time = 1.0 n_steps = 1 order = 1 # Construct circuit swap_network_trotter_step = cirq.Circuit( openfermion.simulate_trotter( qubits, hamiltonian, time, n_steps, order, algorithm=trotter.LINEAR_SWAP_NETWORK), strategy=cirq.InsertStrategy.EARLIEST) # Print circuit. swap_network_trotter_step=cirq.drop_negligible_operations(swap_network_trotter_step) print(swap_network_trotter_step.to_text_diagram(transpose=True)) ``` -------------------------------- ### Use FermionOperator Utility Methods Source: https://github.com/quantumlib/openfermion/blob/main/docs/tutorials/intro_to_openfermion.ipynb Illustrates common utility functions like Hermitian conjugation, normal ordering, and commutator calculation. ```python from openfermion.utils import commutator, count_qubits, hermitian_conjugated from openfermion.transforms import normal_ordered # Get the Hermitian conjugate of a FermionOperator, count its qubit, check if it is normal-ordered. term_1 = FermionOperator('4^ 3 3^', 1. + 2.j) print(hermitian_conjugated(term_1)) print(term_1.is_normal_ordered()) print(count_qubits(term_1)) # Normal order the term. term_2 = normal_ordered(term_1) print('') print(term_2) print(term_2.is_normal_ordered()) # Compute a commutator of the terms. print('') print(commutator(term_1, term_2)) ``` -------------------------------- ### Create and Evaluate BinaryPolynomial Source: https://github.com/quantumlib/openfermion/blob/main/docs/tutorials/binary_code_transforms.ipynb Demonstrates the creation of BinaryPolynomial objects from strings, symbolic operations, and evaluation. Use this to define non-linear binary functions. ```python from openfermion.ops import BinaryPolynomial binary_1 = BinaryPolynomial('w0 w1 + w1 + 1') print("These three expressions are equivalent: \n", binary_1) print(BinaryPolynomial('w0') * BinaryPolynomial('w1 + 1') + BinaryPolynomial('1')) print(BinaryPolynomial([(1, 0), (1, ), ('one', )])) print('The native data type structure can be seen here:') print(binary_1.terms) print('We can always evaluate the expression for instance by the vector (w0, w1, w2) = (1, 0, 0):', binary_1.evaluate('100')) ``` -------------------------------- ### Configure molecule parameters for energy surface calculation Source: https://github.com/quantumlib/openfermion/blob/main/docs/tutorials/intro_to_openfermion.ipynb Sets up basic parameters for a series of calculations, such as bond length intervals, to be used for generating an energy surface. ```python # Set molecule parameters. basis = 'sto-3g' multiplicity = 1 bond_length_interval = 0.1 n_points = 25 ``` -------------------------------- ### Simulate Hamiltonian with Swap Network and Split-Operator Methods Source: https://github.com/quantumlib/openfermion/blob/main/docs/tutorials/circuits_2_diagonal_coulomb_trotter.ipynb Compares the energy of a final state vector obtained using the swap network method versus the split-operator method for Trotterized time evolution. Requires a pre-defined Hamiltonian, qubits, occupied orbitals, and state preparation circuit. ```python simulator = cirq.Simulator() hamiltonian_sparse = openfermion.get_sparse_operator(hamiltonian) initial_state = sum(2 ** (n_qubits - 1 - i) for i in occupied_orbitals) circuit = state_preparation_circuit + swap_network_trotter_step result = simulator.simulate(circuit, initial_state=initial_state) final_state = result.final_state_vector print('Energy of state obtained with swap network method: {}'.format( openfermion.expectation(hamiltonian_sparse, final_state).real)) circuit = state_preparation_circuit + split_operator_trotter_step result = simulator.simulate(circuit, initial_state=initial_state) final_state = result.final_state_vector print('Energy of state obtained with split-operator method: {}'.format( openfermion.expectation(hamiltonian_sparse, final_state).real)) ``` -------------------------------- ### Print Wavefunction in String Format Source: https://github.com/quantumlib/openfermion/blob/main/docs/fqe/guide/introduction.ipynb Print the FQE wavefunction using string formatting, showing alpha-beta strings and their corresponding coefficients. ```python print('String formatting') fqe_wfn.print_wfn(fmt='str') ``` -------------------------------- ### Initialize Wavefunction to Lowest Energy States Source: https://github.com/quantumlib/openfermion/blob/main/docs/fqe/tutorials/fermi_hubbard.ipynb Initializes a wavefunction to occupy the two lowest energy states using the Hartree-Fock strategy. Requires prior definition of nsites. ```python init_wfn = fqe.Wavefunction([[nsites // 2, 0, nsites]]) init_wfn.set_wfn(strategy='hartree-fock') init_wfn.print_wfn() ``` -------------------------------- ### Display Quantum Circuit Diagram Source: https://github.com/quantumlib/openfermion/blob/main/docs/tutorials/intro_workshop_exercises.ipynb Prints a text-based diagram of a quantum circuit. Useful for visualizing circuit structure. ```python print(circuit.to_text_diagram(transpose=True)) ``` -------------------------------- ### Compare Wavefunction RDMs Source: https://github.com/quantumlib/openfermion/blob/main/docs/fqe/tutorials/fqe_vs_openfermion_quadratic_hamiltonians.ipynb Validates the state representation by comparing RDMs across FQE, OpenFermion, and Cirq. ```python fqe_opdm = fqe_wfn.rdm('i^ j') # get the FQE-opdm # get the exactly evolved opdm initial_opdm = np.diag([1] * (norbs//2) + [0] * (norbs//2)) u = expm(1j * ikappa.n_body_tensors[1, 0] * time) final_opdm = u @ initial_opdm @ u.conj().T print(final_opdm) print() # contract the wavefunction opdm test_opdm = get_opdm(final_wfn, norbs) print(test_opdm) assert np.allclose(test_opdm.real, final_opdm.real) assert np.allclose(test_opdm.imag, final_opdm.imag) assert np.allclose(final_opdm, fqe_opdm) cirq_wfn = fqe.to_cirq(fqe_wfn).reshape((-1, 1)) cfqe_opdm = get_opdm(cirq_wfn, 2 * norbs) print() print(cfqe_opdm[::2, ::2]) assert np.allclose(final_opdm, cfqe_opdm[::2, ::2]) # cirq evolution qubits = cirq.LineQubit.range(norbs) prep = cirq.Moment([cirq.X.on(qubits[0]), cirq.X.on(qubits[1])]) rotation = cirq.Circuit(optimal_givens_decomposition(qubits, u.conj().copy())) circuit = prep + rotation final_state = circuit.final_state_vector().reshape((-1, 1)) cirq_opdm = get_opdm(final_state, norbs) print() print(cirq_opdm) assert np.allclose(final_opdm, cirq_opdm) ``` -------------------------------- ### Stabilize, Localize, and Select Active Space with PySCF Source: https://github.com/quantumlib/openfermion/blob/main/src/openfermion/resource_estimates/README.md This Python code snippet shows how to use OpenFermion's resource estimate utilities to ensure wave function stability, localize orbitals using Pipek-Mezey localization, and automatically select an active space using the AVAS method. It takes a PySCF mean-field object as input and returns a modified mean-field object. ```python from openfermion.resource_estimates.molecule import stability, localize, avas_active_space # make sure wave function is stable before we proceed mf = stability(mf) # localize before automatically selecting active space with AVAS mf = localize(mf, loc_type='pm') # default is loc_type ='pm' (Pipek-Mezey) # you can use larger basis for `minao` to select non-valence...here select O 3s and 3p as well mol, mf = avas_active_space(mf, ao_list=['H 1s', 'O 2s', 'O 2p', 'O 3s', 'O 3p'], minao='ccpvtz') ``` -------------------------------- ### Import LiH data module Source: https://github.com/quantumlib/openfermion/blob/main/docs/fqe/tutorials/hamiltonian_time_evolution_and_expectation_estimation.ipynb Imports the locally downloaded LiH data builder. ```python import build_lih_data ``` -------------------------------- ### Simulate Time Evolution via Matrix Exponentiation Source: https://github.com/quantumlib/openfermion/blob/main/docs/tutorials/intro_workshop_exercises.ipynb Performs time evolution on a random initial state using direct matrix exponentiation. ```python # Create a random initial state initial_state = of.haar_random_vector(2**n_qubits) # Set evolution time time = 1.0 # Apply exp(-i H t) to the state final_state = linalg.expm_multiply(-1j * quad_ham_sparse * time, initial_state) ``` -------------------------------- ### Compare Jordan-Wigner and Bravyi-Kitaev Transformations Source: https://context7.com/quantumlib/openfermion/llms.txt Demonstrates the Bravyi-Kitaev transform, which often results in lower average Pauli weight compared to Jordan-Wigner. ```python from openfermion import FermionOperator, bravyi_kitaev, jordan_wigner # Create a fermionic operator fermion_op = FermionOperator('0^ 3', 1.0) fermion_op += FermionOperator('3^ 0', 1.0) fermion_op += FermionOperator('1^ 2', 0.5) fermion_op += FermionOperator('2^ 1', 0.5) # Compare Jordan-Wigner and Bravyi-Kitaev transformations jw_result = jordan_wigner(fermion_op) bk_result = bravyi_kitaev(fermion_op, n_qubits=4) print("Jordan-Wigner result:") print(jw_result) print("\nBravyi-Kitaev result:") print(bk_result) # Bravyi-Kitaev generally produces operators with lower average Pauli weight def average_weight(qubit_op): weights = [len(term) for term in qubit_op.terms.keys()] return sum(weights) / len(weights) if weights else 0 print(f"\nJW average Pauli weight: {average_weight(jw_result):.2f}") print(f"BK average Pauli weight: {average_weight(bk_result):.2f}") ```