Skip to content
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 EigenGate._equal_up_to_global_phase_ #1840

Merged
merged 27 commits into from
Nov 8, 2019

Conversation

bryano
Copy link
Collaborator

@bryano bryano commented Jul 18, 2019

No description provided.

@googlebot googlebot added the cla: yes Makes googlebot stop complaining. label Jul 18, 2019
@bryano bryano requested a review from Strilanc July 18, 2019 21:35
@bryano bryano requested a review from dabacon August 13, 2019 21:27
not np.isclose(exponents[0], exponents[1], atol=atol)):
return False

self_without_exp_or_phase = self._with_exponent(0)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This part confuses me. 1) why does it do a creation of two new objects? 2) what does setting _with_exponent(0) followed by setting global_shift to 0 leave to be different?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There are EigenGates in OFC that have parameters other than exponent and global_shift.

Copy link
Collaborator

@dabacon dabacon left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Forgot to update status to "request changes". I'd like to understand what the final part of the test is doing.

not np.isclose(exponents[0], exponents[1], atol=atol)):
return False

self_without_exp_or_phase = self._with_exponent(0)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

.

@bryano
Copy link
Collaborator Author

bryano commented Sep 27, 2019

@dabacon ping

@@ -322,6 +322,32 @@ def _resolve_parameters_(self: TSelf, param_resolver) -> TSelf:
return self._with_exponent(
exponent=param_resolver.value_of(self._exponent))

def _equal_up_to_global_phase_(self, other, atol):
if not isinstance(other, EigenGate):
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should be type(self) instead of EigenGate. Otherwise you will end up comparing XPowGate to ZPowGate.

Make sure to test that XPowGate is not approximately equal to ZPowGate up to global phase.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The method only returns True if the gates without exponents or phases are approximately equal, so the type check can be done there if desired. Certainly there are gates of different types that are equal up to global phase, e.g., X ** 0 and Z ** 0. False negatives are fine (and I think quite common at the moment), but the change you suggest would preclude them from being addressed eventually.

(Note that I added a test for XPowGate and ZPowGate that passes without any changes to the code.)

Copy link
Contributor

@Strilanc Strilanc Oct 1, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think X**0 is approximately equal to Z**0 up to global phase. Their unitaries are equal, but the classes are distinct. If you wanted to compare the unitaries, you'd compare the unitaries.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You're right that the existing code handles this. I think it's because of the delegating to approx_eq

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is what "equality" of gates means in Cirq documented anywhere?

exponents = (self.exponent, other.exponent)
exponents_is_parameterized = tuple(
protocols.is_parameterized(e) for e in exponents)
if (all(exponents_is_parameterized) and exponents[0] != exponents[1]):
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What is the reason that you needed these checks for? I would have expected that copying with global shift set to 0 and then delegating to approx_eq would have covered the parameterized case.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This check addressed parameterized exponents only, whereas approx_eq is passed the gates stripped of their exponents.

At one point, I was trying to get it so that gates would be equal up to global phase if their exponents were off by half a period (so a phase of -1), but it got too complicated to be worth it. As it is, the checking of exponents modulo the period might be better put in _approx_eq_.

@bryano
Copy link
Collaborator Author

bryano commented Oct 12, 2019

@Strilanc ping

@Strilanc Strilanc changed the title adds EigenGate._equal_up_to_global_phase_ Add EigenGate._equal_up_to_global_phase_ Nov 8, 2019
@Strilanc Strilanc added the automerge Tells CirqBot to sync and merge this PR. (If it's running.) label Nov 8, 2019
@CirqBot CirqBot added the front_of_queue_automerge CirqBot uses this label to indicate (and remember) what's being merged next. label Nov 8, 2019
@CirqBot
Copy link
Collaborator

CirqBot commented Nov 8, 2019

Automerge cancelled: Merging is blocked (I don't understand why).

@CirqBot CirqBot removed automerge Tells CirqBot to sync and merge this PR. (If it's running.) front_of_queue_automerge CirqBot uses this label to indicate (and remember) what's being merged next. labels Nov 8, 2019
@Strilanc Strilanc added the automerge Tells CirqBot to sync and merge this PR. (If it's running.) label Nov 8, 2019
@CirqBot CirqBot added the front_of_queue_automerge CirqBot uses this label to indicate (and remember) what's being merged next. label Nov 8, 2019
@CirqBot CirqBot merged commit 8f1c30a into quantumlib:master Nov 8, 2019
@CirqBot CirqBot removed automerge Tells CirqBot to sync and merge this PR. (If it's running.) front_of_queue_automerge CirqBot uses this label to indicate (and remember) what's being merged next. labels Nov 8, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
cla: yes Makes googlebot stop complaining.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants