From 9573bede3125a5301cc71975a0877e9bbb0373ae Mon Sep 17 00:00:00 2001 From: Fabrizio Date: Fri, 20 Sep 2024 14:03:27 +0100 Subject: [PATCH 1/3] (resolves #93) Probability in tools needs parameter type Problem: - Probability function needs Union[quantum_circuit, ndarray] type for quantum_state - quantum_state rename from quantumstate Issues: - Importing quantum_circuit causes circular dependency - quantum_circuit import base_core imports from tools qubit - measure which is in tools imports probability which imports quantum_circuit Solution: - 1. Rename qunatumstate to quantum_state - 2. Add Union type from typing - 3. Remove qubit from tools and put into separate folder to separate imports this solve the dependency issue. --- src/quantum_circuit/base/base_core.py | 2 +- src/quantum_circuit/gpu/gpu_core.py | 2 +- src/quantum_circuit/gpu_sparse/gpu_sparse_core.py | 2 +- src/quantum_circuit/quantum_circuit.py | 9 ++++++--- src/quantum_circuit/sparse/sparse_core.py | 2 +- src/qubit/__init__.py | 1 + src/{tools => qubit}/qubit.py | 0 src/tools/__init__.py | 2 +- src/tools/probability.py | 14 ++++++++------ 9 files changed, 20 insertions(+), 14 deletions(-) create mode 100644 src/qubit/__init__.py rename src/{tools => qubit}/qubit.py (100%) diff --git a/src/quantum_circuit/base/base_core.py b/src/quantum_circuit/base/base_core.py index 58ab3a3e..4504a49c 100644 --- a/src/quantum_circuit/base/base_core.py +++ b/src/quantum_circuit/base/base_core.py @@ -1,5 +1,5 @@ import numpy as np -from ...tools import qubit +from ...qubit import qubit from ..interface import CoreInterface diff --git a/src/quantum_circuit/gpu/gpu_core.py b/src/quantum_circuit/gpu/gpu_core.py index 969fd8bd..12b50ef0 100644 --- a/src/quantum_circuit/gpu/gpu_core.py +++ b/src/quantum_circuit/gpu/gpu_core.py @@ -1,6 +1,6 @@ import cupy as cp from ..interface import CoreInterface -from ...tools import qubit +from ...qubit import qubit class GpuCore(CoreInterface): diff --git a/src/quantum_circuit/gpu_sparse/gpu_sparse_core.py b/src/quantum_circuit/gpu_sparse/gpu_sparse_core.py index 84caa7f0..a92ecca2 100644 --- a/src/quantum_circuit/gpu_sparse/gpu_sparse_core.py +++ b/src/quantum_circuit/gpu_sparse/gpu_sparse_core.py @@ -2,7 +2,7 @@ from cupyx.scipy.sparse import csr_matrix, csc_matrix from cupyx.scipy.sparse import kron from ..interface import CoreInterface -from ...tools import qubit +from ...qubit import qubit class GpuSparseCore(CoreInterface): diff --git a/src/quantum_circuit/quantum_circuit.py b/src/quantum_circuit/quantum_circuit.py index b8193770..ac6a4a55 100644 --- a/src/quantum_circuit/quantum_circuit.py +++ b/src/quantum_circuit/quantum_circuit.py @@ -216,7 +216,8 @@ def qft(self, qubit_one: int, qubit_two: int, qubit_three: int) -> None: self.calculator.pass_multi_gate(qubit_one, qubit_three, paulix()) self.calculator.pass_multi_gate(qubit_three, qubit_one, paulix()) self.calculator.pass_multi_gate(qubit_one, qubit_three, paulix()) - self.circuit_drawing.add_block("QFT", [qubit_one, qubit_two, qubit_three]) + self.circuit_drawing.add_block( + "QFT", [qubit_one, qubit_two, qubit_three]) def rccx(self, control_one: int, control_two: int, target: int) -> None: self.calculator.pass_single_gate(target, u(np.pi / 2, 0, np.pi)) @@ -228,7 +229,8 @@ def rccx(self, control_one: int, control_two: int, target: int) -> None: self.calculator.pass_multi_gate(control_two, target, paulix()) self.calculator.pass_single_gate(target, u(0, 0, (-1 * np.pi) / 4)) self.calculator.pass_single_gate(target, u(np.pi / 2, 0, np.pi)) - self.circuit_drawing.add_block("RCCX", [control_one, control_two, target]) + self.circuit_drawing.add_block( + "RCCX", [control_one, control_two, target]) def rc3x(self, qubit_1: int, qubit_2: int, qubit_3: int, qubit_4: int) -> None: self.calculator.pass_single_gate(qubit_4, u(np.pi / 2, 0, np.pi)) @@ -249,7 +251,8 @@ def rc3x(self, qubit_1: int, qubit_2: int, qubit_3: int, qubit_4: int) -> None: self.calculator.pass_multi_gate(qubit_3, qubit_4, paulix()) self.calculator.pass_single_gate(qubit_4, u(0, 0, (-1 * np.pi / 4))) self.calculator.pass_single_gate(qubit_4, u(np.pi / 2, 0, np.pi)) - self.circuit_drawing.add_block("RC3X", [qubit_1, qubit_2, qubit_3, qubit_4]) + self.circuit_drawing.add_block( + "RC3X", [qubit_1, qubit_2, qubit_3, qubit_4]) def swap(self, qubit_one: int, qubit_two: int) -> None: self.calculator.pass_multi_gate(qubit_one, qubit_two, paulix()) diff --git a/src/quantum_circuit/sparse/sparse_core.py b/src/quantum_circuit/sparse/sparse_core.py index 602bd3f8..dd5f3839 100644 --- a/src/quantum_circuit/sparse/sparse_core.py +++ b/src/quantum_circuit/sparse/sparse_core.py @@ -1,6 +1,6 @@ from scipy import sparse as sp from ..interface import CoreInterface -from ...tools import qubit +from ...qubit import qubit class SparseCore(CoreInterface): diff --git a/src/qubit/__init__.py b/src/qubit/__init__.py new file mode 100644 index 00000000..3b012dda --- /dev/null +++ b/src/qubit/__init__.py @@ -0,0 +1 @@ +from .qubit import qubit diff --git a/src/tools/qubit.py b/src/qubit/qubit.py similarity index 100% rename from src/tools/qubit.py rename to src/qubit/qubit.py diff --git a/src/tools/__init__.py b/src/tools/__init__.py index ccc6fcd8..6604a2e4 100644 --- a/src/tools/__init__.py +++ b/src/tools/__init__.py @@ -1,4 +1,4 @@ -from .qubit import qubit + from .measure import measure from .probability import probability from .phase_angle import phase_angle as phaseangle diff --git a/src/tools/probability.py b/src/tools/probability.py index 8e6dbe79..c2b7e26c 100644 --- a/src/tools/probability.py +++ b/src/tools/probability.py @@ -1,20 +1,22 @@ -from numpy import abs, around, multiply, square, log2 +from numpy import abs, around, multiply, square, log2, ndarray from .base import convert_state +from typing import Union +from ..quantum_circuit import QuantumCircuit def probability( - quantumstate, show_percent: bool = False, show_bit: int = -1, round: int = 3 + quantum_state: Union[ndarray, QuantumCircuit], show_percent: bool = False, show_bit: int = -1, round: int = 3 ): - circuit_size = int(log2(quantumstate.size)) - quantumstate = convert_state(quantumstate) + circuit_size = int(log2(quantum_state.size)) + quantum_state = convert_state(quantum_state) if round < 0: exit( f"Error: QuantumCircuit.tools.probabilities() -- round placement must be a value greater than 0." ) if isinstance(show_bit, int) and show_bit < 0: - probability = abs(square(quantumstate)) + probability = abs(square(quantum_state)) elif isinstance(show_bit, str) or isinstance(show_bit, int): @@ -22,7 +24,7 @@ def probability( exit( f"Error: QuantumCircuit.tools.probabilities() -- Called bit to find phase angle is not within range of possible values." ) - probability = abs(square(quantumstate[show_bit])) + probability = abs(square(quantum_state[show_bit])) if show_percent: probability = multiply(probability, 100) From cf0ee564daf2bcd756f916931b402d04e0982c63 Mon Sep 17 00:00:00 2001 From: Fabrizio Date: Fri, 20 Sep 2024 14:03:27 +0100 Subject: [PATCH 2/3] (resolves #83) Probability in tools needs parameter type Problem: - Probability function needs Union[quantum_circuit, ndarray] type for quantum_state - quantum_state rename from quantumstate Issues: - Importing quantum_circuit causes circular dependency - quantum_circuit import base_core imports from tools qubit - measure which is in tools imports probability which imports quantum_circuit Solution: - 1. Rename qunatumstate to quantum_state - 2. Add Union type from typing - 3. Remove qubit from tools and put into separate folder to separate imports this solve the dependency issue. --- src/quantum_circuit/base/base_core.py | 2 +- src/quantum_circuit/gpu/gpu_core.py | 2 +- src/quantum_circuit/gpu_sparse/gpu_sparse_core.py | 2 +- src/quantum_circuit/quantum_circuit.py | 9 ++++++--- src/quantum_circuit/sparse/sparse_core.py | 2 +- src/qubit/__init__.py | 1 + src/{tools => qubit}/qubit.py | 0 src/tools/__init__.py | 2 +- src/tools/probability.py | 14 ++++++++------ 9 files changed, 20 insertions(+), 14 deletions(-) create mode 100644 src/qubit/__init__.py rename src/{tools => qubit}/qubit.py (100%) diff --git a/src/quantum_circuit/base/base_core.py b/src/quantum_circuit/base/base_core.py index 58ab3a3e..4504a49c 100644 --- a/src/quantum_circuit/base/base_core.py +++ b/src/quantum_circuit/base/base_core.py @@ -1,5 +1,5 @@ import numpy as np -from ...tools import qubit +from ...qubit import qubit from ..interface import CoreInterface diff --git a/src/quantum_circuit/gpu/gpu_core.py b/src/quantum_circuit/gpu/gpu_core.py index 969fd8bd..12b50ef0 100644 --- a/src/quantum_circuit/gpu/gpu_core.py +++ b/src/quantum_circuit/gpu/gpu_core.py @@ -1,6 +1,6 @@ import cupy as cp from ..interface import CoreInterface -from ...tools import qubit +from ...qubit import qubit class GpuCore(CoreInterface): diff --git a/src/quantum_circuit/gpu_sparse/gpu_sparse_core.py b/src/quantum_circuit/gpu_sparse/gpu_sparse_core.py index 84caa7f0..a92ecca2 100644 --- a/src/quantum_circuit/gpu_sparse/gpu_sparse_core.py +++ b/src/quantum_circuit/gpu_sparse/gpu_sparse_core.py @@ -2,7 +2,7 @@ from cupyx.scipy.sparse import csr_matrix, csc_matrix from cupyx.scipy.sparse import kron from ..interface import CoreInterface -from ...tools import qubit +from ...qubit import qubit class GpuSparseCore(CoreInterface): diff --git a/src/quantum_circuit/quantum_circuit.py b/src/quantum_circuit/quantum_circuit.py index b8193770..ac6a4a55 100644 --- a/src/quantum_circuit/quantum_circuit.py +++ b/src/quantum_circuit/quantum_circuit.py @@ -216,7 +216,8 @@ def qft(self, qubit_one: int, qubit_two: int, qubit_three: int) -> None: self.calculator.pass_multi_gate(qubit_one, qubit_three, paulix()) self.calculator.pass_multi_gate(qubit_three, qubit_one, paulix()) self.calculator.pass_multi_gate(qubit_one, qubit_three, paulix()) - self.circuit_drawing.add_block("QFT", [qubit_one, qubit_two, qubit_three]) + self.circuit_drawing.add_block( + "QFT", [qubit_one, qubit_two, qubit_three]) def rccx(self, control_one: int, control_two: int, target: int) -> None: self.calculator.pass_single_gate(target, u(np.pi / 2, 0, np.pi)) @@ -228,7 +229,8 @@ def rccx(self, control_one: int, control_two: int, target: int) -> None: self.calculator.pass_multi_gate(control_two, target, paulix()) self.calculator.pass_single_gate(target, u(0, 0, (-1 * np.pi) / 4)) self.calculator.pass_single_gate(target, u(np.pi / 2, 0, np.pi)) - self.circuit_drawing.add_block("RCCX", [control_one, control_two, target]) + self.circuit_drawing.add_block( + "RCCX", [control_one, control_two, target]) def rc3x(self, qubit_1: int, qubit_2: int, qubit_3: int, qubit_4: int) -> None: self.calculator.pass_single_gate(qubit_4, u(np.pi / 2, 0, np.pi)) @@ -249,7 +251,8 @@ def rc3x(self, qubit_1: int, qubit_2: int, qubit_3: int, qubit_4: int) -> None: self.calculator.pass_multi_gate(qubit_3, qubit_4, paulix()) self.calculator.pass_single_gate(qubit_4, u(0, 0, (-1 * np.pi / 4))) self.calculator.pass_single_gate(qubit_4, u(np.pi / 2, 0, np.pi)) - self.circuit_drawing.add_block("RC3X", [qubit_1, qubit_2, qubit_3, qubit_4]) + self.circuit_drawing.add_block( + "RC3X", [qubit_1, qubit_2, qubit_3, qubit_4]) def swap(self, qubit_one: int, qubit_two: int) -> None: self.calculator.pass_multi_gate(qubit_one, qubit_two, paulix()) diff --git a/src/quantum_circuit/sparse/sparse_core.py b/src/quantum_circuit/sparse/sparse_core.py index 602bd3f8..dd5f3839 100644 --- a/src/quantum_circuit/sparse/sparse_core.py +++ b/src/quantum_circuit/sparse/sparse_core.py @@ -1,6 +1,6 @@ from scipy import sparse as sp from ..interface import CoreInterface -from ...tools import qubit +from ...qubit import qubit class SparseCore(CoreInterface): diff --git a/src/qubit/__init__.py b/src/qubit/__init__.py new file mode 100644 index 00000000..3b012dda --- /dev/null +++ b/src/qubit/__init__.py @@ -0,0 +1 @@ +from .qubit import qubit diff --git a/src/tools/qubit.py b/src/qubit/qubit.py similarity index 100% rename from src/tools/qubit.py rename to src/qubit/qubit.py diff --git a/src/tools/__init__.py b/src/tools/__init__.py index ccc6fcd8..6604a2e4 100644 --- a/src/tools/__init__.py +++ b/src/tools/__init__.py @@ -1,4 +1,4 @@ -from .qubit import qubit + from .measure import measure from .probability import probability from .phase_angle import phase_angle as phaseangle diff --git a/src/tools/probability.py b/src/tools/probability.py index 8e6dbe79..c2b7e26c 100644 --- a/src/tools/probability.py +++ b/src/tools/probability.py @@ -1,20 +1,22 @@ -from numpy import abs, around, multiply, square, log2 +from numpy import abs, around, multiply, square, log2, ndarray from .base import convert_state +from typing import Union +from ..quantum_circuit import QuantumCircuit def probability( - quantumstate, show_percent: bool = False, show_bit: int = -1, round: int = 3 + quantum_state: Union[ndarray, QuantumCircuit], show_percent: bool = False, show_bit: int = -1, round: int = 3 ): - circuit_size = int(log2(quantumstate.size)) - quantumstate = convert_state(quantumstate) + circuit_size = int(log2(quantum_state.size)) + quantum_state = convert_state(quantum_state) if round < 0: exit( f"Error: QuantumCircuit.tools.probabilities() -- round placement must be a value greater than 0." ) if isinstance(show_bit, int) and show_bit < 0: - probability = abs(square(quantumstate)) + probability = abs(square(quantum_state)) elif isinstance(show_bit, str) or isinstance(show_bit, int): @@ -22,7 +24,7 @@ def probability( exit( f"Error: QuantumCircuit.tools.probabilities() -- Called bit to find phase angle is not within range of possible values." ) - probability = abs(square(quantumstate[show_bit])) + probability = abs(square(quantum_state[show_bit])) if show_percent: probability = multiply(probability, 100) From e0449de1478ba3df9bdda036dc2b02ecf21744ce Mon Sep 17 00:00:00 2001 From: Fabrizio Date: Fri, 20 Sep 2024 14:13:31 +0100 Subject: [PATCH 3/3] (resolves #83) Add qubit to src imports and run black formatter Problem - Project runs black formatter - qubit needs to be included in root import Solution - run `black qcpy/` - add `from ./qubit import *` --- src/__init__.py | 1 + src/quantum_circuit/quantum_circuit.py | 9 +++------ src/tools/__init__.py | 1 - src/tools/probability.py | 5 ++++- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/__init__.py b/src/__init__.py index 206d45f5..af42cce4 100644 --- a/src/__init__.py +++ b/src/__init__.py @@ -2,3 +2,4 @@ from .quantum_gate import gates from .visualize import * from .tools import * +from .qubit import * diff --git a/src/quantum_circuit/quantum_circuit.py b/src/quantum_circuit/quantum_circuit.py index ac6a4a55..b8193770 100644 --- a/src/quantum_circuit/quantum_circuit.py +++ b/src/quantum_circuit/quantum_circuit.py @@ -216,8 +216,7 @@ def qft(self, qubit_one: int, qubit_two: int, qubit_three: int) -> None: self.calculator.pass_multi_gate(qubit_one, qubit_three, paulix()) self.calculator.pass_multi_gate(qubit_three, qubit_one, paulix()) self.calculator.pass_multi_gate(qubit_one, qubit_three, paulix()) - self.circuit_drawing.add_block( - "QFT", [qubit_one, qubit_two, qubit_three]) + self.circuit_drawing.add_block("QFT", [qubit_one, qubit_two, qubit_three]) def rccx(self, control_one: int, control_two: int, target: int) -> None: self.calculator.pass_single_gate(target, u(np.pi / 2, 0, np.pi)) @@ -229,8 +228,7 @@ def rccx(self, control_one: int, control_two: int, target: int) -> None: self.calculator.pass_multi_gate(control_two, target, paulix()) self.calculator.pass_single_gate(target, u(0, 0, (-1 * np.pi) / 4)) self.calculator.pass_single_gate(target, u(np.pi / 2, 0, np.pi)) - self.circuit_drawing.add_block( - "RCCX", [control_one, control_two, target]) + self.circuit_drawing.add_block("RCCX", [control_one, control_two, target]) def rc3x(self, qubit_1: int, qubit_2: int, qubit_3: int, qubit_4: int) -> None: self.calculator.pass_single_gate(qubit_4, u(np.pi / 2, 0, np.pi)) @@ -251,8 +249,7 @@ def rc3x(self, qubit_1: int, qubit_2: int, qubit_3: int, qubit_4: int) -> None: self.calculator.pass_multi_gate(qubit_3, qubit_4, paulix()) self.calculator.pass_single_gate(qubit_4, u(0, 0, (-1 * np.pi / 4))) self.calculator.pass_single_gate(qubit_4, u(np.pi / 2, 0, np.pi)) - self.circuit_drawing.add_block( - "RC3X", [qubit_1, qubit_2, qubit_3, qubit_4]) + self.circuit_drawing.add_block("RC3X", [qubit_1, qubit_2, qubit_3, qubit_4]) def swap(self, qubit_one: int, qubit_two: int) -> None: self.calculator.pass_multi_gate(qubit_one, qubit_two, paulix()) diff --git a/src/tools/__init__.py b/src/tools/__init__.py index 6604a2e4..99e81a84 100644 --- a/src/tools/__init__.py +++ b/src/tools/__init__.py @@ -1,4 +1,3 @@ - from .measure import measure from .probability import probability from .phase_angle import phase_angle as phaseangle diff --git a/src/tools/probability.py b/src/tools/probability.py index c2b7e26c..5df8d5f2 100644 --- a/src/tools/probability.py +++ b/src/tools/probability.py @@ -5,7 +5,10 @@ def probability( - quantum_state: Union[ndarray, QuantumCircuit], show_percent: bool = False, show_bit: int = -1, round: int = 3 + quantum_state: Union[ndarray, QuantumCircuit], + show_percent: bool = False, + show_bit: int = -1, + round: int = 3, ): circuit_size = int(log2(quantum_state.size))