Skip to content

estimators

eigenkit.torch.estimators

The PyTorch estimators: differentiable hybrid quantum-classical models.

The estimator base classes compatible with scikit-learn, the quantum kernels, the support vector machines and the saving and loading of models are in a separate package, eigenkit.qml, which does not need PyTorch. The base classes and load_model are also exported here for convenience, because the hybrid estimators build on them.

BaseQuantumClassifier

Bases: ClassifierMixin, BaseQuantumEstimator

Base class for quantum classifiers. Its score() returns the accuracy.

predict_proba(X)

Predict the class probabilities.

Subclasses should return the probabilities in the order of classes_, with shape (n_samples, n_classes). The default implementation raises a NotImplementedError.

Parameters:

Name Type Description Default
X ndarray

The samples, of shape (n_samples, n_features).

required

Returns:

Type Description
ndarray

The probabilities, of shape (n_samples, n_classes), with the columns in the order of classes_.

BaseQuantumEstimator

Bases: BaseEstimator, ABC

Base class, compatible with scikit-learn, for all quantum algorithms.

Parameters:

Name Type Description Default
provider ProviderSpec

The backend. It can be a registered name ("pennylane", "qiskit", "braket", or any name passed to register()), a configuration instance (for example PennyLaneConfig(device_name=...)), or a backend instance.

'numpy'
random_state int | None

The seed for reproducibility, applied inside fit() and load(). What it seeds depends on the estimator. The PyTorch estimators isolate the random number generator of PyTorch, so seeding one of them does not reseed the random stream of the caller. The kernel estimators are deterministic, and they take it only so that all the estimators have the same interface.

42

fit(X, y) abstractmethod

Fit the estimator on X and y.

Parameters:

Name Type Description Default
X ndarray

The samples, of shape (n_samples, n_features).

required
y ndarray

One target for each sample, of shape (n_samples,).

required

Returns:

Type Description
'BaseQuantumEstimator'

This estimator, so that calls can be chained.

load(path, *, provider=None) classmethod

Load a fitted model from a .eigenkit bundle.

Load only bundles that you trust. A bundle can contain joblib pickles, and unpickling runs code, as with torch.load or joblib.load.

Parameters:

Name Type Description Default
path str | Path

The path of the bundle.

required
provider ProviderSpec | None

A provider that replaces the saved one.

None

Returns:

Type Description
'BaseQuantumEstimator'

The loaded estimator.

Raises:

Type Description
TypeError

If the method is called on a subclass and the bundle holds a different class. BaseQuantumEstimator.load() accepts any class.

predict(X) abstractmethod

Predict a value for every sample in X.

Parameters:

Name Type Description Default
X ndarray

The samples, of shape (n_samples, n_features).

required

Returns:

Type Description
ndarray

One prediction for each sample.

save(path)

Save a fitted model to a .eigenkit bundle.

The bundles of models that hold scikit-learn objects (QSVC, QSVR, the reservoir estimators and the time-series estimators) contain joblib pickles, so loading one can run code. Share them only with people who trust you.

Parameters:

Name Type Description Default
path str | Path

The path of the bundle. The suffix .eigenkit is added when it is missing.

required

BaseQuantumRegressor

Bases: RegressorMixin, BaseQuantumEstimator

Base class for quantum regressors. Its score() returns R².

CustomQuantumClassifier

Bases: ModelAccessMixin, BaseQuantumClassifier

Classifier compatible with scikit-learn, built from your own list of blocks.

Give any sequence of blocks (Encoding, Variational, StrongVariational, Reuploading, or a custom block from CircuitBuilder.to_block()) and an observables specification, as for Circuit. The estimator connects them into a quantum layer followed by a classical nn.Linear head, and trains the whole model with the cross-entropy loss. When the number of features of the data differs from the number of inputs that the circuit expects, an nn.Linear adapter is added in front automatically.

Parameters:

Name Type Description Default
blocks list[Block]

The list of blocks, in order.

required
observables ObservableLike

The observables. It takes the same options as Circuit(observables=...). Default: None (Z on every qubit).

None
provider ProviderSpec

The backend. Default: "numpy".

'numpy'
in_features int | None

The number of features of the data. If None, it is inferred from the first Encoding or Reuploading block.

None
n_classes int | None

The number of output classes. If None, it is inferred from the training labels.

None
lr float

The learning rate of the optimiser.

0.01
optimizer str

The name of the optimiser. The supported names are "adam", "adamw", "rmsprop" and "sgd".

'adam'
optimizer_kwargs dict | None

Extra keyword arguments passed to the optimiser.

None
epochs int

The number of training epochs.

50
batch_size int

The size of each mini-batch.

32
show_progress bool

If True, a tqdm progress bar is shown.

True
random_state int | None

The seed.

42

Attributes:

Name Type Description
train_losses_

The cross-entropy loss of each epoch, set by fit().

validation_losses_

The validation cross-entropy loss of each epoch, set by fit() when validation data is given.

Example
import numpy as np
from eigenkit import (
    CustomQuantumClassifier, Encoding, Variational, all_z,
)

rng = np.random.default_rng(0)
X_train, X_test = rng.uniform(0, np.pi, (20, 4)), rng.uniform(0, np.pi, (5, 4))
y_train = np.array([0, 1] * 10)

blocks = [
    Encoding(in_features=4, rotation="RY"),
    Variational(depth=2, rotation="RY"),
]
model = CustomQuantumClassifier(
    blocks=blocks, observables=all_z(4), epochs=10,
)
model.fit(X_train, y_train)
predictions = model.predict(X_test)

fit(X, y, X_val=None, y_val=None)

Fit the classifier on training data.

Parameters:

Name Type Description Default
X ndarray

The samples, of shape (n_samples, in_features).

required
y ndarray

The class labels, of shape (n_samples,). They can be of any type that scikit-learn's LabelEncoder accepts.

required
X_val ndarray | None

Optional validation samples, used to compute the validation loss of each epoch.

None
y_val ndarray | None

