-
Notifications
You must be signed in to change notification settings - Fork 2.3k
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 inverse function to Operation in rust #13168
base: main
Are you sure you want to change the base?
Conversation
One or more of the following people are relevant to this code:
|
The following gates do not have an inverse which is a
|
Pull Request Test Coverage Report for Build 10922800047Warning: This coverage report may be inaccurate.This pull request's base commit is no longer the HEAD commit of its target branch. This means it includes changes from outside the original pull request, including, potentially, unrelated coverage changes.
Details
💛 - Coveralls |
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 getting this started it looking good. I have a couple of inline comments and questions to start.
fn inverse(&self, _params: &[Param]) -> Option<(StandardGate, Vec<Param>)> { | ||
None | ||
} |
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.
Is there ever a case where a Python Operation
will have an inverse defined? I know it's not part of the abstract interface, but I'm wondering if we should try and fallback to None
? @alexanderivrii maybe you have some thoughts here?
@@ -2043,6 +2057,155 @@ impl Operation for StandardGate { | |||
fn standard_gate(&self) -> Option<StandardGate> { | |||
Some(*self) | |||
} | |||
fn inverse(&self, params: &[Param]) -> Option<(StandardGate, Vec<Param>)> { |
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.
Everywhere else we work with parameters in Rust we tend to use SmallVec<[Param; 3]>
to keep things on the stack unless there are more than 3 elements. It might be worth changing this and updating the vec!
macro usage to smallvec!
.
@@ -167,6 +167,7 @@ pub trait Operation { | |||
fn definition(&self, params: &[Param]) -> Option<CircuitData>; | |||
fn standard_gate(&self) -> Option<StandardGate>; | |||
fn directive(&self) -> bool; | |||
fn inverse(&self, params: &[Param]) -> Option<(StandardGate, Vec<Param>)>; |
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.
Does this work in the case of PyGate
? I don't think there is a guarantee that a Python defined gate's inverse will be a StandardGate
. I actually think it is pretty unlikely in practice, since if a custom gate were expressible as the inverse of a StandardGate
it'd probably just be a StandardGate
. I think you can just do:
fn inverse(&self, params: &[Param]) -> Option<(StandardGate, Vec<Param>)>; | |
fn inverse(&self, params: &[Param]) -> Option<(Self, Vec<Param>)>; |
then for impl Operation for StandardGate
.inverse()
returns a StandardGate
and for impl Operator for PyGate
.inverse()
returns a PyGate
.
Self::C3SXGate => None, // the inverse in not a StandardGate | ||
Self::RC3XGate => None, // the inverse in not a StandardGate | ||
} | ||
} | ||
} |
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.
Did you want to add a rust space test asserting that all the StandardGates multiplied with their inverse were the identity? It would be good to get in the practice of having more rust space tests, but since we have coverage from python I don't think it's strictly necessary.
@kevinhartman has been working on demonstrating a pattern of using the py
token from rust space tests: #13169 (since we still need it for multiply_param
even if there isn't a parameter expression).
Summary
Close #13157
Details and comments