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

MultGate: A gate for multiplying parameters. #182

Merged
merged 6 commits into from
Nov 17, 2024

Conversation

ScottWe
Copy link
Contributor

@ScottWe ScottWe commented Nov 16, 2024

Summary

This pull request introduces a new gate which allows for parameters to be multiplied together. Due to limitations of Non-Linear Real Arithmetic, the python implementation requires that one of the parameters be an integer.

Details

In OpenQASM, it is possible to write parameterized gates whose arguments are written as linear sums of parameters. These are hard to express using only the AddGate and NegGate.

For example, consider the statement rz(5 * p[0] + p[1]) q[0];. To write this as a DAG in Quartz, the term 5 * p[0] must be decomposed into a sequence of AddGate node. For example, one could write:

[4, "", ["add", ["P1"], ["P0", "P0"]], ["add", ["P2"], ["P1", "P1]], ["add", ["P3"], ["P0", "P2"]]]

This pull request introduces a new gate which allows for parameters to be multiplied together.

Features

  1. A new gate, MultGate, which takes two parameters wires and returns their product.
  2. A python implementation for the gate, which handles the case where one of the wires is integral. The implementation achieves logarithmic runtime by applying the double-angle formula and triple-angle formula.

Copy link
Collaborator

@xumingkuan xumingkuan left a comment

Choose a reason for hiding this comment

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

Looks great! Thank you for your contribution.

if isinstance(y, (int, float)):
x, y = y, x

# The only angle formulas expressible in NLRA are integer multiples of angles.
Copy link
Collaborator

Choose a reason for hiding this comment

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

Sorry, what is NLRA?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Whoops: non-linear real arithmetic.

Copy link
Collaborator

Choose a reason for hiding this comment

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

I see. I prefer not using the acronym here :)

Copy link
Collaborator

Choose a reason for hiding this comment

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

Btw this seems not accurate: there is also half-angle formula:
sin(x/2) = ±sqrt((1-cos(x))/2)
cos(x/2) = ±sqrt((1+cos(x))/2)
The signs can be derived from the signs of sin(x) and cos(x).

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Oh, cool. I didn't realize there was a z3.Sqrt function. Though I imagine the constraints would be really hard to solve when the parameters are symbolic.

In any case, I'll update the commit. Thanks!

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@xumingkuan How were you thinking of determining sgn(cos(x/2)) from cos(x) and sin(x).

At first, I was thinking that sgn(sin(x/2)) = 1 and sgn(cos(x/2)) = z3.If(sin(x) >= 0, 1, -1). Then I realized that this is only true when x is in [0, 2pi]. For example, if x = pi/2 + 2pi, then x/2 = pi/4 + pi, and as a result sgn(sin(x)) = 1 =\= -1 = sgn(cos(x/2)).

Can we assume the verifier only works with angles from [0, 2pi]?

Copy link
Collaborator

Choose a reason for hiding this comment

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

Good question! I would also assume that the verifier only works with angles in [0, 2pi) but there are cases that the user needs to be aware of. For example, when computing 1.5 * x, (3 * x) / 2 and x + (x / 2) may have different results.

Unless you need non-integer multiples, I prefer only supporting multiplying integer values, with a comment that dividing by 2 is feasible but the sign needs to be determined. It might be better to have another HalfGate (with only one input x and one output x / 2) for the user to specify if they want (3 * x) / 2 or x + (x / 2) in the future.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yeah, I think a HalfGate would make more sense.

Personally, I don't have a use-case for the HalfGate. I'm happy to implement it and open a new PR if you think it would be useful though.

Copy link
Collaborator

Choose a reason for hiding this comment

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

Actually, I don't think HalfGate will be useful -- it seems to me that it's just better to have the symbolic parameter y = x / 2 and use 2 * y whenever the user needs x.

@xumingkuan xumingkuan merged commit 967080e into quantum-compiler:master Nov 17, 2024
2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants