Secure your code as it's written. Use Snyk Code to scan source code in minutes - no build needed - and fix issues immediately.
def _generate_qubits(self) -> Sequence[cirq.Qid]:
"""Produce qubits that can be used by the ansatz circuit."""
return cirq.LineQubit.range(openfermion.count_qubits(self.hamiltonian))
def _generate_qubits(self) -> Sequence[cirq.Qid]:
"""Produce qubits that can be used by the ansatz circuit."""
return cirq.LineQubit.range(openfermion.count_qubits(self.hamiltonian))
def _generate_qubits(self) -> Sequence[cirq.Qid]:
"""Produce qubits that can be used by the ansatz circuit."""
return cirq.LineQubit.range(openfermion.count_qubits(self.hamiltonian))
to calculate the bitmask for.
n_qubits (int): The number of qubits (modes) in the system. If not
specified, defaults to the maximum of any term in
fermion_term_list.
Returns:
An n_qubits x len(fermion_term_list) boolean numpy array of whether
each term acts on the given mode index.
Raises:
ValueError: if n_qubits is too small for the given terms.
"""
if n_qubits is None:
n_qubits = 0
for term in fermion_term_list:
n_qubits = max(n_qubits, count_qubits(term))
mask = numpy.zeros((n_qubits, len(fermion_term_list)), dtype=bool)
for term_number, term in enumerate(fermion_term_list):
actions = term.terms
for action in actions:
for single_operator in action:
mode = single_operator[0]
try:
mask[mode][term_number] = True
except IndexError:
raise ValueError('Bad n_qubits: must be greater than '
'highest mode in any FermionOperator.')
return mask
error_operator: The second-order Trotter error operator.
Notes:
Follows Eq 9 of Poulin et al., arXiv:1406.4920, applied to the
Trotter step detailed in Kivlichan et al., arxiv:1711.04789.
"""
single_terms = numpy.array(
simulation_ordered_grouped_low_depth_terms_with_info(
hamiltonian,
external_potential_at_end=external_potential_at_end)[0])
# Cache the halved terms for use in the second commutator.
halved_single_terms = single_terms / 2.0
term_mode_mask = bit_mask_of_modes_acted_on_by_fermionic_terms(
single_terms, count_qubits(hamiltonian))
error_operator = FermionOperator.zero()
for beta, term_beta in enumerate(single_terms):
modes_acted_on_by_term_beta = set()
for beta_action in term_beta.terms:
modes_acted_on_by_term_beta.update(
set(operator[0] for operator in beta_action))
beta_mode_mask = numpy.logical_or.reduce(
[term_mode_mask[mode] for mode in modes_acted_on_by_term_beta])
# alpha_prime indices that could have a nonzero commutator, i.e.
# there's overlap between the modes the corresponding terms act on.
valid_alpha_primes = numpy.where(beta_mode_mask)[0]
with the kinetic energy T first (order='T+V') or with
the potential energy V first (order='V+T').
Returns:
error_operator: The second-order Trotter error operator.
Notes:
The second-order split-operator Trotter error is calculated from the
double commutator [T, [V, T]] + [V, [V, T]] / 2 when T is simulated
before V (i.e. exp(-iTt/2) exp(-iVt) exp(-iTt/2)), and from the
double commutator [V, [T, V]] + [T, [T, V]] / 2 when V is simulated
before T, following Equation 9 of "The Trotter Step Size Required for
Accurate Quantum Simulation of Quantum Chemistry" by Poulin et al.
The Trotter error operator is then obtained by dividing by 12.
"""
n_qubits = count_qubits(hamiltonian)
potential_terms, kinetic_terms = (
diagonal_coulomb_potential_and_kinetic_terms_as_arrays(hamiltonian))
# Cache halved potential and kinetic terms for the second commutator.
halved_potential_terms = potential_terms / 2.0
halved_kinetic_terms = kinetic_terms / 2.0
# Assign the outer term of the second commutator based on the ordering.
outer_potential_terms = (halved_potential_terms if order == 'T+V' else
potential_terms)
outer_kinetic_terms = (halved_kinetic_terms if order == 'V+T' else
kinetic_terms)
potential_mask = bit_mask_of_modes_acted_on_by_fermionic_terms(
potential_terms, n_qubits)