Skip to content

Add the XY, PISWAP and CAN standard gate matrices - #521

Open
eastagiletracker wants to merge 1 commit into
rigetti:mainfrom
eastagiletracker:agile-board/standard-gate-matrices-xy-piswap-can
Open

eastagiletracker wants to merge 1 commit into
rigetti:mainfrom
eastagiletracker:agile-board/standard-gate-matrices-xy-piswap-can

Conversation

@eastagiletracker

Copy link
Copy Markdown

This PR proposes adding the XY, PISWAP and CAN standard gate matrices so Gate::to_unitary can build all three, and reporting a parameterized gate that isn't a standard gate as undefined instead of as one given too many parameters (fixes #465). We include this PR work along with a full history of your repo at https://eastagiletracker.com/projects/256. You can sign in with your GitHub ID to claim ownership of the project.

What was wrong

§4.3 of the Quil specification defines XY, PISWAP and CAN among the standard gates, and ReservedGate in quil-rs/src/reserved.rs already lists all three — but PARAMETERIZED_GATE_MATRICES had no entry for any of them, so neither Gate::to_unitary nor Program::to_unitary could produce their matrices. Running each of Program::from_str(source).unwrap().to_unitary(2) on main at ed186cb:

XY(pi/3) 0 1           -> Err: unknown gate `XY` to turn into parameterized matrix
PISWAP(pi/3) 0 1       -> Err: unknown gate `PISWAP` to turn into parameterized matrix
CAN(0.3, 0.5, 0.7) 0 1 -> Err: expected 1 parameters, was given 3
FSIM(pi/3, pi/12) 0 1  -> Err: expected 1 parameters, was given 2

The last two lines are the same limitation, not two different ones: the matrix table could only describe one-parameter gates, so expected 1 parameters is that ceiling talking rather than anything about CAN or FSIM.

The change

ParameterizedMatrix becomes a small enum whose variants carry how many parameters a gate takes (OneParameter, ThreeParameters). gate_matrix now evaluates all of a gate's parameters, looks the gate up once, and asks it for its matrix, so CAN sits in the same table as the one-parameter gates, MatrixArgumentLength reports the count the gate actually takes, and a name that isn't a standard gate comes back as UndefinedGate regardless of how many parameters it was given — which is the message #466 asks for on FSIM.

The matrices are transcribed from the gate definitions in §4.3, which agree entry-for-entry with quilc's src/quil/stdgates.quil, so this adds no new convention: XY(theta) and PISWAP(theta) are the same operator there and share one implementation here, and CAN(alpha, beta, gamma) is the closed form given in the specification. Nothing else about the standard gate table moves, so existing callers see identical matrices for every gate that already worked.

Verification

Same four programs, after the change:

XY(pi/3) 0 1 -> ok:
[[1.000+0.000i, 0.000+0.000i, 0.000+0.000i, 0.000+0.000i],
 [0.000+0.000i, 0.866+0.000i, 0.000+0.500i, 0.000+0.000i],
 [0.000+0.000i, 0.000+0.500i, 0.866+0.000i, 0.000+0.000i],
 [0.000+0.000i, 0.000+0.000i, 0.000+0.000i, 1.000+0.000i]]
PISWAP(pi/3) 0 1 -> ok: (identical to XY(pi/3))
CAN(0.3, 0.5, 0.7) 0 1 -> ok:
[[0.984+0.149i, 0.000+0.000i, 0.000+0.000i, -0.015+0.099i],
 [0.000+0.000i, 0.816-0.123i, -0.084-0.558i, 0.000+0.000i],
 [0.000+0.000i, -0.084-0.558i, 0.816-0.123i, 0.000+0.000i],
 [-0.015+0.099i, 0.000+0.000i, 0.000+0.000i, 0.984+0.149i]]
FSIM(pi/3, pi/12) 0 1 -> Err: unknown gate `FSIM` to turn into parameterized matrix

Eighteen test cases came with it, in test_gate_into_matrix:

  • test_can_matches_specification evaluates the specification's own DEFGATE CAN(%alpha, %beta, %gamma) expressions through Expression::from_str and evaluate, and compares that matrix against to_unitary, over five parameter triples — so the entry is pinned to the specification text rather than to my transcription of it.
  • test_xy_and_piswap_matrices checks both names against the specification matrix at four angles, test_new_gates_are_unitary checks U†U = I, and two new test_to_unitary cases lift XY and CAN into a three-qubit space.
  • test_to_unitary_parameter_errors covers the error paths: an unknown parameterized gate, a standard gate given the wrong number of parameters (both one- and three-parameter), and a non-constant parameter.

Removing just the three new table entries turns 15 of those cases red, so they do test the change rather than the harness. cargo test -p quil-rs goes from 2976 passing / 0 failing on the unmodified tree to 2994 passing / 0 failing with the change; cargo test -p quil-cli, cargo clippy --workspace --all-targets --all-features -- -D warnings and cargo fmt --all --check are clean before and after.

One thing I noticed while checking the table against §4.3 and deliberately kept out of this PR: the RZ entry is the RY matrix rather than diag(cis(-theta/2), cis(theta/2)), and PSWAP's off-diagonal entry is theta.cos() + theta rather than cis(theta). Both look like transcription slips, and unlike the change here they would move results that callers already get, so they seem worth their own PR rather than a rider on this one — happy to send that if it is useful.

How this was managed

This work was tracked as a story on a board imported from this repository's own issues and pull requests — 413 stories in all — which you can browse at https://eastagiletracker.com/projects/256.

board

If you'd rather not receive contributions like this, reply no-more-prs on this pull request and we won't open any further ones on your repositories.


Lawrence W. Sinclair
CEO / East Agile
linkedin.com/in/lwsinclair/
eastagile.com

The Quil specification defines XY, PISWAP, and CAN among its standard
gates, and `ReservedGate` already lists all three, but `to_unitary` had
no matrices for them: XY and PISWAP were rejected as undefined gates,
and CAN, which takes three parameters, could not be expressed at all.

Parameterized gate matrices now carry the number of parameters they
take, so CAN can sit alongside the one-parameter gates, and a standard
gate applied to the wrong number of parameters reports how many that
gate takes. A parameterized gate that isn't a standard gate is now
reported as undefined rather than as having too many parameters.

@windsurf-bot windsurf-bot Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Looks good to me 🤙

💡 To request another review, post a new comment with "/windsurf-review".

This branch has not been deployed

No deployments
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.

GateError: unknown gate XY to turn into parameterized matrix

1 participant