Skip to content

✨ Correct register-aware unitary embedding for CtrlOp::getUnitaryMatrix #1821

Description

@simon1hofmann

Problem Statement

CtrlOp::getUnitaryMatrix() currently embeds the inner gate unitary via setBottomRightCorner, which implements I_{2^c} ⊗ U. That only corresponds to the intended controlled operator when control qubits sit on more significant register positions than the targets (e.g. cx(1, 0) in little-endian indexing).

For the common case cx(0, 1) — control on qubit 0, target on qubit 1 — the returned matrix does not match QuantumComputation with the same register indices. Operand order in the ctrl op is not reflected correctly; cx(0, 1) and cx(1, 0) are not distinguished as they should be.

This limits reliable use of getUnitaryMatrix() for controlled operations in optimizations, verification, and cross-checks against QuantumComputation or Qiskit. An existing CX test inadvertently compared cx(q[0], q[1]) against comp.cx(1, 0) rather than comp.cx(0, 1), hiding the mismatch.

Example:

// QCO: control q[0], target q[1]
ctrl(%c0, %t1) { cx ... }

// Should match qc::QuantumComputation::cx(0, 1), not cx(1, 0)

Proposed Solution

Introduce register-aware controlled embedding for CtrlOp::getUnitaryMatrix().

Metadata

Metadata

Assignees

Labels

MLIRAnything related to MLIRc++Anything related to C++ code

Type

No type

Fields

No fields configured for issues without a type.

Projects

No projects

Relationships

None yet

Development

No branches or pull requests

Issue actions