qilisdk 0.1.0__tar.gz → 0.1.1__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.
Files changed (81) hide show
  1. {qilisdk-0.1.0 → qilisdk-0.1.1}/CHANGELOG.md +9 -0
  2. qilisdk-0.1.1/PKG-INFO +538 -0
  3. qilisdk-0.1.1/README.md +504 -0
  4. {qilisdk-0.1.0 → qilisdk-0.1.1}/pyproject.toml +1 -1
  5. {qilisdk-0.1.0/src/qilisdk/analog → qilisdk-0.1.1/src/qilisdk}/__init__.py +2 -2
  6. qilisdk-0.1.1/src/qilisdk/__init__.pyi +17 -0
  7. qilisdk-0.1.0/src/qilisdk/__init__.pyi → qilisdk-0.1.1/src/qilisdk/analog/__init__.py +16 -12
  8. {qilisdk-0.1.0 → qilisdk-0.1.1}/src/qilisdk/analog/analog_result.py +1 -1
  9. qilisdk-0.1.1/src/qilisdk/common/__init__.py +17 -0
  10. {qilisdk-0.1.0 → qilisdk-0.1.1}/src/qilisdk/digital/__init__.py +5 -12
  11. {qilisdk-0.1.0 → qilisdk-0.1.1}/src/qilisdk/digital/digital_result.py +1 -1
  12. {qilisdk-0.1.0/src/qilisdk → qilisdk-0.1.1/src/qilisdk/extras}/__init__.py +4 -11
  13. qilisdk-0.1.1/src/qilisdk/extras/__init__.pyi +18 -0
  14. {qilisdk-0.1.0 → qilisdk-0.1.1}/src/qilisdk/extras/cuda/cuda_backend.py +1 -3
  15. qilisdk-0.1.1/src/qilisdk/extras/qaas/qaas_analog_result.py +20 -0
  16. {qilisdk-0.1.0 → qilisdk-0.1.1}/src/qilisdk/extras/qaas/qaas_backend.py +2 -2
  17. {qilisdk-0.1.0 → qilisdk-0.1.1}/tests/digital/test_gates.py +2 -1
  18. {qilisdk-0.1.0 → qilisdk-0.1.1}/tests/extras/test_cuda_backend.py +3 -5
  19. {qilisdk-0.1.0 → qilisdk-0.1.1}/uv.lock +55 -55
  20. qilisdk-0.1.0/PKG-INFO +0 -237
  21. qilisdk-0.1.0/README.md +0 -203
  22. qilisdk-0.1.0/src/qilisdk/common/__init__.py +0 -20
  23. qilisdk-0.1.0/src/qilisdk/extras/cuda/__init__.py +0 -18
  24. {qilisdk-0.1.0 → qilisdk-0.1.1}/.github/workflows/code_quality.yml +0 -0
  25. {qilisdk-0.1.0 → qilisdk-0.1.1}/.github/workflows/publish.yml +0 -0
  26. {qilisdk-0.1.0 → qilisdk-0.1.1}/.github/workflows/tests.yml +0 -0
  27. {qilisdk-0.1.0 → qilisdk-0.1.1}/.gitignore +0 -0
  28. {qilisdk-0.1.0 → qilisdk-0.1.1}/.pre-commit-config.yaml +0 -0
  29. {qilisdk-0.1.0 → qilisdk-0.1.1}/.python-version +0 -0
  30. {qilisdk-0.1.0 → qilisdk-0.1.1}/LICENCE +0 -0
  31. {qilisdk-0.1.0 → qilisdk-0.1.1}/src/qilisdk/_optionals.py +0 -0
  32. {qilisdk-0.1.0 → qilisdk-0.1.1}/src/qilisdk/analog/algorithms.py +0 -0
  33. {qilisdk-0.1.0 → qilisdk-0.1.1}/src/qilisdk/analog/analog_backend.py +0 -0
  34. {qilisdk-0.1.0 → qilisdk-0.1.1}/src/qilisdk/analog/exceptions.py +0 -0
  35. {qilisdk-0.1.0 → qilisdk-0.1.1}/src/qilisdk/analog/hamiltonian.py +0 -0
  36. {qilisdk-0.1.0 → qilisdk-0.1.1}/src/qilisdk/analog/quantum_objects.py +0 -0
  37. {qilisdk-0.1.0 → qilisdk-0.1.1}/src/qilisdk/analog/schedule.py +0 -0
  38. {qilisdk-0.1.0 → qilisdk-0.1.1}/src/qilisdk/common/algorithm.py +0 -0
  39. {qilisdk-0.1.0 → qilisdk-0.1.1}/src/qilisdk/common/backend.py +0 -0
  40. {qilisdk-0.1.0 → qilisdk-0.1.1}/src/qilisdk/common/model.py +0 -0
  41. {qilisdk-0.1.0 → qilisdk-0.1.1}/src/qilisdk/common/optimizer.py +0 -0
  42. {qilisdk-0.1.0 → qilisdk-0.1.1}/src/qilisdk/common/optimizer_result.py +0 -0
  43. {qilisdk-0.1.0 → qilisdk-0.1.1}/src/qilisdk/common/result.py +0 -0
  44. {qilisdk-0.1.0 → qilisdk-0.1.1}/src/qilisdk/digital/ansatz.py +0 -0
  45. {qilisdk-0.1.0 → qilisdk-0.1.1}/src/qilisdk/digital/circuit.py +0 -0
  46. {qilisdk-0.1.0 → qilisdk-0.1.1}/src/qilisdk/digital/digital_algorithm.py +0 -0
  47. {qilisdk-0.1.0 → qilisdk-0.1.1}/src/qilisdk/digital/digital_backend.py +0 -0
  48. {qilisdk-0.1.0 → qilisdk-0.1.1}/src/qilisdk/digital/exceptions.py +0 -0
  49. {qilisdk-0.1.0 → qilisdk-0.1.1}/src/qilisdk/digital/gates.py +0 -0
  50. {qilisdk-0.1.0 → qilisdk-0.1.1}/src/qilisdk/digital/vqe.py +0 -0
  51. {qilisdk-0.1.0/src/qilisdk/extras → qilisdk-0.1.1/src/qilisdk/extras/cuda}/__init__.py +0 -0
  52. {qilisdk-0.1.0 → qilisdk-0.1.1}/src/qilisdk/extras/cuda/cuda_analog_result.py +0 -0
  53. {qilisdk-0.1.0 → qilisdk-0.1.1}/src/qilisdk/extras/cuda/cuda_digital_result.py +0 -0
  54. {qilisdk-0.1.0 → qilisdk-0.1.1}/src/qilisdk/extras/qaas/__init__.py +0 -0
  55. {qilisdk-0.1.0 → qilisdk-0.1.1}/src/qilisdk/extras/qaas/keyring.py +0 -0
  56. {qilisdk-0.1.0 → qilisdk-0.1.1}/src/qilisdk/extras/qaas/models.py +0 -0
  57. {qilisdk-0.1.0 → qilisdk-0.1.1}/src/qilisdk/extras/qaas/qaas_digital_result.py +0 -0
  58. {qilisdk-0.1.0 → qilisdk-0.1.1}/src/qilisdk/extras/qaas/qaas_settings.py +0 -0
  59. {qilisdk-0.1.0 → qilisdk-0.1.1}/src/qilisdk/py.typed +0 -0
  60. {qilisdk-0.1.0 → qilisdk-0.1.1}/src/qilisdk/utils/__init__.py +0 -0
  61. {qilisdk-0.1.0 → qilisdk-0.1.1}/src/qilisdk/utils/openqasm2.py +0 -0
  62. {qilisdk-0.1.0 → qilisdk-0.1.1}/src/qilisdk/utils/serialization.py +0 -0
  63. {qilisdk-0.1.0 → qilisdk-0.1.1}/src/qilisdk/yaml.py +0 -0
  64. {qilisdk-0.1.0 → qilisdk-0.1.1}/tests/__init__.py +0 -0
  65. {qilisdk-0.1.0 → qilisdk-0.1.1}/tests/analog/__init__.py +0 -0
  66. {qilisdk-0.1.0 → qilisdk-0.1.1}/tests/analog/test_analog_result.py +0 -0
  67. {qilisdk-0.1.0 → qilisdk-0.1.1}/tests/analog/test_hamiltionian.py +0 -0
  68. {qilisdk-0.1.0 → qilisdk-0.1.1}/tests/analog/test_quantum_objects.py +0 -0
  69. {qilisdk-0.1.0 → qilisdk-0.1.1}/tests/analog/test_schedule.py +0 -0
  70. {qilisdk-0.1.0 → qilisdk-0.1.1}/tests/analog/test_time_evolution.py +0 -0
  71. {qilisdk-0.1.0 → qilisdk-0.1.1}/tests/common/__init__.py +0 -0
  72. {qilisdk-0.1.0 → qilisdk-0.1.1}/tests/common/test_scipy_optimizer.py +0 -0
  73. {qilisdk-0.1.0 → qilisdk-0.1.1}/tests/digital/__init__.py +0 -0
  74. {qilisdk-0.1.0 → qilisdk-0.1.1}/tests/digital/test_ansatz.py +0 -0
  75. {qilisdk-0.1.0 → qilisdk-0.1.1}/tests/digital/test_circuit.py +0 -0
  76. {qilisdk-0.1.0 → qilisdk-0.1.1}/tests/digital/test_vqe.py +0 -0
  77. {qilisdk-0.1.0 → qilisdk-0.1.1}/tests/extras/__init__.py +0 -0
  78. {qilisdk-0.1.0 → qilisdk-0.1.1}/tests/test_placeholder.py +0 -0
  79. {qilisdk-0.1.0 → qilisdk-0.1.1}/tests/utils/__init__.py +0 -0
  80. {qilisdk-0.1.0 → qilisdk-0.1.1}/tests/utils/test_openqasm2.py +0 -0
  81. {qilisdk-0.1.0 → qilisdk-0.1.1}/tests/utils/test_serialization.py +0 -0