Optional validation labels, used to compute the validation loss of each epoch.

None

Returns:

Type Description
'CustomQuantumClassifier'

This estimator, so that calls can be chained.

Raises:

Type Description
ValueError

If in_features is set and X does not have in_features columns.

predict(X)

Predict the class labels of X.

Parameters:

Name Type Description Default
X ndarray

The samples, of shape (n_samples, n_features).

required

Returns:

Type Description
ndarray

One prediction for each sample.

predict_proba(X)

Predict the probability of each class, with a softmax over the logits.

It returns a float32 array of shape (n_samples, n_classes).

Parameters:

Name Type Description Default
X ndarray

The samples, of shape (n_samples, n_features).

required

Returns:

Type Description
ndarray

The probabilities, of shape (n_samples, n_classes), with the columns in the order of classes_.

CustomQuantumRegressor

Bases: ModelAccessMixin, BaseQuantumRegressor

Regressor compatible with scikit-learn, built from your own list of blocks.

It is the regression counterpart of CustomQuantumClassifier. It wraps your quantum Circuit with an nn.Linear head of one neuron, trained with the chosen regression loss. An nn.Linear input adapter is added when the number of features of the data differs from the number of inputs of the circuit.

Parameters:

Name Type Description Default
blocks list[Block]

The list of blocks, in order.

required
observables ObservableLike

The observables. It takes the same options as Circuit(observables=...).

None
provider ProviderSpec

The backend. Default: "numpy".

'numpy'
in_features int | None

The number of features of the data. If None, it is inferred from the first Encoding or Reuploading block.

None
lr float

The learning rate of the optimiser.

0.01
optimizer str

The name of the optimiser: "adam", "adamw", "rmsprop" or "sgd".

'adam'
optimizer_kwargs dict | None

Extra keyword arguments passed to the optimiser.

None
epochs int

The number of training epochs.

50
batch_size int

The size of each mini-batch.

32
loss_func str

The regression loss: "mse", "mae" or "huber".

'mse'
huber_delta float

The threshold of the Huber loss.

1.0
huber_reduction str

The reduction of the Huber loss: "mean" or "sum".

'mean'
show_progress bool

If True, a tqdm progress bar is shown.

True
random_state int | None

The seed.

42

Attributes:

Name Type Description
train_losses_

The training loss of each epoch, set by fit().

validation_losses_

The validation loss of each epoch, set by fit() when validation data is given.

fit(X, y, X_val=None, y_val=None)

Fit the regressor on training data.

Parameters:

Name Type Description Default
X ndarray

The samples, of shape (n_samples, in_features).

required
y ndarray

The real-valued targets, of shape (n_samples,).

required
X_val ndarray | None

Optional validation samples, used to compute the validation loss of each epoch.

None
y_val ndarray | None

Optional validation targets, used to compute the validation loss of each epoch.

None

Returns:

Type Description
'CustomQuantumRegressor'

This estimator, so that calls can be chained.

predict(X)

Predict the continuous targets of X. It returns a float32 array.

Parameters:

Name Type Description Default
X ndarray

The samples, of shape (n_samples, n_features).

required

Returns:

Type Description
ndarray

One prediction for each sample.

GenericClassifier

Bases: ModelAccessMixin, BaseQuantumClassifier

Classifier compatible with scikit-learn that wraps any torch.nn.Module.

You supply a complete model whose forward(X) accepts a float32 tensor of shape (batch, in_features) and returns logits of shape (batch, n_classes). For sequence models (for example a long short-term memory network), set sequence_input=True. The wrapper then passes a 3-D tensor of shape (batch, seq_len, in_features) as it is, instead of flattening it.

The wrapper trains with CrossEntropyLoss and encodes the labels automatically.

Parameters:

Name Type Description Default
model Module

Any nn.Module. It must include its own classification head, which gives n_classes logits.

required
in_features int | None

The expected number of features at each time step (the last dimension of the input). When it is given, fit raises an error if X.shape[-1] does not match. Pass None to skip the check.

None
sequence_input bool

If True, the estimator tells QuantumTimeSeriesClassifier that it expects a 3-D tensor of shape (batch, seq_len, in_features), so the windowed data must not be flattened. Default: False.

False
n_classes int | None

The number of output classes. If None, it is inferred from the training labels. If it is given, it must equal the number of distinct labels in y.

None
lr float

The learning rate of the optimiser.

0.01
optimizer str

The name of the optimiser: "adam", "adamw", "rmsprop" or "sgd".

'adam'
optimizer_kwargs dict | None

Extra keyword arguments passed to the constructor of the optimiser.

None
epochs int

The number of full passes over the training data.

50
batch_size int

The size of each mini-batch.

32
show_progress bool

If True, a tqdm progress bar is shown during training.

True
random_state int | None

The seed, applied before the first training step.

42

Attributes:

Name Type Description
train_losses_

The average cross-entropy loss of each epoch, set by fit().

validation_losses_

The validation cross-entropy loss of each epoch, set by fit() when validation data is given.

Example
import numpy as np
from torch import nn
from eigenkit.torch.estimators import GenericClassifier
from eigenkit.torch.layers import Basic

rng = np.random.default_rng(0)
X_train, X_test = rng.normal(size=(30, 4)), rng.normal(size=(5, 4))
y_train = np.arange(30) % 3

# A plain PyTorch network, with a head for 3 classes.
net = nn.Sequential(nn.Linear(4, 8), nn.ReLU(), nn.Linear(8, 3))
clf = GenericClassifier(model=net, in_features=4, epochs=20)
clf.fit(X_train, y_train)
labels = clf.predict(X_test)
probs  = clf.predict_proba(X_test)

# A quantum layer with a classification head.
q = Basic(n_qubits=4, depth=2)
hybrid = nn.Sequential(q, nn.Linear(4, 3))
clf2 = GenericClassifier(model=hybrid, in_features=4)

accepts_sequence_input property

Whether the model expects a 3-D input (batch, seq_len, features).

