Secure your code as it's written. Use Snyk Code to scan source code in minutes - no build needed - and fix issues immediately.
def random_qubit_operator(n_qubits=16,
max_num_terms=16,
max_many_body_order=16,
seed=None):
prng = numpy.random.RandomState(seed)
op = QubitOperator()
num_terms = prng.randint(1, max_num_terms+1)
for _ in range(num_terms):
many_body_order = prng.randint(max_many_body_order+1)
term = []
for _ in range(many_body_order):
index = prng.randint(n_qubits)
action = prng.choice(('X', 'Y', 'Z'))
term.append((index, action))
coefficient = prng.randn()
op += QubitOperator(term, coefficient)
return op
fixed_op = qubit_pauli[1]
break
else:
# Finds Pauli of the fixed qubit.
for qubit_pauli in selected_stab:
if qubit_pauli[0] == fixed_positions[i]:
fixed_op = qubit_pauli[1]
break
if fixed_op in ['X', 'Z']:
other_op = 'Y'
else:
other_op = 'X'
new_terms = QubitOperator()
for qubit_pauli in terms:
new_terms += fix_single_term(qubit_pauli, fixed_positions[i],
fixed_op,
other_op, stabilizer_list[0])
updated_stabilizers = []
for update_stab in stabilizer_list[1:]:
updated_stabilizers += [fix_single_term(update_stab,
fixed_positions[i],
fixed_op,
other_op,
stabilizer_list[0])]
# Update terms and stabilizer list.
terms = new_terms
stabilizer_list = updated_stabilizers
# 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
else:
with open(file_path, 'rb') as f:
data = marshal.load(f)
operator_type = data[0]
operator_terms = data[1]
if operator_type == 'FermionOperator':
operator = FermionOperator()
for term in operator_terms:
operator += FermionOperator(term, operator_terms[term])
elif operator_type == 'BosonOperator':
operator = BosonOperator()
for term in operator_terms:
operator += BosonOperator(term, operator_terms[term])
elif operator_type == 'QubitOperator':
operator = QubitOperator()
for term in operator_terms:
operator += QubitOperator(term, operator_terms[term])
elif operator_type == 'QuadOperator':
operator = QuadOperator()
for term in operator_terms:
operator += QuadOperator(term, operator_terms[term])
else:
raise TypeError('Operator of invalid type.')
return operator
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
def jordan_wigner_fermion_operator(operator):
transformed_operator = QubitOperator()
for term in operator.terms:
# Initialize identity matrix.
transformed_term = QubitOperator((), operator.terms[term])
# Loop through operators, transform and multiply.
for ladder_operator in term:
z_factors = tuple((index, 'Z') for
index in range(ladder_operator[0]))
pauli_x_component = QubitOperator(
z_factors + ((ladder_operator[0], 'X'),), 0.5)
if ladder_operator[1]:
pauli_y_component = QubitOperator(
z_factors + ((ladder_operator[0], 'Y'),), -0.5j)
else:
pauli_y_component = QubitOperator(
z_factors + ((ladder_operator[0], 'Y'),), 0.5j)
transformed_term *= pauli_x_component + pauli_y_component
transformed_operator += transformed_term
return transformed_operator
fixed_op, other_op,
stabilizer_list[0])]
term_list = new_list
stabilizer_list = updated_stabilizers
check_stabilizer_linearity(stabilizer_list,
msg='Linearly dependent stabilizers.')
check_commuting_stabilizers(stabilizer_list,
msg='Stabilizers anti-commute.')
new_terms = QubitOperator()
for x, ent in enumerate(term_list):
new_terms += ent * terms.terms[term_list_duplicate[x]]
for x, ent in enumerate(term_list):
term_list_duplicate[x] = (
QubitOperator(term_list_duplicate[x]) /
list(ent.terms.items())[0][1])
term_list[x] = list(ent.terms)[0]
even_newer_terms = QubitOperator()
for pauli_string, coefficient in new_terms.terms.items():
even_newer_terms += coefficient * _lookup_term(
pauli_string,
term_list_duplicate,
term_list)
return even_newer_terms, fixed_positions
if not isinstance(code, BinaryCode):
raise TypeError('code provided must be a BinaryCode'
'received {}'.format(type(code)))
new_hamiltonian = QubitOperator()
parity_list = make_parity_list(code)
# for each term in hamiltonian
for term, term_coefficient in hamiltonian.terms.items():
""" the updated parity and occupation account for sign changes due
changed occupations mid-way in the term """
updated_parity = 0 # parity sign exponent
parity_term = BinaryPolynomial()
changed_occupation_vector = [0] * code.n_modes
transformed_term = QubitOperator(())
# keep track of indices appeared before
fermionic_indices = numpy.array([])
# for each multiplier
for op_idx, op_tuple in enumerate(reversed(term)):
# get count exponent, parity exponent addition
fermionic_indices = numpy.append(fermionic_indices, op_tuple[0])
count = numpy.count_nonzero(
fermionic_indices[:op_idx] == op_tuple[0])
updated_parity += numpy.count_nonzero(
fermionic_indices[:op_idx] < op_tuple[0])
# update term
extracted = extractor(code.decoder[op_tuple[0]])
extracted *= (((-1) ** count) * ((-1) ** (op_tuple[1])) * 0.5)
if not isinstance(operator, QubitOperator):
raise TypeError('Can only split QubitOperator into tensor product'
' basis sets. {} is not supported.'.format(
type(operator).__name__))
sub_operators = {}
r = RandomState(seed)
for term, coefficient in operator.terms.items():
bases = list(sub_operators.keys())
r.shuffle(bases)
basis = _find_compatible_basis(term, bases)
if basis is None:
sub_operators[term] = QubitOperator(term, coefficient)
else:
sub_operator = sub_operators.pop(basis)
sub_operator += QubitOperator(term, coefficient)
additions = tuple(op for op in term if op not in basis)
basis = tuple(sorted(basis + additions, key=lambda factor: factor[0]))
sub_operators[basis] = sub_operator
return sub_operators
def jordan_wigner_diagonal_coulomb_hamiltonian(operator):
n_qubits = count_qubits(operator)
qubit_operator = QubitOperator((), operator.constant)
# Transform diagonal one-body terms
for p in range(n_qubits):
coefficient = operator.one_body[p, p] + operator.two_body[p, p]
qubit_operator += QubitOperator(((p, 'Z'),), -.5 * coefficient)
qubit_operator += QubitOperator((), .5 * coefficient)
# Transform other one-body terms and two-body terms
for p, q in itertools.combinations(range(n_qubits), 2):
# One-body
real_part = numpy.real(operator.one_body[p, q])
imag_part = numpy.imag(operator.one_body[p, q])
parity_string = [(i, 'Z') for i in range(p + 1, q)]
qubit_operator += QubitOperator(
[(p, 'X')] + parity_string + [(q, 'X')], .5 * real_part)
qubit_operator += QubitOperator(