Closed
Description
Describe your design idea/issue
It would be nice to make things consistent such that quantum operations (as opposed to control operation classes like subcircuits and feedforward) all have associated gates. Most do. The ones I see that don't are:
- BooleanHamiltonean: This seems straightforward to convert: instead of qubit_map, the BooleanHamiltoneanGate.init would just take a list of names, and then implement the decompose_once_with_qubits protocol to create the qubit_map on demand using self.names and the passed in qubits.
- PauliStringPhasor and PauliStringGateOperation: Haven't looked at these.
- GlobalPhaseOperation: This is always an oddball. But we could make a GlobalPhaseGate easily enough and it would fit better in some ways. Granted, GlobalPhaseGate().on(tuple()) is weird. But it does play well with other gates, like if someone wanted a function that zipped up gates and qubits, this would allow them to add global phases to that.
The advantages of doing this are:
- Gates are more reusable (you can have my_x=X**0.8 and then apply that to different qubits, etc. With an op you'd have to **0.8 each time). With things like BooleanHamiltonean this could be nice too.
- They fit cleaner in gatesets (GlobalPhaseGate would likely allow for cleanup of some existing gateset code)
- You can typically operate on them at a lower level, e.g. with state vectors and axes, rather than requiring qubits and full simulators.
- Consistency for consistency's sake.
Disadvantages:
- e.g.
GateOperation(PauliStringPhasorGate(), q)
is not the same asPauliStringPhasorGate.on(q)
: we still want the latter to return aPauliStringPhasorOperation
because it has extra functionality. So maybe this is confusing.