diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 13eadec..0fe42a7 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -80,4 +80,4 @@ repos: rev: v2.2.5 hooks: - id: codespell - args: [ "-L", "wille,braket,coo", "--skip", "*.ipynb" ] + args: ["-L", "wille,braket,coo", "--skip", "*.ipynb"] diff --git a/src/main.py b/src/main.py index 8988cb5..bde76fb 100644 --- a/src/main.py +++ b/src/main.py @@ -16,7 +16,8 @@ measure q[1] -> meas[1]; measure q[2] -> meas[2]; """ - +c = QuantumCircuit() +c.from_qasm(qasm) print(QASM().parse_ditqasm2_str(qasm)) s = QuantumRegister("x", 2) print(s.__qasm__) diff --git a/src/mqt/circuit/circuit.py b/src/mqt/circuit/circuit.py index 04b095a..ab4a842 100644 --- a/src/mqt/circuit/circuit.py +++ b/src/mqt/circuit/circuit.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from typing import ClassVar from mqt.circuit.quantum_register import QuantumRegister @@ -59,58 +61,70 @@ def append(self, qreg: QuantumRegister): qreg.local_sitemap[i] = num_lines_stored + i self._sitemap[(str(qreg.label), i)] = (num_lines_stored + i, qreg.dimensions[i]) - def csum(self, control: int, target: int): + def csum(self, qudits: list[int]): pass - # self.instructions.append(CSum()) - def custom_unitary(self): + def custom_unitary(self, qudits: list[int] | int): pass - def cx(self): + def cx(self, qudits: list[int]): pass - def h(self): + def h(self, qudit: int): pass - def ls(self): + def ls(self, qudits: list[int]): pass - def ms(self): + def ms(self, qudits: list[int]): pass - def pm(self): + def pm(self, params, qudits: list[int] | int): pass - def r(self): + def r(self, params, qudit: int): pass - def rz(self): + def rz(self, params, qudit: int): pass - def s(self): + def s(self, qudit: int): pass - def z(self): + def z(self, qudit: int): pass - def from_qasm_file(self, fname): + def from_qasm(self, qasm_prog): self.reset() - qasm_parser = QASM().parse_ditqasm2_file(fname) - - self._num_qudits = qasm_parser["n"] + qasm_parser = QASM().parse_ditqasm2_str(qasm_prog) instructions = qasm_parser["instructions"] - self._sitemap = qasm_parser["sitemap"] - # self.number_gates = self._sitemap["n_gates"] + temp_sitemap = qasm_parser["sitemap"] + for qreg in QuantumRegister.from_map(temp_sitemap): + self.append(qreg) qasm_set = self.get_qasm_set() for op in instructions: - if op in qasm_set: + if op["name"] in qasm_set: gate_constructor_name = qasm_set[op["name"]] if hasattr(self, gate_constructor_name): function = getattr(self, gate_constructor_name) - function(op["params"], op["qudits"]) + + tuples_qudits = op["qudits"] + if not tuples_qudits: + msg = "Qudit parameter not applied" + raise IndexError(msg) + # Check if the list contains only one tuple + if len(tuples_qudits) == 1: + qudits_call = tuples_qudits[0][0] + # Extract the first element from each tuple and return as a list + else: + qudits_call = [t[0] for t in list(tuples_qudits)] + if op["params"]: + function(op["params"], qudits_call) + else: + function(qudits_call) else: - msg = "the require gate is not available anymore." + msg = "the required gate is not available anymore." raise NotImplementedError(msg) def to_qasm(self): @@ -121,26 +135,9 @@ def to_qasm(self): for op in self.instructions: text += op.__qasm__ - """ def draw(self): - custom_counter = 0 - - for line in self.qreg: - print("|0>---", end="") - for gate in line: - if isinstance(gate, Rz): - print("--[Rz" + str(gate.lev) + "(" + str(round(gate.theta, 2)) + ")]--", end="") - - elif isinstance(gate, R): - print("--[R" + str(gate.lev_a) + str(gate.lev_b) + "(" + str(round(gate.theta, 2)) + "," + str( - round(gate.phi, 2)) + ")]--", end="") - - elif isinstance(gate, Custom_Unitary): - print("--[C" + str(custom_counter) + "]--", end="") - custom_counter = custom_counter + 1 - - print("---=||") - """ + # TODO + pass def reset(self): self.number_gates = 0 diff --git a/src/mqt/circuit/instructions/gate.py b/src/mqt/circuit/instructions/gate.py index aa02047..040cf2f 100644 --- a/src/mqt/circuit/instructions/gate.py +++ b/src/mqt/circuit/instructions/gate.py @@ -64,8 +64,8 @@ def to_matrix(self) -> Callable[[str], ndarray]: def control( self, num_ctrl_qudits: int = 1, - label_indeces: list[int] | list[str] | int | str | None = None, - ctrl_state: list[int] | list[str] | int | str | None = None, + label_indeces: list[int] | int | None = None, + ctrl_state: list[int] | int | None = None, ): pass """Return controlled version of gate. See :class:`.ControlledGate` for usage. @@ -106,5 +106,9 @@ def validate_parameter(self, parameter) -> bool: @abstractmethod def __qasm__(self) -> str: - # TODO + pass + + @abstractmethod + def __str__(self): + # String representation for drawing? pass diff --git a/src/mqt/circuit/instructions/gate_set/csum.py b/src/mqt/circuit/instructions/gate_set/csum.py index 4ddaf3d..e5213fc 100644 --- a/src/mqt/circuit/instructions/gate_set/csum.py +++ b/src/mqt/circuit/instructions/gate_set/csum.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from typing import Any from mqt.circuit.instructions.gate import Gate @@ -10,7 +12,12 @@ def __qasm__(self) -> str: def __array__(self, dtype: str = "complex") -> Any: pass - def control(self, num_ctrl_qudits: int = 1, label: str | None = None, ctrl_state: int | str | None = None): + def control( + self, + num_ctrl_qudits: int = 1, + label_indeces: list[int] | int | None = None, + ctrl_state: list[int] | int | None = None, + ): pass def validate_parameter(self, parameter): @@ -18,3 +25,6 @@ def validate_parameter(self, parameter): def __init__(self, name: str, num_qudits: int, params: list): super().__init__(name, num_qudits, params) + + def __str__(self): + pass diff --git a/src/mqt/circuit/instructions/gate_set/customunitary.py b/src/mqt/circuit/instructions/gate_set/customunitary.py index c43ecb1..94cb977 100644 --- a/src/mqt/circuit/instructions/gate_set/customunitary.py +++ b/src/mqt/circuit/instructions/gate_set/customunitary.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from typing import Any from mqt.circuit.instructions.gate import Gate @@ -10,7 +12,12 @@ def __qasm__(self) -> str: def __array__(self, dtype: str = "complex") -> Any: pass - def control(self, num_ctrl_qudits: int = 1, label: str | None = None, ctrl_state: int | str | None = None): + def control( + self, + num_ctrl_qudits: int = 1, + label_indeces: list[int] | int | None = None, + ctrl_state: list[int] | int | None = None, + ): pass def validate_parameter(self, parameter): @@ -18,3 +25,6 @@ def validate_parameter(self, parameter): def __init__(self, name: str, num_qudits: int, params: list): super().__init__(name, num_qudits, params) + + def __str__(self): + pass diff --git a/src/mqt/circuit/instructions/gate_set/cx.py b/src/mqt/circuit/instructions/gate_set/cx.py index acd6654..14716ea 100644 --- a/src/mqt/circuit/instructions/gate_set/cx.py +++ b/src/mqt/circuit/instructions/gate_set/cx.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from typing import Any from mqt.circuit.instructions.gate import Gate @@ -10,7 +12,12 @@ def __qasm__(self) -> str: def __array__(self, dtype: str = "complex") -> Any: pass - def control(self, num_ctrl_qudits: int = 1, label: str | None = None, ctrl_state: int | str | None = None): + def control( + self, + num_ctrl_qudits: int = 1, + label_indeces: list[int] | int | None = None, + ctrl_state: list[int] | int | None = None, + ): pass def validate_parameter(self, parameter): @@ -18,3 +25,6 @@ def validate_parameter(self, parameter): def __init__(self, name: str, num_qudits: int, params: list): super().__init__(name, num_qudits, params) + + def __str__(self): + pass diff --git a/src/mqt/simulation/noise/__init__.py b/src/mqt/circuit/instructions/gate_set/gate_utils/__init__.py similarity index 100% rename from src/mqt/simulation/noise/__init__.py rename to src/mqt/circuit/instructions/gate_set/gate_utils/__init__.py diff --git a/src/mqt/circuit/instructions/gate_set/gellman.py b/src/mqt/circuit/instructions/gate_set/gellman.py index aa53fda..45cfcaf 100644 --- a/src/mqt/circuit/instructions/gate_set/gellman.py +++ b/src/mqt/circuit/instructions/gate_set/gellman.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from typing import Any from mqt.circuit.instructions.gate import Gate @@ -10,7 +12,12 @@ def __qasm__(self) -> str: def __array__(self, dtype: str = "complex") -> Any: pass - def control(self, num_ctrl_qudits: int = 1, label: str | None = None, ctrl_state: int | str | None = None): + def control( + self, + num_ctrl_qudits: int = 1, + label_indeces: list[int] | int | None = None, + ctrl_state: list[int] | int | None = None, + ): pass def validate_parameter(self, parameter): @@ -18,3 +25,6 @@ def validate_parameter(self, parameter): def __init__(self, name: str, num_qudits: int, params: list): super().__init__(name, num_qudits, params) + + def __str__(self): + pass diff --git a/src/mqt/circuit/instructions/gate_set/h.py b/src/mqt/circuit/instructions/gate_set/h.py index eb70464..cea207b 100644 --- a/src/mqt/circuit/instructions/gate_set/h.py +++ b/src/mqt/circuit/instructions/gate_set/h.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from typing import Any from mqt.circuit.instructions.gate import Gate @@ -10,7 +12,12 @@ def __qasm__(self) -> str: def __array__(self, dtype: str = "complex") -> Any: pass - def control(self, num_ctrl_qudits: int = 1, label: str | None = None, ctrl_state: int | str | None = None): + def control( + self, + num_ctrl_qudits: int = 1, + label_indeces: list[int] | int | None = None, + ctrl_state: list[int] | int | None = None, + ): pass def validate_parameter(self, parameter): @@ -18,3 +25,6 @@ def validate_parameter(self, parameter): def __init__(self, name: str, num_qudits: int, params: list): super().__init__(name, num_qudits, params) + + def __str__(self): + pass diff --git a/src/mqt/circuit/instructions/gate_set/ls.py b/src/mqt/circuit/instructions/gate_set/ls.py index ffb66dd..95172d6 100644 --- a/src/mqt/circuit/instructions/gate_set/ls.py +++ b/src/mqt/circuit/instructions/gate_set/ls.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from typing import Any from mqt.circuit.instructions.gate import Gate @@ -10,7 +12,12 @@ def __qasm__(self) -> str: def __array__(self, dtype: str = "complex") -> Any: pass - def control(self, num_ctrl_qudits: int = 1, label: str | None = None, ctrl_state: int | str | None = None): + def control( + self, + num_ctrl_qudits: int = 1, + label_indeces: list[int] | int | None = None, + ctrl_state: list[int] | int | None = None, + ): pass def validate_parameter(self, parameter): @@ -18,3 +25,6 @@ def validate_parameter(self, parameter): def __init__(self, name: str, num_qudits: int, params: list): super().__init__(name, num_qudits, params) + + def __str__(self): + pass diff --git a/src/mqt/circuit/instructions/gate_set/ms.py b/src/mqt/circuit/instructions/gate_set/ms.py index 114567a..17e8ccf 100644 --- a/src/mqt/circuit/instructions/gate_set/ms.py +++ b/src/mqt/circuit/instructions/gate_set/ms.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from typing import Any from mqt.circuit.instructions.gate import Gate @@ -10,7 +12,12 @@ def __qasm__(self) -> str: def __array__(self, dtype: str = "complex") -> Any: pass - def control(self, num_ctrl_qudits: int = 1, label: str | None = None, ctrl_state: int | str | None = None): + def control( + self, + num_ctrl_qudits: int = 1, + label_indeces: list[int] | int | None = None, + ctrl_state: list[int] | int | None = None, + ): pass def validate_parameter(self, parameter): @@ -18,3 +25,6 @@ def validate_parameter(self, parameter): def __init__(self, name: str, num_qudits: int, params: list): super().__init__(name, num_qudits, params) + + def __str__(self): + pass diff --git a/src/mqt/circuit/instructions/gate_set/perm.py b/src/mqt/circuit/instructions/gate_set/perm.py index 1e22f3e..fe77360 100644 --- a/src/mqt/circuit/instructions/gate_set/perm.py +++ b/src/mqt/circuit/instructions/gate_set/perm.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from typing import Any from mqt.circuit.instructions.gate import Gate @@ -10,7 +12,12 @@ def __qasm__(self) -> str: def __array__(self, dtype: str = "complex") -> Any: pass - def control(self, num_ctrl_qudits: int = 1, label: str | None = None, ctrl_state: int | str | None = None): + def control( + self, + num_ctrl_qudits: int = 1, + label_indeces: list[int] | int | None = None, + ctrl_state: list[int] | int | None = None, + ): pass def validate_parameter(self, parameter): @@ -18,3 +25,6 @@ def validate_parameter(self, parameter): def __init__(self, name: str, num_qudits: int, params: list): super().__init__(name, num_qudits, params) + + def __str__(self): + pass diff --git a/src/mqt/circuit/instructions/gate_set/r.py b/src/mqt/circuit/instructions/gate_set/r.py index 41917c7..ba0fc90 100644 --- a/src/mqt/circuit/instructions/gate_set/r.py +++ b/src/mqt/circuit/instructions/gate_set/r.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from typing import Any from mqt.circuit.instructions.gate import Gate @@ -10,7 +12,12 @@ def __qasm__(self) -> str: def __array__(self, dtype: str = "complex") -> Any: pass - def control(self, num_ctrl_qudits: int = 1, label: str | None = None, ctrl_state: int | str | None = None): + def control( + self, + num_ctrl_qudits: int = 1, + label_indeces: list[int] | int | None = None, + ctrl_state: list[int] | int | None = None, + ): pass def validate_parameter(self, parameter): @@ -18,3 +25,6 @@ def validate_parameter(self, parameter): def __init__(self, name: str, num_qudits: int, params: list): super().__init__(name, num_qudits, params) + + def __str__(self): + pass diff --git a/src/mqt/circuit/instructions/gate_set/randu.py b/src/mqt/circuit/instructions/gate_set/randu.py index c43cb4b..9f6275c 100644 --- a/src/mqt/circuit/instructions/gate_set/randu.py +++ b/src/mqt/circuit/instructions/gate_set/randu.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from typing import Any from mqt.circuit.instructions.gate import Gate @@ -10,7 +12,12 @@ def __qasm__(self) -> str: def __array__(self, dtype: str = "complex") -> Any: pass - def control(self, num_ctrl_qudits: int = 1, label: str | None = None, ctrl_state: int | str | None = None): + def control( + self, + num_ctrl_qudits: int = 1, + label_indeces: list[int] | int | None = None, + ctrl_state: list[int] | int | None = None, + ): pass def validate_parameter(self, parameter): @@ -18,3 +25,6 @@ def validate_parameter(self, parameter): def __init__(self, name: str, num_qudits: int, params: list): super().__init__(name, num_qudits, params) + + def __str__(self): + pass diff --git a/src/mqt/circuit/instructions/gate_set/rz.py b/src/mqt/circuit/instructions/gate_set/rz.py index cadeedd..decbe95 100644 --- a/src/mqt/circuit/instructions/gate_set/rz.py +++ b/src/mqt/circuit/instructions/gate_set/rz.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from typing import Any from mqt.circuit.instructions.gate import Gate @@ -10,7 +12,12 @@ def __qasm__(self) -> str: def __array__(self, dtype: str = "complex") -> Any: pass - def control(self, num_ctrl_qudits: int = 1, label: str | None = None, ctrl_state: int | str | None = None): + def control( + self, + num_ctrl_qudits: int = 1, + label_indeces: list[int] | int | None = None, + ctrl_state: list[int] | int | None = None, + ): pass def validate_parameter(self, parameter): @@ -18,3 +25,6 @@ def validate_parameter(self, parameter): def __init__(self, name: str, num_qudits: int, params: list): super().__init__(name, num_qudits, params) + + def __str__(self): + pass diff --git a/src/mqt/circuit/instructions/gate_set/s.py b/src/mqt/circuit/instructions/gate_set/s.py index d171c1b..03d7680 100644 --- a/src/mqt/circuit/instructions/gate_set/s.py +++ b/src/mqt/circuit/instructions/gate_set/s.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from typing import Any from mqt.circuit.instructions.gate import Gate @@ -10,7 +12,12 @@ def __qasm__(self) -> str: def __array__(self, dtype: str = "complex") -> Any: pass - def control(self, num_ctrl_qudits: int = 1, label: str | None = None, ctrl_state: int | str | None = None): + def control( + self, + num_ctrl_qudits: int = 1, + label_indeces: list[int] | int | None = None, + ctrl_state: list[int] | int | None = None, + ): pass def validate_parameter(self, parameter): @@ -18,3 +25,6 @@ def validate_parameter(self, parameter): def __init__(self, name: str, num_qudits: int, params: list): super().__init__(name, num_qudits, params) + + def __str__(self): + pass diff --git a/src/mqt/circuit/instructions/gate_set/x.py b/src/mqt/circuit/instructions/gate_set/x.py index c05132f..d09a5ce 100644 --- a/src/mqt/circuit/instructions/gate_set/x.py +++ b/src/mqt/circuit/instructions/gate_set/x.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from typing import Any from mqt.circuit.instructions.gate import Gate @@ -10,7 +12,12 @@ def __qasm__(self) -> str: def __array__(self, dtype: str = "complex") -> Any: pass - def control(self, num_ctrl_qudits: int = 1, label: str | None = None, ctrl_state: int | str | None = None): + def control( + self, + num_ctrl_qudits: int = 1, + label_indeces: list[int] | int | None = None, + ctrl_state: list[int] | int | None = None, + ): pass def validate_parameter(self, parameter): @@ -18,3 +25,6 @@ def validate_parameter(self, parameter): def __init__(self, name: str, num_qudits: int, params: list): super().__init__(name, num_qudits, params) + + def __str__(self): + pass diff --git a/src/mqt/circuit/instructions/gate_set/z.py b/src/mqt/circuit/instructions/gate_set/z.py index 3b63102..4c8f49d 100644 --- a/src/mqt/circuit/instructions/gate_set/z.py +++ b/src/mqt/circuit/instructions/gate_set/z.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from typing import Any from mqt.circuit.instructions.gate import Gate @@ -10,7 +12,12 @@ def __qasm__(self) -> str: def __array__(self, dtype: str = "complex") -> Any: pass - def control(self, num_ctrl_qudits: int = 1, label: str | None = None, ctrl_state: int | str | None = None): + def control( + self, + num_ctrl_qudits: int = 1, + label_indeces: list[int] | int | None = None, + ctrl_state: list[int] | int | None = None, + ): pass def validate_parameter(self, parameter): @@ -18,3 +25,6 @@ def validate_parameter(self, parameter): def __init__(self, name: str, num_qudits: int, params: list): super().__init__(name, num_qudits, params) + + def __str__(self): + pass diff --git a/src/mqt/circuit/quantum_register.py b/src/mqt/circuit/quantum_register.py index 6d892a6..a6de020 100644 --- a/src/mqt/circuit/quantum_register.py +++ b/src/mqt/circuit/quantum_register.py @@ -1,8 +1,26 @@ +from typing import List + + class QuantumRegister: @classmethod - def _from_map(cls, sitemap: dict): - # TODO - pass + def from_map(cls, sitemap: dict) -> List["QuantumRegister"]: + registers_map = {} + + for qreg_with_index, line_info in sitemap.items(): + reg_name, inreg_line_index = qreg_with_index + if reg_name not in registers_map: + registers_map[reg_name] = [{inreg_line_index: line_info[0]}, [line_info[1]]] + else: + registers_map[reg_name][0][inreg_line_index] = line_info[0] + registers_map[reg_name][1].append(line_info[1]) + print(registers_map) + registers_from_qasm = [] + for label, data in registers_map.items(): + temp = QuantumRegister(label, len(data[0]), data[1]) + temp.local_sitemap = data[0] + registers_from_qasm.append(temp) + print(registers_from_qasm) + return registers_from_qasm def __init__(self, name, size, dims=None): self.label = name @@ -14,3 +32,10 @@ def __init__(self, name, size, dims=None): def __qasm__(self): string_dims = str(self.dimensions).replace(" ", "") return "qreg " + self.label + " [" + str(self.size) + "]" + string_dims + ";" + + def __getitem__(self, key): + if isinstance(key, slice): + start, stop = key.start, key.stop + return [self.local_sitemap[i] for i in range(start, stop)] + + return self.local_sitemap[key] diff --git a/src/mqt/interface/qasm.py b/src/mqt/interface/qasm.py index ad9b122..afedfe3 100644 --- a/src/mqt/interface/qasm.py +++ b/src/mqt/interface/qasm.py @@ -44,14 +44,16 @@ def parse_gate(self, line, rgxs, sitemap, gates): if params else () ) + qudits_list = [] for dit in qudits.split(","): match = rgxs["qreg_indexing"].match(str(dit)) if match: name, reg_qudit_index = match.groups() reg_qudit_index = int(*re.search(r"\[(\d+)\]", reg_qudit_index).groups()) - qudits = tuple(sitemap[(name, reg_qudit_index)]) - gate_dict = {"name": label, "params": params, "qudits": qudits} - gates.append(gate_dict) + qudit = tuple(sitemap[(name, reg_qudit_index)]) + qudits_list.append(qudit) + gate_dict = {"name": label, "params": params, "qudits": qudits_list} + gates.append(gate_dict) return True return False diff --git a/src/mqt/simulation/noise/noise.py b/src/mqt/simulation/mqt_provider/noise/__init__.py similarity index 100% rename from src/mqt/simulation/noise/noise.py rename to src/mqt/simulation/mqt_provider/noise/__init__.py diff --git a/src/mqt/simulation/noise/noisy_circuit_factory.py b/src/mqt/simulation/mqt_provider/noise/noise.py similarity index 100% rename from src/mqt/simulation/noise/noisy_circuit_factory.py rename to src/mqt/simulation/mqt_provider/noise/noise.py diff --git a/src/mqt/simulation/mqt_provider/noise/noisy_circuit_factory.py b/src/mqt/simulation/mqt_provider/noise/noisy_circuit_factory.py new file mode 100644 index 0000000..e69de29