fit(X, y, X_val=None, y_val=None)

Fit the model on training data.

Parameters:

Name Type Description Default
X ndarray

The samples, of shape (n_samples, in_features) for flat models, or (n_samples, seq_len, in_features) when sequence_input=True.

required
y ndarray

The class labels, of shape (n_samples,).

required
X_val ndarray | None

Optional validation samples, used to compute the validation loss of each epoch.

None
y_val ndarray | None

Optional validation labels, used to compute the validation loss of each epoch.

None

Returns:

Type Description
'GenericClassifier'

This estimator, so that calls can be chained.

Raises:

Type Description
ValueError

If X.shape[-1] or X_val.shape[-1] differs from in_features, if n_classes differs from the number of distinct labels, or if the model does not give one logit for each class.

load(path, *, model=None, provider=None) classmethod

Load a fitted GenericClassifier from a .eigenkit bundle.

The architecture of the model cannot be rebuilt automatically, so you must give it. The saved weights and the label encoder are restored automatically.

Parameters:

Name Type Description Default
path str | Path

The path of the .eigenkit bundle.

required
model Module | None

An nn.Module with the same architecture as the one used in training. Its weights are not changed: the saved weights go into a deep copy, which is model_ of the loaded estimator.

None
provider ProviderSpec | None

It is ignored. It is kept so that the signature matches the other estimators.

None

Returns:

Type Description
'GenericClassifier'

The loaded estimator.

Raises:

Type Description
SerializationError

If model is not given.

TypeError

If the bundle holds a different class.

Example
from torch import nn
from eigenkit.torch.estimators import GenericClassifier

net = nn.Sequential(nn.Linear(4, 8), nn.ReLU(), nn.Linear(8, 3))
clf = GenericClassifier.load("checkpoint.eigenkit", model=net)

predict(X)

Predict the class labels of X.

Parameters:

Name Type Description Default
X ndarray

The samples, of shape (n_samples, n_features).

required

Returns:

Type Description
ndarray

One prediction for each sample.

predict_proba(X)

Predict the probability of each class, with a softmax over the logits.

It returns a float32 array of shape (n_samples, n_classes).

Parameters:

Name Type Description Default
X ndarray

The samples, of shape (n_samples, n_features).

required

Returns:

Type Description
ndarray

The probabilities, of shape (n_samples, n_classes), with the columns in the order of classes_.

GenericRegressor

Bases: ModelAccessMixin, BaseQuantumRegressor

Regressor compatible with scikit-learn that wraps any torch.nn.Module.

You supply a complete model whose forward(X) accepts a float32 tensor of shape (batch, in_features) and returns a tensor of shape (batch, 1) or (batch,). For sequence models (for example a long short-term memory network), set sequence_input=True. The wrapper then passes a 3-D tensor of shape (batch, seq_len, in_features) as it is, instead of flattening it.

The wrapper trains the model with the standard train_loop() of the library, and returns the predictions as a float32 NumPy array.

Parameters:

Name Type Description Default
model Module

Any nn.Module. It must include its own output head.

required
in_features int | None

The expected number of features at each time step (the last dimension of the input). When it is given, fit raises an error if X.shape[-1] does not match. Pass None to skip the check.

None
sequence_input bool

If True, the estimator tells QuantumTimeSeriesRegressor that it expects a 3-D tensor of shape (batch, seq_len, in_features), so the windowed data must not be flattened. Default: False.

False
loss_func str | Callable

The loss: "mse", "mae", "huber", or any callable (output, target) -> scalar_tensor.

'mse'
huber_delta float

The threshold of the Huber loss. It is ignored for the other losses.

1.0
huber_reduction str

The reduction of the Huber loss: "mean" or "sum".

'mean'
lr float

The learning rate of the optimiser.

0.01
optimizer str

The name of the optimiser: "adam", "adamw", "rmsprop" or "sgd".

'adam'
optimizer_kwargs dict | None

Extra keyword arguments passed to the constructor of the optimiser.

None
epochs int

The number of full passes over the training data.

50
batch_size int

The size of each mini-batch.

32
show_progress bool

If True, a tqdm progress bar is shown during training.

True
random_state int | None

The seed, applied before the first training step.

42

Attributes:

Name Type Description
train_losses_

The list of the average loss of each epoch, set by fit().

validation_losses_

The list of the validation loss of each epoch, set by fit() when validation data is given.

Example
import numpy as np
from torch import nn
from eigenkit.torch.estimators import GenericRegressor
from eigenkit.torch.layers import Basic

rng = np.random.default_rng(0)
X_train, X_test = rng.normal(size=(30, 8)), rng.normal(size=(5, 8))
y_train = X_train.sum(axis=1)

# A plain PyTorch network.
net = nn.Sequential(nn.Linear(8, 16), nn.ReLU(), nn.Linear(16, 1))
reg = GenericRegressor(model=net, in_features=8, epochs=30)
reg.fit(X_train, y_train)
preds = reg.predict(X_test)

# A quantum layer with a classical head.
q = Basic(n_qubits=4, depth=2)
hybrid = nn.Sequential(q, nn.Linear(4, 1))
reg2 = GenericRegressor(model=hybrid, in_features=4)

accepts_sequence_input property

Whether the model expects a 3-D input (batch, seq_len, features).

fit(X, y, X_val=None, y_val=None)

Fit the model on training data.

Parameters:

Name Type Description Default
X ndarray

The samples, of shape (n_samples, in_features) for flat models, or (n_samples, seq_len, in_features) when sequence_input=True.

required
y ndarray

The real-valued targets, of shape (n_samples,).

required
X_val ndarray | None

Optional validation samples, used to compute the validation loss of each epoch.

None
y_val ndarray | None

Optional validation targets, used to compute the validation loss of each epoch.

None

Returns:

Type Description
'GenericRegressor'

This estimator, so that calls can be chained.

Raises:

Type Description
ValueError

If X.shape[-1] or X_val.shape[-1] differs from in_features, or if the output of the model does not have shape (batch,) or (batch, 1).

load(path, *, model=None, provider=None) classmethod

Load a fitted GenericRegressor from a .eigenkit bundle.

The architecture of the model cannot be rebuilt automatically, so you must give it. The saved weights are loaded into a copy of it.

Parameters:

Name Type Description Default
path str | Path

The path of the .eigenkit bundle.

required
model Module | None

An nn.Module with the same architecture as the one used in training. Its weights are not changed: the saved weights go into a deep copy, which is model_ of the loaded estimator.

None
provider ProviderSpec | None

It is ignored. It is kept so that the signature matches the other estimators.

None

Returns:

Type Description
'GenericRegressor'

The loaded estimator.

Raises:

Type Description
SerializationError

If model is not given.

TypeError

If the bundle holds a different class.

Example
from torch import nn
from eigenkit.torch.estimators import GenericRegressor

net = nn.Sequential(nn.Linear(8, 16), nn.ReLU(), nn.Linear(16, 1))
reg = GenericRegressor.load("checkpoint.eigenkit", model=net)

predict(X)

Predict the continuous targets of X. It returns a float32 array.

Parameters:

Name Type Description Default
X ndarray

The samples, of shape (n_samples, n_features).

required

Returns:

Type Description
ndarray

One prediction for each sample.

HQNC

Bases: ModelAccessMixin, BaseQuantumClassifier

Hybrid quantum neural network classifier (HQNC).

The model is MinMaxNorm -> quantum_layer -> nn.Linear(q_out, n_classes). If the number of features of the data differs from the resolved input size of the quantum layer (derived from in_quantum, n_qubits and layer_type), an nn.Linear adapter is added in front automatically.

Parameters:

Name Type Description Default
in_features int

The number of input features.

required
in_quantum int | None

The number of inputs that the quantum layer expects. It defaults to in_features.

None
n_qubits int | None

The number of qubits in each circuit. It defaults to in_quantum.

None
depth int

The number of repetitions of the variational layer.

2
n_classes int | None

The number of output classes. If None, it is inferred from the training labels.

None
layer_type str

The quantum layer. It is one of "Basic", "Reupload" and "Ensemble".

'Basic'
enc_rotation Literal['RX', 'RY', 'RZ'] | None

The encoding rotation: "RX", "RY", "RZ" or None.

None
var_rotation Literal['RX', 'RY', 'RZ'] | None

The variational rotation of the "basic" ansatz: "RX", "RY", "RZ" or None.

None
variational_type Literal['basic', 'strong'] | None

The type of variational block: "basic", "strong" or None.

None
basis Literal['X', 'Y', 'Z'] | None

The measurement basis: "X", "Y", "Z" or None. For these four arguments, None means "use the default of the layer named by layer_type", which is where each of these values is decided.

None
provider ProviderSpec

The backend. It takes the same options as Circuit(provider=...).

'numpy'
lr float

The learning rate of the optimiser.

0.01
optimizer str

The name of the optimiser. The supported names are "adam", "adamw", "rmsprop" and "sgd".

'adam'
optimizer_kwargs dict | None

Extra keyword arguments passed to the optimiser.

None
epochs int

The number of training epochs.

50
batch_size int

The size of each mini-batch.

32
show_progress bool

If True, a tqdm progress bar is shown.

True
random_state int | None

The seed for the initialisation of the weights.

42

Attributes:

Name Type Description
train_losses_

The average cross-entropy loss of each epoch, set by fit().

validation_losses_

The validation cross-entropy loss of each epoch, set by fit() when validation data is given.

Example
import numpy as np
from eigenkit.torch.estimators import HQNC

rng = np.random.default_rng(0)
X_train, X_test = rng.normal(size=(30, 4)), rng.normal(size=(5, 4))
y_train = np.arange(30) % 3

model = HQNC(in_features=4, depth=2, n_classes=3)
model.fit(X_train, y_train)
predictions = model.predict(X_test)

__init__(in_features, in_quantum=None, n_qubits=None, depth=2, n_classes=None, layer_type='Basic', enc_rotation=None, var_rotation=None, variational_type=None, basis=None, provider='numpy', lr=0.01, optimizer='adam', optimizer_kwargs=None, epochs=50, batch_size=32, show_progress=True, random_state=42)

Initialise a hybrid quantum neural network classifier (HQNC).

Parameters:

Name Type Description Default
in_features int

The number of input features that fit() expects.

required
in_quantum int | None

The number of inputs that the quantum layer expects. It defaults to in_features.

None
n_qubits int | None

The number of qubits in each circuit. It defaults to in_quantum.

None
depth int

The number of repetitions of the variational layer.

2
n_classes int | None

The number of output classes. If None, it is inferred from the labels passed to fit().

None
layer_type str

The family of the quantum layer. It is one of "Basic", "Reupload" and "Ensemble".

'Basic'
enc_rotation Literal['RX', 'RY', 'RZ'] | None

The encoding rotation: "RX", "RY", "RZ" or None.

None
var_rotation Literal['RX', 'RY', 'RZ'] | None

The variational rotation of the basic ansatz: "RX", "RY", "RZ" or None.

None
variational_type Literal['basic', 'strong'] | None

The type of variational block: "basic", "strong" or None.

None
basis Literal['X', 'Y', 'Z'] | None

The measurement basis: "X", "Y", "Z" or None. For these four arguments, None means "use the default of the layer named by layer_type", which is where each of these values is decided.

None
provider ProviderSpec

The backend. It takes the same options as Circuit(provider=...).

'numpy'
lr float

The learning rate of the optimiser.

0.01
optimizer str

The name of the optimiser. The supported names are "adam", "adamw", "rmsprop" and "sgd".

'adam'
optimizer_kwargs dict | None

Extra keyword arguments passed to the optimiser.

None
epochs int

The number of training epochs.

50
batch_size int

The size of each mini-batch.

32
show_progress bool

If True, a tqdm progress bar is shown during training.

