-
Notifications
You must be signed in to change notification settings - Fork 1.1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add PhasedFSimGate #3505
Add PhasedFSimGate #3505
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@mrwojtek raised a point separately that I fully agree with - we should make sure to be consistent in our nomenclature. Happy to stick with the delta_p, delta_m, delta_mod names, but we should perhaps document the relationship between them and the Fermi-Hubbard parameters.
Otherwise LGTM. Thanks! This is a useful generalization to have.
cirq/ops/fsim_gate.py
Outdated
where b0 and b1 are phase angles to be applied before the core FSimGate, | ||
a0 and a1 are phase angles to be applied after FSimGate and theta and | ||
phi specify the core FSimGate. Use the static factory function | ||
PhasedFSimGate.from_phase_angles_and_fsim to instantiate the gate |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Internally we also have dataclasses to store just the parameters in these different representations with functions to canonicalize them (since the various phase parameters are periodic) and to convert between them. It might be nice to include that code here, though it might be awkward to support symbolic values so would have to try it out. Note that internally we call the canonical parametrization above FsimPhase
while this alternate parametrization with per-qubit z rotations is called FsimRz
. If we stick with that nomenclature then the factory function would better be called PhasedFSimGate.from_fsim_rz
or something like that, and the properties for getting the rotation angles before and after might also best be renamed as rz_angles_before
and rz_angles_after
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
+1, it would be nice to follow up on this because it will be one of the building blocks of the some calibration features.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Renamed the factory method and the two properties as suggested. As discussed on a different PR, I'd like to defer dataclasses (and possibly re-use existing code that @mrwojtek is introducing elsewhere).
cirq/ops/fsim_gate.py
Outdated
q0_z_exponent_after = self.phase_angles_after[0] / np.pi | ||
q1_z_exponent_after = self.phase_angles_after[1] / np.pi | ||
yield cirq.Z(q0)**q0_z_exponent_before | ||
yield cirq.Z(q1)**q1_z_exponent_before |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd suggest writing this in terms of rotations, and can also use names that correspond with the docstring:
b0, b1 = self.phase_angles_before
a0, a1 = self.phase_angles_after
yield cirq.rz(q0, b0)
yield cirq.rz(q1, b1)
yield FSimGate(self.theta, self.phi).on(q0, q1)
yield cirq.rz(q0, a0)
yield cirq.rz(a1, a1)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is nearly identical to my original implementation. Unfortunately, protocol consistency checks are sensitive to global phase, so we have to give up __unitary__()[0, 0] == 1
or we have to yield cirq.Z
instead of cirq.rz
here. I chose the latter so that __unitary__
agrees with eq (43) from QS supplement.
(Per other comments, I'll be updating this PR to agree with eq (18) in FH paper, but this merely renames existing "delta" parameters, so I think I'll keep the constraint that __unitary__()[0, 0] == 1
.)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
(We could also yield a global phase gate, but that seems even uglier.)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I see. In that case, perhaps include a comment why this differs from the docstring, which shows Rz
gates. In addition, would be good to refactor to avoid evaluating each angle property twice, and you might also consider following the rz
implementation which uses sympy.pi
where appropriate to preserve symbolic values.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good suggestions. All done.
|
||
@value.value_equality(approximate=True) | ||
class PhasedFSimGate(gate_features.TwoQubitGate, | ||
gate_features.InterchangeableQubitsGate): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I just started to wonder about this: what does it mean that this gate implements InterchangeableQubitsGate? Does it mean that operation is equal after qubits are swapped? That's not true, right?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for catching this! Sent #3524.
No description provided.