qmlkit 0.1.0__py3-none-any.whl
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.
- qmlkit/__init__.py +495 -0
- qmlkit/_aliases.py +135 -0
- qmlkit/algorithms/__init__.py +82 -0
- qmlkit/algorithms/adapt.py +297 -0
- qmlkit/algorithms/autoencoder.py +206 -0
- qmlkit/algorithms/chemistry.py +222 -0
- qmlkit/algorithms/clustering.py +149 -0
- qmlkit/algorithms/hamiltonians.py +143 -0
- qmlkit/algorithms/molecule.py +442 -0
- qmlkit/algorithms/qaoa.py +208 -0
- qmlkit/algorithms/rl.py +198 -0
- qmlkit/algorithms/vqe.py +198 -0
- qmlkit/ansatz/__init__.py +68 -0
- qmlkit/ansatz/blocks.py +348 -0
- qmlkit/ansatz/library.py +570 -0
- qmlkit/ansatz/reupload.py +168 -0
- qmlkit/baselines.py +604 -0
- qmlkit/budget.py +234 -0
- qmlkit/core/__init__.py +1 -0
- qmlkit/core/backends/__init__.py +22 -0
- qmlkit/core/backends/_sampling.py +43 -0
- qmlkit/core/backends/base.py +256 -0
- qmlkit/core/backends/cirq_backend.py +110 -0
- qmlkit/core/backends/cirq_density_backend.py +71 -0
- qmlkit/core/backends/noisy.py +86 -0
- qmlkit/core/backends/numpy_backend.py +276 -0
- qmlkit/core/backends/qiskit_aer_backend.py +79 -0
- qmlkit/core/backends/qiskit_backend.py +104 -0
- qmlkit/core/backends/registry.py +210 -0
- qmlkit/core/backends/spinqit_backend.py +233 -0
- qmlkit/core/backends/torch_backend.py +185 -0
- qmlkit/core/builder.py +189 -0
- qmlkit/core/execute.py +193 -0
- qmlkit/core/gates.py +243 -0
- qmlkit/core/ir.py +320 -0
- qmlkit/core/observables.py +269 -0
- qmlkit/datasets.py +178 -0
- qmlkit/diagnostics.py +719 -0
- qmlkit/draw.py +177 -0
- qmlkit/encoding/__init__.py +63 -0
- qmlkit/encoding/amplitude.py +178 -0
- qmlkit/encoding/angle.py +61 -0
- qmlkit/encoding/feature_maps.py +353 -0
- qmlkit/encoding/hamiltonian.py +206 -0
- qmlkit/encoding/pipeline.py +198 -0
- qmlkit/encoding/scaling.py +139 -0
- qmlkit/evaluate.py +686 -0
- qmlkit/fourier.py +124 -0
- qmlkit/generative.py +406 -0
- qmlkit/gradients/__init__.py +61 -0
- qmlkit/gradients/adjoint.py +138 -0
- qmlkit/gradients/batch.py +275 -0
- qmlkit/gradients/dispatch.py +247 -0
- qmlkit/gradients/hadamard.py +108 -0
- qmlkit/gradients/parameter_shift.py +142 -0
- qmlkit/gradients/rules.py +151 -0
- qmlkit/gradients/spsa.py +134 -0
- qmlkit/imbalance.py +335 -0
- qmlkit/info.py +153 -0
- qmlkit/interop.py +778 -0
- qmlkit/kernels/__init__.py +69 -0
- qmlkit/kernels/estimators.py +206 -0
- qmlkit/kernels/matrix.py +439 -0
- qmlkit/kernels/models.py +315 -0
- qmlkit/metrics.py +394 -0
- qmlkit/nn/__init__.py +18 -0
- qmlkit/nn/advanced.py +254 -0
- qmlkit/nn/layer.py +343 -0
- qmlkit/nn/losses.py +124 -0
- qmlkit/nn/models.py +245 -0
- qmlkit/optim.py +306 -0
- qmlkit/provenance.py +271 -0
- qmlkit/py.typed +0 -0
- qmlkit/search.py +561 -0
- qmlkit/shadows.py +117 -0
- qmlkit/utils/__init__.py +19 -0
- qmlkit/utils/errors.py +130 -0
- qmlkit/utils/shots.py +55 -0
- qmlkit-0.1.0.dist-info/METADATA +745 -0
- qmlkit-0.1.0.dist-info/RECORD +83 -0
- qmlkit-0.1.0.dist-info/WHEEL +4 -0
- qmlkit-0.1.0.dist-info/licenses/LICENSE +202 -0
- qmlkit-0.1.0.dist-info/licenses/NOTICE +4 -0
qmlkit/__init__.py
ADDED
|
@@ -0,0 +1,495 @@
|
|
|
1
|
+
"""qmlkit — a backend-agnostic quantum machine learning library.
|
|
2
|
+
|
|
3
|
+
The same circuit runs on SpinQit, Qiskit, Cirq or the built-in exact NumPy
|
|
4
|
+
reference. Simulator-only for the 0.x line; expectations are exact unless you
|
|
5
|
+
ask for shots:
|
|
6
|
+
|
|
7
|
+
>>> import qmlkit as qk
|
|
8
|
+
>>> import numpy as np
|
|
9
|
+
>>> spec = qk.angle_encode([0.7])
|
|
10
|
+
>>> round(qk.expectation(spec, qk.Z(0)), 12) == round(float(np.cos(0.7)), 12)
|
|
11
|
+
True
|
|
12
|
+
"""
|
|
13
|
+
|
|
14
|
+
from __future__ import annotations
|
|
15
|
+
|
|
16
|
+
__version__ = "0.1.0"
|
|
17
|
+
|
|
18
|
+
from qmlkit import (
|
|
19
|
+
algorithms,
|
|
20
|
+
datasets,
|
|
21
|
+
evaluate,
|
|
22
|
+
fourier,
|
|
23
|
+
generative,
|
|
24
|
+
imbalance,
|
|
25
|
+
info,
|
|
26
|
+
kernels,
|
|
27
|
+
metrics,
|
|
28
|
+
optim,
|
|
29
|
+
shadows,
|
|
30
|
+
)
|
|
31
|
+
from qmlkit.ansatz import (
|
|
32
|
+
Ansatz,
|
|
33
|
+
Custom,
|
|
34
|
+
EncodingLayer,
|
|
35
|
+
EntanglerLayer,
|
|
36
|
+
ParametricEntangler,
|
|
37
|
+
PoolLayer,
|
|
38
|
+
RotationLayer,
|
|
39
|
+
basic_entangler,
|
|
40
|
+
conv_block,
|
|
41
|
+
get_ansatz,
|
|
42
|
+
hardware_efficient,
|
|
43
|
+
list_ansatze,
|
|
44
|
+
list_conv_filters,
|
|
45
|
+
mps_ansatz,
|
|
46
|
+
qaoa_ansatz,
|
|
47
|
+
qcnn_ansatz,
|
|
48
|
+
random_layers,
|
|
49
|
+
register_ansatz,
|
|
50
|
+
register_conv_filter,
|
|
51
|
+
repeat,
|
|
52
|
+
reupload,
|
|
53
|
+
share,
|
|
54
|
+
simplified_two_design,
|
|
55
|
+
strongly_entangling,
|
|
56
|
+
tree_tensor_network,
|
|
57
|
+
two_local,
|
|
58
|
+
)
|
|
59
|
+
from qmlkit.baselines import (
|
|
60
|
+
BaselineRow,
|
|
61
|
+
BaselineSpec,
|
|
62
|
+
BaselineTable,
|
|
63
|
+
baseline,
|
|
64
|
+
get_baseline,
|
|
65
|
+
list_baselines,
|
|
66
|
+
register_baseline,
|
|
67
|
+
)
|
|
68
|
+
from qmlkit.budget import Plan, Reduction, plan
|
|
69
|
+
from qmlkit.core.backends.base import Backend, BackendNotAvailable
|
|
70
|
+
from qmlkit.core.backends.numpy_backend import NumpyBackend
|
|
71
|
+
from qmlkit.core.backends.registry import (
|
|
72
|
+
available_backends,
|
|
73
|
+
backend_report,
|
|
74
|
+
default_backend,
|
|
75
|
+
get_backend,
|
|
76
|
+
is_available,
|
|
77
|
+
list_backends,
|
|
78
|
+
register_backend,
|
|
79
|
+
set_default_backend,
|
|
80
|
+
)
|
|
81
|
+
from qmlkit.core.builder import QCircuit, entangler_pairs
|
|
82
|
+
from qmlkit.core.execute import (
|
|
83
|
+
expectation,
|
|
84
|
+
expectation_batch,
|
|
85
|
+
expectation_over,
|
|
86
|
+
expval,
|
|
87
|
+
probabilities,
|
|
88
|
+
run_counts,
|
|
89
|
+
statevector,
|
|
90
|
+
)
|
|
91
|
+
from qmlkit.core.gates import GateDef, get_gate, list_gates, register_gate
|
|
92
|
+
from qmlkit.core.ir import CircuitSpec, Op, ParamRef, Slot
|
|
93
|
+
from qmlkit.core.observables import ZZ, I, PauliString, PauliSum, X, Y, Z
|
|
94
|
+
from qmlkit.diagnostics import Finding, Report, diagnose
|
|
95
|
+
from qmlkit.draw import draw, specs
|
|
96
|
+
from qmlkit.encoding import (
|
|
97
|
+
AngleFeatureMap,
|
|
98
|
+
AngleScaler,
|
|
99
|
+
DataReuploadEncoder,
|
|
100
|
+
FeatureMap,
|
|
101
|
+
FeaturePipeline,
|
|
102
|
+
PauliFeatureMap,
|
|
103
|
+
PCAReducer,
|
|
104
|
+
SklearnCompatible,
|
|
105
|
+
ZFeatureMap,
|
|
106
|
+
ZZFeatureMap,
|
|
107
|
+
amplitude_encode,
|
|
108
|
+
angle_encode,
|
|
109
|
+
basis_encode,
|
|
110
|
+
basis_index,
|
|
111
|
+
hamiltonian_encode,
|
|
112
|
+
n_qubits_for,
|
|
113
|
+
reduce_to_qubits,
|
|
114
|
+
to_angle_range,
|
|
115
|
+
)
|
|
116
|
+
from qmlkit.gradients import (
|
|
117
|
+
SPSASchedule,
|
|
118
|
+
adjoint_grad,
|
|
119
|
+
choose_method,
|
|
120
|
+
grad,
|
|
121
|
+
gradient_cost,
|
|
122
|
+
hadamard_grad,
|
|
123
|
+
hessian,
|
|
124
|
+
list_gradient_methods,
|
|
125
|
+
minimize_spsa,
|
|
126
|
+
register_gradient,
|
|
127
|
+
spsa_grad,
|
|
128
|
+
supports_adjoint,
|
|
129
|
+
)
|
|
130
|
+
from qmlkit.gradients.batch import (
|
|
131
|
+
adjoint_grad_batch,
|
|
132
|
+
grad_batch,
|
|
133
|
+
param_shift_grad_batch,
|
|
134
|
+
)
|
|
135
|
+
from qmlkit.gradients.parameter_shift import (
|
|
136
|
+
finite_diff_grad,
|
|
137
|
+
grad_circuit_cost,
|
|
138
|
+
param_shift_grad,
|
|
139
|
+
param_shift_grad_circuit,
|
|
140
|
+
)
|
|
141
|
+
from qmlkit.gradients.rules import (
|
|
142
|
+
ShiftRule,
|
|
143
|
+
four_term_rule,
|
|
144
|
+
general_shift_rule,
|
|
145
|
+
rule_for_gate,
|
|
146
|
+
two_term_rule,
|
|
147
|
+
)
|
|
148
|
+
from qmlkit.info import (
|
|
149
|
+
bloch_vector,
|
|
150
|
+
concurrence,
|
|
151
|
+
mutual_info,
|
|
152
|
+
purity,
|
|
153
|
+
reduced_dm,
|
|
154
|
+
state_fidelity,
|
|
155
|
+
vn_entropy,
|
|
156
|
+
)
|
|
157
|
+
from qmlkit.interop import (
|
|
158
|
+
UnsupportedGate,
|
|
159
|
+
from_cirq,
|
|
160
|
+
from_pennylane,
|
|
161
|
+
from_qasm,
|
|
162
|
+
from_qiskit,
|
|
163
|
+
get_importer,
|
|
164
|
+
list_importers,
|
|
165
|
+
register_importer,
|
|
166
|
+
)
|
|
167
|
+
from qmlkit.kernels import (
|
|
168
|
+
QSVC,
|
|
169
|
+
QSVR,
|
|
170
|
+
NearestFidelityClassifier,
|
|
171
|
+
QuantumKernel,
|
|
172
|
+
TrainableKernel,
|
|
173
|
+
closest_psd_matrix,
|
|
174
|
+
concentration_report,
|
|
175
|
+
displace_matrix,
|
|
176
|
+
fidelity_kernel,
|
|
177
|
+
flip_matrix,
|
|
178
|
+
geometric_difference,
|
|
179
|
+
hadamard_test,
|
|
180
|
+
is_psd,
|
|
181
|
+
kernel_matrix,
|
|
182
|
+
min_eigenvalue,
|
|
183
|
+
projected_kernel_matrix,
|
|
184
|
+
swap_test_kernel,
|
|
185
|
+
target_alignment,
|
|
186
|
+
threshold_matrix,
|
|
187
|
+
)
|
|
188
|
+
from qmlkit.metrics import (
|
|
189
|
+
AnsatzReport,
|
|
190
|
+
barren_plateau_scan,
|
|
191
|
+
compare_ansatze,
|
|
192
|
+
effective_dimension,
|
|
193
|
+
entangling_capability,
|
|
194
|
+
expressibility,
|
|
195
|
+
generalization_bound,
|
|
196
|
+
gradient_variance,
|
|
197
|
+
meyer_wallach,
|
|
198
|
+
)
|
|
199
|
+
from qmlkit.optim import (
|
|
200
|
+
metric_tensor,
|
|
201
|
+
minimize_qng,
|
|
202
|
+
minimize_rotosolve,
|
|
203
|
+
quantum_fisher_information,
|
|
204
|
+
rotosolve_step,
|
|
205
|
+
)
|
|
206
|
+
from qmlkit.provenance import Fingerprint, fingerprint, selfcheck
|
|
207
|
+
from qmlkit.search import (
|
|
208
|
+
AXES,
|
|
209
|
+
SearchResult,
|
|
210
|
+
SearchRow,
|
|
211
|
+
list_feature_maps,
|
|
212
|
+
register_feature_map,
|
|
213
|
+
search,
|
|
214
|
+
)
|
|
215
|
+
from qmlkit.utils.shots import (
|
|
216
|
+
p0_from_z,
|
|
217
|
+
shots_for_precision,
|
|
218
|
+
standard_error,
|
|
219
|
+
variance,
|
|
220
|
+
z_from_p0,
|
|
221
|
+
)
|
|
222
|
+
|
|
223
|
+
__all__ = [
|
|
224
|
+
"__version__",
|
|
225
|
+
# core
|
|
226
|
+
"CircuitSpec",
|
|
227
|
+
"Op",
|
|
228
|
+
"ParamRef",
|
|
229
|
+
"Slot",
|
|
230
|
+
"QCircuit",
|
|
231
|
+
"entangler_pairs",
|
|
232
|
+
# gates
|
|
233
|
+
"GateDef",
|
|
234
|
+
"get_gate",
|
|
235
|
+
"list_gates",
|
|
236
|
+
"register_gate",
|
|
237
|
+
# observables
|
|
238
|
+
"PauliString",
|
|
239
|
+
"PauliSum",
|
|
240
|
+
"I",
|
|
241
|
+
"X",
|
|
242
|
+
"Y",
|
|
243
|
+
"Z",
|
|
244
|
+
"ZZ",
|
|
245
|
+
# backends
|
|
246
|
+
"Backend",
|
|
247
|
+
"BackendNotAvailable",
|
|
248
|
+
"NumpyBackend",
|
|
249
|
+
"get_backend",
|
|
250
|
+
"default_backend",
|
|
251
|
+
"set_default_backend",
|
|
252
|
+
"register_backend",
|
|
253
|
+
"list_backends",
|
|
254
|
+
"available_backends",
|
|
255
|
+
"is_available",
|
|
256
|
+
"backend_report",
|
|
257
|
+
# execution
|
|
258
|
+
"statevector",
|
|
259
|
+
"run_counts",
|
|
260
|
+
"probabilities",
|
|
261
|
+
"expectation",
|
|
262
|
+
"expectation_batch",
|
|
263
|
+
"expectation_over",
|
|
264
|
+
# encoding
|
|
265
|
+
"angle_encode",
|
|
266
|
+
"basis_encode",
|
|
267
|
+
"basis_index",
|
|
268
|
+
"n_qubits_for",
|
|
269
|
+
"amplitude_encode",
|
|
270
|
+
"hamiltonian_encode",
|
|
271
|
+
"FeatureMap",
|
|
272
|
+
"PauliFeatureMap",
|
|
273
|
+
"ZFeatureMap",
|
|
274
|
+
"ZZFeatureMap",
|
|
275
|
+
"AngleFeatureMap",
|
|
276
|
+
"DataReuploadEncoder",
|
|
277
|
+
"to_angle_range",
|
|
278
|
+
"AngleScaler",
|
|
279
|
+
"FeaturePipeline",
|
|
280
|
+
"SklearnCompatible",
|
|
281
|
+
"reduce_to_qubits",
|
|
282
|
+
"PCAReducer",
|
|
283
|
+
# gradients
|
|
284
|
+
"ShiftRule",
|
|
285
|
+
"two_term_rule",
|
|
286
|
+
"four_term_rule",
|
|
287
|
+
"general_shift_rule",
|
|
288
|
+
"rule_for_gate",
|
|
289
|
+
"param_shift_grad",
|
|
290
|
+
"param_shift_grad_circuit",
|
|
291
|
+
"grad_circuit_cost",
|
|
292
|
+
"finite_diff_grad",
|
|
293
|
+
"grad_batch",
|
|
294
|
+
"adjoint_grad_batch",
|
|
295
|
+
"param_shift_grad_batch",
|
|
296
|
+
# submodules
|
|
297
|
+
"kernels",
|
|
298
|
+
"metrics",
|
|
299
|
+
"optim",
|
|
300
|
+
"fourier",
|
|
301
|
+
"info",
|
|
302
|
+
"algorithms",
|
|
303
|
+
"datasets",
|
|
304
|
+
"shadows",
|
|
305
|
+
"generative",
|
|
306
|
+
"evaluate",
|
|
307
|
+
"imbalance",
|
|
308
|
+
# baselines
|
|
309
|
+
"baseline",
|
|
310
|
+
"BaselineTable",
|
|
311
|
+
"BaselineRow",
|
|
312
|
+
"BaselineSpec",
|
|
313
|
+
"register_baseline",
|
|
314
|
+
"list_baselines",
|
|
315
|
+
"get_baseline",
|
|
316
|
+
# search
|
|
317
|
+
"search",
|
|
318
|
+
"SearchResult",
|
|
319
|
+
"SearchRow",
|
|
320
|
+
"AXES",
|
|
321
|
+
"register_feature_map",
|
|
322
|
+
"list_feature_maps",
|
|
323
|
+
# interop
|
|
324
|
+
"from_qasm",
|
|
325
|
+
"from_qiskit",
|
|
326
|
+
"from_pennylane",
|
|
327
|
+
"from_cirq",
|
|
328
|
+
"register_importer",
|
|
329
|
+
"list_importers",
|
|
330
|
+
"get_importer",
|
|
331
|
+
"UnsupportedGate",
|
|
332
|
+
# budget and provenance
|
|
333
|
+
"plan",
|
|
334
|
+
"Plan",
|
|
335
|
+
"Reduction",
|
|
336
|
+
"fingerprint",
|
|
337
|
+
"Fingerprint",
|
|
338
|
+
"selfcheck",
|
|
339
|
+
# kernels
|
|
340
|
+
"QuantumKernel",
|
|
341
|
+
"fidelity_kernel",
|
|
342
|
+
"swap_test_kernel",
|
|
343
|
+
"hadamard_test",
|
|
344
|
+
"kernel_matrix",
|
|
345
|
+
"target_alignment",
|
|
346
|
+
"is_psd",
|
|
347
|
+
"closest_psd_matrix",
|
|
348
|
+
"threshold_matrix",
|
|
349
|
+
"displace_matrix",
|
|
350
|
+
"flip_matrix",
|
|
351
|
+
"min_eigenvalue",
|
|
352
|
+
"projected_kernel_matrix",
|
|
353
|
+
"concentration_report",
|
|
354
|
+
"geometric_difference",
|
|
355
|
+
"QSVC",
|
|
356
|
+
"QSVR",
|
|
357
|
+
"NearestFidelityClassifier",
|
|
358
|
+
"TrainableKernel",
|
|
359
|
+
# metrics
|
|
360
|
+
"expressibility",
|
|
361
|
+
"meyer_wallach",
|
|
362
|
+
"entangling_capability",
|
|
363
|
+
"gradient_variance",
|
|
364
|
+
"barren_plateau_scan",
|
|
365
|
+
"effective_dimension",
|
|
366
|
+
"generalization_bound",
|
|
367
|
+
"AnsatzReport",
|
|
368
|
+
"compare_ansatze",
|
|
369
|
+
# optimisers
|
|
370
|
+
"minimize_rotosolve",
|
|
371
|
+
"rotosolve_step",
|
|
372
|
+
"metric_tensor",
|
|
373
|
+
"quantum_fisher_information",
|
|
374
|
+
"minimize_qng",
|
|
375
|
+
# quantum information
|
|
376
|
+
"reduced_dm",
|
|
377
|
+
"purity",
|
|
378
|
+
"vn_entropy",
|
|
379
|
+
"mutual_info",
|
|
380
|
+
"state_fidelity",
|
|
381
|
+
"concurrence",
|
|
382
|
+
"bloch_vector",
|
|
383
|
+
# diagnostics
|
|
384
|
+
"diagnose",
|
|
385
|
+
"Finding",
|
|
386
|
+
"Report",
|
|
387
|
+
# visualisation
|
|
388
|
+
"draw",
|
|
389
|
+
"specs",
|
|
390
|
+
"expval",
|
|
391
|
+
# ansatz
|
|
392
|
+
"Ansatz",
|
|
393
|
+
"register_ansatz",
|
|
394
|
+
"get_ansatz",
|
|
395
|
+
"list_ansatze",
|
|
396
|
+
"RotationLayer",
|
|
397
|
+
"EntanglerLayer",
|
|
398
|
+
"ParametricEntangler",
|
|
399
|
+
"PoolLayer",
|
|
400
|
+
"Custom",
|
|
401
|
+
"EncodingLayer",
|
|
402
|
+
"reupload",
|
|
403
|
+
"repeat",
|
|
404
|
+
"share",
|
|
405
|
+
"hardware_efficient",
|
|
406
|
+
"strongly_entangling",
|
|
407
|
+
"simplified_two_design",
|
|
408
|
+
"tree_tensor_network",
|
|
409
|
+
"mps_ansatz",
|
|
410
|
+
"qcnn_ansatz",
|
|
411
|
+
"qaoa_ansatz",
|
|
412
|
+
"conv_block",
|
|
413
|
+
"list_conv_filters",
|
|
414
|
+
"register_conv_filter",
|
|
415
|
+
"basic_entangler",
|
|
416
|
+
"two_local",
|
|
417
|
+
"random_layers",
|
|
418
|
+
# gradient dispatch
|
|
419
|
+
"grad",
|
|
420
|
+
"choose_method",
|
|
421
|
+
"register_gradient",
|
|
422
|
+
"list_gradient_methods",
|
|
423
|
+
"adjoint_grad",
|
|
424
|
+
"hadamard_grad",
|
|
425
|
+
"hessian",
|
|
426
|
+
"gradient_cost",
|
|
427
|
+
"supports_adjoint",
|
|
428
|
+
"spsa_grad",
|
|
429
|
+
"minimize_spsa",
|
|
430
|
+
"SPSASchedule",
|
|
431
|
+
# shots
|
|
432
|
+
"standard_error",
|
|
433
|
+
"variance",
|
|
434
|
+
"shots_for_precision",
|
|
435
|
+
"p0_from_z",
|
|
436
|
+
"z_from_p0",
|
|
437
|
+
]
|
|
438
|
+
|
|
439
|
+
|
|
440
|
+
#: Names served by :mod:`qmlkit.nn`, resolved on demand so that importing qmlkit
|
|
441
|
+
#: never requires torch. Deliberately outside ``__all__``, which keeps
|
|
442
|
+
#: ``from qmlkit import *`` torch-free.
|
|
443
|
+
_TORCH_EXPORTS = (
|
|
444
|
+
"QuantumLayer",
|
|
445
|
+
"QuantumFunction",
|
|
446
|
+
"VQC",
|
|
447
|
+
"VQRegressor",
|
|
448
|
+
"HybridModel",
|
|
449
|
+
"QCNNLayer",
|
|
450
|
+
"MPSLayer",
|
|
451
|
+
"QLSTMCell",
|
|
452
|
+
"QLSTM",
|
|
453
|
+
"DressedQuantumNet",
|
|
454
|
+
"nn",
|
|
455
|
+
)
|
|
456
|
+
|
|
457
|
+
|
|
458
|
+
def __getattr__(name: str) -> object:
|
|
459
|
+
"""Resolve the torch bridge lazily, and answer a wrong name with the right one.
|
|
460
|
+
|
|
461
|
+
A missing attribute is where most first attempts at an unfamiliar library land,
|
|
462
|
+
so it is worth more than ``has no attribute``. Three things are tried, in order
|
|
463
|
+
of how much they know: the lazy torch exports; the table of what PennyLane and
|
|
464
|
+
Qiskit call the same thing (:mod:`qmlkit._aliases`); and failing both, a
|
|
465
|
+
near-match over everything qmlkit does export.
|
|
466
|
+
|
|
467
|
+
``qk.AngleEmbedding`` reports that PennyLane's name for it is
|
|
468
|
+
:class:`~qmlkit.encoding.feature_maps.AngleFeatureMap`, rather than only that
|
|
469
|
+
the attribute is missing.
|
|
470
|
+
"""
|
|
471
|
+
if name in _TORCH_EXPORTS:
|
|
472
|
+
try:
|
|
473
|
+
import qmlkit.nn as _nn
|
|
474
|
+
except ImportError as exc: # pragma: no cover - depends on the environment
|
|
475
|
+
raise ImportError(
|
|
476
|
+
f"{name} needs PyTorch, which is an optional extra:\n"
|
|
477
|
+
" pip install 'qmlkit[torch]'"
|
|
478
|
+
) from exc
|
|
479
|
+
return _nn if name == "nn" else getattr(_nn, name)
|
|
480
|
+
|
|
481
|
+
from qmlkit._aliases import advice
|
|
482
|
+
from qmlkit.utils.errors import did_you_mean
|
|
483
|
+
|
|
484
|
+
hint = advice(name)
|
|
485
|
+
if hint is None:
|
|
486
|
+
near = did_you_mean(name, (*__all__, *_TORCH_EXPORTS))
|
|
487
|
+
if near:
|
|
488
|
+
hint = "Did you mean " + " or ".join(repr(s) for s in near) + "?"
|
|
489
|
+
message = f"module 'qmlkit' has no attribute {name!r}."
|
|
490
|
+
raise AttributeError(f"{message} {hint}" if hint else message)
|
|
491
|
+
|
|
492
|
+
|
|
493
|
+
def __dir__() -> list[str]:
|
|
494
|
+
"""List the lazily-served torch exports too, so introspection finds them."""
|
|
495
|
+
return sorted({*globals(), *__all__, *_TORCH_EXPORTS})
|
qmlkit/_aliases.py
ADDED
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
"""What the other libraries call it.
|
|
2
|
+
|
|
3
|
+
A model writing qmlkit has read far more PennyLane and Qiskit than qmlkit, so its
|
|
4
|
+
first guess at a name is usually *their* name. ``qk.AngleEmbedding``,
|
|
5
|
+
``qk.QuantumCircuit``, ``qk.PauliZ`` — all reasonable, all wrong here, and all
|
|
6
|
+
producing the same bare ``AttributeError`` that says only that the name is absent.
|
|
7
|
+
|
|
8
|
+
This table turns that dead end into a correction. It is a translation, not an
|
|
9
|
+
alias: the foreign name still raises. Two reasons for that choice.
|
|
10
|
+
|
|
11
|
+
*Aliases become API.* Anything importable is something somebody depends on, and a
|
|
12
|
+
shadow vocabulary of thirty PennyLane spellings is a second public surface to keep
|
|
13
|
+
working forever.
|
|
14
|
+
|
|
15
|
+
*Aliases hide semantic drift.* ``qml.expval`` takes a QNode; ``qk.expectation``
|
|
16
|
+
takes a :class:`~qmlkit.core.ir.CircuitSpec` and an observable. A name that
|
|
17
|
+
silently resolves would fail later, further from its cause, with a worse message.
|
|
18
|
+
Correcting costs one round trip and leaves the caller holding the real name.
|
|
19
|
+
|
|
20
|
+
Genuine aliases are still fine where the semantics are *identical* and only the
|
|
21
|
+
spelling differs — ``expval`` for ``expectation`` is one, and it is a real export.
|
|
22
|
+
|
|
23
|
+
``tests/test_agent_api.py`` asserts every target below exists, so the table cannot
|
|
24
|
+
drift out of date without the build going red.
|
|
25
|
+
"""
|
|
26
|
+
|
|
27
|
+
from __future__ import annotations
|
|
28
|
+
|
|
29
|
+
__all__ = ["ELSEWHERE", "advice"]
|
|
30
|
+
|
|
31
|
+
#: foreign name -> (qmlkit attribute, extra guidance). ``None`` means there is no
|
|
32
|
+
#: single equivalent and the note carries the whole answer.
|
|
33
|
+
_PENNYLANE: dict[str, tuple[str | None, str]] = {
|
|
34
|
+
"qnode": (None, "qmlkit has no QNode - build a CircuitSpec and call expectation(spec, obs)"),
|
|
35
|
+
"QNode": (None, "qmlkit has no QNode - build a CircuitSpec and call expectation(spec, obs)"),
|
|
36
|
+
"device": ("get_backend", ""),
|
|
37
|
+
"probs": ("probabilities", ""),
|
|
38
|
+
"state": ("statevector", ""),
|
|
39
|
+
"sample": ("run_counts", ""),
|
|
40
|
+
"counts": ("run_counts", ""),
|
|
41
|
+
"jacobian": ("grad", ""),
|
|
42
|
+
"about": ("backend_report", ""),
|
|
43
|
+
"AngleEmbedding": ("AngleFeatureMap", "or angle_encode(x) for a one-shot circuit"),
|
|
44
|
+
"AmplitudeEmbedding": ("amplitude_encode", "or the AmplitudeEncoder feature map"),
|
|
45
|
+
"BasisEmbedding": ("basis_encode", ""),
|
|
46
|
+
"IQPEmbedding": ("ZZFeatureMap", ""),
|
|
47
|
+
"StatePrep": ("amplitude_encode", ""),
|
|
48
|
+
"QubitStateVector": ("amplitude_encode", ""),
|
|
49
|
+
"StronglyEntanglingLayers": ("strongly_entangling", ""),
|
|
50
|
+
"BasicEntanglerLayers": ("basic_entangler", ""),
|
|
51
|
+
"SimplifiedTwoDesign": ("simplified_two_design", ""),
|
|
52
|
+
"RandomLayers": ("random_layers", ""),
|
|
53
|
+
"MPS": ("mps_ansatz", ""),
|
|
54
|
+
"TTN": ("tree_tensor_network", ""),
|
|
55
|
+
"PauliX": ("X", ""),
|
|
56
|
+
"PauliY": ("Y", ""),
|
|
57
|
+
"PauliZ": ("Z", ""),
|
|
58
|
+
"Identity": ("I", ""),
|
|
59
|
+
"Hamiltonian": ("PauliSum", ""),
|
|
60
|
+
"density_matrix": ("reduced_dm", ""),
|
|
61
|
+
"TorchLayer": ("QuantumLayer", ""),
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
_QISKIT: dict[str, tuple[str | None, str]] = {
|
|
65
|
+
"QuantumCircuit": ("QCircuit", ""),
|
|
66
|
+
"Statevector": ("statevector", ""),
|
|
67
|
+
"SparsePauliOp": ("PauliSum", ""),
|
|
68
|
+
"Pauli": ("PauliString", ""),
|
|
69
|
+
"Operator": (None, "build observables from Z/X/Y/I, PauliString or PauliSum"),
|
|
70
|
+
"Estimator": ("expectation", "qmlkit needs no primitive object"),
|
|
71
|
+
"Sampler": ("run_counts", "qmlkit needs no primitive object"),
|
|
72
|
+
"AerSimulator": ("get_backend", 'get_backend("qiskit") runs the same circuit on Aer'),
|
|
73
|
+
"transpile": (None, "qmlkit has no transpiler - a simulator runs the circuit as written"),
|
|
74
|
+
"EfficientSU2": ("hardware_efficient", ""),
|
|
75
|
+
"RealAmplitudes": ("two_local", 'two_local(n, rotations=("ry",), entangler="cx")'),
|
|
76
|
+
"TwoLocal": ("two_local", ""),
|
|
77
|
+
"NLocal": ("two_local", ""),
|
|
78
|
+
"FidelityQuantumKernel": ("QuantumKernel", ""),
|
|
79
|
+
"TrainableFidelityQuantumKernel": ("TrainableKernel", ""),
|
|
80
|
+
"TorchConnector": ("QuantumLayer", "a QuantumLayer already is an nn.Module"),
|
|
81
|
+
"EstimatorQNN": ("QuantumLayer", ""),
|
|
82
|
+
"SamplerQNN": ("QuantumLayer", ""),
|
|
83
|
+
"NeuralNetworkClassifier": ("VQC", ""),
|
|
84
|
+
"NeuralNetworkRegressor": ("VQRegressor", ""),
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
#: Plausible names that belong to no library in particular - the shape of guess a
|
|
88
|
+
#: model makes when it is reasoning from the domain rather than from another API.
|
|
89
|
+
_GUESSES: dict[str, tuple[str | None, str]] = {
|
|
90
|
+
"Circuit": ("QCircuit", ""),
|
|
91
|
+
"expectation_value": ("expectation", ""),
|
|
92
|
+
"expected_value": ("expectation", ""),
|
|
93
|
+
"parameter_shift": ("param_shift_grad", 'or grad(..., method="parameter-shift")'),
|
|
94
|
+
"parameter_shift_grad": ("param_shift_grad", ""),
|
|
95
|
+
"gradient": ("grad", ""),
|
|
96
|
+
"QNN": ("QuantumLayer", ""),
|
|
97
|
+
"Model": ("VQC", "or VQRegressor for regression"),
|
|
98
|
+
"Classifier": ("VQC", ""),
|
|
99
|
+
"Regressor": ("VQRegressor", ""),
|
|
100
|
+
"encode": ("angle_encode", "or a FeatureMap for something reusable"),
|
|
101
|
+
"measure": ("expectation", "or run_counts for samples"),
|
|
102
|
+
"simulate": ("statevector", ""),
|
|
103
|
+
"Observable": (None, "build observables from Z/X/Y/I, PauliString or PauliSum"),
|
|
104
|
+
"Kernel": ("QuantumKernel", ""),
|
|
105
|
+
"FeatureMapBase": ("FeatureMap", ""),
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
#: Every foreign name, with the library it came from.
|
|
109
|
+
ELSEWHERE: dict[str, tuple[str, str | None, str]] = {
|
|
110
|
+
**{k: ("PennyLane", *v) for k, v in _PENNYLANE.items()},
|
|
111
|
+
**{k: ("Qiskit", *v) for k, v in _QISKIT.items()},
|
|
112
|
+
**{k: ("", *v) for k, v in _GUESSES.items()},
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
|
|
116
|
+
def advice(name: str) -> str | None:
|
|
117
|
+
"""One sentence naming the qmlkit equivalent of ``name``, or ``None``.
|
|
118
|
+
|
|
119
|
+
>>> advice("PauliZ")
|
|
120
|
+
"'PauliZ' is PennyLane's name for qmlkit.Z."
|
|
121
|
+
>>> advice("gradient")
|
|
122
|
+
"qmlkit calls that 'grad'."
|
|
123
|
+
>>> advice("not_a_real_name") is None
|
|
124
|
+
True
|
|
125
|
+
"""
|
|
126
|
+
if name not in ELSEWHERE:
|
|
127
|
+
return None
|
|
128
|
+
source, target, note = ELSEWHERE[name]
|
|
129
|
+
tail = f" ({note})" if note else ""
|
|
130
|
+
if target is None:
|
|
131
|
+
lead = f"{name!r} is {source}'s;" if source else f"There is no {name!r};"
|
|
132
|
+
return f"{lead} {note}."
|
|
133
|
+
if source:
|
|
134
|
+
return f"{name!r} is {source}'s name for qmlkit.{target}{tail}."
|
|
135
|
+
return f"qmlkit calls that {target!r}{tail}."
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
"""Algorithms built on the rest of the library.
|
|
2
|
+
|
|
3
|
+
Each one is a *loop* over machinery that already exists — ansatz, gradients,
|
|
4
|
+
optimisers, observables — so each is thin, and every structural choice it makes is
|
|
5
|
+
an argument rather than something baked in.
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
from __future__ import annotations
|
|
9
|
+
|
|
10
|
+
from qmlkit.algorithms.adapt import (
|
|
11
|
+
AdaptResult,
|
|
12
|
+
AdaptVQE,
|
|
13
|
+
chemistry_operator_pool,
|
|
14
|
+
default_operator_pool,
|
|
15
|
+
pauli_rotation,
|
|
16
|
+
)
|
|
17
|
+
from qmlkit.algorithms.autoencoder import AutoencoderResult, QuantumAutoencoder
|
|
18
|
+
from qmlkit.algorithms.chemistry import (
|
|
19
|
+
CHEMICAL_ACCURACY,
|
|
20
|
+
HARTREE_TO_KCAL,
|
|
21
|
+
h2_curve,
|
|
22
|
+
h2_hamiltonian,
|
|
23
|
+
)
|
|
24
|
+
from qmlkit.algorithms.clustering import QMeans, QMeansResult
|
|
25
|
+
from qmlkit.algorithms.hamiltonians import (
|
|
26
|
+
exact_ground_energy,
|
|
27
|
+
exact_ground_state,
|
|
28
|
+
hamiltonian_matrix,
|
|
29
|
+
heisenberg_hamiltonian,
|
|
30
|
+
ising_hamiltonian,
|
|
31
|
+
max_cut_hamiltonian,
|
|
32
|
+
pauli_hamiltonian,
|
|
33
|
+
)
|
|
34
|
+
from qmlkit.algorithms.molecule import (
|
|
35
|
+
MolecularInfo,
|
|
36
|
+
Molecule,
|
|
37
|
+
from_integrals,
|
|
38
|
+
hydrogen_chain,
|
|
39
|
+
hydrogen_ring,
|
|
40
|
+
molecular_hamiltonian,
|
|
41
|
+
)
|
|
42
|
+
from qmlkit.algorithms.qaoa import QAOA, QAOAResult
|
|
43
|
+
from qmlkit.algorithms.rl import ContextualBandit, QuantumPolicy, ReinforceResult, train_reinforce
|
|
44
|
+
from qmlkit.algorithms.vqe import OPTIMIZERS, VQE, VQEResult
|
|
45
|
+
|
|
46
|
+
__all__ = [
|
|
47
|
+
"VQE",
|
|
48
|
+
"QAOA",
|
|
49
|
+
"QAOAResult",
|
|
50
|
+
"AdaptVQE",
|
|
51
|
+
"AdaptResult",
|
|
52
|
+
"pauli_rotation",
|
|
53
|
+
"default_operator_pool",
|
|
54
|
+
"chemistry_operator_pool",
|
|
55
|
+
"QuantumAutoencoder",
|
|
56
|
+
"AutoencoderResult",
|
|
57
|
+
"QMeans",
|
|
58
|
+
"h2_hamiltonian",
|
|
59
|
+
"Molecule",
|
|
60
|
+
"MolecularInfo",
|
|
61
|
+
"molecular_hamiltonian",
|
|
62
|
+
"from_integrals",
|
|
63
|
+
"hydrogen_chain",
|
|
64
|
+
"hydrogen_ring",
|
|
65
|
+
"h2_curve",
|
|
66
|
+
"CHEMICAL_ACCURACY",
|
|
67
|
+
"HARTREE_TO_KCAL",
|
|
68
|
+
"QMeansResult",
|
|
69
|
+
"QuantumPolicy",
|
|
70
|
+
"ContextualBandit",
|
|
71
|
+
"train_reinforce",
|
|
72
|
+
"ReinforceResult",
|
|
73
|
+
"VQEResult",
|
|
74
|
+
"OPTIMIZERS",
|
|
75
|
+
"pauli_hamiltonian",
|
|
76
|
+
"ising_hamiltonian",
|
|
77
|
+
"heisenberg_hamiltonian",
|
|
78
|
+
"max_cut_hamiltonian",
|
|
79
|
+
"hamiltonian_matrix",
|
|
80
|
+
"exact_ground_energy",
|
|
81
|
+
"exact_ground_state",
|
|
82
|
+
]
|