Solver options¶
Version 0.5 provides named categorical values in
vbpca_py.options. Ordinary string calls to the numerical solver remain
supported. Parsing is explicit, and occurs when resolving a configuration;
estimator constructors retain the values supplied by the caller.
from vbpca_py.options import Algorithm, CompatMode
algorithm = Algorithm.parse("vb")
compatibility = CompatMode.MODERN
These values describe requested settings. Runtime eligibility checks still control execution paths. For example, requesting complement statistics does not bypass the numerical screening rules. Naming a stopping criterion does not enable or qualify it.
parse normalizes case and surrounding whitespace, and raises for unknown
values. Historical low-level normalization rules remain separate: the
algorithm keyword lowercases without stripping whitespace, and invalid legacy
runtime-mode strings retain their documented fallback behavior. This explicit
parser does not inherit those fallbacks.
Initialization is not a random/custom choice alone. init also accepts a
warm-start mapping or a MAT filename; those inputs remain supported. Enum
values serialize as strings in JSON and retain their identity through pickle.
They do not make mappings or arrays immutable.
Typed configuration and estimator parameters¶
PCAOptions describes requested solver settings. Use the typed argument or
legacy keywords on each low-level call:
import numpy as np
from vbpca_py import PCAOptions, VBPCA
from vbpca_py._pca_full import pca_full
from vbpca_py.options import Algorithm, RuntimeTuning
x = np.random.default_rng(7).normal(size=(5, 12)) # features x samples
config = PCAOptions(
algorithm=Algorithm.VB,
maxiters=4,
niter_broadprior=0,
verbose=0,
random_state=7,
num_cpu=1,
runtime_tuning=RuntimeTuning.OFF,
)
result = pca_full(x, 2, options=config)
legacy_result = pca_full(x, 2, **config.to_kwargs())
model = VBPCA(2, maxiters=4, niter_broadprior=0, verbose=0, random_state=7)
model.set_params(algorithm=Algorithm.MAP, num_cpu=1)
resolved_request = model.get_config()
keyword_request = model.get_options()
model.fit(x.T) # native estimator: samples x features
For a fully typed direct constructor, use the categorical enum values shown
below. PCAOptions.from_kwargs(**existing_settings) is the compatibility
conversion for existing keyword dictionaries: it applies the established
case and numeric normalization rules. The final fitting boundary also checks
cross-option constraints and initialization shapes. Passing options= and
solver keyword overrides together raises TypeError; update a configuration
with dataclasses.replace(config, maxiters=20) before fitting instead.
The estimator exposes all solver controls as explicit constructor parameters,
plus n_components, the deprecated inert tol, and xprobe_fraction.
Pass held-out probe data using model.fit(x, xprobe=probe); it is not a
constructor hyperparameter. Constructor values are stored unchanged. Native sklearn get_params,
set_params, clone, and grid-search parameter selection can inspect every
parameter. Configuration validation happens in get_config() or fitting.
This typed parameter contract does not change the low-level pca_full
features × samples boundary. The native estimator uses samples × features and
supports conditional projection of new rows through transform and
transform_posterior; the 0.5 migration guide distinguishes
those interfaces. Use the package's model-selection helpers for
missing-entry validation workflows.
Migrating keyword dictionaries and .opts¶
| Previous use | 0.5 interface |
|---|---|
VBPCA(2, **settings) with recognized settings |
Continue using it; every setting is now a named constructor parameter |
VBPCA(2, xprobe=probe) |
VBPCA(2).fit(x, xprobe=probe) |
model.opts["maxiters"] = 20 |
model.set_params(maxiters=20) |
| Inspect constructor values | model.get_params(deep=False) |
| Inspect normalized public requests | model.get_config() or model.get_options() |
pca_full(x, 2, **settings) |
Still supported for recognized keyword names |
| Convert a low-level settings dictionary | PCAOptions.from_kwargs(**settings) |
| Misspelled or previously ignored names | Correct/remove them; unknown names now fail clearly |
Estimator names are canonical and case-sensitive, as expected by sklearn.
Recognized low-level keyword names retain their historical case-insensitive
spelling. The generic internal keyword utility can still report unknown names,
but the public solver rejects them. In particular, MATLAB's autosave never
saved Python solver state and is now rejected; remove it from Python calls.
Private runtime metadata is not a constructor parameter or public keyword
export. Fitted caches, preflight records, complement plans, and autotuned
execution choices stay in per-fit state. Mutating the dictionary returned by
get_options() changes neither the estimator nor another fit.
Ownership and thread inheritance¶
The configuration is frozen and slotted. Small stopping arrays, criterion
orders and policy mappings are copied into immutable tuples/mappings. Each
keyword export creates fresh mutable stopping containers. Initialization and
probe payloads are borrowed until fitting; the existing fit preparation owns
its numerical working arrays. Exporting configuration does not copy large
payloads. Mutating a borrowed payload before fitting changes what that fit
receives. A supplied NumPy Generator keeps its usual stateful semantics;
use an integer seed for reproducible repeated fits. Pickle/deepcopy retain
configuration, and sklearn clones independently copy mutable constructor
arguments.
num_cpu=None means inherit execution policy, including for legacy callers
that explicitly pass None. Configuration creation, replacement, pickle and
get_options() preserve that request. Environment/profile defaults are resolved
at fit time, so adding a probe does not change precedence and constructing a
configuration does not freeze an environment-derived thread count. A positive
num_cpu is an explicit global hint; per-kernel hints keep their existing
precedence. Use runtime_report=True and inspect model.runtime_report_
(or the low-level result's RuntimeReport) for resolved settings and effective
native worker pools. Requested configuration alone is not a report of which
kernels ran or how many workers each used.
PCAOptions
dataclass
¶
PCAOptions(init: object = 'random', maxiters: int = 1000, bias: bool = True, max_dense_bytes: int | None = 2000000000, uniquesv: bool = False, auto_pattern_masked: bool = False, angle_every: int = 1, minangle: float = 1e-08, algorithm: Algorithm = Algorithm.VB, niter_broadprior: int = 100, hp_va: float = 0.001, hp_vb: float = 0.001, hp_v: float = 0.001, va_init: float = 1000.0, random_state: int | Generator | None = None, earlystop: bool = False, rmsstop: tuple[float, ...] | None = (100.0, 0.0001, 0.001), cfstop: tuple[float, ...] | None = (), cfstop_rel: float | None = None, cfstop_curv: float | None = None, record_cost: bool = False, cost_diagnostics: CostDiagnostics = CostDiagnostics.TRACE, record_prior_trace: bool = False, composite_stop: Mapping[str, float] | None = None, patience: int = 1, criterion_order: tuple[str, ...] | None = None, convergence_criteria: Mapping[str, bool] | None = None, verbose: int = 1, num_cpu: int | None = None, num_cpu_score_update: int | None = None, num_cpu_loadings_update: int | None = None, num_cpu_noise_update: int | None = None, num_cpu_rms: int | None = None, runtime_tuning: RuntimeTuning = RuntimeTuning.SAFE, runtime_profile: str | Path | None = None, dense_sufficient_statistics: StatisticsMode = StatisticsMode.AUTO, noise_sufficient_statistics: StatisticsMode = StatisticsMode.AUTO, masked_batch_size: int = 0, cov_writeback_mode: CovarianceWriteback | None = None, log_progress_stride: int | None = None, accessor_mode: AccessorMode | None = None, xprobe: ArrayLike | spmatrix | None = None, rotate2pca: bool = True, display: bool = False, bias_update_order: BiasUpdateOrder = BiasUpdateOrder.AUTO, variance_update_order: VarianceUpdateOrder = VarianceUpdateOrder.AUTO, compat_mode: CompatMode = CompatMode.STRICT_LEGACY, return_diagnostics: bool = True, runtime_report: bool = False, explained_var_solver: ExplainedVarianceSolver = ExplainedVarianceSolver.AUTO, explained_var_gram_ratio: float = 4.0)
Typed configuration accepted by pca_full(..., options=config).
Use :meth:from_kwargs to import legacy keyword dictionaries (including
case normalization and runtime defaults). Direct construction exposes typed
fields and snapshots stopping containers. Estimators store their original
constructor arguments and assemble this record at fit time. See the options
guide for the statistical and execution meaning of every field.
init is the localized dynamic MAT/struct boundary: it also accepts
third-party objects exposing _fieldnames; normalization and shape checks
run during fitting. Array shapes are runtime contracts, not type promises.
Examples:
>>> from vbpca_py import PCAOptions, VBPCA
>>> from vbpca_py.options import Algorithm, CompatMode
>>> flags = {"angle": False}
>>> options = PCAOptions(
... algorithm=Algorithm.VB,
... compat_mode=CompatMode.MODERN,
... convergence_criteria=flags,
... )
>>> flags["angle"] = True
>>> options.convergence_criteria["angle"]
False
>>> options.algorithm.value, options.compat_mode.value
('vb', 'modern')
>>> restored = PCAOptions.from_kwargs(**options.to_kwargs())
>>> restored.algorithm is Algorithm.VB
True
>>> VBPCA(1).get_config().compat_mode.value
'modern'
>>> PCAOptions().compat_mode.value
'strict_legacy'
from_kwargs
classmethod
¶
Resolve an existing keyword dictionary into typed configuration.
Returns:
| Type | Description |
|---|---|
PCAOptions
|
Validated immutable settings with the legacy defaults resolved. |
to_kwargs ¶
Export fresh policy containers for legacy low-level keyword callers.
Data, probe and initialization payloads retain their identities. Fitting owns their numerical working copies; exporting does not copy large data.
Returns:
| Type | Description |
|---|---|
dict[str, object]
|
A new canonical-name keyword mapping. Inherited threads remain None. |
Warm-start layouts¶
The low-level pca_full boundary uses features × samples. Let p be the
original feature count, n the original sample count and q the component
count. Initialization axes are explicit even when those dimensions coincide.
| Field | Accepted layout |
|---|---|
A |
(p, q) loadings |
S |
(q, n) scores |
Mu |
(p,), (p, 1) or (1, p) feature means; empty requests default initialization |
Muv |
(p,) or (p, 1) feature mean variances; empty requests the existing zero fallback |
Av |
(p, q) diagonal variances, (p, q, q) full blocks, or a list of p full blocks |
Sv |
(q, k) diagonal variances, (k, q, q) full blocks, or a list of k full blocks |
Isv |
Optional length-n sample-to-source-bank indices, zero-based; MAT row/column vectors and integral floating values are accepted |
V |
One noise-variance value, including a one-element MAT array |
Without Isv, k=n means per-sample score covariances. When target pattern
sharing is active, an explicitly target-sized bank can instead use those target
labels. Supplying Isv makes its source-bank mapping authoritative, including
when the bank count happens to equal the sample or component count. Nonintegral,
negative, out-of-range and incompatible indices fail clearly. Full covariance
blocks retain cross terms; a square two-dimensional table remains a diagonal
representation rather than being guessed to be a shared full covariance.
This zero-based contract also applies to MAT files and struct objects. Explicitly
subtract one from native MATLAB Isv values at the import boundary before using
them as a Python initialization. The loader does not infer index origin from
the labels or dimensions: an all-positive vector may be valid zero-based data.
Before fitting, mappings, supported struct objects and flat or single-struct
MAT files are normalized into an owned payload. Removing empty features slices
A, Av, Mu and Muv together. Removing samples slices S and per-sample
Sv, or slices Isv while retaining the source covariance bank. The caller's
arrays and mapping remain unchanged.
The solver's prepared missingness-pattern labels are separate from source
Isv. It first resolves source covariances per retained sample, then chooses
the first retained sample for each destination pattern. A round trip from fit
results must therefore retain Sv and Isv. Matching dimensions or loading
a payload does not establish that it is a valid posterior warm start for a
different dataset or model.
options ¶
String-compatible categorical options for solver configuration.
Ordinary strings remain accepted by the numerical solver. These enums provide
named values without changing the solver's numerical defaults. parse is
an explicit, strict conversion for configuration boundaries; legacy keyword
normalizers retain their documented fallback and whitespace behavior.
Initialization is a separate contract: init can also be a MAT filename or
a warm-start mapping, so it is not represented by a random/custom enum.
Examples:
>>> from vbpca_py.options import Algorithm, CompatMode
>>> Algorithm.parse(" VB ") is Algorithm.VB
True
>>> str(Algorithm.VB), Algorithm.VB == "vb"
('vb', True)
>>> import json
>>> json.dumps({"algorithm": Algorithm.VB})
'{"algorithm": "vb"}'
>>> CompatMode.parse("modern")
<CompatMode.MODERN: 'modern'>
>>> Algorithm.parse("approximate")
Traceback (most recent call last):
...
ValueError: Algorithm must be one of {'ppca', 'map', 'vb'} (got 'approximate').
Algorithm ¶
Bases: _StringOption
PPCA, maximum a posteriori PCA or full-covariance VB PCA.
CompatMode ¶
Bases: _StringOption
Historical versus modern numerical update and observation policies.
BiasUpdateOrder ¶
Bases: _StringOption
Requested mean-update order; auto resolves from compatibility mode.
VarianceUpdateOrder ¶
Bases: _StringOption
Requested prior-variance update order; auto resolves from compatibility.
CostDiagnostics ¶
Bases: _StringOption
Full objective trace or endpoint-only objective diagnostics.
StatisticsMode ¶
Bases: _StringOption
Requested sufficient-statistic accumulation, subject to eligibility.
ExplainedVarianceSolver ¶
Bases: _StringOption
Factor-based explained-variance decomposition strategy.
RuntimeTuning ¶
Bases: _StringOption
Automatic execution-policy tuning, without changing statistical settings.
CovarianceWriteback ¶
Bases: _StringOption
Covariance return/writeback path; bulk and kernel currently share code.
AccessorMode ¶
Bases: _StringOption
Observation access strategy for sparse and masked updates.
Criterion ¶
Bases: _StringOption
Accepted stopping-rule names, including unavailable legacy slowing-down.
Naming a criterion does not enable or qualify it. The live fitter keeps
slowing_down disabled because it has no event counter.