True
random_state int | None

The seed for the initialisation of the weights.

42

fit(X, y, X_val=None, y_val=None)

Fit the classifier on training data.

Parameters:

Name Type Description Default
X ndarray

The samples, of shape (n_samples, in_features).

required
y ndarray

The class labels, of shape (n_samples,). They can be of any type that scikit-learn's LabelEncoder accepts.

required
X_val ndarray | None

Optional validation samples, used to compute the validation loss of each epoch.

None
y_val ndarray | None

Optional validation labels, used to compute the validation loss of each epoch.

None

Returns:

Type Description
HQNC

This estimator, so that calls can be chained.

Raises:

Type Description
ValueError

If X does not have in_features columns.

predict(X)

Predict the class labels of X.

Parameters:

Name Type Description Default
X ndarray

The samples, of shape (n_samples, n_features).

required

Returns:

Type Description
ndarray

One prediction for each sample.

predict_proba(X)

Predict the probability of each class, with a softmax over the logits.

It returns a float32 array of shape (n_samples, n_classes). Each row sums to 1.

Parameters:

Name Type Description Default
X ndarray

The samples, of shape (n_samples, n_features).

required

Returns:

Type Description
ndarray

The probabilities, of shape (n_samples, n_classes), with the columns in the order of classes_.

HQNR

Bases: ModelAccessMixin, BaseQuantumRegressor

Hybrid quantum neural network regressor (HQNR).

It is the regression counterpart of HQNC. The model is MinMaxNorm -> quantum_layer -> nn.Linear(q_out, 1). If the number of features of the data differs from the resolved input size of the quantum layer, an nn.Linear adapter is added in front automatically.

Parameters:

Name Type Description Default
in_features int

The number of input features.

required
in_quantum int | None

The number of inputs that the quantum layer expects. It defaults to in_features.

None
n_qubits int | None

The number of qubits in each circuit. It defaults to in_quantum.

None
depth int

The number of repetitions of the variational layer.

2
layer_type str

The quantum layer. It is one of "Basic", "Reupload" and "Ensemble".

'Basic'
enc_rotation Literal['RX', 'RY', 'RZ'] | None

The encoding rotation: "RX", "RY", "RZ" or None.

None
var_rotation Literal['RX', 'RY', 'RZ'] | None

The variational rotation of the "basic" ansatz: "RX", "RY", "RZ" or None.

None
variational_type Literal['basic', 'strong'] | None

The type of variational block: "basic", "strong" or None.

None
basis Literal['X', 'Y', 'Z'] | None

The measurement basis: "X", "Y", "Z" or None. For these four arguments, None means "use the default of the layer named by layer_type", which is where each of these values is decided.

None
provider ProviderSpec

The backend. It takes the same options as Circuit(provider=...).

'numpy'
lr float

The learning rate of the optimiser.

0.01
optimizer str

The name of the optimiser. The supported names are "adam", "adamw", "rmsprop" and "sgd".

'adam'
optimizer_kwargs dict | None

Extra keyword arguments passed to the optimiser.

None
epochs int

The number of training epochs.

50
batch_size int

The size of each mini-batch.

32
show_progress bool

If True, a tqdm progress bar is shown.

True
loss_func str

The regression loss: "mse", "mae" or "huber".

'mse'
huber_delta float

The threshold of the Huber loss.

1.0
huber_reduction str

The reduction of the Huber loss: "mean" or "sum".

'mean'
random_state int | None

The seed.

42

Attributes:

Name Type Description
train_losses_

The training loss of each epoch, set by fit().

validation_losses_

The validation loss of each epoch, set by fit() when validation data is given.

Example
import numpy as np
from eigenkit.torch.estimators import HQNR

rng = np.random.default_rng(0)
X_train, X_test = rng.normal(size=(30, 8)), rng.normal(size=(5, 8))
y_train = X_train.sum(axis=1)

model = HQNR(in_features=8, depth=2)
model.fit(X_train, y_train)
predictions = model.predict(X_test)

fit(X, y, X_val=None, y_val=None)

Fit the regressor on training data.

Parameters:

Name Type Description Default
X ndarray

The samples, of shape (n_samples, in_features).

required
y ndarray

The real-valued targets, of shape (n_samples,).

required
X_val ndarray | None

Optional validation samples, used to compute the validation loss of each epoch.

None
y_val ndarray | None

Optional validation targets, used to compute the validation loss of each epoch.

None

Returns:

Type Description
HQNR

This estimator, so that calls can be chained.

Raises:

Type Description
ValueError

If X does not have in_features columns.

predict(X)

Predict the continuous targets of X. It returns a float32 array.

Parameters:

Name Type Description Default
X ndarray

The samples, of shape (n_samples, n_features).

required

Returns:

Type Description
ndarray

One prediction for each sample.

QuantumTimeSeriesClassifier

Bases: BaseQuantumClassifier

Supervised wrapper for time-series classification.

It builds sliding windows over the rows of X (one row for each time step). Each window has shape (in_size, n_features). Stacked along the batch axis, they form an array of shape (n_windows, in_size, n_features), ready for sequence models such as RecurrentHQNC. When autoregressive=True, an extra last channel holds the target value of each timestep, so each step has n_features + 1 values. For a window that starts at row i, the classification target is y[i + in_size - 1 + shift].

Parameters:

Name Type Description Default
estimator Any

The inner estimator. It must have fit(X, y) and predict(X).

required
in_size int | None

The length of the window, in time steps. If None, it is treated as 1.

None
shift int

How many steps after the last timestep of the window the target is. It must be zero or more. shift=0 predicts the target at the last timestep.

1
autoregressive bool

If True, a channel with y[i + k] for k = 0, ..., in_size - 1 is added to each window. With shift=0, this leaks the target into the inputs, and a UserWarning is raised. When autoregressive=True, predict() and predict_proba() require a y_history argument.

False

Attributes:

Name Type Description
classes_

The distinct class labels seen by fit().

train_losses_

The training loss of each epoch, copied from the inner estimator if it has train_losses_ (HQNC, RecurrentHQNC), and an empty list otherwise. It is set by fit().

Example
import numpy as np
from eigenkit.torch.estimators import (
    QuantumTimeSeriesClassifier, RecurrentHQNC,
)

rng = np.random.default_rng(0)
X_train, X_test = rng.normal(size=(40, 4)), rng.normal(size=(15, 4))
y_train = np.arange(40) % 2

inner = RecurrentHQNC(seq_feature_dim=4, rnn_hidden_dim=4, depth=2)
model = QuantumTimeSeriesClassifier(estimator=inner, in_size=10, shift=1)
model.fit(X_train, y_train)
predictions = model.predict(X_test)

output property

The number of classes.

After fit(), it is the number of classes seen. Before, it is the n_classes of the inner estimator, or None if it has none.

fit(X, y)

Fit the inner classifier on the windows and their labels.

Parameters:

Name Type Description Default
X ndarray

The features in time order, of shape (n_timesteps, n_features).

required
y ndarray

The class labels, of shape (n_timesteps,) or (n_timesteps, 1).

required

Returns:

Type Description
'QuantumTimeSeriesClassifier'

This estimator, so that calls can be chained.

load(path, *, provider=None, model=None) classmethod

Load a fitted time-series classifier wrapper from a .eigenkit bundle.

Parameters:

Name Type Description Default
path str | Path

The path of the .eigenkit bundle.

required
provider ProviderSpec | None

An optional provider that replaces the saved one. It is passed to the inner estimator.

None
model Any

The nn.Module architecture, required when the inner estimator is GenericClassifier. Pass the same architecture as the one used in training.

None

Returns:

Type Description
'QuantumTimeSeriesClassifier'

The loaded wrapper.

Raises:

Type Description
TypeError

If the bundle holds a different class.

SerializationError

If the inner estimator needs model and it is not given.

predict(X, y_history=None)

Predict the class labels of the windows of X.

Parameters:

Name Type Description Default
X ndarray

The features in time order, of shape (n_timesteps, n_features).

required
y_history ndarray | None

The past class labels, aligned with the rows of X. They fill the autoregressive channel of each window. It is required when autoregressive=True, and it must have at least n_timesteps - shift elements (that is, n_timesteps - in_size - shift + 1 + in_size - 1).

None

Returns:

Type Description
ndarray

The predicted labels, of shape (n_timesteps - in_size - shift + 1,).

predict_proba(X, y_history=None)

Return the estimated class probabilities of the windows of X.

Parameters:

Name Type Description Default
X ndarray

The features in time order, of shape (n_timesteps, n_features).

required
y_history ndarray | None

The past class labels. It is required when autoregressive=True. See predict().

None

Returns:

Type Description
ndarray

A float32 array of shape (n_windows, n_classes).

Raises:

Type Description
NotImplementedError

If the inner estimator has no predict_proba.

score(X, y, *, return_dict=False)

score(
    X: np.ndarray,
    y: np.ndarray,
    *,
    return_dict: Literal[False] = False,
) -> float
score(
    X: np.ndarray,
    y: np.ndarray,
    *,
    return_dict: Literal[True],
) -> dict[str, float]

Score the estimator on the window targets, aligned as in predict.

By default, it returns the accuracy, for compatibility with scikit-learn (cross_val_score, GridSearchCV). Pass return_dict=True to get a dict with accuracy, f1 (weighted), precision (weighted) and recall (weighted).

Note

When autoregressive=True, the true labels y are used as the autoregressive history channel (teacher forcing). This is the correct behaviour for held-out evaluation, but it means that score cannot be called without the true labels of all the timesteps in X.

Parameters:

Name Type Description Default
X ndarray

The samples, of shape (n_samples, n_features). The windows are built inside.

required
y ndarray

One target for each sample, of shape (n_samples,).

required
return_dict bool

If True, every metric is returned in a dict, instead of the single main score. Default: False.

False

Returns:

Type Description
float | dict[str, float]

The accuracy, or a dict of metrics when return_dict is set.

QuantumTimeSeriesRegressor

Bases: BaseQuantumRegressor

Supervised wrapper with a single output, for time-series regression.

It builds sliding windows over the rows of X (one row for each time step). Each window has shape (in_size, n_features). Stacked along the batch axis, they form an array of shape (n_windows, in_size, n_features), ready for sequence models such as torch.nn.LSTM. When autoregressive=True, an extra last channel holds the target value of each timestep, so each step has n_features + 1 values. For a window that starts at row i, the regression target is y[i + in_size - 1 + shift].

Parameters:

Name Type Description Default
estimator Any

The inner estimator. It must have fit(X, y) and predict(X).

required
in_size int | None

The length of the window, in time steps. If None, it is treated as 1.

None
shift int

How many steps after the last timestep of the window the target is. It must be zero or more. shift=0 predicts the target at the last timestep.

1
autoregressive bool

If True, a channel with y[i + k] for k = 0, ..., in_size - 1 is added to each window. With shift=0, this leaks the target into the inputs, and a UserWarning is raised.

False

Attributes:

Name Type Description
train_losses_

The training loss of each epoch, copied from the inner estimator if it has train_losses_ (HQNR, RecurrentHQNR), and an empty list otherwise. It is set by fit().

Example
import numpy as np
from eigenkit.torch.estimators import QuantumTimeSeriesRegressor, RecurrentHQNR

rng = np.random.default_rng(0)
X_train, X_test = rng.normal(size=(40, 3)), rng.normal(size=(15, 3))
y_train = np.sin(np.arange(40) / 4)

# The inner estimator should accept X of shape (batch, in_size, n_features).
inner = RecurrentHQNR(seq_feature_dim=3, rnn_hidden_dim=4, epochs=5)
model = QuantumTimeSeriesRegressor(estimator=inner, in_size=10, shift=1)
model.fit(X_train, y_train)
predictions = model.predict(X_test)

output property

