Skip to content

Commit

Permalink
Draft code assigning shots to each H term
Browse files Browse the repository at this point in the history
  • Loading branch information
chmwzc committed Dec 12, 2023
1 parent c10e46a commit 6b45d25
Showing 1 changed file with 30 additions and 1 deletion.
31 changes: 30 additions & 1 deletion src/qibochem/measurement/expectation.py
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,8 @@ def expectation(
hamiltonian: SymbolicHamiltonian,
from_samples: bool = False,
n_shots: int = 1000,
n_shots_per_pauli_term: bool = True,
shot_distribution: str = "uniform",
) -> float:
"""
Calculate expectation value of some Hamiltonian using either the state vector or sample measurements from running a
Expand All @@ -57,12 +59,39 @@ def expectation(
from_samples (Boolean): Whether the expectation value calculation uses samples or the simulated
state vector. Default: ``False``; Results are from a state vector simulation
n_shots (int): Number of times the circuit is run if ``from_samples=True``. Default: ``1000``
n_shots_per_pauli_term (Boolean): Whether or not ``n_shots`` is used for each Pauli term in the Hamiltonian, or for
*all* the terms in the Hamiltonian. Default: ``True``; ``n_shots`` are used to get the expectation value for each
term in the Hamiltonian.
shot_distribution: If ``n_shots_per_pauli_term`` is ``False``, determines how to distribute n_shots amongst each term
in the Hamiltonian. Default: ``uniform``; ``n_shots`` is distributed evenly amongst each term. Available options: ???
Returns:
Hamiltonian expectation value (float)
"""
if from_samples:
total = sum(pauli_term_sample_expectation(circuit, term, n_shots) for term in hamiltonian.terms)
# n_shots is used to get the expectation value of each individual Pauli term
if n_shots_per_pauli_term:
total = sum(pauli_term_sample_expectation(circuit, term, n_shots) for term in hamiltonian.terms)
else:
# Determine how to allocate n_shots first
if shot_distribution == "uniform":
# Split evenly amongst all the terms in the Hamiltonian
shot_allocation = np.array([n_shots // n_terms for _ in range(n_terms)])

# Remaining shots distributed evenly amongst the terms that already have shots allocated to them
while True:
remaining_shots = n_shots - sum(shot_allocation)
if not remaining_shots:
break
shot_allocation += np.array(
[1 if (_i < remaining_shots and shots) else 0 for _i, shots in enumerate(shot_allocation)]
)

# Then sum up the individual Pauli terms in the Hamiltonian to get the overall expectation value
total = sum(
pauli_term_sample_expectation(circuit, term, shots)
for shots, term in zip(shot_allocation, hamiltonian.terms)
)
# Add the constant term if present. Note: Energies (in chemistry) are all real values
total += hamiltonian.constant.real
return total
Expand Down

0 comments on commit 6b45d25

Please sign in to comment.