@@ -1,3 +1,12 @@
1
+ # Qilisdk 0.1.1 (2025-04-11)
2
+
3
+ ### Misc
4
+
5
+ - Improved README documentation with comprehensive usage examples, and restructured module imports to expose core user-facing symbols for a more intuitive experience.
6
+
7
+ [PR #25](https://github.com/qilimanjaro-tech/qilisdk/pulls/25)
8
+
9
+
1
10
  # Qilisdk 0.1.0 (2025-04-10)
2
11
 
3
12
  ### Features
qilisdk-0.1.1/PKG-INFO ADDED
@@ -0,0 +1,538 @@
1
+ Metadata-Version: 2.4
2
+ Name: qilisdk
3
+ Version: 0.1.1
4
+ Summary: qilisdk is a Python framework for writing digital and analog quantum algorithms and executing them across multiple quantum backends. Its modular design streamlines the development process and enables easy integration with a variety of quantum platforms.
5
+ Author-email: Qilimanjaro Quantum Tech <info@qilimanjaro.tech>
6
+ License-File: LICENCE
7
+ Keywords: analog quantum computing,digital quantum computing,qilimanjaro,quantum computing
8
+ Classifier: Development Status :: 1 - Planning
9
+ Classifier: Environment :: Console
10
+ Classifier: Intended Audience :: Developers
11
+ Classifier: Intended Audience :: Science/Research
12
+ Classifier: License :: OSI Approved :: Apache Software License
13
+ Classifier: Operating System :: POSIX :: Linux
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
19
+ Classifier: Topic :: Scientific/Engineering :: Physics
20
+ Classifier: Topic :: Scientific/Engineering :: Quantum Computing
21
+ Requires-Python: >=3.10
22
+ Requires-Dist: dill>=0.3.9
23
+ Requires-Dist: numpy>=2.2.4
24
+ Requires-Dist: ruamel-yaml>=0.18.10
25
+ Requires-Dist: scipy>=1.15.1
26
+ Provides-Extra: cuda
27
+ Requires-Dist: cudaq==0.9.1; extra == 'cuda'
28
+ Provides-Extra: qaas
29
+ Requires-Dist: httpx>=0.28.1; extra == 'qaas'
30
+ Requires-Dist: keyring>=25.6.0; extra == 'qaas'
31
+ Requires-Dist: pydantic-settings>=2.8.0; extra == 'qaas'
32
+ Requires-Dist: pydantic>=2.10.6; extra == 'qaas'
33
+ Description-Content-Type: text/markdown
34
+
35
+ # QiliSDK
36
+
37
+ [![Python Versions](https://img.shields.io/pypi/pyversions/qilisdk.svg)](https://pypi.org/project/qilisdk/)
38
+ [![PyPI Version](https://img.shields.io/pypi/v/qilisdk.svg)](https://pypi.org/project/qilisdk/)
39
+ [![License](https://img.shields.io/pypi/l/qilisdk.svg)](#license)
40
+
41
+ **QiliSDK** is a Python framework for writing digital and analog quantum algorithms and executing them across multiple quantum backends. Its modular design streamlines the development process and enables easy integration with a variety of quantum platforms.
42
+
43
+ ---
44
+
45
+ ## Table of Contents
46
+ - [QiliSDK](#qilisdk)
47
+ - [Table of Contents](#table-of-contents)
48
+ - [Installation](#installation)
49
+ - [Base Installation](#base-installation)
50
+ - [Optional Extras](#optional-extras)
51
+ - [Usage](#usage)
52
+ - [Digital Quantum Circuits](#digital-quantum-circuits)
53
+ - [Hamiltonian and Analog Operations](#hamiltonian-and-analog-operations)
54
+ - [Optimizers](#optimizers)
55
+ - [Quantum-as-a-Service (QaaS)](#quantum-as-a-service-qaas)
56
+ - [CUDA-Accelerated Simulation](#cuda-accelerated-simulation)
57
+ - [Time Evolution](#time-evolution)
58
+ - [Variational Quantum Eigensolver (VQE)](#variational-quantum-eigensolver-vqe)
59
+ - [Open QASM Serialization](#open-qasm-serialization)
60
+ - [YAML Serialization](#yaml-serialization)
61
+ - [Development](#development)
62
+ - [Prerequisites](#prerequisites)
63
+ - [Setup \& Dependency Management](#setup--dependency-management)
64
+ - [Testing](#testing)
65
+ - [Linting \& Formatting](#linting--formatting)
66
+ - [Type Checking](#type-checking)
67
+ - [Changelog Management](#changelog-management)
68
+ - [Contributing](#contributing)
69
+ - [License](#license)
70
+ - [Acknowledgments](#acknowledgments)
71
+
72
+ ---
73
+
74
+ ## Installation
75
+
76
+ QiliSDK is available via [PyPI](https://pypi.org/project/qilisdk/). You can install the core package as well as optional extras for additional features.
77
+
78
+ ### Base Installation
79
+
80
+ Install the core QiliSDK package using pip:
81
+
82
+ ```bash
83
+ pip install qilisdk
84
+ ```
85
+
86
+ ### Optional Extras
87
+
88
+ QiliSDK supports optional modules for additional functionality:
89
+
90
+ - **QaaS (Quantum-as-a-Service):**
91
+ To interface with Qilimanjaro’s cloud-based quantum services, install the QaaS extra:
92
+
93
+ ```bash
94
+ pip install qilisdk[qaas]
95
+ ```
96
+
97
+ - **CUDA Acceleration:**
98
+ For GPU-accelerated quantum simulation using NVIDIA GPUs, install the CUDA extra:
99
+
100
+ ```bash
101
+ pip install qilisdk[cuda]
102
+ ```
103
+
104
+ You can also install both optional dependencies using a single command:
105
+
106
+ ```bash
107
+ pip install qilisdk[cuda,qaas]
108
+ ```
109
+
110
+ ---
111
+
112
+ ## Usage
113
+
114
+ QiliSDK is designed to simplify both digital and analog quantum computing workflows. This guide provides example code snippets for creating quantum circuits, performing Hamiltonian arithmetic, optimization, simulation on various backends (including CUDA and cloud-based QaaS), and using additional utility functions.
115
+
116
+ ### Digital Quantum Circuits
117
+
118
+ Create and simulate quantum circuits with a flexible gate framework. The following example demonstrates how to assemble a circuit, adjust gate parameters, and execute it with the Qibo backend:
119
+
120
+ ```python
121
+ import numpy as np
122
+ from qilisdk.digital import Circuit, H, RX, CNOT, M
123
+
124
+ # Create a circuit with 2 qubits
125
+ circuit = Circuit(2)
126
+ circuit.add(H(0)) # Apply Hadamard on qubit 0
127
+ circuit.add(RX(0, theta=np.pi)) # Apply RX rotation on qubit 0
128
+ circuit.add(CNOT(0, 1)) # Add a CNOT gate between qubit 0 and 1
129
+
130
+ # Retrieve the current gate parameters
131
+ print("Initial parameters:", circuit.get_parameter_values())
132
+
133
+ # Update circuit parameters (e.g., update RX rotation angle)
134
+ circuit.set_parameter_values([2 * np.pi])
135
+
136
+ # Execute the circuit simulation using CudaBackend
137
+ backend = CudaBackend()
138
+ results = backend.execute(circuit)
139
+
140
+ # Display the simulation output and measurement probabilities
141
+ print("Simulation Results:")
142
+ print(results)
143
+ print("Probabilities:", results.probabilities)
144
+ ```
145
+
146
+ ### Hamiltonian and Analog Operations
147
+
148
+ Utilize the `Hamiltonian` class for Pauli operator arithmetic. Build expressions, iterate through terms, and even round-trip using the parse feature:
149
+
150
+ ```python
151
+ from qilisdk.analog import Hamiltonian, X, Y, Z, I
152
+
153
+ # Build a Hamiltonian expression using Pauli operators
154
+ H_expr = (Z(0) + X(0)) * (Z(0) - X(0))
155
+ print("Hamiltonian Expression:", H_expr)
156
+
157
+ # Iterate over Hamiltonian terms
158
+ for coeff, ops in H_expr:
159
+ print("Coefficient:", coeff, "Operators:", ops)
160
+
161
+ # Parse a Hamiltonian from its string representation
162
+ parsed_H = Hamiltonian.parse("-2j Y(0)")
163
+ assert H_expr == parsed_H, "The Hamiltonian does not match after parsing."
164
+ ```
165
+
166
+ ### Optimizers
167
+
168
+ Run optimization routines using the `SciPyOptimizer` and integrate them with a variational algorithm (VQE). In the example below, a simple quadratic cost function is minimized:
169
+
170
+ ```python
171
+ from qilisdk.common import SciPyOptimizer
172
+
173
+ def cost_function(params):
174
+ # A simple quadratic cost: minimum at [1, 1, 1]
175
+ return sum((p - 1) ** 2 for p in params)
176
+
177
+ # Initialize the optimizer with the BFGS method
178
+ optimizer = SciPyOptimizer(method="BFGS")
179
+ initial_parameters = [0, 0, 0]
180
+ result = optimizer.optimize(cost_function, initial_parameters)
181
+
182
+ print("Optimal cost:", result.optimal_cost)
183
+ print("Optimal Parameters:", result.optimal_parameters)
184
+ ```
185
+
186
+ ### Quantum-as-a-Service (QaaS)
187
+
188
+ QiliSDK now includes a draft backend for interfacing with Qilimanjaro's QaaS platform. This module supports secure login and a unified interface for both digital circuits and analog evolutions:
189
+
190
+ ```python
191
+ from qilisdk.extras import QaaSBackend
192
+
193
+ # Login to QaaSBackend with credentials (or use environment variables)
194
+ # This only needs to be run once.
195
+ QaaSBackend.login(username="your_username", apikey="your_apikey")
196
+
197
+ # Instantiate QaaSBackend
198
+ qaas_backend = QaaSBackend()
199
+
200
+ # Execute a pre-built circuit (see Digital Quantum Circuits section)
201
+ results = qaas_backend.execute(circuit)
202
+ print("QaaS Simulation Results:", results)
203
+ ```
204
+
205
+ ### CUDA-Accelerated Simulation
206
+
207
+ For users with NVIDIA GPUs, the `CudaBackend` provides GPU-accelerated simulation using several simulation methods. For example, using the TENSOR_NETWORK method:
208
+
209
+ ```python
210
+ from qilisdk.extras import CudaBackend
211
+ from qilisdk.digital import Circuit, H, M, DigitalSimulationMethod
212
+
213
+ # Build a single-qubit circuit
214
+ circuit = Circuit(nqubits=1)
215
+ circuit.add(H(0))
216
+ circuit.add(M(0))
217
+
218
+ # Initialize CudaBackend with the TENSOR_NETWORK simulation method
219
+ cuda_backend = CudaBackend(digital_simulation_method=DigitalSimulationMethod.TENSOR_NETWORK)
220
+ results = cuda_backend.execute(circuit, nshots=1000)
221
+ print("CUDA Backend Results:", results)
222
+ ```
223
+
224
+ ### Time Evolution
225
+
226
+ For analog simulations, the new `TimeEvolution` and `Schedule` classes allow you to simulate time-dependent quantum dynamics. The following example uses a linear schedule to interpolate between two Hamiltonians on a CUDA backend:
227
+
228
+ ```python
229
+ import numpy as np
230
+ from qilisdk.analog import TimeEvolution, Schedule, tensor, ket, X, Z, Y
231
+ from qilisdk.extras import CudaBackend
232
+
233
+ T = 10 # Total evolution time
234
+ dt = 0.1 # Time-step
235
+ steps = np.linspace(0, T, int(T / dt))
236
+ nqubits = 1
237
+
238
+ # Define two Hamiltonians for the simulation
239
+ H1 = sum(X(i) for i in range(nqubits))
240
+ H2 = sum(Z(i) for i in range(nqubits))
241
+
242
+ # Create a schedule for the time evolution
243
+ schedule = Schedule(
244
+ T,
245
+ dt,
246
+ hamiltonians={"h1": H1, "h2": H2},
247
+ schedule={
248
+ t: {"h1": 1 - steps[t] / T, "h2": steps[t] / T}
249
+ for t in range(len(steps))
250
+ },
251
+ )
252
+
253
+ # Prepare an initial state (equal superposition)
254
+ state = tensor([(ket(0) + ket(1)).unit() for _ in range(nqubits)]).unit()
255
+
256
+ # Perform time evolution on the CUDA backend with observables to monitor
257
+ time_evolution = TimeEvolution(
258
+ backend=CudaBackend(),
259
+ schedule=schedule,
260
+ initial_state=state,
261
+ observables=[Z(0), X(0), Y(0)],
262
+ )
263
+ results = time_evolution.evolve(store_intermediate_results=True)
264
+ print("Time Evolution Results:", results)
265
+ ```
266
+
267
+ ### Variational Quantum Eigensolver (VQE)
268
+
269
+ The VQE algorithm integrates ansatz design, cost function evaluation, and classical optimization. Below is an illustrative example that sets up a VQE instance using a hardware-efficient ansatz and the SciPy optimizer:
270
+
271
+ ```python
272
+ import numpy as np
273
+ from qilisdk.common import SciPyOptimizer
274
+ from qilisdk.digital import HardwareEfficientAnsatz, VQE
275
+ from qilisdk.extras import CudaBackend
276
+
277
+
278
+ # Define problem parameters
279
+ n_items = 4
280
+ weights = [np.random.randint(1, 5) for _ in range(n_items)]
281
+ values = [np.random.randint(1, 10) for _ in range(n_items)]
282
+ max_weight_perc = 0.6
283
+ max_w = int(max_weight_perc * sum(weights))
284
+ nqubits = n_items
285
+
286
+ # Initialize a hardware-efficient ansatz
287
+ ansatz = HardwareEfficientAnsatz(
288
+ n_qubits=nqubits,
289
+ connectivity="Full",
290
+ layers=1,
291
+ one_qubit_gate="U3",
292
+ two_qubit_gate="CNOT"
293
+ )
294
+
295
+ # Use a CUDA backend for simulation
296
+ backend = CudaBackend()
297
+
298
+ LM = sum(values)
299
+
300
+ def cost_function(result):
301
+ # Get the most probable outcomes from the digital result
302
+ most_probable = result.get_probabilities()
303
+ final_cost = 0
304
+ for bitstring, prob in most_probable:
305
+ x_n = [int(bit) for bit in bitstring]
306
+ total_weight = sum(weights[i] * x_n[i] for i in range(n_items))
307
+ penalty = (total_weight - max_w) if total_weight > max_w else 0
308
+ reward = -sum(values[i] * x_n[i] for i in range(n_items))
309
+ final_cost += prob * (LM * penalty + reward)
310
+ return final_cost
311
+
312
+ optimizer = SciPyOptimizer(
313
+ method="Powell",
314
+ bounds=[(0, np.pi)] * ansatz.nparameters
315
+ )
316
+
317
+ # Initialize and execute the VQE algorithm
318
+ vqe = VQE(ansatz, [0.5] * ansatz.nparameters, cost_function)
319
+ results = vqe.execute(backend, optimizer, store_intermediate_results=True)
320
+
321
+ print("Optimal Cost:", results.optimal_cost)
322
+ print("Optimal Parameters:", results.optimal_parameters)
323
+ print("Intermediate Optimization Steps:")
324
+ for intermediate in results.intermediate_results:
325
+ print("Cost:", intermediate.cost)
326
+ ```
327
+
328
+ ### Open QASM Serialization
329
+
330
+ Serialize and deserialize quantum circuits using Open QASM 2.0 grammar. The utility functions below allow conversion to a QASM string or file and vice versa:
331
+
332
+ ```python
333
+ from qilisdk.digital import Circuit, CNOT, RX, H, M
334
+ from qilisdk.utils import to_qasm2, from_qasm2, to_qasm2_file, from_qasm2_file
335
+
336
+ # Create a sample circuit
337
+ circuit = Circuit(3)
338
+ circuit.add(H(0))
339
+ circuit.add(CNOT(0, 1))
340
+ circuit.add(RX(2, theta=3.1415))
341
+ circuit.add(M(0, 1, 2))
342
+
343
+ # Serialize to QASM string
344
+ qasm_code = to_qasm2(circuit)
345
+ print("Generated QASM:")
346
+ print(qasm_code)
347
+
348
+ # Deserialize back to a circuit
349
+ reconstructed_circuit = from_qasm2(qasm_code)
350
+
351
+ # Save to and load from a file
352
+ to_qasm2_file(circuit, "circuit.qasm")
353
+ reconstructed_circuit = from_qasm2_file("circuit.qasm")
354
+ ```
355
+
356
+ ### YAML Serialization
357
+
358
+ Easily save and restore circuits, hamiltonians, simulation and execution results, and virtually any other class in YAML format using the provided serialization functions:
359
+
360
+ ```python
361
+ from qilisdk.digital import Circuit, H, CNOT, M
362
+ from qilisdk.utils import serialize, deserialize, serialize_to, deserialize_from
363
+
364
+ circuit = Circuit(2)
365
+ circuit.add(H(0))
366
+ circuit.add(CNOT(0, 1))
367
+ circuit.add(M(0, 1))
368
+
369
+ # Serialize a circuit to a YAML string
370
+ yaml_string = serialize(circuit)
371
+
372
+ # Deserialize back into a Circuit object
373
+ restored_circuit = deserialize(yaml_string, cls=Circuit)
374
+
375
+ # Alternatively, work with files:
376
+ serialize_to(circuit, 'circuit.yml')
377
+ restored_circuit = deserialize_from('circuit.yml', cls=Circuit)
378
+ ```
379
+
380
+ ---
381
+
382
+ ## Development
383
+
384
+ This section covers how to set up a local development environment for qilisdk, run tests, enforce code style, manage dependencies, and contribute to the project. We use a number of tools to maintain code quality and consistency:
385
+
386
+ - **[uv](https://pypi.org/project/uv/)** for dependency management and packaging.
387
+ - **[ruff](https://beta.ruff.rs/docs/)** for linting and code formatting.
388
+ - **[mypy](http://mypy-lang.org/)** for static type checking.
389
+ - **[towncrier](https://github.com/twisted/towncrier)** for automated changelog generation.
390
+
391
+ ### Prerequisites
392
+
393
+ - Python **3.10+** (we test against multiple versions, but 3.10 is the minimum for local dev).
394
+ - [Git](https://git-scm.com/) for version control.
395
+ - [uv](https://pypi.org/project/uv/) for dependency management.
396
+
397
+ ### Setup & Dependency Management
398
+
399
+ 1. **Clone the repository**:
400
+ ```bash
401
+ git clone https://github.com/qilimanjaro-tech/qilisdk.git
402
+ cd qilisdk
403
+ ```
404
+
405
+ 2. **Install [uv](https://pypi.org/project/uv/) globally** (if not already):
406
+ ```bash
407
+ curl -LsSf https://astral.sh/uv/install.sh | sh
408
+ ```
409
+
410
+ 3. **Sync dependencies**:
411
+ - We maintain a `pyproject.toml` listing all dev and optional requirements.
412
+ - To install the dev environment locally, run:
413
+ ```bash
414
+ uv sync
415
+ ```
416
+ This sets up a virtual environment and installs all pinned dependencies (including `ruff`, `mypy`, `towncrier`, etc.).
417
+ - To install extra dependencies such as `qibo-backend`, run:
418
+ ```bash
419
+ uv sync --extra qibo-backend -extra ...
420
+ ```
421
+ This sets up a virtual environment and installs all pinned dependencies (previous), plus the specified extras.
422
+
423
+ 4. **Activate the virtual environment**:
424
+ - uv typically creates and manages its own environment, e.g., `.venv/`.
425
+ - Run:
426
+ ```bash
427
+ source .venv/bin/activate
428
+ ```
429
+ *(Exact command can vary depending on your shell and OS.)*
430
+
431
+ Now you can run all development commands (tests, linting, etc.) within this environment.
432
+
433
+ ### Testing
434
+
435
+ TODO: to_be_filled
436
+
437
+ ### Linting & Formatting
438
+
439
+ We enforce code style and best practices using [**ruff**](https://beta.ruff.rs/docs/). ruff handles:
440
+
441
+ - Lint checks (similar to flake8, pylint).
442
+ - Formatting (similar to black or isort).
443
+ - Automated fixes for certain issues.
444
+
445
+ To check linting:
446
+
447
+ ```bash
448
+ ruff check
449
+ ```
450
+
451
+ To automatically fix lint issues (where possible):
452
+
453
+ ```bash
454
+ ruff check --fix
455
+ ```
456
+
457
+ To automatically format your code:
458
+
459
+ ```bash
460
+ ruff format
461
+ ```
462
+
463
+ *(We recommend running `ruff check --fix` and `ruff format` before committing any changes.)*
464
+
465
+ ### Type Checking
466
+
467
+ We use [**mypy**](http://mypy-lang.org/) for static type checking. This helps ensure our code is type-safe and maintainable.
468
+
469
+ ```bash
470
+ mypy qilisdk
471
+ ```
472
+
473
+ If you have extra modules or tests you want type-checked, specify them:
474
+
475
+ ```bash
476
+ mypy qilisdk tests
477
+ ```
478
+
479
+ *(We encourage developers to annotate new functions, classes, and methods with type hints.)*
480
+
481
+ ### Changelog Management
482
+
483
+ We manage our changelog using [**towncrier**](https://github.com/twisted/towncrier). Instead of editing `CHANGELOG.md` directly, **each pull request** includes a small *news fragment* file in the `changes/` directory describing the user-facing changes.
484
+
485
+ For example, if you create a PR with id #123 adding a new feature, you add:
486
+ ```
487
+ changes/123.feature.rst
488
+ ```
489
+ Inside this file, you briefly describe the new feature:
490
+ ```rst
491
+ Added a new `cool_feature` in the `qilisdk.extras` module.
492
+ ```
493
+ Instead of manually creating the file, you can run:
494
+ ```bash
495
+ towncrier create --no-edit
496
+ ```
497
+ When we cut a new release, we update the version in `pyproject.toml` file and run:
498
+ ```bash
499
+ towncrier
500
+ ```
501
+ This aggregates all the news fragments into the `CHANGELOG.md` under the new version and removes the used fragments.
502
+
503
+ ### Contributing
504
+
505
+ We welcome contributions! Here’s the workflow:
506
+
507
+ 1. **Fork** this repository and create a feature branch.
508
+ 2. **Write** your changes (code, docs, or tests).
509
+ 3. **Add a news fragment** (if applicable) in `changes/` describing the user-facing impact.
510
+ 4. **Run** the following checks locally:
511
+ ```bash
512
+ ruff check --fix
513
+ ruff format
514
+ mypy qilisdk
515
+ pytest tests
516
+ ```
517
+ 5. **Commit** and push your branch to your fork. `pre-commit` will also run the checks automatically.
518
+ 6. **Open a Pull Request** against the `main` branch here.
519
+
520
+ Our CI will run tests, linting, and type checks. Please make sure your branch passes these checks before requesting a review.
521
+
522
+ ---
523
+
524
+ ## License
525
+
526
+ This project is licensed under the [Apache License](LICENSE).
527
+
528
+ ---
529
+
530
+ ## Acknowledgments
531
+
532
+ - Thanks to all the contributors who help develop qilisdk!
533
+ - [uv](https://pypi.org/project/uv/) for making dependency management smoother.
534
+ - [ruff](https://beta.ruff.rs/docs/), [mypy](http://mypy-lang.org/), and [towncrier](https://github.com/twisted/towncrier) for their amazing tooling.
535
+
536
+ ---
537
+
538
+ Feel free to open [issues](https://github.com/qilimanjaro-tech/qilisdk/issues) or [pull requests](https://github.com/qilimanjaro-tech/qilisdk/pulls) if you have questions or contributions. Happy coding!