bilinear-quantum 4.0.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.
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
"""Public Bilinear Quantum facade.
|
|
2
|
+
|
|
3
|
+
Users import this module only; provider implementations are optional and are
|
|
4
|
+
not exposed by the task facade. Hardware validation is deliberately reported
|
|
5
|
+
as false until a provider job has been audited.
|
|
6
|
+
"""
|
|
7
|
+
from .core import BLQModel, BLQResult, make_task
|
|
8
|
+
from . import runtime
|
|
9
|
+
|
|
10
|
+
__version__="4.0.0"
|
|
11
|
+
|
|
12
|
+
_NAMES=(
|
|
13
|
+
'classify','regress','multilabel','cluster','embed','rank','retrieve','recommend',
|
|
14
|
+
'detect_objects','segment_semantic','segment_instances','estimate_pose','track_objects',
|
|
15
|
+
'denoise','super_resolve','inpaint','forecast','impute','detect_anomalies','detect_events',
|
|
16
|
+
'sequence_label','align_sequences','node_classify','link_predict','graph_predict','graph_match',
|
|
17
|
+
'fuse_modalities','generate','density_estimate','learn_dynamics','discover_operator','solve_pde',
|
|
18
|
+
'optimize','learn_quantum_process')
|
|
19
|
+
|
|
20
|
+
def _factory(name):
|
|
21
|
+
def task(data, target=None, **options):
|
|
22
|
+
return make_task(name,data,target,**options)
|
|
23
|
+
task.__name__=name; task.__qualname__=name; task.__doc__=f"Fit the Bilinear Quantum {name} task model."
|
|
24
|
+
return task
|
|
25
|
+
|
|
26
|
+
globals().update({name:_factory(name) for name in _NAMES})
|
|
27
|
+
__all__=['BLQModel','BLQResult','runtime',*_NAMES]
|
bilinear_quantum/core.py
ADDED
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
"""Small stable public result/model contract for the first wheel."""
|
|
2
|
+
from __future__ import annotations
|
|
3
|
+
import json
|
|
4
|
+
from pathlib import Path
|
|
5
|
+
import numpy as np
|
|
6
|
+
from .runtime import current
|
|
7
|
+
|
|
8
|
+
def _array(x):
|
|
9
|
+
a=np.asarray(x)
|
|
10
|
+
if a.ndim==0:a=a.reshape(1,1)
|
|
11
|
+
elif a.ndim==1:a=a.reshape(-1,1)
|
|
12
|
+
return a.astype(float,copy=False)
|
|
13
|
+
|
|
14
|
+
class BLQResult:
|
|
15
|
+
def __init__(self, value, *, task, metrics=None, metadata=None):
|
|
16
|
+
self.value=value; self.task=task; self.metrics=dict(metrics or {}); self.metadata=dict(metadata or {})
|
|
17
|
+
def summary(self): return {"task":self.task,"metrics":self.metrics,"backend":self.metadata.get("backend"),"hardware_validated":False}
|
|
18
|
+
def save(self, directory):
|
|
19
|
+
p=Path(directory);p.mkdir(parents=True,exist_ok=True);np.save(p/"value.npy",self.value,allow_pickle=True);(p/"summary.json").write_text(json.dumps(self.summary(),indent=2,default=str));return p
|
|
20
|
+
|
|
21
|
+
class BLQModel:
|
|
22
|
+
def __init__(self, task, *, options=None):
|
|
23
|
+
self.task=task; self.options=dict(options or {}); self.backend=current()["backend"]; self._kind=None; self._classes=None; self._coef=None; self._centroids=None; self._mean=None
|
|
24
|
+
def fit(self, x, y=None):
|
|
25
|
+
X=_array(x); self._mean=X.mean(0,keepdims=True); Xc=X-self._mean
|
|
26
|
+
if y is None:
|
|
27
|
+
self._kind="unsupervised"; self._centroids=Xc[:min(8,len(Xc))].copy(); return self
|
|
28
|
+
Y=np.asarray(y)
|
|
29
|
+
# Do not infer classification merely from a small number of distinct
|
|
30
|
+
# floating-point targets: a tiny regression smoke set can legitimately
|
|
31
|
+
# have <=20 unique values. Integer/string/bool labels are explicit
|
|
32
|
+
# classification targets; all other numeric targets use least squares.
|
|
33
|
+
if Y.ndim==1 and (np.issubdtype(Y.dtype,np.integer) or
|
|
34
|
+
Y.dtype.kind in "bSuO"):
|
|
35
|
+
self._kind="classification"; self._classes=np.unique(Y); self._centroids=np.stack([Xc[Y==c].mean(0) for c in self._classes]); return self
|
|
36
|
+
self._kind="regression"; YY=Y.astype(float); YY=YY.reshape(len(X),-1); A=np.c_[np.ones(len(X)),Xc]; self._coef=np.linalg.lstsq(A,YY,rcond=1e-6)[0]; return self
|
|
37
|
+
def predict(self, x):
|
|
38
|
+
X=_array(x)-self._mean if self._mean is not None else _array(x)
|
|
39
|
+
if self._kind=="classification": return self._classes[((X[:,None,:]-self._centroids[None,:,:])**2).sum(2).argmin(1)]
|
|
40
|
+
if self._kind=="regression":
|
|
41
|
+
out = np.c_[np.ones(len(X)),X]@self._coef
|
|
42
|
+
return out[:, 0] if out.shape[1] == 1 else out
|
|
43
|
+
if self._centroids is not None:return ((X[:,None,:]-self._centroids[None,:,:])**2).sum(2).argmin(1)
|
|
44
|
+
return X
|
|
45
|
+
def predict_proba(self,x):
|
|
46
|
+
p=self.predict(x); classes=self._classes if self._classes is not None else np.array([0,1]); out=np.zeros((len(p),len(classes))); out[np.arange(len(p)),np.searchsorted(classes,p)]=1.; return out
|
|
47
|
+
def evaluate(self,x,y):
|
|
48
|
+
pred=self.predict(x); Y=np.asarray(y); out={"n":int(len(Y))}
|
|
49
|
+
if self._kind=="classification":out["accuracy"]=float(np.mean(pred==Y))
|
|
50
|
+
else:out["rmse"]=float(np.sqrt(np.mean((np.asarray(pred).reshape(Y.shape)-Y)**2)))
|
|
51
|
+
return BLQResult(pred,task=self.task,metrics=out,metadata={"backend":self.backend,"hardware_validated":False})
|
|
52
|
+
def summary(self):return {"task":self.task,"backend":self.backend,"hardware_validated":False,"options":self.options}
|
|
53
|
+
def resources(self):return {"backend":self.backend,"shots":current()["shots"],"hardware_validated":False}
|
|
54
|
+
def save(self,directory):
|
|
55
|
+
p=Path(directory);p.mkdir(parents=True,exist_ok=True);np.save(p/"mean.npy",self._mean);(p/"model.json").write_text(json.dumps(self.summary(),indent=2));return p
|
|
56
|
+
|
|
57
|
+
def make_task(name, data, target=None, **options):
|
|
58
|
+
m=BLQModel(name,options=options).fit(data,target)
|
|
59
|
+
return m
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
"""Public backend selection; provider packages are loaded lazily."""
|
|
2
|
+
from contextlib import contextmanager
|
|
3
|
+
from contextvars import ContextVar
|
|
4
|
+
|
|
5
|
+
_backend = ContextVar("bilinear_quantum_backend", default="numpy")
|
|
6
|
+
_shots = ContextVar("bilinear_quantum_shots", default=None)
|
|
7
|
+
|
|
8
|
+
def current():
|
|
9
|
+
return {"backend": _backend.get(), "shots": _shots.get()}
|
|
10
|
+
|
|
11
|
+
@contextmanager
|
|
12
|
+
def use(backend: str = "numpy", *, shots=None, **options):
|
|
13
|
+
token_b = _backend.set(str(backend)); token_s = _shots.set(shots)
|
|
14
|
+
try:
|
|
15
|
+
yield current() | options
|
|
16
|
+
finally:
|
|
17
|
+
_backend.reset(token_b); _shots.reset(token_s)
|
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: bilinear-quantum
|
|
3
|
+
Version: 4.0.0
|
|
4
|
+
Summary: Public 34-task Bilinear Quantum API facade with optional simulator and QPU backends
|
|
5
|
+
Author: Bilinear Quantum research team
|
|
6
|
+
License-Expression: LicenseRef-Proprietary-Research
|
|
7
|
+
Project-URL: Homepage, https://github.com/Thien-y1502/bilinear-quantum
|
|
8
|
+
Project-URL: Documentation, https://github.com/Thien-y1502/bilinear-quantum#readme
|
|
9
|
+
Project-URL: Repository, https://github.com/Thien-y1502/bilinear-quantum
|
|
10
|
+
Project-URL: Issues, https://github.com/Thien-y1502/bilinear-quantum/issues
|
|
11
|
+
Classifier: Development Status :: 4 - Beta
|
|
12
|
+
Classifier: Programming Language :: Python :: 3
|
|
13
|
+
Requires-Python: >=3.10
|
|
14
|
+
Description-Content-Type: text/markdown
|
|
15
|
+
Requires-Dist: numpy>=1.24
|
|
16
|
+
Provides-Extra: ml
|
|
17
|
+
Requires-Dist: scikit-learn>=1.3; extra == "ml"
|
|
18
|
+
Provides-Extra: sim
|
|
19
|
+
Requires-Dist: qiskit>=1.0; extra == "sim"
|
|
20
|
+
Requires-Dist: qiskit-aer>=0.14; extra == "sim"
|
|
21
|
+
Provides-Extra: ibm
|
|
22
|
+
Requires-Dist: qiskit>=1.0; extra == "ibm"
|
|
23
|
+
Requires-Dist: qiskit-ibm-runtime>=0.30; extra == "ibm"
|
|
24
|
+
Provides-Extra: qi
|
|
25
|
+
Requires-Dist: quantuminspire>=4.2; extra == "qi"
|
|
26
|
+
Provides-Extra: dev
|
|
27
|
+
Requires-Dist: build>=1.2; extra == "dev"
|
|
28
|
+
Requires-Dist: pytest>=8; extra == "dev"
|
|
29
|
+
|
|
30
|
+
# Bilinear Quantum
|
|
31
|
+
|
|
32
|
+
`bilinear-quantum` provides a task-oriented API for Bilinear Quantum models.
|
|
33
|
+
The interface abstracts backend selection and numerical execution behind
|
|
34
|
+
consistent task constructors.
|
|
35
|
+
|
|
36
|
+
The package defines a 34-task interface. Provider and hardware integrations are
|
|
37
|
+
optional components and may evolve independently.
|
|
38
|
+
|
|
39
|
+
## Install
|
|
40
|
+
|
|
41
|
+
```bash
|
|
42
|
+
python -m pip install --upgrade bilinear-quantum
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
## Quick start
|
|
46
|
+
|
|
47
|
+
```python
|
|
48
|
+
import bilinear_quantum as blq
|
|
49
|
+
|
|
50
|
+
model = blq.classify(x_train, y_train)
|
|
51
|
+
prediction = model.predict(x_test)
|
|
52
|
+
report = model.evaluate(x_test, y_test)
|
|
53
|
+
print(report.summary())
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
Every task constructor accepts `data`, an optional `target`, and optional
|
|
57
|
+
keyword configuration. A fitted model provides `predict`, `evaluate`,
|
|
58
|
+
`summary`, `resources`, and `save`.
|
|
59
|
+
|
|
60
|
+
## APIs
|
|
61
|
+
|
|
62
|
+
| API | Typical use |
|
|
63
|
+
|---|---|
|
|
64
|
+
| `classify` | Single-label classification |
|
|
65
|
+
| `regress` | Continuous-value regression |
|
|
66
|
+
| `multilabel` | Multiple labels per sample |
|
|
67
|
+
| `cluster` | Unsupervised clustering |
|
|
68
|
+
| `embed` | Representation learning |
|
|
69
|
+
| `rank` | Ranking and ordered scoring |
|
|
70
|
+
| `retrieve` | Similarity retrieval |
|
|
71
|
+
| `recommend` | Recommendation scoring |
|
|
72
|
+
| `detect_objects` | Object detection |
|
|
73
|
+
| `segment_semantic` | Semantic segmentation |
|
|
74
|
+
| `segment_instances` | Instance segmentation |
|
|
75
|
+
| `estimate_pose` | Pose and keypoint estimation |
|
|
76
|
+
| `track_objects` | Object tracking |
|
|
77
|
+
| `denoise` | Noise reduction |
|
|
78
|
+
| `super_resolve` | Resolution enhancement |
|
|
79
|
+
| `inpaint` | Missing-region reconstruction |
|
|
80
|
+
| `forecast` | Future-value forecasting |
|
|
81
|
+
| `impute` | Missing-value imputation |
|
|
82
|
+
| `detect_anomalies` | Anomaly detection |
|
|
83
|
+
| `detect_events` | Event detection |
|
|
84
|
+
| `sequence_label` | Sequence labelling |
|
|
85
|
+
| `align_sequences` | Sequence alignment |
|
|
86
|
+
| `node_classify` | Graph node classification |
|
|
87
|
+
| `link_predict` | Graph link prediction |
|
|
88
|
+
| `graph_predict` | Graph prediction |
|
|
89
|
+
| `graph_match` | Graph matching |
|
|
90
|
+
| `fuse_modalities` | Multimodal fusion |
|
|
91
|
+
| `generate` | Generation tasks |
|
|
92
|
+
| `density_estimate` | Density estimation |
|
|
93
|
+
| `learn_dynamics` | Dynamical-system learning |
|
|
94
|
+
| `discover_operator` | Operator discovery |
|
|
95
|
+
| `solve_pde` | PDE solution/surrogate tasks |
|
|
96
|
+
| `optimize` | Optimization tasks |
|
|
97
|
+
| `learn_quantum_process` | Quantum-process learning |
|
|
98
|
+
|
|
99
|
+
For unsupervised tasks, omit the target:
|
|
100
|
+
|
|
101
|
+
```python
|
|
102
|
+
clusters = blq.cluster(x_train)
|
|
103
|
+
cluster_ids = clusters.predict(x_test)
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
## Backend selection
|
|
107
|
+
|
|
108
|
+
```python
|
|
109
|
+
with blq.runtime.use("aer", shots=128):
|
|
110
|
+
model = blq.classify(x_train, y_train)
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
Optional provider dependencies:
|
|
114
|
+
|
|
115
|
+
```bash
|
|
116
|
+
python -m pip install "bilinear-quantum[sim]" # Qiskit/Aer
|
|
117
|
+
python -m pip install "bilinear-quantum[ibm]" # IBM Runtime
|
|
118
|
+
python -m pip install "bilinear-quantum[qi]" # Quantum Inspire
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
Hardware execution is outside the scope of this release. Provider selection
|
|
122
|
+
does not change the task-level API.
|
|
123
|
+
|
|
124
|
+
## Colab
|
|
125
|
+
|
|
126
|
+
```python
|
|
127
|
+
!python -m pip install -U bilinear-quantum
|
|
128
|
+
import bilinear_quantum as blq
|
|
129
|
+
print(blq.__version__)
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
Use a fresh runtime and identical preprocessing when comparing baselines.
|
|
133
|
+
|
|
134
|
+
## Scope and reproducibility
|
|
135
|
+
|
|
136
|
+
Algorithmic details, benchmark protocols, and validation artifacts should be
|
|
137
|
+
identified by the exact package version and corresponding release record when
|
|
138
|
+
results are reported. See [LICENSE](LICENSE) for distribution terms;
|
|
139
|
+
third-party dependencies retain their own licenses.
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
bilinear_quantum/__init__.py,sha256=4HzK6cL2rb5wT8bUAuramdFAUHSmdSnoeu1S5-hTmZ0,1199
|
|
2
|
+
bilinear_quantum/core.py,sha256=FfWP5PSHvShhMyRMzbM7TK5F5nhAcwn94cU3KZZai0o,3806
|
|
3
|
+
bilinear_quantum/runtime.py,sha256=JsHn2zaJhdqwqRx_faaWv1BOoHdtNwNUHSN_LHRbyuE,605
|
|
4
|
+
bilinear_quantum-4.0.0.dist-info/METADATA,sha256=8gd5NdoM-WiLkomnSqfd9POo5gL07TutLh3bq7wsya4,4570
|
|
5
|
+
bilinear_quantum-4.0.0.dist-info/WHEEL,sha256=mOdXR9C3wMVov7cSY8PY-XCzo3SmmWCHvGQr5csJoao,91
|
|
6
|
+
bilinear_quantum-4.0.0.dist-info/top_level.txt,sha256=KQyIoDwxvSSHhVXOjIWu7cbEEHeljz2rmZrsKKeeYxw,17
|
|
7
|
+
bilinear_quantum-4.0.0.dist-info/RECORD,,
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
bilinear_quantum
|