The number of outputs, which is always 1.

fit(X, y)

Fit the inner estimator on the windows and their targets.

Parameters:

Name Type Description Default
X ndarray

The features in time order, of shape (n_timesteps, n_features).

required
y ndarray

The targets, of shape (n_timesteps,) or (n_timesteps, 1).

required

Returns:

Type Description
'QuantumTimeSeriesRegressor'

This estimator, so that calls can be chained.

load(path, *, provider=None, model=None) classmethod

Load a fitted time-series wrapper from a .eigenkit bundle.

Parameters:

Name Type Description Default
path str | Path

The path of the .eigenkit bundle.

required
provider ProviderSpec | None

An optional provider that replaces the saved one. It is passed to the inner estimator.

None
model Any

The nn.Module architecture, required when the inner estimator is GenericRegressor. Pass the same architecture as the one used in training.

None

Returns:

Type Description
'QuantumTimeSeriesRegressor'

The loaded wrapper.

Raises:

Type Description
TypeError

If the bundle holds a different class.

SerializationError

If the inner estimator needs model and it is not given.

predict(X, y_history=None)

Predict the regression targets of the windows of X.

Parameters:

Name Type Description Default
X ndarray

The features in time order, of shape (n_timesteps, n_features).

required
y_history ndarray | None

The past targets, aligned with the rows of X. They fill the autoregressive channel of each window. It is required when autoregressive=True.

None

Returns:

Type Description
ndarray

The predictions, of shape (n_timesteps - in_size - shift + 1,).

score(X, y, *, return_dict=False)

score(
    X: np.ndarray,
    y: np.ndarray,
    *,
    return_dict: Literal[False] = False,
) -> float
score(
    X: np.ndarray,
    y: np.ndarray,
    *,
    return_dict: Literal[True],
) -> dict[str, float]

Score the estimator on the window targets, aligned as in predict.

By default, it returns R², for compatibility with scikit-learn (cross_val_score, GridSearchCV). Pass return_dict=True to get a dict with r2, mse, mae, rmse and mape.

Parameters:

Name Type Description Default
X ndarray

The samples, of shape (n_samples, n_features). The windows are built inside.

required
y ndarray

One target for each sample, of shape (n_samples,).

required
return_dict bool

If True, every metric is returned in a dict, instead of the single main score. Default: False.

False

Returns:

Type Description
float | dict[str, float]

The R² score, or a dict of metrics when return_dict is set.

RecurrentHQNC

Bases: ModelAccessMixin, BaseQuantumClassifier

Hybrid classifier: a recurrent encoder, a quantum layer and a linear class head.

The recurrent encoder is a recurrent neural network (RNN). The estimator expects 3-D inputs of shape (n_samples, seq_len, seq_feature_dim). By default, only the last timestep of the RNN output goes to the quantum layer. Set rnn_return_last_timestep=False, together with sequence_length, to use the full RNN output (flattened) instead. The quantum part is the same as in HQNC: MinMaxNorm, the quantum layer and an nn.Linear head.

Parameters:

Name Type Description Default
seq_feature_dim int

The number of features at each time step (the last axis of X).

required
rnn_type Literal['rnn', 'gru', 'lstm']

The type of recurrent layer: "rnn", "gru" (gated recurrent unit) or "lstm" (long short-term memory).

'gru'
rnn_hidden_dim int

The hidden size in each direction.

32
rnn_num_layers int

The number of stacked RNN layers.

1
rnn_dropout float

The dropout between the RNN layers. It applies only if rnn_num_layers > 1.

0.0
rnn_bidirectional bool

If True, the RNN is bidirectional, and its output size doubles.

False
rnn_return_last_timestep bool

If True, only the last output step is kept. Otherwise, the full sequence is flattened, which requires sequence_length.

True
sequence_length int | None

The number of time steps in each sample. It is required when rnn_return_last_timestep=False, and it must equal X.shape[1] in fit.

None
in_quantum int | None

The number of inputs of the quantum layer. It defaults to the size of the RNN output that reaches the quantum layer: rnn_hidden_dim, doubled when the RNN is bidirectional, and multiplied by sequence_length when rnn_return_last_timestep=False.

None
n_qubits int | None

The number of qubits in each circuit. It defaults to in_quantum.

None
depth int

The number of repetitions of the variational layer.

2
n_classes int | None

The number of output classes. If None, it is inferred from the labels passed to fit(). If it is given, it must equal the number of distinct labels in y.

None
layer_type str

The quantum layer. It is one of "Basic", "Reupload" and "Ensemble".

'Basic'
enc_rotation Literal['RX', 'RY', 'RZ'] | None

The encoding rotation: "RX", "RY", "RZ" or None.

None
var_rotation Literal['RX', 'RY', 'RZ'] | None

The variational rotation of the basic ansatz: "RX", "RY", "RZ" or None.

None
variational_type Literal['basic', 'strong'] | None

The type of variational block: "basic", "strong" or None.

None
basis Literal['X', 'Y', 'Z'] | None

The measurement basis: "X", "Y", "Z" or None. For these four arguments, None means "use the default of the layer named by layer_type", which is where each of these values is decided.

None
provider ProviderSpec

The backend. It takes the same options as Circuit(provider=...).

'numpy'
lr float

The learning rate of the optimiser.

0.01
optimizer str

The name of the optimiser. The supported names are "adam", "adamw", "rmsprop" and "sgd".

'adam'
optimizer_kwargs dict | None

Extra keyword arguments passed to the optimiser.

None
epochs int

The number of training epochs.

50
batch_size int

The size of each mini-batch.

32
show_progress bool

If True, a tqdm progress bar is shown during training.

True
random_state int | None

The seed for the initialisation of the weights.

42

Attributes:

Name Type Description
train_losses_

The cross-entropy loss of each epoch, set by fit().

validation_losses_

The validation cross-entropy loss of each epoch, set by fit() when validation data is given.

fit(X, y, X_val=None, y_val=None)

Fit the estimator on X and y.

