Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
50 commits
Select commit Hold shift + click to select a range
309f3eb
feat: add Rzz gate implementation and update initialization parameters
JulienCalistoTD Feb 18, 2026
ba3648b
fix: update CustomGate to use identity operation and improve label fo…
JulienCalistoTD Feb 24, 2026
8bf4811
feat: add PRX gate implementation and update gate imports
JulienCalistoTD Feb 25, 2026
0ee55c9
feat: update PRX gate to use parameters directly and improve language…
JulienCalistoTD Feb 25, 2026
c1852e4
feat: update PRX gate to use sympy functions for trigonometric calcul…
JulienCalistoTD Feb 25, 2026
7495a58
feat: refactor PRX gate to use Rz and Rx matrices for canonical matri…
JulienCalistoTD Feb 25, 2026
f9219fc
feat: update PRX gate initialization to store target as a list
JulienCalistoTD Feb 25, 2026
0d796e2
feat: update PRX gate to use 'targets' attribute for multiple target …
JulienCalistoTD Feb 25, 2026
1201814
feat: update PRX gate to return RZ and RX gates for Qiskit integration
JulienCalistoTD Feb 25, 2026
5f4f658
chore: Files formated
github-actions[bot] Feb 25, 2026
c9bf744
feat: add disable_qubit_rewiring option to device.run calls in run_br…
JulienCalistoTD Feb 26, 2026
ede5deb
Merge branch 'feat-New-gate' of https://github.com/ColibrITD-SAS/mpqp…
JulienCalistoTD Feb 26, 2026
68e333f
chore: Files formated
github-actions[bot] Feb 26, 2026
e29381a
feat: adjust target indexing for Braket circuit instructions in QCircuit
JulienCalistoTD Feb 26, 2026
2d28df5
Merge branch 'feat-New-gate' of https://github.com/ColibrITD-SAS/mpqp…
JulienCalistoTD Feb 26, 2026
f9d71cb
feat: update Braket circuit handling to use add_verbatim_box method
JulienCalistoTD Mar 10, 2026
4331396
feat: optimize target indexing for Braket circuit instructions in QCi…
JulienCalistoTD Mar 10, 2026
76af3b6
feat: update Braket circuit handling to directly add instructions wit…
JulienCalistoTD Mar 10, 2026
05bdd6d
feat: update installation instructions for providers in getting-start…
JulienCalistoTD Mar 16, 2026
9017258
fix: PRX repr and Braket translation issues
MathieuG-Colibri Mar 24, 2026
de7a220
feat: fix adjust_measure on simple pauli strings
MathieuG-Colibri Mar 25, 2026
c2001a0
fix: adjust_measure padding, apply pre_measure swap
MoHermes Mar 26, 2026
2d4eb43
fix: remove pre_measure swaps, apply direct embedding
MoHermes Mar 29, 2026
9340557
chore: Files formated
github-actions[bot] Mar 29, 2026
724f062
fix: added observables all providers handling
MathieuG-Colibri Apr 1, 2026
e969527
chore: Files formated
github-actions[bot] Apr 1, 2026
12a4bb0
Merge branch 'dev' into feat-New-gate
MathieuG-Colibri Apr 3, 2026
8ebd474
feat: added ComposedGates and fixed tests
MathieuG-Colibri Apr 13, 2026
1050804
Merge branch 'feat-New-gate' of https://github.com/ColibrITD-SAS/mpqp…
MathieuG-Colibri Apr 13, 2026
939f92e
chore: Files formated
github-actions[bot] Apr 13, 2026
8a30c81
feat: added testsuite
MathieuG-Colibri Apr 21, 2026
442132e
fix: merge and testsuite
MathieuG-Colibri Apr 21, 2026
60ef840
chore: Files formated
github-actions[bot] Apr 21, 2026
bdbb6b7
fix: pyright
MathieuG-Colibri Apr 21, 2026
6343ce4
Merge branch 'feat-New-gate' of github.com:ColibrITD-SAS/mpqp into fe…
MathieuG-Colibri Apr 21, 2026
56f8508
feat: added test and translation for ccu
MathieuG-Colibri Apr 23, 2026
7571814
fix: ccu qiskit and braket issues, changed cirq unitary behavior to h…
MathieuG-Colibri Apr 30, 2026
aef067c
chore: Files formated
github-actions[bot] Apr 30, 2026
001d400
fix: custom gate handling in cirq, decomposition bugs, particular gat…
MathieuG-Colibri May 5, 2026
aae68c2
fix: unitary decomposition non ordered qubits
MathieuG-Colibri May 6, 2026
0bd147c
feat: add native Rxx and Ryy rotation gates
MoHermes May 13, 2026
18d6c9c
fix: stabilize CustomGate translation across qiskit and cirq, tests p…
MoHermes May 18, 2026
9b6e0a2
chore: Files formated
github-actions[bot] May 18, 2026
a6d2be7
fix: type annotations for decomposition angles
MoHermes May 19, 2026
25e8f71
Merge branch 'feat-New-gate' of github.com:ColibrITD-SAS/mpqp into fe…
MoHermes May 19, 2026
1d297cf
test: clarify CustomControlledGate translation tests
MoHermes May 19, 2026
0a971f5
test: add Rxx and Ryy composed decompositions
MoHermes May 19, 2026
7864f92
docs: add Rxx and Ryy documentation
MoHermes May 20, 2026
c87d5c4
test: cover Rxx, Ryy, Rzz and PRX gates
MoHermes May 20, 2026
f4477b3
docs: update docs
MoHermes May 27, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions mpqp/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@
CNOT,
CP,
CZ,
PRX,
SWAP,
TOF,
ControlledGate,
Expand All @@ -53,8 +54,11 @@
Rk,
Rk_dagger,
Rx,
Rxx,
Ry,
Ryy,
Rz,
Rzz,
S,
S_dagger,
T,
Expand Down
335 changes: 81 additions & 254 deletions mpqp/core/circuit.py

