-
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
[WIP] symbolic expression for symbolic pulse equating #9247
Conversation
Co-authored-by: Naoki Kanazawa <nkanazawa1989@gmail.com>
…bcf742eac8945.yaml Co-authored-by: Naoki Kanazawa <nkanazawa1989@gmail.com>
Co-authored-by: Naoki Kanazawa <nkanazawa1989@gmail.com>
Thank you for opening a new pull request. Before your PR can be merged it will first need to pass continuous integration tests and be reviewed. Sometimes the review process can be slow, so please be patient. While you're waiting, please feel free to review other open PRs. While only a subset of people are authorized to approve pull requests for merging, everyone is encouraged to review open pull requests. Doing reviews helps reduce the burden on the core team and helps make the project's code better for everyone. One or more of the the following people are requested to review this:
|
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 @TsafrirA this is a good start to discuss implementation. Current implementation has a fundamental limitation, namely, there is always only one amplitude; F(t, theta) = A F'(t, theta')
. To me this seems very strong assumption. For example, we may want to define geometric pulse consisting of two tones at different frequencies.
I also want to avoid adding new symbolic expression, since this increases the complexity and computational overhead to build a program. Indeed, current symbolic pulse implementation is already too complicated, i.e. expression for envelope, validation, and condition to invoke waveform generation.
Alternatively you can delegate canonicalize to ParameterExpression
object to manage the case when amp or angle are given by parameter expression. For example,
from qiskit.circuit import Parameter, ParameterExpression
from qiskit.pulse.utils import format_parameter_value
import symengine as sym
def amplitude_formatter(amp, angle):
_amp, _angle = sym.symbols("amp, angle")
tmp_amp = Parameter("amp")
tmp_angle = Parameter("angle")
canonical_amp = ParameterExpression(
symbol_map={tmp_amp: _amp},
expr=sym.Abs(_amp),
)
canonical_amp = canonical_amp.assign(tmp_amp, amp)
canonical_angle = ParameterExpression(
symbol_map={tmp_amp: _amp, tmp_angle: _angle},
expr=_angle + (1 - sym.sign(_amp)) / 2 * sym.pi,
)
canonical_angle = canonical_angle.assign(tmp_angle, angle)
canonical_angle = canonical_angle.assign(tmp_amp, amp)
params = {
"amp": format_parameter_value(canonical_amp),
"angle": format_parameter_value(canonical_angle),
}
return params
Edit; As a side effect, this implicitly canonicalize user parameter, i.e. amp=-1 will appear as amp=1 when the user access to parameters.
@nkanazawa1989 I know we have only recently dropped the sub-classes (PR #8278), but it would seem like the easiest solution is to create subclasses where you can hard-code things whatever way you like (Note that the inability to differentiate library pulses from custom built ones also gave us a hard time in #9002). However, I am sure there was a good reason to drop out the subclasses. |
Summary
Qiskit-Terra PR #9002, converted the library symbolic pulses from a complex
amp
representation to a real (float)amp
,angle
representation. To overcome the non-unique nature of the new representation (particularly, when negative amp is allowed), this PR adds an optional attributeparams_comp_exp
to store symbolic expression\s which are used to equate pulses.Details and comments
Qiskit-Terra PR #9002, converted the library symbolic pulses from a complex
amp
representation to a real (float)amp
,angle
representation. To better support several experiments in Qiskit-Experiments, theamp
parameter is allowed to take both positive and negative values. This decision creates a non-unique representation for the pulses, where a pi shift ofangle
and a sign flip ofamp
have the same effect (the issue obviously also exists for 2*pi shift ofangle
). For example, the following two pulsesare not the same when equated (because their parameters are different):
but they represent the same waveform:
This PR sets to correct this situation, by introducing a new attribute to the
SymbolicPulse
class -param_comp_exp
. This new optional argument stores symbolic expression\s which are used when equating two pulses. Parameters appearing in these expressions are not equated individually, but only via the value of the total expression. For custom pulses, one can use any expression, but for the library pulses the expression in use isamp*sym.exp(sym.I*angle)
which removes the problem. Returning to the example above, the new PR yields:Discussion
The new addition is flexible and allows for a single expression or a list of expressions to be used. However, it is not obvious that such flexibility is needed. I can't think of an example where one would want two or more such expressions for a pulse.
Additionally, performance seems to be an issue. The new test added to
test\python\pulse\test_pulse_lib.py
is by far the slowest of the entire batch - despite testing a rather modest scenario. Furthermore, the new attribute will increase instances' size, for example, when saved to QPY.