Parameters:

Name Type Description Default
X ndarray

The sequences, of shape (n_samples, seq_len, seq_feature_dim).

required
y ndarray

One label for each sequence, of shape (n_samples,).

required
X_val ndarray | None

Optional validation sequences, of the same shape as X. Default: None.

None
y_val ndarray | None

The labels of X_val. Default: None.

None

Returns:

Type Description
RecurrentHQNC

This estimator, so that calls can be chained.

predict(X)

Predict a label for every sample in X.

Parameters:

Name Type Description Default
X ndarray

The sequences, of shape (n_samples, seq_len, seq_feature_dim).

required

Returns:

Type Description
ndarray

One prediction for each sequence, of shape (n_samples,).

predict_proba(X)

Predict the class probabilities of every sample in X.

Parameters:

Name Type Description Default
X ndarray

The sequences, of shape (n_samples, seq_len, seq_feature_dim).

required

Returns:

Type Description
ndarray

The probabilities, of shape (n_samples, n_classes), with the columns in the order of classes_.

RecurrentHQNR

Bases: ModelAccessMixin, BaseQuantumRegressor

Hybrid regressor: a recurrent encoder, a quantum layer and a linear head.

The recurrent encoder is a recurrent neural network (RNN). The estimator expects 3-D inputs of shape (n_samples, seq_len, seq_feature_dim). By default, only the last timestep of the RNN output goes to the quantum layer. Set rnn_return_last_timestep=False, together with sequence_length, to use the full RNN output (flattened) instead. The quantum part is the same as in HQNR: MinMaxNorm, the quantum layer and an nn.Linear head.

Parameters:

Name Type Description Default
seq_feature_dim int

The number of features at each time step (the last axis of X).

required
rnn_type Literal['rnn', 'gru', 'lstm']

The type of recurrent layer: "rnn", "gru" (gated recurrent unit) or "lstm" (long short-term memory).

'gru'
rnn_hidden_dim int

The hidden size in each direction.

32
rnn_num_layers int

The number of stacked RNN layers.

1
rnn_dropout float

The dropout between the RNN layers. It applies only if rnn_num_layers > 1.

0.0
rnn_bidirectional bool

If True, the RNN is bidirectional, and its output size doubles.

False
rnn_return_last_timestep bool

If True, only the last output step is kept. Otherwise, the full sequence is flattened, which requires sequence_length.

True
sequence_length int | None

The number of time steps in each sample. It is required when rnn_return_last_timestep=False, and it must equal X.shape[1] in fit.

None
in_quantum int | None

The number of inputs of the quantum layer. It defaults to the size of the RNN output that reaches the quantum layer: rnn_hidden_dim, doubled when the RNN is bidirectional, and multiplied by sequence_length when rnn_return_last_timestep=False.

None
n_qubits int | None

The number of qubits in each circuit. It defaults to in_quantum.

None
depth int

The number of repetitions of the variational layer.

2
layer_type str

The quantum layer. It is one of "Basic", "Reupload" and "Ensemble".

'Basic'
enc_rotation Literal['RX', 'RY', 'RZ'] | None

The encoding rotation: "RX", "RY", "RZ" or None.

None
var_rotation Literal['RX', 'RY', 'RZ'] | None

The variational rotation of the "basic" ansatz: "RX", "RY", "RZ" or None.

None
variational_type Literal['basic', 'strong'] | None

The type of variational block: "basic", "strong" or None.

None
basis Literal['X', 'Y', 'Z'] | None

The measurement basis: "X", "Y", "Z" or None. For these four arguments, None means "use the default of the layer named by layer_type", which is where each of these values is decided.

None
provider ProviderSpec

The backend. It takes the same options as Circuit(provider=...).

'numpy'
lr float

The learning rate of the optimiser.

0.01
optimizer str

The name of the optimiser.

'adam'
optimizer_kwargs dict | None

Extra keyword arguments passed to the optimiser.

None
epochs int

The number of training epochs.

50
batch_size int

The size of each mini-batch.

32
show_progress bool

If True, a tqdm progress bar is shown.

True
loss_func str

The regression loss: "mse", "mae" or "huber".

'mse'
huber_delta float

The threshold of the Huber loss.

1.0
huber_reduction str

The reduction of the Huber loss: "mean" or "sum".

'mean'
random_state int | None

The seed.

42

Attributes:

Name Type Description
train_losses_

The training loss of each epoch, set by fit().

validation_losses_

The validation loss of each epoch, set by fit() when validation data is given.

fit(X, y, X_val=None, y_val=None)

Fit the estimator on X and y.

Parameters:

Name Type Description Default
X ndarray

The sequences, of shape (n_samples, seq_len, seq_feature_dim).

required
y ndarray

One target for each sequence, of shape (n_samples,) or (n_samples, 1).

required
X_val ndarray | None

Optional validation sequences, of the same shape as X. Default: None.

None
y_val ndarray | None

The targets of X_val. Default: None.

None

Returns:

Type Description
RecurrentHQNR

This estimator, so that calls can be chained.

predict(X)

Predict a value for every sample in X.

Parameters:

Name Type Description Default
X ndarray

The sequences, of shape (n_samples, seq_len, seq_feature_dim).

required

Returns:

Type Description
ndarray

One prediction for each sequence, as a float32 array of shape (n_samples,).

load_model(path, *, provider=None, model=None)

Load any saved model. The class of the model is read from metadata.json.

Load only bundles that you trust. A bundle can contain joblib pickles, and unpickling runs code, as with torch.load or joblib.load.

Parameters:

Name Type Description Default
path str | Path

The path to the .eigenkit bundle.

required
provider ProviderSpec | None

A provider that replaces the saved one. It is passed to the load() method of the estimator.

None
model Any

The nn.Module architecture, for checkpoints of GenericRegressor and GenericClassifier. It is ignored for the other estimators.

None

Returns:

Type Description
BaseQuantumEstimator

The loaded estimator, an instance of the class named in the bundle.