Skip to content

C[Toffoli] swaps control register depending on control value #1768

@petim0

Description

@petim0

The controlled version of Toffoli() has inconsistent register ordering depending on the value of cvs
See this minimal example:

from qualtran.bloqs.basic_gates import Toffoli, CNOT
from qualtran import CtrlSpec, QBit

print(Toffoli().controlled(CtrlSpec(QBit(), cvs=0)).signature)
print(Toffoli().controlled(CtrlSpec(QBit(), cvs=1)).signature)

>>> Signature((
        Register(name='ctrl2', dtype=QBit(), _shape=(), side=<Side.THRU: 3>), 
        Register(name='ctrl', dtype=QBit(), _shape=(2,), side=<Side.THRU: 3>), 
        Register(name='target', dtype=QBit(), _shape=(), side=<Side.THRU: 3>)))
>>> Signature((
        Register(name='ctrl2', dtype=QBit(), _shape=(2,), side=<Side.THRU: 3>), 
        Register(name='ctrl', dtype=QBit(), _shape=(), side=<Side.THRU: 3>), 
        Register(name='target', dtype=QBit(), _shape=(), side=<Side.THRU: 3>)))

We see here that when we change the control value from 0 to 1, the control registers are swapped:

  • In the first case ctrl2 is contains the new control and ctrl holds the initial 2 controls
  • In the second case ctrl2 holds the initial 2 controls and ctrl is the new control qubit.

It is an issue since when the control value is a parameter of the bloq we must call bb.add(...) differently which adds a lot of overhead.

Note: This does not happens when the qdtype of CtrlSpec is not a QBit

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions