Skip to content

Commit ff5568b

Browse files
committed
Add if_ method also to Python package
1 parent 0bf6533 commit ff5568b

File tree

4 files changed

+316
-18
lines changed

4 files changed

+316
-18
lines changed

bindings/ir/register_quantum_computation.cpp

Lines changed: 62 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -441,22 +441,77 @@ void registerQuantumComputation(py::module& m) {
441441
self.ifElse(std::move(thenPtr), std::move(elsePtr), controlRegister,
442442
expectedValue, kind);
443443
},
444-
"then_operation"_a, "else_operation"_a, "creg"_a, "expected_value"_a = 1U,
445-
"comparison_kind"_a = qc::ComparisonKind::Eq);
444+
"then_operation"_a, "else_operation"_a, "control_register"_a,
445+
"expected_value"_a = 1U, "comparison_kind"_a = qc::ComparisonKind::Eq);
446446
qc.def(
447447
"if_else",
448448
[](qc::QuantumComputation& self, qc::Operation* thenOp,
449-
qc::Operation* elseOp, const qc::Bit cbit,
449+
qc::Operation* elseOp, const qc::Bit controlBit,
450450
const std::uint64_t expectedValue = 1U,
451451
const qc::ComparisonKind kind = qc::ComparisonKind::Eq) {
452452
std::unique_ptr<qc::Operation> thenPtr =
453453
thenOp ? thenOp->clone() : nullptr;
454454
std::unique_ptr<qc::Operation> elsePtr =
455455
elseOp ? elseOp->clone() : nullptr;
456-
self.ifElse(std::move(thenPtr), std::move(elsePtr), cbit, expectedValue,
457-
kind);
456+
self.ifElse(std::move(thenPtr), std::move(elsePtr), controlBit,
457+
expectedValue, kind);
458458
},
459-
"then_op"_a, "else_op"_a, "cbit"_a, "expected_value"_a = 1U,
460-
"comparison_kind"_a = qc::ComparisonKind::Eq);
459+
"then_operation"_a, "else_operation"_a, "control_bit"_a,
460+
"expected_value"_a = 1U, "comparison_kind"_a = qc::ComparisonKind::Eq);
461+
462+
qc.def(
463+
"if_",
464+
py::overload_cast<const qc::OpType, const qc::Qubit,
465+
const qc::ClassicalRegister&, const std::uint64_t,
466+
const qc::ComparisonKind, const std::vector<qc::fp>&>(
467+
&qc::QuantumComputation::if_),
468+
"op"_a, "target"_a, "control_register"_a, "expected_value"_a = 1U,
469+
"comparison_kind"_a = qc::ComparisonKind::Eq,
470+
"params"_a = std::vector<qc::fp>{});
471+
qc.def(
472+
"if_",
473+
py::overload_cast<const qc::OpType, const qc::Qubit, const qc::Control,
474+
const qc::ClassicalRegister&, const std::uint64_t,
475+
const qc::ComparisonKind, const std::vector<qc::fp>&>(
476+
&qc::QuantumComputation::if_),
477+
"op"_a, "target"_a, "control"_a, "control_register"_a,
478+
"expected_value"_a = 1U, "comparison_kind"_a = qc::ComparisonKind::Eq,
479+
"params"_a = std::vector<qc::fp>{});
480+
qc.def(
481+
"if_",
482+
py::overload_cast<const qc::OpType, const qc::Qubit, const qc::Controls&,
483+
const qc::ClassicalRegister&, const std::uint64_t,
484+
const qc::ComparisonKind, const std::vector<qc::fp>&>(
485+
&qc::QuantumComputation::if_),
486+
"op"_a, "target"_a, "controls"_a, "control_register"_a,
487+
"expected_value"_a = 1U, "comparison_kind"_a = qc::ComparisonKind::Eq,
488+
"params"_a = std::vector<qc::fp>{});
489+
qc.def("if_",
490+
py::overload_cast<const qc::OpType, const qc::Qubit, const qc::Bit,
491+
const bool, const qc::ComparisonKind,
492+
const std::vector<qc::fp>&>(
493+
&qc::QuantumComputation::if_),
494+
"op"_a, "target"_a, "control_bit"_a, "expected_value"_a = true,
495+
"comparison_kind"_a = qc::ComparisonKind::Eq,
496+
"params"_a = std::vector<qc::fp>{});
497+
qc.def("if_",
498+
py::overload_cast<const qc::OpType, const qc::Qubit, const qc::Control,
499+
const qc::Bit, const bool, const qc::ComparisonKind,
500+
const std::vector<qc::fp>&>(
501+
&qc::QuantumComputation::if_),
502+
"op"_a, "target"_a, "control"_a, "control_bit"_a,
503+
"expected_value"_a = true,
504+
"comparison_kind"_a = qc::ComparisonKind::Eq,
505+
"params"_a = std::vector<qc::fp>{});
506+
qc.def(
507+
"if_",
508+
py::overload_cast<const qc::OpType, const qc::Qubit, const qc::Controls&,
509+
const qc::Bit, const bool, const qc::ComparisonKind,
510+
const std::vector<qc::fp>&>(
511+
&qc::QuantumComputation::if_),
512+
"op"_a, "target"_a, "controls"_a, "control_bit"_a,
513+
"expected_value"_a = true, "comparison_kind"_a = qc::ComparisonKind::Eq,
514+
"params"_a = std::vector<qc::fp>{});
461515
}
516+
462517
} // namespace mqt

python/mqt/core/ir/__init__.pyi

Lines changed: 143 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ from collections.abc import ItemsView, Iterable, Iterator, Mapping, MutableMappi
1212
from os import PathLike
1313
from typing import overload
1414

15-
from .operations import ComparisonKind, Control, Operation
15+
from .operations import ComparisonKind, Control, Operation, OpType
1616
from .registers import ClassicalRegister, QuantumRegister
1717
from .symbolic import Expression, Variable
1818

@@ -1868,17 +1868,17 @@ class QuantumComputation(MutableSequence[Operation]):
18681868
self,
18691869
then_operation: Operation,
18701870
else_operation: Operation | None,
1871-
creg: ClassicalRegister,
1871+
control_register: ClassicalRegister,
18721872
expected_value: int = 1,
18731873
comparison_kind: ComparisonKind = ComparisonKind.eq,
18741874
) -> None:
1875-
"""Add a classic-controlled operation to the circuit.
1875+
"""Add an if-else operation to the circuit.
18761876
18771877
Args:
18781878
then_operation: The operation to apply if the condition is met
18791879
else_operation: The operation to apply if the condition is not met
1880-
creg: The classical register
1881-
expected_value: The expected value of the classical register
1880+
control_register: The classical register to check against
1881+
expected_value: The expected value of the control register
18821882
comparison_kind: The kind of comparison to perform
18831883
"""
18841884

@@ -1887,16 +1887,150 @@ class QuantumComputation(MutableSequence[Operation]):
18871887
self,
18881888
then_operation: Operation,
18891889
else_operation: Operation | None,
1890-
cbit: int,
1890+
control_bit: int,
18911891
expected_value: int = 1,
18921892
comparison_kind: ComparisonKind = ComparisonKind.eq,
18931893
) -> None:
1894-
"""Add a classic-controlled operation to the circuit.
1894+
"""Add an if-else operation to the circuit.
18951895
18961896
Args:
18971897
then_operation: The operation to apply if the condition is met
18981898
else_operation: The operation to apply if the condition is not met
1899-
cbit: The classical bit index
1900-
expected_value: The expected value of the classical register
1899+
control_bit: The index of the classical bit to check against
1900+
expected_value: The expected value of the control bit
1901+
comparison_kind: The kind of comparison to perform
1902+
"""
1903+
1904+
@overload
1905+
def if_(
1906+
self,
1907+
op: OpType,
1908+
target: int,
1909+
control_register: ClassicalRegister,
1910+
expected_value: int = 1,
1911+
comparison_kind: ComparisonKind = ComparisonKind.eq,
1912+
params: Sequence[float] = (),
1913+
) -> None:
1914+
"""Add an if operartion to the circuit.
1915+
1916+
Args:
1917+
op: The operation to apply
1918+
target: The target qubit
1919+
control_register: The classical register to check against
1920+
expected_value: The expected value of the control register
1921+
comparison_kind: The kind of comparison to perform
1922+
params: The parameters of the operation
1923+
"""
1924+
1925+
@overload
1926+
def if_(
1927+
self,
1928+
op: OpType,
1929+
target: int,
1930+
control: Control | int,
1931+
control_register: ClassicalRegister,
1932+
expected_value: int = 1,
1933+
comparison_kind: ComparisonKind = ComparisonKind.eq,
1934+
params: Sequence[float] = (),
1935+
) -> None:
1936+
"""Add a classic-controlled operation to the circuit.
1937+
1938+
Args:
1939+
op: The operation to apply
1940+
target: The target qubit
1941+
control: The control qubit
1942+
control_register: The classical register to check against
1943+
expected_value: The expected value of the control register
1944+
comparison_kind: The kind of comparison to perform
1945+
params: The parameters of the operation.
1946+
"""
1947+
1948+
@overload
1949+
def if_(
1950+
self,
1951+
op: OpType,
1952+
target: int,
1953+
controls: set[Control | int],
1954+
control_register: ClassicalRegister,
1955+
expected_value: int = 1,
1956+
comparison_kind: ComparisonKind = ComparisonKind.eq,
1957+
params: Sequence[float] = (),
1958+
) -> None:
1959+
"""Add a classic-controlled operation to the circuit.
1960+
1961+
Args:
1962+
op: The operation to apply
1963+
target: The target qubit
1964+
controls: The control qubits
1965+
control_register: The classical register to check against
1966+
expected_value: The expected value of the control register
1967+
comparison_kind: The kind of comparison to perform
1968+
params: The parameters of the operation.
1969+
"""
1970+
1971+
@overload
1972+
def if_(
1973+
self,
1974+
op: OpType,
1975+
target: int,
1976+
control_bit: int,
1977+
expected_value: bool = True,
1978+
comparison_kind: ComparisonKind = ComparisonKind.eq,
1979+
params: Sequence[float] = (),
1980+
) -> None:
1981+
"""Add a classic-controlled operation to the circuit.
1982+
1983+
Args:
1984+
op: The operation to apply
1985+
target: The target qubit
1986+
control_bit: The index of the classical bit to check against
1987+
expected_value: The expected value of the control bit
1988+
comparison_kind: The kind of comparison to perform
1989+
params: The parameters of the operation.
1990+
"""
1991+
1992+
@overload
1993+
def if_(
1994+
self,
1995+
op: OpType,
1996+
target: int,
1997+
control: Control | int,
1998+
control_bit: int,
1999+
expected_value: bool = True,
2000+
comparison_kind: ComparisonKind = ComparisonKind.eq,
2001+
params: Sequence[float] = (),
2002+
) -> None:
2003+
"""Add a classic-controlled operation to the circuit.
2004+
2005+
Args:
2006+
op: The operation to apply
2007+
target: The target qubit
2008+
control: The control qubit
2009+
control_bit: The index of the classical bit to check against
2010+
expected_value: The expected value of the control bit
2011+
comparison_kind: The kind of comparison to perform
2012+
params: The parameters of the operation.
2013+
"""
2014+
2015+
@overload
2016+
def if_(
2017+
self,
2018+
op: OpType,
2019+
target: int,
2020+
controls: set[Control | int],
2021+
control_bit: int,
2022+
expected_value: bool = True,
2023+
comparison_kind: ComparisonKind = ComparisonKind.eq,
2024+
params: Sequence[float] = (),
2025+
) -> None:
2026+
"""Add a classic-controlled operation to the circuit.
2027+
2028+
Args:
2029+
op: The operation to apply
2030+
target: The target qubit
2031+
controls: The control qubits
2032+
control_bit: The index of the classical bit to check against
2033+
expected_value: The expected value of the control bit
19012034
comparison_kind: The kind of comparison to perform
2035+
params: The parameters of the operation.
19022036
"""

test/python/dd/test_dd_package.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414

1515
from mqt.core.dd import DDPackage, build_functionality, sample, simulate
1616
from mqt.core.ir import QuantumComputation
17-
from mqt.core.ir.operations import OpType, StandardOperation
17+
from mqt.core.ir.operations import OpType
1818

1919

2020
def test_sample_simple_circuit() -> None:
@@ -35,7 +35,7 @@ def test_sample_dynamic_circuit() -> None:
3535
qc.h(0)
3636
# reset the qubit
3737
qc.measure(0, 0)
38-
qc.if_else(StandardOperation(0, OpType.x), None, cbit=0, expected_value=1)
38+
qc.if_(OpType.x, target=0, control_bit=0)
3939
# flip to |1>
4040
qc.x(0)
4141
# measure the qubit

0 commit comments

Comments
 (0)