def symbolic_dtc_circuit_list(
qubits: Sequence[cirq.Qid], cycles: int
) -> List[cirq.Circuit]:
"""Create a list of symbolically parameterized dtc circuits, with increasing cycles
Args:
qubits: ordered sequence of available qubits, which are connected in a chain
cycles: maximum number of cycles to generate up to
Returns:
list of circuits with `0, 1, 2, ... cycles` many cycles
"""
num_qubits = len(qubits)
# Symbol for g
g_value = sp.Symbol("g")
# Symbols for random variance (h) and initial state, one per qubit
local_fields = sp.symbols(f"local_field_:{num_qubits}")
initial_state = sp.symbols(f"initial_state_:{num_qubits}")
# Symbols used for PhasedFsimGate, one for every qubit pair in the chain
thetas = sp.symbols(f"theta_:{num_qubits - 1}")
zetas = sp.symbols(f"zeta_:{num_qubits - 1}")
chis = sp.symbols(f"chi_:{num_qubits - 1}")
gammas = sp.symbols(f"gamma_:{num_qubits - 1}")
phis = sp.symbols(f"phi_:{num_qubits - 1}")
# Initial moment of Y gates, conditioned on initial state
initial_operations = cirq.Moment(
[cirq.Y(qubit) ** initial_state[index] for index, qubit in enumerate(qubits)]
)
# First component of U cycle, a moment of XZ gates.
sequence_operations = []
for index, qubit in enumerate(qubits):
sequence_operations.append(
cirq.PhasedXZGate(
x_exponent=g_value,
axis_phase_exponent=0.0,
z_exponent=local_fields[index],
)(qubit)
)
# Initialize U cycle
u_cycle = [cirq.Moment(sequence_operations)]
# Second and third components of U cycle, a chain of 2-qubit PhasedFSim gates
# The first component is all the 2-qubit PhasedFSim gates starting on even qubits
# The second component is the 2-qubit gates starting on odd qubits
even_qubit_moment = []
odd_qubit_moment = []
for index, (qubit, next_qubit) in enumerate(zip(qubits, qubits[1:])):
# Add an fsim gate
coupling_gate = cirq.ops.PhasedFSimGate(
theta=thetas[index],
zeta=zetas[index],
chi=chis[index],
gamma=gammas[index],
phi=phis[index],
)
if index % 2:
even_qubit_moment.append(coupling_gate.on(qubit, next_qubit))
else:
odd_qubit_moment.append(coupling_gate.on(qubit, next_qubit))
# Add the two components into the U cycle
u_cycle.append(cirq.Moment(even_qubit_moment))
u_cycle.append(cirq.Moment(odd_qubit_moment))
# Prepare a list of circuits, with n=0,1,2,3 ... cycles many cycles
circuit_list = []
total_circuit = cirq.Circuit(initial_operations)
circuit_list.append(total_circuit.copy())
for _ in range(cycles):
for moment in u_cycle:
total_circuit.append(moment)
circuit_list.append(total_circuit.copy())
return circuit_list