Secure your code as it's written. Use Snyk Code to scan source code in minutes - no build needed - and fix issues immediately.
TypeError: Invalid number of qubits specified.
TypeError: Pauli operators must be X, Y or Z.
"""
if not isinstance(qubit_operator, QubitOperator):
raise TypeError('Input must be a QubitOperator.')
if n_qubits is None:
n_qubits = count_qubits(qubit_operator)
if n_qubits < count_qubits(qubit_operator):
raise ValueError('Invalid number of qubits specified.')
# Loop through terms.
transformed_operator = FermionOperator()
for term in qubit_operator.terms:
transformed_term = FermionOperator(())
if term:
working_term = QubitOperator(term)
pauli_operator = term[-1]
while pauli_operator is not None:
# Handle Pauli Z.
if pauli_operator[1] == 'Z':
transformed_pauli = FermionOperator(
()) + number_operator(n_qubits, pauli_operator[0], -2.)
# Handle Pauli X and Y.
else:
raising_term = FermionOperator(((pauli_operator[0], 1),))
lowering_term = FermionOperator(((pauli_operator[0], 0),))
if pauli_operator[1] == 'Y':
raising_term *= 1.j
lowering_term *= -1.j
c = q
# Get operators.
parity_string = tuple((z, 'Z') for z in range(a + 1, b))
pauli_z = QubitOperator(((c, 'Z'),))
for operator in ['X', 'Y']:
operators = ((a, operator),) + parity_string + ((b, operator),)
# Get coefficient.
if (p == s) or (q == r):
coefficient = .25
else:
coefficient = -.25
# Add term.
hopping_term = QubitOperator(operators, coefficient)
qubit_operator -= pauli_z * hopping_term
qubit_operator += hopping_term
# Handle case of two unique indices.
elif len(set([p, q, r, s])) == 2:
# Get coefficient.
if p == s:
coefficient = -.25
else:
coefficient = .25
# Add terms.
qubit_operator -= QubitOperator((), coefficient)
qubit_operator += QubitOperator(((p, 'Z'),), coefficient)
qubit_operator += QubitOperator(((q, 'Z'),), coefficient)
Args:
terms: a list of QubitTerms in the Hamiltonian to be simulated.
series_order: the order at which to compute the BCH expansion.
Only the second order formula is currently implemented
(corresponding to Equation 9 of the paper).
Returns:
The difference between the true and effective generators of time
evolution for a single Trotter step.
Notes: follows Equation 9 of Poulin et al.'s work in "The Trotter Step
Size Required for Accurate Quantum Simulation of Quantum Chemistry".
"""
if series_order != 2:
raise NotImplementedError
error_operator = QubitOperator()
for beta in range(len(terms)):
for alpha in range(beta + 1):
for alpha_prime in range(beta):
if not trivially_double_commutes(terms[alpha], terms[beta],
terms[alpha_prime]):
double_com = commutator(terms[alpha],
commutator(terms[beta],
terms[alpha_prime]))
error_operator += double_com
if alpha == beta:
error_operator -= double_com / 2.0
return error_operator / 12.0
# The C(j) set.
ancestor_children = [node.index for node in
fenwick_tree.get_remainder_set(index)]
# Switch between lowering/raising operators.
d_coefficient = -.5j if ladder_operator[1] else .5j
# The fermion lowering operator is given by
# a = (c+id)/2 where c, d are the majoranas.
d_majorana_component = QubitOperator(
(((ladder_operator[0], 'Y'),) +
tuple((index, 'Z') for index in ancestor_children) +
tuple((index, 'X') for index in ancestors)),
d_coefficient)
c_majorana_component = QubitOperator(
(((ladder_operator[0], 'X'),) +
tuple((index, 'Z') for index in parity_set) +
tuple((index, 'X') for index in ancestors)),
0.5)
return c_majorana_component + d_majorana_component
def jordan_wigner_two_body(p, q, r, s):
"""Map the term a^\dagger_p a^\dagger_q a_r a_s + h.c. to QubitOperator.
Note that the diagonal terms are divided by a factor of two
because they are equal to their own Hermitian conjugate.
"""
# Initialize qubit operator.
qubit_operator = QubitOperator()
# Return zero terms.
if (p == q) or (r == s):
return qubit_operator
# Handle case of four unique indices.
elif len(set([p, q, r, s])) == 4:
# Loop through different operators which act on each tensor factor.
for operator_p, operator_q, operator_r in itertools.product(
['X', 'Y'], repeat=3):
if [operator_p, operator_q, operator_r].count('X') % 2:
operator_s = 'X'
else:
operator_s = 'Y'
Note that the diagonal terms are divided by a factor of 2
because they are equal to their own Hermitian conjugate.
"""
# Handle off-diagonal terms.
qubit_operator = QubitOperator()
if p != q:
a, b = sorted([p, q])
parity_string = tuple((z, 'Z') for z in range(a + 1, b))
for operator in ['X', 'Y']:
operators = ((a, operator),) + parity_string + ((b, operator),)
qubit_operator += QubitOperator(operators, .5)
# Handle diagonal terms.
else:
qubit_operator += QubitOperator((), .5)
qubit_operator += QubitOperator(((p, 'Z'),), -.5)
return qubit_operator
Args:
edge_matrix_indices(numpy array(square and symmetric):
i (int): index for specifying the edge operator B.
Returns:
An instance of QubitOperator
"""
B_i = QubitOperator()
qubit_position_matrix = numpy.array(numpy.where(edge_matrix_indices == i))
qubit_position = qubit_position_matrix[1][:]
qubit_position = numpy.sort(qubit_position)
operator = tuple()
for d1 in qubit_position:
operator += ((int(d1), 'Z'),)
B_i += QubitOperator(operator, 1)
return B_i
The fermionic swap is applied to the qubits corresponding to mode
and mode + 1, after the Jordan-Wigner transformation.
Args:
register (projectq.Qureg): The register of qubits to act on.
mode (int): The lower of the two modes to apply the phase to.
Notes:
fswap_adjacent is a slightly optimized version of fswap for a
more restricted case. Because the modes are adjacent, the
Jordan-Wigner transform doesn't need to be computed.
"""
operator = (QubitOperator(((mode, 'Z'),)) +
QubitOperator(((mode + 1, 'Z'),)) +
QubitOperator(((mode, 'X'), (mode + 1, 'X'))) +
QubitOperator(((mode, 'Y'), (mode + 1, 'Y'))))
TimeEvolution(numpy.pi / 4., operator) | register
Note that the diagonal terms are divided by a factor of 2
because they are equal to their own Hermitian conjugate.
"""
# Handle off-diagonal terms.
qubit_operator = QubitOperator()
if p != q:
a, b = sorted([p, q])
parity_string = tuple((z, 'Z') for z in range(a + 1, b))
for operator in ['X', 'Y']:
operators = ((a, operator),) + parity_string + ((b, operator),)
qubit_operator += QubitOperator(operators, .5)
# Handle diagonal terms.
else:
qubit_operator += QubitOperator((), .5)
qubit_operator += QubitOperator(((p, 'Z'),), -.5)
return qubit_operator