Skip to content

Conversation

@viathor
Copy link
Collaborator

@viathor viathor commented Jun 23, 2022

This makes it easier to use any single-qubit Clifford gate in tests, including currently neglected order-3 Cliffords. See context.

The PR also simplifies the construction of the gates. In particular, we don't need a simulator to get a gate's tableau.

@viathor viathor requested review from a team, cduck and vtomole as code owners June 23, 2022 16:55
@viathor viathor requested a review from pavoljuhas June 23, 2022 16:55
@CirqBot CirqBot added the size: M 50< lines changed <250 label Jun 23, 2022
@viathor viathor requested a review from maffoo June 23, 2022 16:57
"""A metaclass used to lazy initialize several common Clifford Gate as class attributes."""

@property
def all_single_qubit_cliffords(cls):
Copy link
Contributor

Choose a reason for hiding this comment

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

nit: add return type annotation.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Done

mY = (pauli_gates.Y, True)
pZ = (pauli_gates.Z, False)
mZ = (pauli_gates.Z, True)
cls._all_single_qubit_cliffords = tuple([
Copy link
Contributor

Choose a reason for hiding this comment

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

nit: use tuple literal instead:

Suggested change
cls._all_single_qubit_cliffords = tuple([
cls._all_single_qubit_cliffords = (

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Hehe, done before I saw the comment :-)

if getattr(cls, '_I', None) is None:
cls._I = cls._generate_clifford_from_known_gate(1, identity.I)
return cls._I
return cls.all_single_qubit_cliffords[0]
Copy link
Contributor

Choose a reason for hiding this comment

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

I'm not stoked about these indices which could get out of sync with the tuple of all gates, but I don't have a great alternative. At very least, we should document that the order of the all gates tuple should not be changed without updating these indices.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Also not a big fan of the constants. An alternative I considered was to use a Dict[str, ...], but it involves making up names for all Clifford gates most of which would be highly non-standard.

I imagine that anyone wanting access to a specific gate would use a property (e.g. CliffordGate.X_sqrt) and folks would use all_single_qubit_cliffords if they really want to get all 24. Here's to wishful thinking :-)

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

WDYT?

Copy link
Contributor

Choose a reason for hiding this comment

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

SGTM

Copy link
Collaborator

Choose a reason for hiding this comment

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

Perhaps a namedtuple could help here. You could use property names for the items that should be accessible as properties and a say repeated _12 name with the rename=True argument for all other gates for which you don't care about the name.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

AFAICT, the primary (only?) use-case for all_single_qubit_cliffords is the situation where someone wants to iterate over all single-qubit Cliffords, e.g. to execute a test-case on all of them. I think using namedtuple adds unnecessary clutter to output and is potentially confusing.

Copy link
Collaborator Author

@viathor viathor left a comment

Choose a reason for hiding this comment

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

PTAL

if getattr(cls, '_I', None) is None:
cls._I = cls._generate_clifford_from_known_gate(1, identity.I)
return cls._I
return cls.all_single_qubit_cliffords[0]
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

WDYT?

Copy link
Contributor

@maffoo maffoo left a comment

Choose a reason for hiding this comment

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

Minor comments, then LGTM.

t = qis.CliffordTableau(num_qubits=2)
t.xs = [[1, 1], [0, 1], [0, 0], [0, 0]]
t.zs = [[0, 0], [0, 0], [1, 0], [1, 1]]
cls._CNOT = cls.from_clifford_tableau(t)
Copy link
Contributor

Choose a reason for hiding this comment

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

For two-qubit cliffords, I'd suggest explicitly calling the method on CliffordGate, since this will be mixed in to the single-qubit class as well:

Suggested change
cls._CNOT = cls.from_clifford_tableau(t)
cls._CNOT = CliffordGate.from_clifford_tableau(t)

Same for CZ and SWAP below.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Thanks for catching this! Done.

@viathor viathor merged commit 2cdf05f into quantumlib:master Jun 24, 2022
@viathor viathor deleted the u/viathor/sq-cliffords branch June 24, 2022 03:00
)
cls._Z_sqrt = SingleQubitCliffordGate.from_clifford_tableau(_clifford_tableau)
return cls._Z_sqrt
return cls.all_single_qubit_cliffords[6]
Copy link
Collaborator

@pavoljuhas pavoljuhas Jun 24, 2022

Choose a reason for hiding this comment

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

This is the same as S on line 234. Not sure which one is a typo.

Can you perhaps add an independent test that class-property gates have correct values?
If you keep the current property implementation with indexed lookup, such test will fail when
all_single_qubit_cliffords go out of order.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

The S gate and Z_sqrt are the same gate. Square the S gate to convince yourself of that.

The PR does include independent test (test_all_single_qubit_clifford_unitaries) that checks all the gates have correct values. It is already order-sensitive.

Copy link
Collaborator

@pavoljuhas pavoljuhas left a comment

Choose a reason for hiding this comment

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

S and Z_sqrt are identical, perhaps a typo.

rht pushed a commit to rht/Cirq that referenced this pull request May 1, 2023
harry-phasecraft pushed a commit to PhaseCraft/Cirq that referenced this pull request Oct 31, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size: M 50< lines changed <250

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants