qilisdk 0.1.0__tar.gz → 0.1.2__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.
- {qilisdk-0.1.0 → qilisdk-0.1.2}/CHANGELOG.md +18 -0
- qilisdk-0.1.2/PKG-INFO +538 -0
- qilisdk-0.1.2/README.md +504 -0
- {qilisdk-0.1.0 → qilisdk-0.1.2}/pyproject.toml +1 -1
- {qilisdk-0.1.0/src/qilisdk/analog → qilisdk-0.1.2/src/qilisdk}/__init__.py +2 -2
- qilisdk-0.1.2/src/qilisdk/__init__.pyi +17 -0
- qilisdk-0.1.0/src/qilisdk/__init__.pyi → qilisdk-0.1.2/src/qilisdk/analog/__init__.py +16 -12
- {qilisdk-0.1.0 → qilisdk-0.1.2}/src/qilisdk/analog/analog_result.py +1 -1
- qilisdk-0.1.2/src/qilisdk/common/__init__.py +17 -0
- {qilisdk-0.1.0 → qilisdk-0.1.2}/src/qilisdk/digital/__init__.py +5 -12
- {qilisdk-0.1.0 → qilisdk-0.1.2}/src/qilisdk/digital/ansatz.py +18 -1
- {qilisdk-0.1.0 → qilisdk-0.1.2}/src/qilisdk/digital/digital_result.py +1 -1
- {qilisdk-0.1.0 → qilisdk-0.1.2}/src/qilisdk/digital/vqe.py +1 -0
- {qilisdk-0.1.0/src/qilisdk → qilisdk-0.1.2/src/qilisdk/extras}/__init__.py +4 -11
- qilisdk-0.1.2/src/qilisdk/extras/__init__.pyi +18 -0
- {qilisdk-0.1.0 → qilisdk-0.1.2}/src/qilisdk/extras/cuda/cuda_backend.py +1 -3
- qilisdk-0.1.2/src/qilisdk/extras/qaas/models.py +132 -0
- qilisdk-0.1.2/src/qilisdk/extras/qaas/qaas_analog_result.py +20 -0
- qilisdk-0.1.2/src/qilisdk/extras/qaas/qaas_backend.py +254 -0
- qilisdk-0.1.2/src/qilisdk/extras/qaas/qaas_time_evolution_result.py +20 -0
- qilisdk-0.1.2/src/qilisdk/extras/qaas/qaas_vqe_result.py +20 -0
- {qilisdk-0.1.0 → qilisdk-0.1.2}/src/qilisdk/yaml.py +34 -2
- {qilisdk-0.1.0 → qilisdk-0.1.2}/tests/digital/test_gates.py +2 -1
- {qilisdk-0.1.0 → qilisdk-0.1.2}/tests/extras/test_cuda_backend.py +3 -5
- {qilisdk-0.1.0 → qilisdk-0.1.2}/uv.lock +875 -875
- qilisdk-0.1.0/PKG-INFO +0 -237
- qilisdk-0.1.0/README.md +0 -203
- qilisdk-0.1.0/src/qilisdk/common/__init__.py +0 -20
- qilisdk-0.1.0/src/qilisdk/extras/cuda/__init__.py +0 -18
- qilisdk-0.1.0/src/qilisdk/extras/qaas/models.py +0 -57
- qilisdk-0.1.0/src/qilisdk/extras/qaas/qaas_backend.py +0 -154
- {qilisdk-0.1.0 → qilisdk-0.1.2}/.github/workflows/code_quality.yml +0 -0
- {qilisdk-0.1.0 → qilisdk-0.1.2}/.github/workflows/publish.yml +0 -0
- {qilisdk-0.1.0 → qilisdk-0.1.2}/.github/workflows/tests.yml +0 -0
- {qilisdk-0.1.0 → qilisdk-0.1.2}/.gitignore +0 -0
- {qilisdk-0.1.0 → qilisdk-0.1.2}/.pre-commit-config.yaml +0 -0
- {qilisdk-0.1.0 → qilisdk-0.1.2}/.python-version +0 -0
- {qilisdk-0.1.0 → qilisdk-0.1.2}/LICENCE +0 -0
- {qilisdk-0.1.0 → qilisdk-0.1.2}/src/qilisdk/_optionals.py +0 -0
- {qilisdk-0.1.0 → qilisdk-0.1.2}/src/qilisdk/analog/algorithms.py +0 -0
- {qilisdk-0.1.0 → qilisdk-0.1.2}/src/qilisdk/analog/analog_backend.py +0 -0
- {qilisdk-0.1.0 → qilisdk-0.1.2}/src/qilisdk/analog/exceptions.py +0 -0
- {qilisdk-0.1.0 → qilisdk-0.1.2}/src/qilisdk/analog/hamiltonian.py +0 -0
- {qilisdk-0.1.0 → qilisdk-0.1.2}/src/qilisdk/analog/quantum_objects.py +0 -0
- {qilisdk-0.1.0 → qilisdk-0.1.2}/src/qilisdk/analog/schedule.py +0 -0
- {qilisdk-0.1.0 → qilisdk-0.1.2}/src/qilisdk/common/algorithm.py +0 -0
- {qilisdk-0.1.0 → qilisdk-0.1.2}/src/qilisdk/common/backend.py +0 -0
- {qilisdk-0.1.0 → qilisdk-0.1.2}/src/qilisdk/common/model.py +0 -0
- {qilisdk-0.1.0 → qilisdk-0.1.2}/src/qilisdk/common/optimizer.py +0 -0
- {qilisdk-0.1.0 → qilisdk-0.1.2}/src/qilisdk/common/optimizer_result.py +0 -0
- {qilisdk-0.1.0 → qilisdk-0.1.2}/src/qilisdk/common/result.py +0 -0
- {qilisdk-0.1.0 → qilisdk-0.1.2}/src/qilisdk/digital/circuit.py +0 -0
- {qilisdk-0.1.0 → qilisdk-0.1.2}/src/qilisdk/digital/digital_algorithm.py +0 -0
- {qilisdk-0.1.0 → qilisdk-0.1.2}/src/qilisdk/digital/digital_backend.py +0 -0
- {qilisdk-0.1.0 → qilisdk-0.1.2}/src/qilisdk/digital/exceptions.py +0 -0
- {qilisdk-0.1.0 → qilisdk-0.1.2}/src/qilisdk/digital/gates.py +0 -0
- {qilisdk-0.1.0/src/qilisdk/extras → qilisdk-0.1.2/src/qilisdk/extras/cuda}/__init__.py +0 -0
- {qilisdk-0.1.0 → qilisdk-0.1.2}/src/qilisdk/extras/cuda/cuda_analog_result.py +0 -0
- {qilisdk-0.1.0 → qilisdk-0.1.2}/src/qilisdk/extras/cuda/cuda_digital_result.py +0 -0
- {qilisdk-0.1.0 → qilisdk-0.1.2}/src/qilisdk/extras/qaas/__init__.py +0 -0
- {qilisdk-0.1.0 → qilisdk-0.1.2}/src/qilisdk/extras/qaas/keyring.py +0 -0
- {qilisdk-0.1.0 → qilisdk-0.1.2}/src/qilisdk/extras/qaas/qaas_digital_result.py +0 -0
- {qilisdk-0.1.0 → qilisdk-0.1.2}/src/qilisdk/extras/qaas/qaas_settings.py +0 -0
- {qilisdk-0.1.0 → qilisdk-0.1.2}/src/qilisdk/py.typed +0 -0
- {qilisdk-0.1.0 → qilisdk-0.1.2}/src/qilisdk/utils/__init__.py +0 -0
- {qilisdk-0.1.0 → qilisdk-0.1.2}/src/qilisdk/utils/openqasm2.py +0 -0
- {qilisdk-0.1.0 → qilisdk-0.1.2}/src/qilisdk/utils/serialization.py +0 -0
- {qilisdk-0.1.0 → qilisdk-0.1.2}/tests/__init__.py +0 -0
- {qilisdk-0.1.0 → qilisdk-0.1.2}/tests/analog/__init__.py +0 -0
- {qilisdk-0.1.0 → qilisdk-0.1.2}/tests/analog/test_analog_result.py +0 -0
- {qilisdk-0.1.0 → qilisdk-0.1.2}/tests/analog/test_hamiltionian.py +0 -0
- {qilisdk-0.1.0 → qilisdk-0.1.2}/tests/analog/test_quantum_objects.py +0 -0
- {qilisdk-0.1.0 → qilisdk-0.1.2}/tests/analog/test_schedule.py +0 -0
- {qilisdk-0.1.0 → qilisdk-0.1.2}/tests/analog/test_time_evolution.py +0 -0
- {qilisdk-0.1.0 → qilisdk-0.1.2}/tests/common/__init__.py +0 -0
- {qilisdk-0.1.0 → qilisdk-0.1.2}/tests/common/test_scipy_optimizer.py +0 -0
- {qilisdk-0.1.0 → qilisdk-0.1.2}/tests/digital/__init__.py +0 -0
- {qilisdk-0.1.0 → qilisdk-0.1.2}/tests/digital/test_ansatz.py +0 -0
- {qilisdk-0.1.0 → qilisdk-0.1.2}/tests/digital/test_circuit.py +0 -0
- {qilisdk-0.1.0 → qilisdk-0.1.2}/tests/digital/test_vqe.py +0 -0
- {qilisdk-0.1.0 → qilisdk-0.1.2}/tests/extras/__init__.py +0 -0
- {qilisdk-0.1.0 → qilisdk-0.1.2}/tests/test_placeholder.py +0 -0
- {qilisdk-0.1.0 → qilisdk-0.1.2}/tests/utils/__init__.py +0 -0
- {qilisdk-0.1.0 → qilisdk-0.1.2}/tests/utils/test_openqasm2.py +0 -0
- {qilisdk-0.1.0 → qilisdk-0.1.2}/tests/utils/test_serialization.py +0 -0
|
@@ -1,3 +1,21 @@
|
|
|
1
|
+
# Qilisdk 0.1.2 (2025-04-22)
|
|
2
|
+
|
|
3
|
+
### Misc
|
|
4
|
+
|
|
5
|
+
- Improved `QaaSBacked` functionality to include methods for executing digital and analog algorithms.
|
|
6
|
+
|
|
7
|
+
[PR #27](https://github.com/qilimanjaro-tech/qilisdk/pulls/27)
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
# Qilisdk 0.1.1 (2025-04-11)
|
|
11
|
+
|
|
12
|
+
### Misc
|
|
13
|
+
|
|
14
|
+
- Improved README documentation with comprehensive usage examples, and restructured module imports to expose core user-facing symbols for a more intuitive experience.
|
|
15
|
+
|
|
16
|
+
[PR #25](https://github.com/qilimanjaro-tech/qilisdk/pulls/25)
|
|
17
|
+
|
|
18
|
+
|
|
1
19
|
# Qilisdk 0.1.0 (2025-04-10)
|
|
2
20
|
|
|
3
21
|
### Features
|
qilisdk-0.1.2/PKG-INFO
ADDED
|
@@ -0,0 +1,538 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: qilisdk
|
|
3
|
+
Version: 0.1.2
|
|
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
|
+
[](https://pypi.org/project/qilisdk/)
|
|
38
|
+
[](https://pypi.org/project/qilisdk/)
|
|
39
|
+
[](#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!
|