rigetti / pyquil

A Python library for quantum programming using Quil.
http://docs.rigetti.com
Apache License 2.0
1.4k stars 341 forks source link

latex display: unify display of CCNOT equivalents #1193

Open adamglos92 opened 4 years ago

adamglos92 commented 4 years ago

Pre-Request Checklist

Issue Description

Currently, when displaying CCNOT gate we have a big multigate when displaying. Would it be possible to replace the output to similar as for X(2).controlled(0).controlled(1) or CNOT? In general, is it possible to unify the displaying?

from pyquil import Program
from pyquil.gates import X, CNOT, CCNOT
from pyquil.latex import display

p = Program()
p += X(2).controlled(0).controlled(1)
p += CNOT(1, 2).controlled(0)
p += CNOT(1, 2)
p += CCNOT(0, 1, 2)

display(p)

cnots

adamglos92 commented 4 years ago

Is there a difference between CCNOT and X.controlled().controlled()?

appleby commented 4 years ago

Functionally they are equivalent, but AFAIK it will result in different code paths through the compiler / simulator, so it may be useful to distinguish them in diagrams.

CC @kilimanjaro

braised-babbage commented 4 years ago

This is doable, although it makes sense to think about exactly what cases we want to cover.

As @appleby mentions, the difference between CCNOT and X.controlled().controlled() is that they are represented by distinct syntax objects, and software processing these may or may not recognize them as equivalent (e.g. parts of quilc consider them to be equivalent, since they produce the same gate matrices, but other parts, such as the printer, consider them as distinct).

The latex code generation is pretty dumb about all of this. Basically I treated every syntactically distinct gate as being actually distinct, and then hardcoded a few special cases to get diagrams that people like (e.g. the crowd goes wild for that CNOT(1,2) above).

It wouldn't be terribly difficult to add a similar special case for CCNOT. Right now the data for these special cases is stored in pyquil.latex._diagram.SOURCE_TARGET_OP, indexed by the gate name, and handled by pyquil.latex._diagram.DiagramBuilder._build_custom_source_target_op. I am, however, sensitive to putting in too many weird special cases, and as it stands these cases assume 2q gates (which is what we see with CZ, CNOT, SWAP, etc).

I think if we wanted to do this work we should just go the extra mile and implement something akin to what is proposed in #1197.

Edit: Created #1197 with details that were previously discussed here.