-
Notifications
You must be signed in to change notification settings - Fork 2.4k
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 some abbreviations for gates and linear algebra #12651
Conversation
This comment was marked as off-topic.
This comment was marked as off-topic.
One or more of the following people are relevant to this code:
|
fc05ef1
to
44df001
Compare
Pull Request Test Coverage Report for Build 9668651215Details
💛 - Coveralls |
In an out of band discussion we agreed to reduce use of the constants The commit message for b6b315e is written as if the |
Pull Request Test Coverage Report for Build 9700404596Details
💛 - 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.
This looks fine to me and inline with what we discussed. If you want to squash-rebase / change your commit messages or anything, feel free to and I'll re-approve. If you don't mind, just tag it for merge.
This PR introduces some abbreviations for repetitive Rust code. Motivations are reducing clutter, improving readability, and perhaps modest support for rapid development. * Use the definition of `const fn 64` that was introduced in Qiskit#12459 uniformly in all crates. * Define some complex constants `C_ONE`, `C_ZERO`, `IM`, etc. * Introduce type definitions for arrays representing gates. For example: `GateArray1Q = [[Complex64; 2]; 2];`
e7cd465
to
d1ef4cd
Compare
Pull Request Test Coverage Report for Build 9701734273Details
💛 - Coveralls |
This PR introduces some abbreviations for repetitive Rust code. Motivations are reducing clutter, improving readability, and perhaps modest support for rapid development. * Use the definition of `const fn 64` that was introduced in Qiskit#12459 uniformly in all crates. * Define some complex constants `C_ONE`, `C_ZERO`, `IM`, etc. * Introduce type definitions for arrays representing gates. For example: `GateArray1Q = [[Complex64; 2]; 2];`
Add constant abbreviations for some values and types.
This PR introduces some abbreviations for repetitive Rust code. Motivations are reducing clutter, improving readability, and perhaps modest support for rapid development.
Construction of complex numbers
Complex numbers are common in scientific computing and ubiquitous in quantum computation. They are supported in Rust via libraries, one in particular, with few ergonomic features beyond those provided for any
struct
. We do haveComplex64
forComplex<f64>
so that numbers are constructed withIn other scientific languages and platforms, developers typically appreciate ergonomic features1 reflecting special status of complex numbers. Improving ergonomic for complex numbers in Qiskit is a worthwhile task.
In this PR, I chose to continue using the definition of
const fn 64
that was introduced in #12459qiskit/crates/circuit/src/gate_matrix.rs
Lines 19 to 22 in 1ed5951
I chose this in part to try to make this appealing to Qiskit devs. However there are choices.
c64
(referenced above). Can be used instatic
andconst
constructs. Requiresf64
arguments.c64
introduced recently innum-complex
. This creates a newComplex<f64>
from arguments that can convertInto<f64>
. For examplec64(1.0, 2.0)
andc64(1, 2)
.static
andconst
not supported, which is a major disadvantage for Qiskit.c64
slightly more generally so thatc64(1, 2.0)
is allowed (The version in item 2. does not support this.). This is a minor tweak to the implementation. However,static
andconst
are still not supported.c64!
is the most capable and flexible. This is functionally nearly the same as item 3. with the major advantage thatstatic
andconst
are supported.One might argue that having
c64(1, 2)
(orc64!(1, 2)
) return aComplex64
goes against the spirit of Rust. But I find decimal points that exist only to satisfy language semantics irksome and distracting. For rapid development, allowing more flexibility within constraints of semantics is useful. It would be better thatc64(1, 2)
construct a complex number with integer types in combination with facilities mix complex types. But Rust in general is too explicit for this.However, examining this PR, you can see that the number of superfluous decimal points is actually rather small at least so far. So retaining choice
1
is not a big burden.Constants for common complex and
f64
valuesThese are
const
bindings for very common complex values, such asC_ONE
,C_ZERO
etc. I think justONE
andZERO
are just as good, a bit less explicit, but neater and more readable (@sbrandhsn). These make source more readable and less cluttered, and likely less error prone. A couple of commonf64
values that are defined repeatedly locally have been moved to a common location. (@ShellyGarion @alexanderivrii)Type definitions for arrays representing gates
For example
GateArray1Q = [[Complex64; 2]; 2];
. Advantages are reducing clutter, signalling intent, etc.One could object to this and the previous item. These are less explicit and one might mistakenly assume that an identifier is bound to a different value. But these are generic objections to binding an identifier to a value. The statements of the objections are always true. Yet we find these refactorings sometimes worthwhile.
Relation to other PRs
The other part of #12507, which implements a gate, will be included in a separate PR.
Footnotes
In Python the suffix
j
is recognized by the parser, so2j
represents the complex value(0.0, 2.0)
.In Julia,
Complex{T<:Real}
is a parametric type and the constantim
is bound to the valueComplex{Bool}(false, true)
. The parser reads a numeric literal followed by an identifier as a call to the function*
. Methods are defined for arithmetic with mixed types, so that2.0im
dispatches to*(x::Real, z::Complex{Bool}) = Complex(x * real(z), x * imag(z))
.Technical computing is not a core domain of C. However concessions to ergonomics exist. In C99 a complex number is typically constructed like this:
1.0 + 2.0*I
. In C11,CMPLX(1.0, 2.0)
.Fortran has special support for complex numbers, since it's main application domain is scientific/technical computing. For example
z%re = 3.0
assigns the real part ofz
. ↩