Open steve-jeffrey opened 1 year ago
Fair enough. A generic analytic compilation routine for parametric gates, including controlled versions of simple gates, is somewhere between hard and impossible — but for specific cases, we can probably figure it out.
Definitely CONTROLLED PHASE is a variant of CONTROLLED RZ up to local phase. I think, but I am not certain, that CONTROLLED XY p q r is XY q r followed by a (CZ p q)-conjugate of XY q r, maybe with some more local gates to balance out phases. One would have to chase it out.
It doesn't look like there's any phase to chase. Here's some quilc -P -m
output:
XY(0.4) 0 1
CZ 2 1
XY(-0.4) 0 1
CZ 2 1
#Matrix read off from input code (unitary)
#<MATRIX/COMPLEX-DOUBLE-FLOAT (8x8):
# 1.000 + 0.000j 0.000 + 0.000j 0.000 + 0.000j 0.000 + 0.000j 0.000 + 0.000j 0.000 + 0.000j 0.000 + 0.000j 0.000 + 0.000j
# 0.000 + 0.000j 1.000 + 0.000j 0.000 + 0.000j 0.000 + 0.000j 0.000 + 0.000j 0.000 + 0.000j 0.000 + 0.000j 0.000 + 0.000j
# 0.000 + 0.000j 0.000 + 0.000j 1.000 + 0.000j 0.000 + 0.000j 0.000 + 0.000j 0.000 + 0.000j 0.000 + 0.000j 0.000 + 0.000j
# 0.000 + 0.000j 0.000 + 0.000j 0.000 + 0.000j 1.000 + 0.000j 0.000 + 0.000j 0.000 + 0.000j 0.000 + 0.000j 0.000 + 0.000j
# 0.000 + 0.000j 0.000 + 0.000j 0.000 + 0.000j 0.000 + 0.000j 1.000 + 0.000j 0.000 + 0.000j 0.000 + 0.000j 0.000 + 0.000j
# 0.000 + 0.000j 0.000 + 0.000j 0.000 + 0.000j 0.000 + 0.000j 0.000 + 0.000j 0.921 + 0.000j 0.000 + 0.389j 0.000 + 0.000j
# 0.000 + 0.000j 0.000 + 0.000j 0.000 + 0.000j 0.000 + 0.000j 0.000 + 0.000j 0.000 + 0.389j 0.921 + 0.000j 0.000 + 0.000j
# 0.000 + 0.000j 0.000 + 0.000j 0.000 + 0.000j 0.000 + 0.000j 0.000 + 0.000j 0.000 + 0.000j 0.000 + 0.000j 1.000 + 0.000j>
which looks like the controlled version of
XY(0.8) 0 1
#Matrix read off from input code (unitary)
#<MATRIX/COMPLEX-DOUBLE-FLOAT (4x4):
# 1.000 + 0.000j 0.000 + 0.000j 0.000 + 0.000j 0.000 + 0.000j
# 0.000 + 0.000j 0.921 + 0.000j 0.000 + 0.389j 0.000 + 0.000j
# 0.000 + 0.000j 0.000 + 0.389j 0.921 + 0.000j 0.000 + 0.000j
# 0.000 + 0.000j 0.000 + 0.000j 0.000 + 0.000j 1.000 + 0.000j>
For funsies, here's a recipe for CONTROLLED CONTROLLED XY(0.8) 3 2 1 0
:
CONTROLLED CONTROLLED Z 3 2 1
XY(-0.4) 0 1
CONTROLLED CONTROLLED Z 3 2 1
XY(0.4) 0 1
#Matrix read off from input code (unitary)
#<MATRIX/COMPLEX-DOUBLE-FLOAT (16x16):
# 1.000 + 0.000j 0.000 + 0.000j 0.000 + 0.000j 0.000 + 0.000j 0.000 + 0.000j 0.000 + 0.000j 0.000 + 0.000j 0.000 + 0.000j 0.000 + 0.000j 0.000 + 0.000j 0.000 + 0.000j 0.000 + 0.000j 0.000 + 0.000j 0.000 + 0.000j 0.000 + 0.000j 0.000 + 0.000j
# 0.000 + 0.000j 1.000 + 0.000j 0.000 + 0.000j 0.000 + 0.000j 0.000 + 0.000j 0.000 + 0.000j 0.000 + 0.000j 0.000 + 0.000j 0.000 + 0.000j 0.000 + 0.000j 0.000 + 0.000j 0.000 + 0.000j 0.000 + 0.000j 0.000 + 0.000j 0.000 + 0.000j 0.000 + 0.000j
# 0.000 + 0.000j 0.000 + 0.000j 1.000 + 0.000j 0.000 + 0.000j 0.000 + 0.000j 0.000 + 0.000j 0.000 + 0.000j 0.000 + 0.000j 0.000 + 0.000j 0.000 + 0.000j 0.000 + 0.000j 0.000 + 0.000j 0.000 + 0.000j 0.000 + 0.000j 0.000 + 0.000j 0.000 + 0.000j
# 0.000 + 0.000j 0.000 + 0.000j 0.000 + 0.000j 1.000 + 0.000j 0.000 + 0.000j 0.000 + 0.000j 0.000 + 0.000j 0.000 + 0.000j 0.000 + 0.000j 0.000 + 0.000j 0.000 + 0.000j 0.000 + 0.000j 0.000 + 0.000j 0.000 + 0.000j 0.000 + 0.000j 0.000 + 0.000j
# 0.000 + 0.000j 0.000 + 0.000j 0.000 + 0.000j 0.000 + 0.000j 1.000 + 0.000j 0.000 + 0.000j 0.000 + 0.000j 0.000 + 0.000j 0.000 + 0.000j 0.000 + 0.000j 0.000 + 0.000j 0.000 + 0.000j 0.000 + 0.000j 0.000 + 0.000j 0.000 + 0.000j 0.000 + 0.000j
# 0.000 + 0.000j 0.000 + 0.000j 0.000 + 0.000j 0.000 + 0.000j 0.000 + 0.000j 1.000 + 0.000j 0.000 + 0.000j 0.000 + 0.000j 0.000 + 0.000j 0.000 + 0.000j 0.000 + 0.000j 0.000 + 0.000j 0.000 + 0.000j 0.000 + 0.000j 0.000 + 0.000j 0.000 + 0.000j
# 0.000 + 0.000j 0.000 + 0.000j 0.000 + 0.000j 0.000 + 0.000j 0.000 + 0.000j 0.000 + 0.000j 1.000 + 0.000j 0.000 + 0.000j 0.000 + 0.000j 0.000 + 0.000j 0.000 + 0.000j 0.000 + 0.000j 0.000 + 0.000j 0.000 + 0.000j 0.000 + 0.000j 0.000 + 0.000j
# 0.000 + 0.000j 0.000 + 0.000j 0.000 + 0.000j 0.000 + 0.000j 0.000 + 0.000j 0.000 + 0.000j 0.000 + 0.000j 1.000 + 0.000j 0.000 + 0.000j 0.000 + 0.000j 0.000 + 0.000j 0.000 + 0.000j 0.000 + 0.000j 0.000 + 0.000j 0.000 + 0.000j 0.000 + 0.000j
# 0.000 + 0.000j 0.000 + 0.000j 0.000 + 0.000j 0.000 + 0.000j 0.000 + 0.000j 0.000 + 0.000j 0.000 + 0.000j 0.000 + 0.000j 1.000 + 0.000j 0.000 + 0.000j 0.000 + 0.000j 0.000 + 0.000j 0.000 + 0.000j 0.000 + 0.000j 0.000 + 0.000j 0.000 + 0.000j
# 0.000 + 0.000j 0.000 + 0.000j 0.000 + 0.000j 0.000 + 0.000j 0.000 + 0.000j 0.000 + 0.000j 0.000 + 0.000j 0.000 + 0.000j 0.000 + 0.000j 1.000 + 0.000j 0.000 + 0.000j 0.000 + 0.000j 0.000 + 0.000j 0.000 + 0.000j 0.000 + 0.000j 0.000 + 0.000j
# 0.000 + 0.000j 0.000 + 0.000j 0.000 + 0.000j 0.000 + 0.000j 0.000 + 0.000j 0.000 + 0.000j 0.000 + 0.000j 0.000 + 0.000j 0.000 + 0.000j 0.000 + 0.000j 1.000 + 0.000j 0.000 + 0.000j 0.000 + 0.000j 0.000 + 0.000j 0.000 + 0.000j 0.000 + 0.000j
# 0.000 + 0.000j 0.000 + 0.000j 0.000 + 0.000j 0.000 + 0.000j 0.000 + 0.000j 0.000 + 0.000j 0.000 + 0.000j 0.000 + 0.000j 0.000 + 0.000j 0.000 + 0.000j 0.000 + 0.000j 1.000 + 0.000j 0.000 + 0.000j 0.000 + 0.000j 0.000 + 0.000j 0.000 + 0.000j
# 0.000 + 0.000j 0.000 + 0.000j 0.000 + 0.000j 0.000 + 0.000j 0.000 + 0.000j 0.000 + 0.000j 0.000 + 0.000j 0.000 + 0.000j 0.000 + 0.000j 0.000 + 0.000j 0.000 + 0.000j 0.000 + 0.000j 1.000 + 0.000j 0.000 + 0.000j 0.000 + 0.000j 0.000 + 0.000j
# 0.000 + 0.000j 0.000 + 0.000j 0.000 + 0.000j 0.000 + 0.000j 0.000 + 0.000j 0.000 + 0.000j 0.000 + 0.000j 0.000 + 0.000j 0.000 + 0.000j 0.000 + 0.000j 0.000 + 0.000j 0.000 + 0.000j 0.000 + 0.000j 0.921 + 0.000j 0.000 + 0.389j 0.000 + 0.000j
# 0.000 + 0.000j 0.000 + 0.000j 0.000 + 0.000j 0.000 + 0.000j 0.000 + 0.000j 0.000 + 0.000j 0.000 + 0.000j 0.000 + 0.000j 0.000 + 0.000j 0.000 + 0.000j 0.000 + 0.000j 0.000 + 0.000j 0.000 + 0.000j 0.000 + 0.389j 0.921 + 0.000j 0.000 + 0.000j
# 0.000 + 0.000j 0.000 + 0.000j 0.000 + 0.000j 0.000 + 0.000j 0.000 + 0.000j 0.000 + 0.000j 0.000 + 0.000j 0.000 + 0.000j 0.000 + 0.000j 0.000 + 0.000j 0.000 + 0.000j 0.000 + 0.000j 0.000 + 0.000j 0.000 + 0.000j 0.000 + 0.000j 1.000 + 0.000j>
and a recipe for FORKED XY(0.35, 0.25) 2 1 0
:
XY(0.3) 0 1
CZ 2 1
XY(0.05) 0 1
CZ 2 1
#<MATRIX/COMPLEX-DOUBLE-FLOAT (8x8):
# 1.000 + 0.000j 0.000 + 0.000j 0.000 + 0.000j 0.000 + 0.000j 0.000 + 0.000j 0.000 + 0.000j 0.000 + 0.000j 0.000 + 0.000j
# 0.000 + 0.000j 0.985 + 0.000j 0.000 + 0.174j 0.000 + 0.000j 0.000 + 0.000j 0.000 + 0.000j 0.000 + 0.000j 0.000 + 0.000j
# 0.000 + 0.000j 0.000 + 0.174j 0.985 + 0.000j 0.000 + 0.000j 0.000 + 0.000j 0.000 + 0.000j 0.000 + 0.000j 0.000 + 0.000j
# 0.000 + 0.000j 0.000 + 0.000j 0.000 + 0.000j 1.000 + 0.000j 0.000 + 0.000j 0.000 + 0.000j 0.000 + 0.000j 0.000 + 0.000j
# 0.000 + 0.000j 0.000 + 0.000j 0.000 + 0.000j 0.000 + 0.000j 1.000 + 0.000j 0.000 + 0.000j 0.000 + 0.000j 0.000 + 0.000j
# 0.000 + 0.000j 0.000 + 0.000j 0.000 + 0.000j 0.000 + 0.000j 0.000 + 0.000j 0.992 + 0.000j 0.000 + 0.125j 0.000 + 0.000j
# 0.000 + 0.000j 0.000 + 0.000j 0.000 + 0.000j 0.000 + 0.000j 0.000 + 0.000j 0.000 + 0.125j 0.992 + 0.000j 0.000 + 0.000j
# 0.000 + 0.000j 0.000 + 0.000j 0.000 + 0.000j 0.000 + 0.000j 0.000 + 0.000j 0.000 + 0.000j 0.000 + 0.000j 1.000 + 0.000j>
@stylewarning: This sounds like it should be tagged "good first issue". I don't have tag permissions, myself.
Just to finish the job, here's an example circuit which relates CONTROLLED PHASE and CONTROLLED RZ by implementing the identity:
CONTROLLED RZ(0.4) 1 0
RZ(0.2) 1
CONTROLLED PHASE(-0.4) 1 0
#Matrix read off from input code (unitary)
#<MATRIX/COMPLEX-DOUBLE-FLOAT (4x4):
# 0.995 - 0.100j 0.000 + 0.000j 0.000 + 0.000j 0.000 + 0.000j
# 0.000 + 0.000j 0.995 - 0.100j 0.000 + 0.000j 0.000 + 0.000j
# 0.000 + 0.000j 0.000 + 0.000j 0.995 - 0.100j 0.000 + 0.000j
# 0.000 + 0.000j 0.000 + 0.000j 0.000 + 0.000j 0.995 - 0.100j>
The decomposition of FORKED ... FORKED XY
proposed here is what's already done in ucr-explode.lisp . To extend that to handle CZ decompositions of FORKED XY, we need only change uniformly-controlled-roll-p
to permit "XY"
as a gate name. To make this more ergonomic, there are then some other translators to write, like converting CONTROLLED XY into FORKED XY.
Dunno about the ISWAP version of the same change, since that compiler is also guarded by uniformly-controlled-roll-p
. The easiest fix is to change the error
in the cond
to a try-next-compiler
. Another thought, though, is to try dropping the ISWAP version entirely; since we began trampolining, I'm not sure we've (in the relevant era: I've) checked that the ISWAP-specific decomposition is giving something better than chaining UCR->CZ->ISWAP + compressor. If it isn't, let's drop it. If it is, then it shouldn't be hard to bang out the same hand-optimizations that went into building the old ISWAP decompositions, which are based off of the CZ->ISWAP translator anyway.
Description
Controlled gates (other than RX, RY, RZ) with symbolic parameters will not compile.
Controlled RX, RY, RZ gates with symbolic parameters will compile (see related issue).
How to Reproduce
Either run the example code provided, or:
and
Code Snippet
Error Output
or
Environment
Quilc version 1.26.0