qilisdk 0.1.5__tar.gz → 0.1.6__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.5 → qilisdk-0.1.6}/CHANGELOG.md +47 -0
- {qilisdk-0.1.5 → qilisdk-0.1.6}/PKG-INFO +17 -17
- {qilisdk-0.1.5 → qilisdk-0.1.6}/README.md +13 -13
- {qilisdk-0.1.5 → qilisdk-0.1.6}/pyproject.toml +6 -6
- {qilisdk-0.1.5 → qilisdk-0.1.6}/src/qilisdk/analog/hamiltonian.py +3 -3
- {qilisdk-0.1.5 → qilisdk-0.1.6}/src/qilisdk/analog/linear_schedule.py +5 -2
- {qilisdk-0.1.5 → qilisdk-0.1.6}/src/qilisdk/analog/schedule.py +8 -5
- {qilisdk-0.1.5 → qilisdk-0.1.6}/src/qilisdk/backends/cuda_backend.py +1 -1
- {qilisdk-0.1.5 → qilisdk-0.1.6}/src/qilisdk/backends/qutip_backend.py +2 -21
- {qilisdk-0.1.5/src/qilisdk/common → qilisdk-0.1.6/src/qilisdk/core}/model.py +7 -7
- {qilisdk-0.1.5/src/qilisdk/common → qilisdk-0.1.6/src/qilisdk/core}/qtensor.py +1 -1
- {qilisdk-0.1.5/src/qilisdk/common → qilisdk-0.1.6/src/qilisdk/core}/variables.py +42 -4
- {qilisdk-0.1.5 → qilisdk-0.1.6}/src/qilisdk/cost_functions/cost_function.py +1 -1
- {qilisdk-0.1.5 → qilisdk-0.1.6}/src/qilisdk/cost_functions/model_cost_function.py +5 -5
- {qilisdk-0.1.5 → qilisdk-0.1.6}/src/qilisdk/cost_functions/observable_cost_function.py +2 -2
- {qilisdk-0.1.5 → qilisdk-0.1.6}/src/qilisdk/digital/ansatz.py +0 -3
- {qilisdk-0.1.5 → qilisdk-0.1.6}/src/qilisdk/digital/circuit.py +2 -2
- {qilisdk-0.1.5 → qilisdk-0.1.6}/src/qilisdk/digital/gates.py +3 -3
- {qilisdk-0.1.5 → qilisdk-0.1.6}/src/qilisdk/functionals/functional.py +2 -2
- {qilisdk-0.1.5 → qilisdk-0.1.6}/src/qilisdk/functionals/functional_result.py +1 -1
- {qilisdk-0.1.5 → qilisdk-0.1.6}/src/qilisdk/functionals/sampling.py +1 -1
- {qilisdk-0.1.5 → qilisdk-0.1.6}/src/qilisdk/functionals/time_evolution.py +3 -3
- {qilisdk-0.1.5 → qilisdk-0.1.6}/src/qilisdk/functionals/time_evolution_result.py +2 -2
- {qilisdk-0.1.5 → qilisdk-0.1.6}/src/qilisdk/optimizers/optimizer_result.py +1 -1
- {qilisdk-0.1.5 → qilisdk-0.1.6}/src/qilisdk/speqtrum/__init__.py +2 -0
- {qilisdk-0.1.5 → qilisdk-0.1.6}/src/qilisdk/speqtrum/speqtrum.py +216 -61
- {qilisdk-0.1.5 → qilisdk-0.1.6}/src/qilisdk/speqtrum/speqtrum_models.py +167 -0
- {qilisdk-0.1.5 → qilisdk-0.1.6}/src/qilisdk/utils/visualization/schedule_renderers.py +6 -1
- {qilisdk-0.1.5 → qilisdk-0.1.6}/uv.lock +46 -46
- {qilisdk-0.1.5 → qilisdk-0.1.6}/.gitignore +0 -0
- {qilisdk-0.1.5 → qilisdk-0.1.6}/.pre-commit-config.yaml +0 -0
- {qilisdk-0.1.5 → qilisdk-0.1.6}/.python-version +0 -0
- {qilisdk-0.1.5 → qilisdk-0.1.6}/LICENCE +0 -0
- {qilisdk-0.1.5 → qilisdk-0.1.6}/src/qilisdk/__init__.py +0 -0
- {qilisdk-0.1.5 → qilisdk-0.1.6}/src/qilisdk/__init__.pyi +0 -0
- {qilisdk-0.1.5 → qilisdk-0.1.6}/src/qilisdk/_logging.py +0 -0
- {qilisdk-0.1.5 → qilisdk-0.1.6}/src/qilisdk/_optionals.py +0 -0
- {qilisdk-0.1.5 → qilisdk-0.1.6}/src/qilisdk/analog/__init__.py +0 -0
- {qilisdk-0.1.5 → qilisdk-0.1.6}/src/qilisdk/analog/exceptions.py +0 -0
- {qilisdk-0.1.5 → qilisdk-0.1.6}/src/qilisdk/backends/__init__.py +0 -0
- {qilisdk-0.1.5 → qilisdk-0.1.6}/src/qilisdk/backends/__init__.pyi +0 -0
- {qilisdk-0.1.5 → qilisdk-0.1.6}/src/qilisdk/backends/backend.py +0 -0
- {qilisdk-0.1.5/src/qilisdk/common → qilisdk-0.1.6/src/qilisdk/core}/__init__.py +0 -0
- {qilisdk-0.1.5/src/qilisdk/common → qilisdk-0.1.6/src/qilisdk/core}/algorithm.py +0 -0
- {qilisdk-0.1.5/src/qilisdk/common → qilisdk-0.1.6/src/qilisdk/core}/exceptions.py +0 -0
- {qilisdk-0.1.5/src/qilisdk/common → qilisdk-0.1.6/src/qilisdk/core}/parameterizable.py +0 -0
- {qilisdk-0.1.5/src/qilisdk/common → qilisdk-0.1.6/src/qilisdk/core}/result.py +0 -0
- {qilisdk-0.1.5 → qilisdk-0.1.6}/src/qilisdk/cost_functions/__init__.py +0 -0
- {qilisdk-0.1.5 → qilisdk-0.1.6}/src/qilisdk/digital/__init__.py +0 -0
- {qilisdk-0.1.5 → qilisdk-0.1.6}/src/qilisdk/digital/exceptions.py +0 -0
- {qilisdk-0.1.5 → qilisdk-0.1.6}/src/qilisdk/functionals/__init__.py +0 -0
- {qilisdk-0.1.5 → qilisdk-0.1.6}/src/qilisdk/functionals/sampling_result.py +0 -0
- {qilisdk-0.1.5 → qilisdk-0.1.6}/src/qilisdk/functionals/variational_program.py +0 -0
- {qilisdk-0.1.5 → qilisdk-0.1.6}/src/qilisdk/functionals/variational_program_result.py +0 -0
- {qilisdk-0.1.5 → qilisdk-0.1.6}/src/qilisdk/logging_config.yaml +0 -0
- {qilisdk-0.1.5 → qilisdk-0.1.6}/src/qilisdk/optimizers/__init__.py +0 -0
- {qilisdk-0.1.5 → qilisdk-0.1.6}/src/qilisdk/optimizers/optimizer.py +0 -0
- {qilisdk-0.1.5 → qilisdk-0.1.6}/src/qilisdk/optimizers/scipy_optimizer.py +0 -0
- {qilisdk-0.1.5 → qilisdk-0.1.6}/src/qilisdk/py.typed +0 -0
- {qilisdk-0.1.5 → qilisdk-0.1.6}/src/qilisdk/settings.py +0 -0
- {qilisdk-0.1.5 → qilisdk-0.1.6}/src/qilisdk/speqtrum/__init__.pyi +0 -0
- {qilisdk-0.1.5 → qilisdk-0.1.6}/src/qilisdk/speqtrum/experiments/__init__.py +0 -0
- {qilisdk-0.1.5 → qilisdk-0.1.6}/src/qilisdk/speqtrum/experiments/experiment_functional.py +0 -0
- {qilisdk-0.1.5 → qilisdk-0.1.6}/src/qilisdk/speqtrum/experiments/experiment_result.py +0 -0
- {qilisdk-0.1.5 → qilisdk-0.1.6}/src/qilisdk/speqtrum/keyring.py +0 -0
- {qilisdk-0.1.5 → qilisdk-0.1.6}/src/qilisdk/utils/__init__.py +0 -0
- {qilisdk-0.1.5 → qilisdk-0.1.6}/src/qilisdk/utils/openqasm2.py +0 -0
- {qilisdk-0.1.5 → qilisdk-0.1.6}/src/qilisdk/utils/serialization.py +0 -0
- {qilisdk-0.1.5 → qilisdk-0.1.6}/src/qilisdk/utils/visualization/PlusJakartaSans-SemiBold.ttf +0 -0
- {qilisdk-0.1.5 → qilisdk-0.1.6}/src/qilisdk/utils/visualization/__init__.py +0 -0
- {qilisdk-0.1.5 → qilisdk-0.1.6}/src/qilisdk/utils/visualization/circuit_renderers.py +0 -0
- {qilisdk-0.1.5 → qilisdk-0.1.6}/src/qilisdk/utils/visualization/style.py +0 -0
- {qilisdk-0.1.5 → qilisdk-0.1.6}/src/qilisdk/utils/visualization/themes.py +0 -0
- {qilisdk-0.1.5 → qilisdk-0.1.6}/src/qilisdk/yaml.py +0 -0
|
@@ -1,3 +1,50 @@
|
|
|
1
|
+
# qilisdk 0.1.6 (2025-10-31)
|
|
2
|
+
|
|
3
|
+
## Features
|
|
4
|
+
|
|
5
|
+
- Added ``job_name`` to speqtrum's ``submit`` method to allow the user to give a custom name to their job. ([PR #86](https://github.com/qilimanjaro-tech/qilisdk/pulls/86))
|
|
6
|
+
- SpeQtrum jobs now retain their concrete result types from submission through retrieval, so every handle produced by `submit` returns the right `FunctionalResult` whether you are sampling, evolving in time, or orchestrating a variational loop. Waiting for a fresh job still takes a single call, but the typed detail that comes back no longer needs manual casting:
|
|
7
|
+
|
|
8
|
+
```python
|
|
9
|
+
job_handle = speqtrum.submit(Sampling(circuit), device="cuda_state_vector")
|
|
10
|
+
job = speqtrum.wait_for_job(job_handle)
|
|
11
|
+
results = job.get_results() # Your IDE will now know this is a SamplingResult
|
|
12
|
+
```
|
|
13
|
+
|
|
14
|
+
The same strong typing applies when inspecting historical runs. Recreate a handle with the appropriate class method, pass it to `get_job`, and the returned `TypedJobDetail` exposes the precise payload you expect:
|
|
15
|
+
|
|
16
|
+
```python
|
|
17
|
+
job_handle = JobHandle.sampling(1200853)
|
|
18
|
+
job = speqtrum.get_job(job_handle)
|
|
19
|
+
results = job.get_results() # Your IDE will now know this is a SamplingResult
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
Variational programs are the only scenario that needs an extra hint: because they wrap another functional, recreate the handle with the inner functional’s result type so the execution results can be validated against your expectations:
|
|
23
|
+
|
|
24
|
+
```python
|
|
25
|
+
job_handle = JobHandle.variational_program(1200853, result_type=SamplingResult)
|
|
26
|
+
job = speqtrum.get_job(job_handle)
|
|
27
|
+
results = job.get_results() # Your IDE will now know this is a VariationalProgramResult
|
|
28
|
+
optimal = results.optimal_execution_results # Your IDE will now know this is a SamplingResult
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
Passing a bare integer job identifier to `wait_for_job` or `get_job` remains valid for quick checks and backwards-compatibility, but doing so skips the handle metadata and yields an untyped `JobDetail`, so you will need to inspect or cast the result manually. ([PR #87](https://github.com/qilimanjaro-tech/qilisdk/pulls/87))
|
|
32
|
+
|
|
33
|
+
## Bugfixes
|
|
34
|
+
|
|
35
|
+
- Fixed the `HardwareEfficientAnsatz` so the first layer of single-qubit gates is not duplicated, restoring the expected gate and parameter counts. ([PR #90](https://github.com/qilimanjaro-tech/qilisdk/pulls/90))
|
|
36
|
+
- Fixed the scheduler so numpy floats are accepted without errors. Fixed the QuTiP backend by aligning the schedule-to-backend mapping structure. ([PR #91](https://github.com/qilimanjaro-tech/qilisdk/pulls/91))
|
|
37
|
+
|
|
38
|
+
## Improved Documentation
|
|
39
|
+
|
|
40
|
+
- Updating the documentation and README to correspond to the latest version of QiliSDK. ([PR #80](https://github.com/qilimanjaro-tech/qilisdk/pulls/80))
|
|
41
|
+
- Added extra doc-strings, and fixed outdated doc-strings. ([PR #84](https://github.com/qilimanjaro-tech/qilisdk/pulls/84))
|
|
42
|
+
|
|
43
|
+
## Misc
|
|
44
|
+
|
|
45
|
+
- [PR #88](https://github.com/qilimanjaro-tech/qilisdk/pulls/88), [PR #92](https://github.com/qilimanjaro-tech/qilisdk/pulls/92)
|
|
46
|
+
|
|
47
|
+
|
|
1
48
|
# qilisdk 0.1.5 (2025-10-17)
|
|
2
49
|
|
|
3
50
|
## Features
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: qilisdk
|
|
3
|
-
Version: 0.1.
|
|
3
|
+
Version: 0.1.6
|
|
4
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
5
|
Project-URL: Homepage, https://github.com/qilimanjaro-tech/qilisdk
|
|
6
6
|
Project-URL: Documentation, https://qilimanjaro-tech.github.io/qilisdk/
|
|
@@ -29,11 +29,11 @@ Requires-Dist: loguru>=0.7.3
|
|
|
29
29
|
Requires-Dist: matplotlib>=3.10.7
|
|
30
30
|
Requires-Dist: numpy>=1.26.4
|
|
31
31
|
Requires-Dist: pydantic-settings>=2.11.0
|
|
32
|
-
Requires-Dist: pydantic>=2.12.
|
|
33
|
-
Requires-Dist: ruamel-yaml>=0.18.
|
|
32
|
+
Requires-Dist: pydantic>=2.12.3
|
|
33
|
+
Requires-Dist: ruamel-yaml>=0.18.16
|
|
34
34
|
Requires-Dist: scipy>=1.15.3
|
|
35
35
|
Provides-Extra: cuda
|
|
36
|
-
Requires-Dist: cuda-quantum-cu12==0.12.0; extra == 'cuda'
|
|
36
|
+
Requires-Dist: cuda-quantum-cu12==0.12.0.post1; extra == 'cuda'
|
|
37
37
|
Provides-Extra: qutip
|
|
38
38
|
Requires-Dist: qutip-qip>=0.4.1; extra == 'qutip'
|
|
39
39
|
Requires-Dist: qutip>=5.2.1; extra == 'qutip'
|
|
@@ -58,15 +58,15 @@ Description-Content-Type: text/markdown
|
|
|
58
58
|
- [Table of Contents](#table-of-contents)
|
|
59
59
|
- [Installation](#installation)
|
|
60
60
|
- [Base Installation](#base-installation)
|
|
61
|
-
- [Optional
|
|
61
|
+
- [Optional Dependencies: speqtrum, cuda, qutip](#optional-dependencies-speqtrum-cuda-qutip)
|
|
62
62
|
- [Usage](#usage)
|
|
63
63
|
- [Digital Quantum Circuits](#digital-quantum-circuits)
|
|
64
|
-
- [
|
|
64
|
+
- [Hamiltonians](#hamiltonians)
|
|
65
65
|
- [Optimizers](#optimizers)
|
|
66
|
-
- [
|
|
67
|
-
- [CUDA-Accelerated
|
|
68
|
-
- [Time Evolution](#time-evolution)
|
|
69
|
-
- [Variational
|
|
66
|
+
- [Qilimanjaro SpeQtrum](#qilimanjaro-speqtrum)
|
|
67
|
+
- [Sample a quantum Circuit Using a CUDA-Accelerated Simulator](#sample-a-quantum-circuit-using-a-cuda-accelerated-simulator)
|
|
68
|
+
- [Time Evolution using Qutip](#time-evolution-using-qutip)
|
|
69
|
+
- [Variational Programs](#variational-programs)
|
|
70
70
|
- [Open QASM Serialization](#open-qasm-serialization)
|
|
71
71
|
- [YAML Serialization](#yaml-serialization)
|
|
72
72
|
- [Development](#development)
|
|
@@ -94,7 +94,7 @@ Install the core QiliSDK package using pip:
|
|
|
94
94
|
pip install qilisdk
|
|
95
95
|
```
|
|
96
96
|
|
|
97
|
-
### Optional Dependencies
|
|
97
|
+
### Optional Dependencies: speqtrum, cuda, qutip
|
|
98
98
|
|
|
99
99
|
QiliSDK supports optional modules for additional functionality:
|
|
100
100
|
|
|
@@ -197,7 +197,7 @@ print("Optimal cost:", result.optimal_cost)
|
|
|
197
197
|
print("Optimal Parameters:", result.optimal_parameters)
|
|
198
198
|
```
|
|
199
199
|
|
|
200
|
-
### SpeQtrum
|
|
200
|
+
### Qilimanjaro SpeQtrum
|
|
201
201
|
|
|
202
202
|
QiliSDK includes a client for interacting with Qilimanjaro's SpeQtrum platform. This module supports secure login and a unified interface for both digital circuits and analog evolutions:
|
|
203
203
|
|
|
@@ -215,8 +215,8 @@ client = SpeQtrum()
|
|
|
215
215
|
# # Execute a pre-built circuit (see Digital Quantum Circuits section)
|
|
216
216
|
job_id = client.submit(Sampling(circuit, 1000), device="cuda_state_vector")
|
|
217
217
|
print("job id:", job_id)
|
|
218
|
-
print("job status:", client.
|
|
219
|
-
print("job result:", client.
|
|
218
|
+
print("job status:", client.get_job(job_id).status)
|
|
219
|
+
print("job result:", client.get_job(job_id).result)
|
|
220
220
|
```
|
|
221
221
|
|
|
222
222
|
### Sample a quantum Circuit Using a CUDA-Accelerated Simulator
|
|
@@ -246,7 +246,7 @@ For analog simulations, the new `TimeEvolution` and `Schedule` classes allow you
|
|
|
246
246
|
```python
|
|
247
247
|
import numpy as np
|
|
248
248
|
from qilisdk.analog import Schedule, X, Z, Y
|
|
249
|
-
from qilisdk.
|
|
249
|
+
from qilisdk.core import ket, tensor_prod
|
|
250
250
|
from qilisdk.backends import QutipBackend
|
|
251
251
|
from qilisdk.functionals import TimeEvolution
|
|
252
252
|
|
|
@@ -299,8 +299,8 @@ Here you find an example of building a Variational Quantum Eigensolver (VQE). To
|
|
|
299
299
|
```python
|
|
300
300
|
from qilisdk.digital.gates import U2, CNOT
|
|
301
301
|
from qilisdk.optimizers import SciPyOptimizer
|
|
302
|
-
from qilisdk.
|
|
303
|
-
from qilisdk.
|
|
302
|
+
from qilisdk.core.model import Model
|
|
303
|
+
from qilisdk.core.variables import LEQ, BinaryVariable
|
|
304
304
|
from qilisdk.digital.ansatz import HardwareEfficientAnsatz
|
|
305
305
|
from qilisdk.functionals import VariationalProgram, Sampling
|
|
306
306
|
from qilisdk.backends import CudaBackend
|
|
@@ -13,15 +13,15 @@
|
|
|
13
13
|
- [Table of Contents](#table-of-contents)
|
|
14
14
|
- [Installation](#installation)
|
|
15
15
|
- [Base Installation](#base-installation)
|
|
16
|
-
- [Optional
|
|
16
|
+
- [Optional Dependencies: speqtrum, cuda, qutip](#optional-dependencies-speqtrum-cuda-qutip)
|
|
17
17
|
- [Usage](#usage)
|
|
18
18
|
- [Digital Quantum Circuits](#digital-quantum-circuits)
|
|
19
|
-
- [
|
|
19
|
+
- [Hamiltonians](#hamiltonians)
|
|
20
20
|
- [Optimizers](#optimizers)
|
|
21
|
-
- [
|
|
22
|
-
- [CUDA-Accelerated
|
|
23
|
-
- [Time Evolution](#time-evolution)
|
|
24
|
-
- [Variational
|
|
21
|
+
- [Qilimanjaro SpeQtrum](#qilimanjaro-speqtrum)
|
|
22
|
+
- [Sample a quantum Circuit Using a CUDA-Accelerated Simulator](#sample-a-quantum-circuit-using-a-cuda-accelerated-simulator)
|
|
23
|
+
- [Time Evolution using Qutip](#time-evolution-using-qutip)
|
|
24
|
+
- [Variational Programs](#variational-programs)
|
|
25
25
|
- [Open QASM Serialization](#open-qasm-serialization)
|
|
26
26
|
- [YAML Serialization](#yaml-serialization)
|
|
27
27
|
- [Development](#development)
|
|
@@ -49,7 +49,7 @@ Install the core QiliSDK package using pip:
|
|
|
49
49
|
pip install qilisdk
|
|
50
50
|
```
|
|
51
51
|
|
|
52
|
-
### Optional Dependencies
|
|
52
|
+
### Optional Dependencies: speqtrum, cuda, qutip
|
|
53
53
|
|
|
54
54
|
QiliSDK supports optional modules for additional functionality:
|
|
55
55
|
|
|
@@ -152,7 +152,7 @@ print("Optimal cost:", result.optimal_cost)
|
|
|
152
152
|
print("Optimal Parameters:", result.optimal_parameters)
|
|
153
153
|
```
|
|
154
154
|
|
|
155
|
-
### SpeQtrum
|
|
155
|
+
### Qilimanjaro SpeQtrum
|
|
156
156
|
|
|
157
157
|
QiliSDK includes a client for interacting with Qilimanjaro's SpeQtrum platform. This module supports secure login and a unified interface for both digital circuits and analog evolutions:
|
|
158
158
|
|
|
@@ -170,8 +170,8 @@ client = SpeQtrum()
|
|
|
170
170
|
# # Execute a pre-built circuit (see Digital Quantum Circuits section)
|
|
171
171
|
job_id = client.submit(Sampling(circuit, 1000), device="cuda_state_vector")
|
|
172
172
|
print("job id:", job_id)
|
|
173
|
-
print("job status:", client.
|
|
174
|
-
print("job result:", client.
|
|
173
|
+
print("job status:", client.get_job(job_id).status)
|
|
174
|
+
print("job result:", client.get_job(job_id).result)
|
|
175
175
|
```
|
|
176
176
|
|
|
177
177
|
### Sample a quantum Circuit Using a CUDA-Accelerated Simulator
|
|
@@ -201,7 +201,7 @@ For analog simulations, the new `TimeEvolution` and `Schedule` classes allow you
|
|
|
201
201
|
```python
|
|
202
202
|
import numpy as np
|
|
203
203
|
from qilisdk.analog import Schedule, X, Z, Y
|
|
204
|
-
from qilisdk.
|
|
204
|
+
from qilisdk.core import ket, tensor_prod
|
|
205
205
|
from qilisdk.backends import QutipBackend
|
|
206
206
|
from qilisdk.functionals import TimeEvolution
|
|
207
207
|
|
|
@@ -254,8 +254,8 @@ Here you find an example of building a Variational Quantum Eigensolver (VQE). To
|
|
|
254
254
|
```python
|
|
255
255
|
from qilisdk.digital.gates import U2, CNOT
|
|
256
256
|
from qilisdk.optimizers import SciPyOptimizer
|
|
257
|
-
from qilisdk.
|
|
258
|
-
from qilisdk.
|
|
257
|
+
from qilisdk.core.model import Model
|
|
258
|
+
from qilisdk.core.variables import LEQ, BinaryVariable
|
|
259
259
|
from qilisdk.digital.ansatz import HardwareEfficientAnsatz
|
|
260
260
|
from qilisdk.functionals import VariationalProgram, Sampling
|
|
261
261
|
from qilisdk.backends import CudaBackend
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "qilisdk"
|
|
3
|
-
version = "0.1.
|
|
3
|
+
version = "0.1.6"
|
|
4
4
|
description = "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
5
|
readme = "README.md"
|
|
6
6
|
authors = [{name = "Qilimanjaro Quantum Tech", email = "info@qilimanjaro.tech"}]
|
|
@@ -25,9 +25,9 @@ classifiers = [
|
|
|
25
25
|
dependencies = [
|
|
26
26
|
"dill>=0.3.9",
|
|
27
27
|
"numpy>=1.26.4",
|
|
28
|
-
"ruamel-yaml>=0.18.
|
|
28
|
+
"ruamel-yaml>=0.18.16",
|
|
29
29
|
"scipy>=1.15.3",
|
|
30
|
-
"pydantic>=2.12.
|
|
30
|
+
"pydantic>=2.12.3",
|
|
31
31
|
"pydantic-settings>=2.11.0",
|
|
32
32
|
"loguru>=0.7.3",
|
|
33
33
|
"matplotlib>=3.10.7",
|
|
@@ -35,7 +35,7 @@ dependencies = [
|
|
|
35
35
|
|
|
36
36
|
[project.optional-dependencies]
|
|
37
37
|
cuda = [
|
|
38
|
-
"cuda-quantum-cu12==0.12.0",
|
|
38
|
+
"cuda-quantum-cu12==0.12.0.post1",
|
|
39
39
|
]
|
|
40
40
|
speqtrum = [
|
|
41
41
|
"httpx>=0.28.1",
|
|
@@ -49,13 +49,13 @@ qutip = [
|
|
|
49
49
|
|
|
50
50
|
[dependency-groups]
|
|
51
51
|
dev = [
|
|
52
|
-
"hypothesis>=6.142.
|
|
52
|
+
"hypothesis>=6.142.3",
|
|
53
53
|
"ipykernel>=7.0.1",
|
|
54
54
|
"mypy>=1.18.2",
|
|
55
55
|
"pre-commit>=4.3.0",
|
|
56
56
|
"pytest>=8.4.2",
|
|
57
57
|
"pytest-sugar>=1.1.1",
|
|
58
|
-
"ruff>=0.14.
|
|
58
|
+
"ruff>=0.14.2",
|
|
59
59
|
"towncrier>=25.8.0",
|
|
60
60
|
"loguru-caplog>=0.2.0",
|
|
61
61
|
"pytest-cov>=7.0.0",
|
|
@@ -24,9 +24,9 @@ from typing import TYPE_CHECKING, Callable, ClassVar
|
|
|
24
24
|
import numpy as np
|
|
25
25
|
from scipy.sparse import csr_matrix, identity, kron, spmatrix
|
|
26
26
|
|
|
27
|
-
from qilisdk.
|
|
28
|
-
from qilisdk.
|
|
29
|
-
from qilisdk.
|
|
27
|
+
from qilisdk.core.parameterizable import Parameterizable
|
|
28
|
+
from qilisdk.core.qtensor import QTensor
|
|
29
|
+
from qilisdk.core.variables import BaseVariable, Parameter, Term
|
|
30
30
|
from qilisdk.yaml import yaml
|
|
31
31
|
|
|
32
32
|
from .exceptions import InvalidHamiltonianOperation
|
|
@@ -15,7 +15,7 @@ from __future__ import annotations
|
|
|
15
15
|
|
|
16
16
|
from qilisdk.analog.hamiltonian import Hamiltonian
|
|
17
17
|
from qilisdk.analog.schedule import Schedule
|
|
18
|
-
from qilisdk.
|
|
18
|
+
from qilisdk.core.variables import Number, Parameter, Term
|
|
19
19
|
from qilisdk.yaml import yaml
|
|
20
20
|
|
|
21
21
|
|
|
@@ -85,7 +85,9 @@ class LinearSchedule(Schedule):
|
|
|
85
85
|
if next_idx is None or prev_idx is None or prev_expr is None or next_expr is None:
|
|
86
86
|
raise ValueError("Something unexpected happened while retrieving the coefficient.")
|
|
87
87
|
alpha: float = (t - prev_idx) / (next_idx - prev_idx)
|
|
88
|
-
|
|
88
|
+
e1 = next_expr * alpha
|
|
89
|
+
e2 = prev_expr * (1 - alpha)
|
|
90
|
+
return e1 + e2
|
|
89
91
|
|
|
90
92
|
def get_coefficient(self, time_step: float, hamiltonian_key: str) -> Number:
|
|
91
93
|
"""
|
|
@@ -98,6 +100,7 @@ class LinearSchedule(Schedule):
|
|
|
98
100
|
Returns:
|
|
99
101
|
Number: Evaluated coefficient value.
|
|
100
102
|
"""
|
|
103
|
+
time_step = float(time_step)
|
|
101
104
|
val = self.get_coefficient_expression(time_step=time_step, hamiltonian_key=hamiltonian_key)
|
|
102
105
|
return val.evaluate({}) if isinstance(val, Term) else (val.evaluate() if isinstance(val, Parameter) else val)
|
|
103
106
|
|
|
@@ -18,8 +18,8 @@ from typing import Callable
|
|
|
18
18
|
from loguru import logger
|
|
19
19
|
|
|
20
20
|
from qilisdk.analog.hamiltonian import Hamiltonian
|
|
21
|
-
from qilisdk.
|
|
22
|
-
from qilisdk.
|
|
21
|
+
from qilisdk.core.parameterizable import Parameterizable
|
|
22
|
+
from qilisdk.core.variables import BaseVariable, Number, Parameter, Term
|
|
23
23
|
from qilisdk.utils.visualization import ScheduleStyle
|
|
24
24
|
from qilisdk.yaml import yaml
|
|
25
25
|
|
|
@@ -110,7 +110,7 @@ class Schedule(Parameterizable):
|
|
|
110
110
|
f"The schedule can only contain Parameters, but a generic variable was provided ({time_step})"
|
|
111
111
|
)
|
|
112
112
|
self._parameters[v.label] = v
|
|
113
|
-
|
|
113
|
+
elif isinstance(coeff, BaseVariable):
|
|
114
114
|
if not isinstance(coeff, Parameter):
|
|
115
115
|
raise ValueError(
|
|
116
116
|
f"The schedule can only contain Parameters, but a generic variable was provided ({time_step})"
|
|
@@ -256,12 +256,12 @@ class Schedule(Parameterizable):
|
|
|
256
256
|
self._hamiltonians[label] = hamiltonian
|
|
257
257
|
self._schedule[0][label] = 0
|
|
258
258
|
self._nqubits = max(self._nqubits, hamiltonian.nqubits)
|
|
259
|
-
for
|
|
259
|
+
for _, param in hamiltonian.parameters.items():
|
|
260
260
|
self._parameters[param.label] = param
|
|
261
261
|
|
|
262
262
|
if schedule is not None:
|
|
263
263
|
for t in range(int(self.T / self.dt)):
|
|
264
|
-
time_step = schedule(t, **kwargs)
|
|
264
|
+
time_step = schedule(float(t), **kwargs)
|
|
265
265
|
if isinstance(time_step, Term):
|
|
266
266
|
for v in time_step.variables():
|
|
267
267
|
if not isinstance(v, Parameter):
|
|
@@ -422,6 +422,7 @@ class Schedule(Parameterizable):
|
|
|
422
422
|
Returns:
|
|
423
423
|
Number: The coefficient of the Hamiltonian at the specified time, or 0 if not defined.
|
|
424
424
|
"""
|
|
425
|
+
time_step = float(time_step)
|
|
425
426
|
val = self.get_coefficient_expression(time_step=time_step, hamiltonian_key=hamiltonian_key)
|
|
426
427
|
return val.evaluate({}) if isinstance(val, Term) else (val.evaluate() if isinstance(val, Parameter) else val)
|
|
427
428
|
|
|
@@ -502,3 +503,5 @@ class Schedule(Parameterizable):
|
|
|
502
503
|
renderer.plot()
|
|
503
504
|
if filepath:
|
|
504
505
|
renderer.save(filepath)
|
|
506
|
+
else:
|
|
507
|
+
renderer.show()
|
|
@@ -24,7 +24,7 @@ from loguru import logger
|
|
|
24
24
|
|
|
25
25
|
from qilisdk.analog.hamiltonian import Hamiltonian, PauliI, PauliOperator, PauliX, PauliY, PauliZ
|
|
26
26
|
from qilisdk.backends.backend import Backend
|
|
27
|
-
from qilisdk.
|
|
27
|
+
from qilisdk.core.qtensor import QTensor
|
|
28
28
|
from qilisdk.digital.exceptions import UnsupportedGateError
|
|
29
29
|
from qilisdk.digital.gates import RX, RY, RZ, SWAP, U1, U2, U3, Adjoint, BasicGate, Controlled, H, I, M, S, T, X, Y, Z
|
|
30
30
|
from qilisdk.functionals.sampling_result import SamplingResult
|
|
@@ -25,7 +25,7 @@ from qutip_qip.operations.gateclass import SingleQubitGate, is_qutip5
|
|
|
25
25
|
|
|
26
26
|
from qilisdk.analog.hamiltonian import Hamiltonian, PauliI, PauliOperator
|
|
27
27
|
from qilisdk.backends.backend import Backend
|
|
28
|
-
from qilisdk.
|
|
28
|
+
from qilisdk.core.qtensor import QTensor, tensor_prod
|
|
29
29
|
from qilisdk.digital import RX, RY, RZ, SWAP, U1, U2, U3, Circuit, H, I, M, S, T, X, Y, Z
|
|
30
30
|
from qilisdk.digital.exceptions import UnsupportedGateError
|
|
31
31
|
from qilisdk.digital.gates import Adjoint, BasicGate, Controlled
|
|
@@ -33,7 +33,6 @@ from qilisdk.functionals.sampling_result import SamplingResult
|
|
|
33
33
|
from qilisdk.functionals.time_evolution_result import TimeEvolutionResult
|
|
34
34
|
|
|
35
35
|
if TYPE_CHECKING:
|
|
36
|
-
from qilisdk.common.variables import Number
|
|
37
36
|
from qilisdk.functionals.sampling import Sampling
|
|
38
37
|
from qilisdk.functionals.time_evolution import TimeEvolution
|
|
39
38
|
|
|
@@ -183,28 +182,10 @@ class QutipBackend(Backend):
|
|
|
183
182
|
)
|
|
184
183
|
)
|
|
185
184
|
|
|
186
|
-
def get_hamiltonian_schedule(
|
|
187
|
-
hamiltonian: str, dt: float, schedule: dict[int, dict[str, Number]], T: float
|
|
188
|
-
) -> Callable:
|
|
189
|
-
def get_coeff(t: float) -> Number:
|
|
190
|
-
if int(t / dt) in schedule:
|
|
191
|
-
return schedule[int(t / dt)][hamiltonian]
|
|
192
|
-
time_step = int(t / dt)
|
|
193
|
-
while time_step > 0:
|
|
194
|
-
time_step -= 1
|
|
195
|
-
if time_step in schedule:
|
|
196
|
-
return schedule[time_step][hamiltonian]
|
|
197
|
-
return 0
|
|
198
|
-
|
|
199
|
-
return get_coeff
|
|
200
|
-
# return lambda t: schedule[int(t / dt)][ham] if int(t / dt) < int(T / dt) else schedule[int(T / dt)][ham]
|
|
201
|
-
|
|
202
185
|
H_t = [
|
|
203
186
|
[
|
|
204
187
|
qutip_hamiltonians[i],
|
|
205
|
-
|
|
206
|
-
h, functional.schedule.dt, functional.schedule.schedule, functional.schedule.T
|
|
207
|
-
),
|
|
188
|
+
np.array([functional.schedule.get_coefficient(t, h) for t in tlist]),
|
|
208
189
|
]
|
|
209
190
|
for i, h in enumerate(functional.schedule.hamiltonians)
|
|
210
191
|
]
|
|
@@ -103,8 +103,8 @@ class Constraint:
|
|
|
103
103
|
Example:
|
|
104
104
|
.. code-block:: python
|
|
105
105
|
|
|
106
|
-
from qilisdk.
|
|
107
|
-
from qilisdk.
|
|
106
|
+
from qilisdk.core.model import Constraint
|
|
107
|
+
from qilisdk.core.variables import BinaryVariable, LEQ
|
|
108
108
|
|
|
109
109
|
x = BinaryVariable("x")
|
|
110
110
|
constraint = Constraint("limit", LEQ(x, 1))
|
|
@@ -195,8 +195,8 @@ class Objective:
|
|
|
195
195
|
Example:
|
|
196
196
|
.. code-block:: python
|
|
197
197
|
|
|
198
|
-
from qilisdk.
|
|
199
|
-
from qilisdk.
|
|
198
|
+
from qilisdk.core.model import Objective, ObjectiveSense
|
|
199
|
+
from qilisdk.core.variables import BinaryVariable
|
|
200
200
|
|
|
201
201
|
x = BinaryVariable("x")
|
|
202
202
|
obj = Objective("profit", 3 * x, sense=ObjectiveSense.MAXIMIZE)
|
|
@@ -275,7 +275,7 @@ class Model:
|
|
|
275
275
|
Example:
|
|
276
276
|
.. code-block:: python
|
|
277
277
|
|
|
278
|
-
from qilisdk.
|
|
278
|
+
from qilisdk.core import BinaryVariable, LEQ, Model
|
|
279
279
|
|
|
280
280
|
num_items = 4
|
|
281
281
|
values = [1, 3, 5, 2]
|
|
@@ -517,8 +517,8 @@ class QUBO(Model):
|
|
|
517
517
|
Example:
|
|
518
518
|
.. code-block:: python
|
|
519
519
|
|
|
520
|
-
from qilisdk.
|
|
521
|
-
from qilisdk.
|
|
520
|
+
from qilisdk.core.model import QUBO
|
|
521
|
+
from qilisdk.core.variables import BinaryVariable
|
|
522
522
|
|
|
523
523
|
x0, x1 = BinaryVariable("x0"), BinaryVariable("x1")
|
|
524
524
|
qubo = QUBO("Example")
|
|
@@ -23,7 +23,7 @@ from typing import TYPE_CHECKING, Iterator, Mapping, Sequence, TypeVar
|
|
|
23
23
|
import numpy as np
|
|
24
24
|
from loguru import logger
|
|
25
25
|
|
|
26
|
-
from qilisdk.
|
|
26
|
+
from qilisdk.core.exceptions import EvaluationError, InvalidBoundsError, NotSupportedOperation, OutOfBoundsException
|
|
27
27
|
from qilisdk.yaml import yaml
|
|
28
28
|
|
|
29
29
|
if TYPE_CHECKING:
|
|
@@ -890,6 +890,9 @@ class BaseVariable(ABC):
|
|
|
890
890
|
if isinstance(other, Term):
|
|
891
891
|
return other + self
|
|
892
892
|
|
|
893
|
+
if isinstance(other, np.generic):
|
|
894
|
+
other = other.item()
|
|
895
|
+
|
|
893
896
|
return Term(elements=[self, other], operation=Operation.ADD)
|
|
894
897
|
|
|
895
898
|
__radd__ = __add__
|
|
@@ -901,6 +904,9 @@ class BaseVariable(ABC):
|
|
|
901
904
|
if isinstance(other, Term):
|
|
902
905
|
return other * self
|
|
903
906
|
|
|
907
|
+
if isinstance(other, np.generic):
|
|
908
|
+
other = other.item()
|
|
909
|
+
|
|
904
910
|
return Term(elements=[self, other], operation=Operation.MUL)
|
|
905
911
|
|
|
906
912
|
def __rmul__(self, other: Number | BaseVariable | Term) -> Term:
|
|
@@ -909,6 +915,9 @@ class BaseVariable(ABC):
|
|
|
909
915
|
if isinstance(other, Term):
|
|
910
916
|
return other * self
|
|
911
917
|
|
|
918
|
+
if isinstance(other, np.generic):
|
|
919
|
+
other = other.item()
|
|
920
|
+
|
|
912
921
|
return Term(elements=[other, self], operation=Operation.MUL)
|
|
913
922
|
|
|
914
923
|
__imul__ = __mul__
|
|
@@ -916,11 +925,19 @@ class BaseVariable(ABC):
|
|
|
916
925
|
def __sub__(self, other: Number | BaseVariable | Term) -> Term:
|
|
917
926
|
if not isinstance(other, (Number, BaseVariable, Term)):
|
|
918
927
|
return NotImplemented
|
|
928
|
+
|
|
929
|
+
if isinstance(other, np.generic):
|
|
930
|
+
other = other.item()
|
|
931
|
+
|
|
919
932
|
return self + -1 * other
|
|
920
933
|
|
|
921
934
|
def __rsub__(self, other: Number | BaseVariable | Term) -> Term:
|
|
922
935
|
if not isinstance(other, (Number, BaseVariable, Term)):
|
|
923
936
|
return NotImplemented
|
|
937
|
+
|
|
938
|
+
if isinstance(other, np.generic):
|
|
939
|
+
other = other.item()
|
|
940
|
+
|
|
924
941
|
return -1 * self + other
|
|
925
942
|
|
|
926
943
|
__isub__ = __sub__
|
|
@@ -935,6 +952,8 @@ class BaseVariable(ABC):
|
|
|
935
952
|
if other == 0:
|
|
936
953
|
raise ValueError("Division by zero is not allowed")
|
|
937
954
|
|
|
955
|
+
if isinstance(other, np.generic):
|
|
956
|
+
other = other.item()
|
|
938
957
|
other = 1 / other
|
|
939
958
|
return self * other
|
|
940
959
|
|
|
@@ -979,7 +998,7 @@ class BinaryVariable(BaseVariable):
|
|
|
979
998
|
Example:
|
|
980
999
|
.. code-block:: python
|
|
981
1000
|
|
|
982
|
-
from qilisdk.
|
|
1001
|
+
from qilisdk.core.variables import BinaryVariable
|
|
983
1002
|
|
|
984
1003
|
x = BinaryVariable("x")
|
|
985
1004
|
"""
|
|
@@ -1048,7 +1067,7 @@ class Variable(BaseVariable):
|
|
|
1048
1067
|
Example:
|
|
1049
1068
|
.. code-block:: python
|
|
1050
1069
|
|
|
1051
|
-
from qilisdk.
|
|
1070
|
+
from qilisdk.core.variables import Domain, Variable
|
|
1052
1071
|
|
|
1053
1072
|
price = Variable("price", domain=Domain.REAL, bounds=(0, 10))
|
|
1054
1073
|
binary_term = price.to_binary()
|
|
@@ -1183,7 +1202,7 @@ class Parameter(BaseVariable):
|
|
|
1183
1202
|
Example:
|
|
1184
1203
|
.. code-block:: python
|
|
1185
1204
|
|
|
1186
|
-
from qilisdk.
|
|
1205
|
+
from qilisdk.core.variables import Parameter
|
|
1187
1206
|
|
|
1188
1207
|
theta = Parameter("theta", value=0.5)
|
|
1189
1208
|
theta.set_value(0.75)
|
|
@@ -1665,6 +1684,10 @@ class Term:
|
|
|
1665
1684
|
if not isinstance(other, (Number, BaseVariable, Term)):
|
|
1666
1685
|
return NotImplemented
|
|
1667
1686
|
out = self.to_list() if self.operation == Operation.ADD else [copy.copy(self)]
|
|
1687
|
+
|
|
1688
|
+
if isinstance(other, np.generic):
|
|
1689
|
+
other = other.item()
|
|
1690
|
+
|
|
1668
1691
|
out.append(other)
|
|
1669
1692
|
return Term(out, Operation.ADD)
|
|
1670
1693
|
|
|
@@ -1674,6 +1697,9 @@ class Term:
|
|
|
1674
1697
|
if not isinstance(other, (Number, BaseVariable, Term)):
|
|
1675
1698
|
return NotImplemented
|
|
1676
1699
|
out = self.to_list() if self.operation == Operation.ADD else [copy.copy(self)]
|
|
1700
|
+
|
|
1701
|
+
if isinstance(other, np.generic):
|
|
1702
|
+
other = other.item()
|
|
1677
1703
|
out.insert(0, other)
|
|
1678
1704
|
return Term(out, Operation.ADD)
|
|
1679
1705
|
|
|
@@ -1683,6 +1709,10 @@ class Term:
|
|
|
1683
1709
|
out = self.to_list() if self.operation == Operation.MUL else [copy.copy(self)]
|
|
1684
1710
|
if len(out) == 0:
|
|
1685
1711
|
out = [0]
|
|
1712
|
+
|
|
1713
|
+
if isinstance(other, np.generic):
|
|
1714
|
+
other = other.item()
|
|
1715
|
+
|
|
1686
1716
|
out.append(other)
|
|
1687
1717
|
return Term(out, Operation.MUL)._unfold_parentheses()
|
|
1688
1718
|
|
|
@@ -1694,6 +1724,10 @@ class Term:
|
|
|
1694
1724
|
out = self.to_list() if self.operation == Operation.MUL else [copy.copy(self)]
|
|
1695
1725
|
if len(out) == 0:
|
|
1696
1726
|
out = [0]
|
|
1727
|
+
|
|
1728
|
+
if isinstance(other, np.generic):
|
|
1729
|
+
other = other.item()
|
|
1730
|
+
|
|
1697
1731
|
out.insert(0, other)
|
|
1698
1732
|
return Term(out, Operation.MUL)._unfold_parentheses()
|
|
1699
1733
|
|
|
@@ -1703,6 +1737,10 @@ class Term:
|
|
|
1703
1737
|
def __sub__(self, other: Number | BaseVariable | Term) -> Term:
|
|
1704
1738
|
if not isinstance(other, (Number, BaseVariable, Term)):
|
|
1705
1739
|
return NotImplemented
|
|
1740
|
+
|
|
1741
|
+
if isinstance(other, np.generic):
|
|
1742
|
+
other = other.item()
|
|
1743
|
+
|
|
1706
1744
|
return self + -1 * other
|
|
1707
1745
|
|
|
1708
1746
|
def __rsub__(self, other: Number | BaseVariable | Term) -> Term:
|
|
@@ -21,7 +21,7 @@ from qilisdk.functionals.sampling_result import SamplingResult
|
|
|
21
21
|
from qilisdk.functionals.time_evolution_result import TimeEvolutionResult
|
|
22
22
|
|
|
23
23
|
if TYPE_CHECKING:
|
|
24
|
-
from qilisdk.
|
|
24
|
+
from qilisdk.core.variables import Number
|
|
25
25
|
|
|
26
26
|
TResult = TypeVar("TResult", bound=FunctionalResult)
|
|
27
27
|
|
|
@@ -17,24 +17,24 @@ from typing import TYPE_CHECKING
|
|
|
17
17
|
|
|
18
18
|
import numpy as np
|
|
19
19
|
|
|
20
|
-
from qilisdk.
|
|
21
|
-
from qilisdk.
|
|
20
|
+
from qilisdk.core.model import QUBO, Model
|
|
21
|
+
from qilisdk.core.qtensor import QTensor, expect_val, ket
|
|
22
22
|
from qilisdk.cost_functions.cost_function import CostFunction
|
|
23
23
|
|
|
24
24
|
if TYPE_CHECKING:
|
|
25
|
-
from qilisdk.
|
|
25
|
+
from qilisdk.core.variables import Number
|
|
26
26
|
from qilisdk.functionals.sampling_result import SamplingResult
|
|
27
27
|
from qilisdk.functionals.time_evolution_result import TimeEvolutionResult
|
|
28
28
|
|
|
29
29
|
|
|
30
30
|
class ModelCostFunction(CostFunction):
|
|
31
31
|
"""
|
|
32
|
-
Evaluate the cost of functional results with respect to a :class:`~qilisdk.
|
|
32
|
+
Evaluate the cost of functional results with respect to a :class:`~qilisdk.core.model.Model`.
|
|
33
33
|
|
|
34
34
|
Example:
|
|
35
35
|
.. code-block:: python
|
|
36
36
|
|
|
37
|
-
from qilisdk.
|
|
37
|
+
from qilisdk.core import BinaryVariable, Model, LEQ
|
|
38
38
|
from qilisdk.cost_functions import ModelCostFunction
|
|
39
39
|
|
|
40
40
|
model = Model("demo")
|
|
@@ -18,11 +18,11 @@ from typing import TYPE_CHECKING
|
|
|
18
18
|
import numpy as np
|
|
19
19
|
|
|
20
20
|
from qilisdk.analog.hamiltonian import Hamiltonian, PauliOperator
|
|
21
|
-
from qilisdk.
|
|
21
|
+
from qilisdk.core.qtensor import QTensor, expect_val, ket, tensor_prod
|
|
22
22
|
from qilisdk.cost_functions.cost_function import CostFunction
|
|
23
23
|
|
|
24
24
|
if TYPE_CHECKING:
|
|
25
|
-
from qilisdk.
|
|
25
|
+
from qilisdk.core.variables import Number
|
|
26
26
|
from qilisdk.functionals.sampling_result import SamplingResult
|
|
27
27
|
from qilisdk.functionals.time_evolution_result import TimeEvolutionResult
|
|
28
28
|
|