Large diffs are not rendered by default.

9 changes: 7 additions & 2 deletions mpqp/core/instruction/gates/__init__.py
Original file line number Diff line number Diff line change
@@ -1,25 +1,30 @@
# pyright: reportUnusedImport=false
from .controlled_gate import ControlledGate
from .custom_gate import CustomGate, UnitaryMatrix
from .custom_controlled_gate import CustomControlledGate
from .custom_gate import CustomGate, UnitaryMatrix
from .gate import Gate
from .gate_definition import GateDefinition
from .native_gates import (
CNOT,
CP,
CZ,
PRX,
SWAP,
TOF,
ComposedGate,
CRk,
CRk_dagger,
H,
Id,
P,
CP,
Rk,
Rk_dagger,
Rx,
Rxx,
Ry,
Ryy,
Rz,
Rzz,
S,
S_dagger,
T,
Expand Down
37 changes: 26 additions & 11 deletions mpqp/core/instruction/gates/custom_controlled_gate.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,11 +34,13 @@ class CustomControlledGate(ControlledGate):
>>> circuit = QCircuit(3)
>>> circuit.add(CustomControlledGate([0,2], CustomGate(np.array([[1,0],[0,-1]]),[1])))
>>> print(circuit) # doctest: +NORMALIZE_WHITESPACE
q_0: ─────■─────
┌────┴────┐
q_1: ┤ Unitary ├
└────┬────┘
q_2: ─────■─────
┌──────────┐
q_0: ┤2 ├
│ │
q_1: ┤1 Unitary ├
│ │
q_2: ┤0 ├
└──────────┘
Comment on lines +37 to +43
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

We lose here the info that the gate is controlled by qubit 0 and 2 in the print, do you think there is still a way to do it, or it is not a big loss ? Because from a conceptual MPQP point of view we mentioned explicitly (in the example) that it is a CustomControlledGate, so it is sad that it is handled after like a generic 3-qubit Unitary


"""

Expand Down Expand Up @@ -85,21 +87,34 @@ def to_other_language(
language: Language = Language.QISKIT,
qiskit_parameters: Optional[set["Parameter"]] = None,
) -> Any:
if isinstance(self.non_controlled_gate, CustomGate):
return self.to_custom_gate().to_other_language(language)
if language == Language.QISKIT:

from qiskit.quantum_info import Operator

gate = self.non_controlled_gate.to_other_language()
if isinstance(gate, Operator):
gate = gate.to_instruction()
gate = gate.control(len(self.controls))
return gate
elif language == Language.QASM2:
if isinstance(self.non_controlled_gate, CustomGate):
targets = self.targets + self.controls
targets.sort()
gate = CustomGate(self.to_matrix(), targets)
elif language == Language.CIRQ:

from cirq import ControlledGate as cirqControlledGate

return gate.to_other_language(Language.QASM2)
return cirqControlledGate(
sub_gate=self.non_controlled_gate.to_other_language(Language.CIRQ),
num_controls=len(self.controls),
)
elif language == Language.BRAKET:
from braket.circuits import Instruction as BraketInstruction

return BraketInstruction(
operator=self.non_controlled_gate.to_other_language(language).operator,
target=self.targets,
control=self.controls,
)
elif language == Language.QASM2:

from qiskit import QuantumCircuit, qasm2

Expand Down
59 changes: 24 additions & 35 deletions mpqp/core/instruction/gates/custom_gate.py
Original file line number Diff line number Diff line change
Expand Up @@ -129,12 +129,11 @@ def to_other_language(
from qiskit import QuantumCircuit

dummy_circuit = QuantumCircuit(self.nb_qubits)
for param in qiskit_parameters:
# Rx is just a random choice so to have the parameter in the
# list of inputs
dummy_circuit.rx(param, 0)
return dummy_circuit.to_gate(label="CustomGate")
return UnitaryGate(self.matrix)
dummy_circuit.id(0)
return dummy_circuit.to_gate(
label=f"CustomGate({', '.join([str(s) for s in gate_symbols])})"
)
return UnitaryGate(self.matrix, label=self.label, check_input=False)
elif language == Language.BRAKET:
from sympy import Expr

Expand Down Expand Up @@ -162,32 +161,9 @@ def to_other_language(
target=self.targets,
)
elif language == Language.CIRQ:
from cirq import Gate as cirqGate

# TODO: find clean way of initiating this class once
# Cost is negli
class cirqCustomGate(cirqGate):
def __init__(self, matrix: Matrix, label: str | None):
import numpy as np

self.matrix = matrix
self.label = label
self._nb_qubits = int(np.log2(len(matrix)))
super(cirqCustomGate, self)

def _num_qubits_(self) -> int:
return self._nb_qubits

def _unitary_(self) -> Matrix:
return self.matrix

def _circuit_diagram_info_(self, args: list[float]) -> str | list[str]:
# we keep args for later implementation
if self.label:
return [self.label] * self._nb_qubits
return ["CustomGate"] * self._nb_qubits
from cirq import MatrixGate

return cirqCustomGate(self.matrix, self.label)
return MatrixGate(matrix=self.matrix, name=self.label, unitary_check=False)

elif language == Language.QASM2:
from qiskit import QuantumCircuit, qasm2
Expand All @@ -209,9 +185,7 @@ def _circuit_diagram_info_(self, args: list[float]) -> str | list[str]:
self.label,
)

circuit, gphase = replace_custom_gate(
qiskit_circ.data[0], nb_qubits, self.targets
)
circuit, gphase = replace_custom_gate(qiskit_circ, nb_qubits, self.targets)

qasm_str = qasm2.dumps(circuit)
qasm_lines = qasm_str.splitlines()
Expand Down Expand Up @@ -251,7 +225,22 @@ def decompose(self) -> "QCircuit":
"""
from mpqp.tools.unitary_decomposition import quantum_shannon_decomposition

return quantum_shannon_decomposition(self.matrix)
# non ordered targets
if any(
self.targets[i + 1] < self.targets[i] for i in range(len(self.targets) - 1)
):
from copy import deepcopy

from mpqp.tools import rearrange_matrix

targets = deepcopy(self.targets)
targets.sort()

return quantum_shannon_decomposition(
rearrange_matrix(self.matrix, self.targets, copy=True), targets
)

return quantum_shannon_decomposition(self.matrix, self.targets)

def subs(self, values: dict[Expr | str, Complex]) -> CustomGate:
res = copy(self)
Expand Down
Loading
Loading