qusim-np 1.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
qusim_np-1.0/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Furkan Nar
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
qusim_np-1.0/PKG-INFO ADDED
@@ -0,0 +1,205 @@
1
+ Metadata-Version: 2.4
2
+ Name: qusim-np
3
+ Version: 1.0
4
+ Summary: A minimal, readable quantum computing simulator: gates, state-vector algorithms, and VQE
5
+ Author-email: Furkan Nar <furkan_nar4185@outlook.com>
6
+ License: MIT
7
+ Project-URL: Homepage, https://github.com/furkannar/qusim-np
8
+ Project-URL: Repository, https://github.com/furkannar/qusim-np
9
+ Keywords: quantum,quantum-computing,simulation,vqe,grover,qft
10
+ Classifier: Development Status :: 3 - Alpha
11
+ Classifier: Intended Audience :: Science/Research
12
+ Classifier: Intended Audience :: Education
13
+ Classifier: License :: OSI Approved :: MIT License
14
+ Classifier: Programming Language :: Python :: 3
15
+ Classifier: Programming Language :: Python :: 3.10
16
+ Classifier: Programming Language :: Python :: 3.11
17
+ Classifier: Programming Language :: Python :: 3.12
18
+ Classifier: Topic :: Scientific/Engineering :: Physics
19
+ Requires-Python: >=3.10
20
+ Description-Content-Type: text/markdown
21
+ License-File: LICENSE
22
+ Requires-Dist: numpy>=2.0.0
23
+ Requires-Dist: scipy>=1.11.0
24
+ Provides-Extra: dev
25
+ Requires-Dist: pytest>=8.0.0; extra == "dev"
26
+ Dynamic: license-file
27
+
28
+ # qusim-np
29
+
30
+ **A minimal, readable quantum computing simulator in pure NumPy.**
31
+
32
+ State-vector gates, textbook quantum algorithms, and a working
33
+ Variational Quantum Eigensolver — in ~1,200 lines of well-documented,
34
+ well-tested code. Built for learning, teaching, and prototyping.
35
+
36
+ [![Python 3.10+](https://img.shields.io/badge/python-3.10%2B-blue)](pyproject.toml)
37
+ [![License: MIT](https://img.shields.io/badge/license-MIT-green)](LICENSE)
38
+ [![Tests](https://img.shields.io/badge/tests-178%20passing-brightgreen)](tests/)
39
+
40
+ ---
41
+
42
+ ## Features
43
+
44
+ | Category | What you get |
45
+ |---|---|
46
+ | **Gates** | Pauli X/Y/Z, Hadamard, S, T, CNOT, SWAP, CZ, Toffoli, `rx`/`ry`/`rz` rotations |
47
+ | **Algorithms** | Grover search, Deutsch–Jozsa, Quantum Fourier Transform |
48
+ | **VQE** | Pauli-string Hamiltonians, hardware-efficient ansatz, `scipy` optimizer |
49
+ | **Performance** | 1- and 2-qubit gates applied to state vectors in O(n·2ⁿ) — no dense 2ⁿ×2ⁿ matrices in the hot path |
50
+
51
+ ## Install
52
+
53
+ ```bash
54
+ pip install qusim-np
55
+ ```
56
+
57
+ From source:
58
+
59
+ ```bash
60
+ git clone https://github.com/furkannar/qusim-np.git
61
+ cd qusim-np
62
+ pip install -e .
63
+ ```
64
+
65
+ Requires Python ≥ 3.10, NumPy ≥ 2.0, SciPy ≥ 1.11.
66
+
67
+ ## Quick start
68
+
69
+ ```python
70
+ import qusim_np
71
+
72
+ # Grover's search — find state |101> among 8 possibilities
73
+ state, k, p = qusim_np.grover_search(3, marked_states=[5])
74
+ print(f"{k} iterations -> P(marked) = {p:.3f}")
75
+
76
+ # Deutsch-Jozsa — constant or balanced with ONE query
77
+ print(qusim_np.deutsch_jozsa_classify(3, lambda x: x % 2)) # 'balanced'
78
+
79
+ # Quantum Fourier Transform
80
+ F = qusim_np.qft_matrix(3) # 8x8 unitary
81
+ ```
82
+
83
+ ### The math, briefly
84
+
85
+ Grover's algorithm rotates the state vector in the plane spanned by the
86
+ marked and unmarked subspaces. With $N = 2^n$ basis states and $M$ marked
87
+ states, each iteration rotates by
88
+
89
+ $$\theta = 2\arcsin\sqrt{\frac{M}{N}}, \qquad
90
+ k_{\mathrm{opt}} \approx \frac{\pi}{4}\sqrt{\frac{N}{M}}$$
91
+
92
+ so the marked states are amplified after $O(\sqrt{N/M})$ oracle queries.
93
+
94
+ The Quantum Fourier Transform is the unitary
95
+
96
+ $$F_{jk} = \frac{1}{\sqrt{N}}\,\omega^{jk}, \qquad
97
+ \omega = e^{2\pi i / N}, \qquad j,k = 0,\dots,N-1$$
98
+
99
+ ## Variational Quantum Eigensolver
100
+
101
+ The flagship feature: find the ground-state energy of a Hamiltonian
102
+ written as a linear combination of Pauli strings,
103
+
104
+ $$H = \sum_{i=0}^{m-1} \alpha_i P_i, \qquad
105
+ P_i = \bigotimes_{k=0}^{n-1} \sigma_{i,k}, \qquad
106
+ \sigma_{i,k} \in \{I, X, Y, Z\}$$
107
+
108
+ by minimizing the variational energy
109
+
110
+ $$E(\theta) = \langle \psi(\theta) \,|\, H \,|\, \psi(\theta) \rangle$$
111
+
112
+ over the parameters of a hardware-efficient ansatz (HEA).
113
+
114
+ ```python
115
+ import numpy as np
116
+ import qusim_np
117
+
118
+ # H = 0.3·II + 1.2·ZZ - 0.8·XI - 0.8·IX (2 qubits)
119
+ coeffs = [0.3, 1.2, -0.8, -0.8]
120
+ strings = ["II", "ZZ", "XI", "IX"]
121
+
122
+ # Minimize <psi(theta)|H|psi(theta)> over a hardware-efficient ansatz
123
+ res = qusim_np.vqe_optimize(2, layers=2,
124
+ coefficients=coeffs, pauli_strings=strings)
125
+ print(f"VQE energy: {res.fun:.6f}")
126
+
127
+ # Exact answer for comparison (dense diagonalization)
128
+ H = qusim_np.hamiltonian(coeffs, strings)
129
+ print(f"Exact: {np.linalg.eigvalsh(H)[0]:.6f}")
130
+ # -> VQE energy: -1.700000 Exact: -1.700000
131
+ ```
132
+
133
+ ### VQE building blocks
134
+
135
+ ```python
136
+ # Pauli strings: "XZI", ("X","Z","I"), or index tuples (1,3,0) — all equivalent
137
+ P = qusim_np.pauli_string_matrix("XZI") # 8x8 matrix, 3 qubits
138
+
139
+ # Expectation values WITHOUT building the 2^n x 2^n matrix
140
+ qusim_np.pauli_string_expval(state, "ZZ")
141
+
142
+ # Apply gates straight to state vectors (O(n·2^n), no big matrices)
143
+ state = qusim_np.initialize_uniform_superposition(2)
144
+ state = qusim_np.apply_single_qubit(state, qusim_np.gates.hadamard().matrix, 0)
145
+ state = qusim_np.apply_two_qubit(state, qusim_np.gates.cnot().matrix, 0, 1)
146
+
147
+ # Inspect the ansatz before optimizing
148
+ theta = np.zeros(qusim_np.hea_param_count(2, layers=2))
149
+ psi = qusim_np.hea_state(2, theta, layers=2)
150
+ ```
151
+
152
+ ## Qubit convention
153
+
154
+ Qubit 0 is the **most significant bit** of the basis-state index:
155
+
156
+ $$|q_0 q_1 \dots q_{n-1}\rangle \;\longleftrightarrow\;
157
+ \sum_{k=0}^{n-1} q_k\, 2^{\,n-1-k}$$
158
+
159
+ A Pauli string `"XZI"` means X on qubit 0, Z on qubit 1, I on qubit 2 —
160
+ same convention as Qiskit and most textbooks.
161
+
162
+ ## Project layout
163
+
164
+ ```
165
+ qusim_np/
166
+ ├── config.py # constants + Pauli matrices
167
+ ├── gates.py # QuantumGate + gate constructors
168
+ ├── grover_search.py # Hadamard transforms, oracle, diffusion, Grover
169
+ ├── deutsch_jozsa.py # Deutsch-Jozsa algorithm
170
+ ├── qft.py # QFT / inverse QFT
171
+ └── vqe.py # Pauli strings, Hamiltonians, HEA ansatz, VQE driver
172
+ tests/ # 178 tests
173
+ ```
174
+
175
+ ## Limitations
176
+
177
+ Honest scope notes — this is a teaching/reference simulator:
178
+
179
+ - **Dense state vectors**: memory is O(2ⁿ); practical limit ~15–20 qubits
180
+ - **No noise model**: pure-state simulation only (no decoherence, no sampling noise)
181
+ - **No circuit API**: you compose gates programmatically, not via a `QuantumCircuit` builder
182
+ - **Classical only**: no real-device or cloud backend integration
183
+
184
+ For production quantum computing, see [Qiskit](https://www.ibm.com/quantum/qiskit),
185
+ [PennyLane](https://pennylane.ai/), or [Cirq](https://quantumai.google/cirq).
186
+
187
+ ## Development
188
+
189
+ ```bash
190
+ pip install -e .[dev]
191
+ pytest # 178 tests, ~1s
192
+ ```
193
+
194
+ Contributions welcome — see the test suite for conventions.
195
+
196
+ ## AI assistance
197
+
198
+ Parts of this codebase were written with assistance from **SWE-2 by
199
+ Cognition**, accessed through the **Devin** platform, for coding tasks
200
+ such as implementing algorithms, tests, and documentation. All
201
+ architectural and design decisions were made by the author.
202
+
203
+ ## License
204
+
205
+ [MIT](LICENSE) © 2026 Furkan Nar
qusim_np-1.0/README.md ADDED
@@ -0,0 +1,178 @@
1
+ # qusim-np
2
+
3
+ **A minimal, readable quantum computing simulator in pure NumPy.**
4
+
5
+ State-vector gates, textbook quantum algorithms, and a working
6
+ Variational Quantum Eigensolver — in ~1,200 lines of well-documented,
7
+ well-tested code. Built for learning, teaching, and prototyping.
8
+
9
+ [![Python 3.10+](https://img.shields.io/badge/python-3.10%2B-blue)](pyproject.toml)
10
+ [![License: MIT](https://img.shields.io/badge/license-MIT-green)](LICENSE)
11
+ [![Tests](https://img.shields.io/badge/tests-178%20passing-brightgreen)](tests/)
12
+
13
+ ---
14
+
15
+ ## Features
16
+
17
+ | Category | What you get |
18
+ |---|---|
19
+ | **Gates** | Pauli X/Y/Z, Hadamard, S, T, CNOT, SWAP, CZ, Toffoli, `rx`/`ry`/`rz` rotations |
20
+ | **Algorithms** | Grover search, Deutsch–Jozsa, Quantum Fourier Transform |
21
+ | **VQE** | Pauli-string Hamiltonians, hardware-efficient ansatz, `scipy` optimizer |
22
+ | **Performance** | 1- and 2-qubit gates applied to state vectors in O(n·2ⁿ) — no dense 2ⁿ×2ⁿ matrices in the hot path |
23
+
24
+ ## Install
25
+
26
+ ```bash
27
+ pip install qusim-np
28
+ ```
29
+
30
+ From source:
31
+
32
+ ```bash
33
+ git clone https://github.com/furkannar/qusim-np.git
34
+ cd qusim-np
35
+ pip install -e .
36
+ ```
37
+
38
+ Requires Python ≥ 3.10, NumPy ≥ 2.0, SciPy ≥ 1.11.
39
+
40
+ ## Quick start
41
+
42
+ ```python
43
+ import qusim_np
44
+
45
+ # Grover's search — find state |101> among 8 possibilities
46
+ state, k, p = qusim_np.grover_search(3, marked_states=[5])
47
+ print(f"{k} iterations -> P(marked) = {p:.3f}")
48
+
49
+ # Deutsch-Jozsa — constant or balanced with ONE query
50
+ print(qusim_np.deutsch_jozsa_classify(3, lambda x: x % 2)) # 'balanced'
51
+
52
+ # Quantum Fourier Transform
53
+ F = qusim_np.qft_matrix(3) # 8x8 unitary
54
+ ```
55
+
56
+ ### The math, briefly
57
+
58
+ Grover's algorithm rotates the state vector in the plane spanned by the
59
+ marked and unmarked subspaces. With $N = 2^n$ basis states and $M$ marked
60
+ states, each iteration rotates by
61
+
62
+ $$\theta = 2\arcsin\sqrt{\frac{M}{N}}, \qquad
63
+ k_{\mathrm{opt}} \approx \frac{\pi}{4}\sqrt{\frac{N}{M}}$$
64
+
65
+ so the marked states are amplified after $O(\sqrt{N/M})$ oracle queries.
66
+
67
+ The Quantum Fourier Transform is the unitary
68
+
69
+ $$F_{jk} = \frac{1}{\sqrt{N}}\,\omega^{jk}, \qquad
70
+ \omega = e^{2\pi i / N}, \qquad j,k = 0,\dots,N-1$$
71
+
72
+ ## Variational Quantum Eigensolver
73
+
74
+ The flagship feature: find the ground-state energy of a Hamiltonian
75
+ written as a linear combination of Pauli strings,
76
+
77
+ $$H = \sum_{i=0}^{m-1} \alpha_i P_i, \qquad
78
+ P_i = \bigotimes_{k=0}^{n-1} \sigma_{i,k}, \qquad
79
+ \sigma_{i,k} \in \{I, X, Y, Z\}$$
80
+
81
+ by minimizing the variational energy
82
+
83
+ $$E(\theta) = \langle \psi(\theta) \,|\, H \,|\, \psi(\theta) \rangle$$
84
+
85
+ over the parameters of a hardware-efficient ansatz (HEA).
86
+
87
+ ```python
88
+ import numpy as np
89
+ import qusim_np
90
+
91
+ # H = 0.3·II + 1.2·ZZ - 0.8·XI - 0.8·IX (2 qubits)
92
+ coeffs = [0.3, 1.2, -0.8, -0.8]
93
+ strings = ["II", "ZZ", "XI", "IX"]
94
+
95
+ # Minimize <psi(theta)|H|psi(theta)> over a hardware-efficient ansatz
96
+ res = qusim_np.vqe_optimize(2, layers=2,
97
+ coefficients=coeffs, pauli_strings=strings)
98
+ print(f"VQE energy: {res.fun:.6f}")
99
+
100
+ # Exact answer for comparison (dense diagonalization)
101
+ H = qusim_np.hamiltonian(coeffs, strings)
102
+ print(f"Exact: {np.linalg.eigvalsh(H)[0]:.6f}")
103
+ # -> VQE energy: -1.700000 Exact: -1.700000
104
+ ```
105
+
106
+ ### VQE building blocks
107
+
108
+ ```python
109
+ # Pauli strings: "XZI", ("X","Z","I"), or index tuples (1,3,0) — all equivalent
110
+ P = qusim_np.pauli_string_matrix("XZI") # 8x8 matrix, 3 qubits
111
+
112
+ # Expectation values WITHOUT building the 2^n x 2^n matrix
113
+ qusim_np.pauli_string_expval(state, "ZZ")
114
+
115
+ # Apply gates straight to state vectors (O(n·2^n), no big matrices)
116
+ state = qusim_np.initialize_uniform_superposition(2)
117
+ state = qusim_np.apply_single_qubit(state, qusim_np.gates.hadamard().matrix, 0)
118
+ state = qusim_np.apply_two_qubit(state, qusim_np.gates.cnot().matrix, 0, 1)
119
+
120
+ # Inspect the ansatz before optimizing
121
+ theta = np.zeros(qusim_np.hea_param_count(2, layers=2))
122
+ psi = qusim_np.hea_state(2, theta, layers=2)
123
+ ```
124
+
125
+ ## Qubit convention
126
+
127
+ Qubit 0 is the **most significant bit** of the basis-state index:
128
+
129
+ $$|q_0 q_1 \dots q_{n-1}\rangle \;\longleftrightarrow\;
130
+ \sum_{k=0}^{n-1} q_k\, 2^{\,n-1-k}$$
131
+
132
+ A Pauli string `"XZI"` means X on qubit 0, Z on qubit 1, I on qubit 2 —
133
+ same convention as Qiskit and most textbooks.
134
+
135
+ ## Project layout
136
+
137
+ ```
138
+ qusim_np/
139
+ ├── config.py # constants + Pauli matrices
140
+ ├── gates.py # QuantumGate + gate constructors
141
+ ├── grover_search.py # Hadamard transforms, oracle, diffusion, Grover
142
+ ├── deutsch_jozsa.py # Deutsch-Jozsa algorithm
143
+ ├── qft.py # QFT / inverse QFT
144
+ └── vqe.py # Pauli strings, Hamiltonians, HEA ansatz, VQE driver
145
+ tests/ # 178 tests
146
+ ```
147
+
148
+ ## Limitations
149
+
150
+ Honest scope notes — this is a teaching/reference simulator:
151
+
152
+ - **Dense state vectors**: memory is O(2ⁿ); practical limit ~15–20 qubits
153
+ - **No noise model**: pure-state simulation only (no decoherence, no sampling noise)
154
+ - **No circuit API**: you compose gates programmatically, not via a `QuantumCircuit` builder
155
+ - **Classical only**: no real-device or cloud backend integration
156
+
157
+ For production quantum computing, see [Qiskit](https://www.ibm.com/quantum/qiskit),
158
+ [PennyLane](https://pennylane.ai/), or [Cirq](https://quantumai.google/cirq).
159
+
160
+ ## Development
161
+
162
+ ```bash
163
+ pip install -e .[dev]
164
+ pytest # 178 tests, ~1s
165
+ ```
166
+
167
+ Contributions welcome — see the test suite for conventions.
168
+
169
+ ## AI assistance
170
+
171
+ Parts of this codebase were written with assistance from **SWE-2 by
172
+ Cognition**, accessed through the **Devin** platform, for coding tasks
173
+ such as implementing algorithms, tests, and documentation. All
174
+ architectural and design decisions were made by the author.
175
+
176
+ ## License
177
+
178
+ [MIT](LICENSE) © 2026 Furkan Nar
@@ -0,0 +1,45 @@
1
+ [build-system]
2
+ requires = ["setuptools>=68", "wheel"]
3
+ build-backend = "setuptools.build_meta"
4
+
5
+ [project]
6
+ name = "qusim-np"
7
+ version = "1.0"
8
+ description = "A minimal, readable quantum computing simulator: gates, state-vector algorithms, and VQE"
9
+ readme = "README.md"
10
+ license = {text = "MIT"}
11
+ authors = [
12
+ {name = "Furkan Nar", email = "furkan_nar4185@outlook.com"},
13
+ ]
14
+ keywords = ["quantum", "quantum-computing", "simulation", "vqe", "grover", "qft"]
15
+ classifiers = [
16
+ "Development Status :: 3 - Alpha",
17
+ "Intended Audience :: Science/Research",
18
+ "Intended Audience :: Education",
19
+ "License :: OSI Approved :: MIT License",
20
+ "Programming Language :: Python :: 3",
21
+ "Programming Language :: Python :: 3.10",
22
+ "Programming Language :: Python :: 3.11",
23
+ "Programming Language :: Python :: 3.12",
24
+ "Topic :: Scientific/Engineering :: Physics",
25
+ ]
26
+ requires-python = ">=3.10"
27
+ dependencies = [
28
+ "numpy>=2.0.0",
29
+ "scipy>=1.11.0",
30
+ ]
31
+
32
+ [project.optional-dependencies]
33
+ dev = [
34
+ "pytest>=8.0.0",
35
+ ]
36
+
37
+ [project.urls]
38
+ Homepage = "https://github.com/furkannar/qusim-np"
39
+ Repository = "https://github.com/furkannar/qusim-np"
40
+
41
+ [tool.setuptools.packages.find]
42
+ include = ["qusim_np*"]
43
+
44
+ [tool.pytest.ini_options]
45
+ testpaths = ["tests"]
@@ -0,0 +1,40 @@
1
+ """Quantum computing engine: gates, state-vector simulation, and algorithms."""
2
+
3
+ from qusim_np.config import QuantumConfig, config
4
+ from qusim_np.gates import (
5
+ QuantumGate,
6
+ pauli_x, pauli_y, pauli_z, hadamard, phase_gate, t_gate,
7
+ identity, cnot, swap, controlled_phase, toffoli, rx, ry, rz,
8
+ )
9
+ from qusim_np.grover_search import (
10
+ hadamard_transform, hadamard_matrix_closed_form,
11
+ initialize_uniform_superposition, grover_oracle, diffusion_operator,
12
+ grover_iteration, calculate_theta, calculate_optimal_iterations,
13
+ grover_search,
14
+ )
15
+ from qusim_np.deutsch_jozsa import (
16
+ deutsch_jozsa_oracle, deutsch_jozsa, deutsch_jozsa_classify,
17
+ )
18
+ from qusim_np.qft import (
19
+ qft_matrix, inverse_qft_matrix, qft_state, inverse_qft_state,
20
+ )
21
+ from qusim_np.vqe import (
22
+ pauli_string_matrix, apply_single_qubit, apply_two_qubit,
23
+ apply_pauli_string, pauli_string_expval, hamiltonian, expectation_value,
24
+ hea_param_count, hea_state, vqe_energy, vqe_optimize,
25
+ )
26
+
27
+ __all__ = [
28
+ "QuantumConfig", "config", "QuantumGate",
29
+ "pauli_x", "pauli_y", "pauli_z", "hadamard", "phase_gate", "t_gate",
30
+ "identity", "cnot", "swap", "controlled_phase", "toffoli", "rx", "ry", "rz",
31
+ "hadamard_transform", "hadamard_matrix_closed_form",
32
+ "initialize_uniform_superposition", "grover_oracle", "diffusion_operator",
33
+ "grover_iteration", "calculate_theta", "calculate_optimal_iterations",
34
+ "grover_search",
35
+ "deutsch_jozsa_oracle", "deutsch_jozsa", "deutsch_jozsa_classify",
36
+ "qft_matrix", "inverse_qft_matrix", "qft_state", "inverse_qft_state",
37
+ "pauli_string_matrix", "apply_single_qubit", "apply_two_qubit",
38
+ "apply_pauli_string", "pauli_string_expval", "hamiltonian", "expectation_value",
39
+ "hea_param_count", "hea_state", "vqe_energy", "vqe_optimize",
40
+ ]
@@ -0,0 +1,46 @@
1
+ r"""
2
+ Quantum Computing Configuration
3
+
4
+ This module contains constants and configuration values used across
5
+ the quantum computing implementation.
6
+ """
7
+
8
+ import numpy as np
9
+ from dataclasses import dataclass
10
+
11
+
12
+ @dataclass
13
+ class QuantumConfig:
14
+ """Configuration constants for quantum computing implementation."""
15
+
16
+ # Mathematical constants
17
+ SQRT_2: float = np.sqrt(2)
18
+ INV_SQRT_2: float = 1 / SQRT_2
19
+
20
+ # Quantum gate constants
21
+ HADAMARD_SCALE: float = INV_SQRT_2
22
+
23
+ # Grover's algorithm constants
24
+ # These will be computed dynamically based on n and M
25
+ # N = 2^n (total number of basis states)
26
+ # M = number of marked solutions
27
+
28
+ # Rotation gate constants
29
+ # theta parameter for Rx, Ry, Rz gates
30
+ DEFAULT_ROTATION_ANGLE: float = np.pi / 4
31
+
32
+ # SU(2) constraints
33
+ # Unitary: U^dagger * U = I
34
+ # Special Unitary: det(U) = 1
35
+ SU2_TOLERANCE: float = 1e-10
36
+
37
+
38
+ # Global config instance
39
+ config = QuantumConfig()
40
+
41
+
42
+ # Single-qubit Pauli matrices (used by VQE Hamiltonians and Pauli strings)
43
+ PAULI_I = np.array([[1, 0], [0, 1]], dtype=complex)
44
+ PAULI_X = np.array([[0, 1], [1, 0]], dtype=complex)
45
+ PAULI_Y = np.array([[0, -1j], [1j, 0]], dtype=complex)
46
+ PAULI_Z = np.array([[1, 0], [0, -1]], dtype=complex)
@@ -0,0 +1,119 @@
1
+ r"""
2
+ qusim_np/deutsch_jozsa.py
3
+ Deutsch-Jozsa Algorithm
4
+
5
+ This module implements the Deutsch-Jozsa algorithm using the custom gates.
6
+
7
+ Deutsch-Jozsa Algorithm:
8
+ - Determines whether a function f: {0,1}^n -> {0,1} is constant or balanced
9
+ using a single quantum query (classically requires up to 2^{n-1} + 1 queries)
10
+ - n-qubit Hadamard transform: H^{\otimes n}
11
+ - Initial state: |s> = H^{\otimes n}|0>^{\otimes n} = (1/sqrt(N)) * sum_x |x>
12
+ - Oracle O_f: O_f|x> = (-1)^{f(x)}|x> (phase kickback, no ancilla needed)
13
+ - Final Hadamard transform: H^{\otimes n} again (H is self-inverse)
14
+ - If f is constant: measurement yields |0^n> with probability 1
15
+ - If f is balanced: amplitude of |0^n> is 0, so a nonzero outcome is certain
16
+ - Amplitude of |y> after final transform:
17
+ A_y = (1/N) * sum_x (-1)^{f(x)} (-1)^{x \cdot y} (Walsh-Hadamard transform)
18
+ """
19
+
20
+ import numpy as np
21
+ from qusim_np.grover_search import (
22
+ _validate_n, hadamard_transform, initialize_uniform_superposition
23
+ )
24
+
25
+
26
+ def _evaluate_f(f, N):
27
+ """
28
+ Evaluate f on all N basis states.
29
+
30
+ Args:
31
+ f: Callable f(x) -> bool/int, or a sequence of N bits
32
+ N: Number of basis states (2^n)
33
+
34
+ Returns:
35
+ list: f-values for x = 0..N-1 as 0/1 ints
36
+ """
37
+ if callable(f):
38
+ return [int(bool(f(x))) for x in range(N)]
39
+ values = list(f)
40
+ if len(values) != N:
41
+ raise ValueError(f"f sequence must have length {N}, got {len(values)}")
42
+ return [int(bool(v)) for v in values]
43
+
44
+
45
+ def deutsch_jozsa_oracle(n, f):
46
+ r"""
47
+ Construct the Deutsch-Jozsa oracle O_f that encodes f as a phase.
48
+
49
+ O_f|x> = (-1)^{f(x)}|x>, where f(x) = 1 picks up a phase of -1.
50
+ This is a diagonal unitary: diag((-1)^{f(0)}, ..., (-1)^{f(N-1)}).
51
+
52
+ Args:
53
+ n: Number of qubits
54
+ f: Function to evaluate - either a callable f(x) -> bool/int
55
+ or a sequence of N = 2^n bits (f(0), f(1), ..., f(N-1))
56
+
57
+ Returns:
58
+ numpy.ndarray: The oracle matrix of shape (2^n, 2^n)
59
+ """
60
+ _validate_n(n)
61
+ N = 2 ** n
62
+ values = _evaluate_f(f, N)
63
+ phases = np.array([1 - 2 * v for v in values]) # +1 if f=0, -1 if f=1
64
+ return np.diag(phases).astype(complex)
65
+
66
+
67
+ def deutsch_jozsa(n, f):
68
+ r"""
69
+ Run the Deutsch-Jozsa algorithm on function f.
70
+
71
+ Algorithm:
72
+ 1. Initialize |s> = H^{\otimes n}|0^n>
73
+ 2. Apply oracle: O_f|s>
74
+ 3. Apply H^{\otimes n} again
75
+ 4. Measure: |0^n> outcome implies f is constant
76
+
77
+ Args:
78
+ n: Number of qubits
79
+ f: Callable f(x) -> bool/int, or sequence of N = 2^n bits
80
+
81
+ Returns:
82
+ tuple: (final_state, zero_probability)
83
+ final_state: state vector of shape (2^n,)
84
+ zero_probability: probability of measuring |0^n>;
85
+ ~1.0 indicates constant, ~0.0 indicates balanced
86
+ """
87
+ _validate_n(n)
88
+
89
+ # Step 1: uniform superposition
90
+ state = initialize_uniform_superposition(n)
91
+
92
+ # Step 2: oracle phase kickback
93
+ O = deutsch_jozsa_oracle(n, f)
94
+ state = O @ state
95
+
96
+ # Step 3: Hadamard transform again (H^{\otimes n} is self-inverse)
97
+ H_n = hadamard_transform(n)
98
+ state = H_n @ state
99
+
100
+ # Step 4: probability of measuring |0...0>
101
+ zero_probability = abs(state[0]) ** 2
102
+
103
+ return state, zero_probability
104
+
105
+
106
+ def deutsch_jozsa_classify(n, f, threshold=0.5):
107
+ r"""
108
+ Classify f as 'constant' or 'balanced' using the Deutsch-Jozsa algorithm.
109
+
110
+ Args:
111
+ n: Number of qubits
112
+ f: Callable f(x) -> bool/int, or sequence of N = 2^n bits
113
+ threshold: Decision boundary on P(|0^n>) (default 0.5)
114
+
115
+ Returns:
116
+ str: 'constant' if P(|0^n>) > threshold, else 'balanced'
117
+ """
118
+ _, p0 = deutsch_jozsa(n, f)
119
+ return "constant" if p0 > threshold else "balanced"