Advanced separator fitting
pyvoro2.inverse.separator owns the separator implementation and exposes the
canonical core names alongside advanced model, problem, realization, report,
and diagnostic objects.
The fixed-observation fit is distinct from realization-aware active-set refinement. The active-set API is experimental and separator-specific; it is a practical outer algorithm without a universal convergence guarantee.
Most advanced model, problem, operator, report, realization, and layered-view objects on this page are provisional. Active-set refinement is experimental. The optional explicit sparse quadratic backend is provisional and is limited to the static squared-loss branch documented below.
Historical names remain identity aliases during v0.7 and will be removed in v0.8. New code should use the canonical five-name map documented in the compatibility reference.
Layered result access
The provisional view types below organize existing result data without adding fields to the established result dataclasses or copying their arrays.
| Owning result | Access | View or reused object |
|---|---|---|
SeparatorFitResult |
.state |
SeparatorFitStateView |
SeparatorFitResult |
.identification |
SeparatorIdentificationView |
SeparatorFitResult |
.observation_view(observations) |
SeparatorObservationView |
SeparatorFitResult |
.objective |
existing PowerFitObjectiveBreakdown or None |
SeparatorFitResult |
.algebraic |
SeparatorAlgebraicView containing existing edge and connectivity diagnostics |
SeparatorFitResult |
.solver_termination |
SeparatorSolverTerminationView |
RealizedPairDiagnostics |
.requested_image_matching |
RequestedImageMatchView |
RealizedPairDiagnostics |
.geometry |
RealizedGeometryView |
SelfConsistentPowerFitResult |
.inner_fit, .final_realization, .candidate_diagnostics |
existing final objects |
SelfConsistentPowerFitResult |
.outer_termination, .path |
ActiveSetTerminationView, ActiveSetPathView |
observation_view(...) accepts the originating resolved observations or a
fully equivalent independently resolved set. It checks pair indices,
confidence, targets, requested shifts, and resolved geometry before combining
observation-owned arrays with fit-owned predictions. The private binding is
retained by shallow copies, deep copies, pickle round trips, and
dataclasses.replace(...). Directly constructed results without source
observations fail closed when this accessor is called.
inspect.signature(SeparatorFitResult) consequently includes the private
optional keyword-only parameter _originating_observations_init=None; it is an
init-only reconstruction channel, not a public result field or user input.
SeparatorIdentificationView.unconstrained_sites contains sites isolated in
the informative observation graph, which contains only positive-confidence
separator rows. Zero-confidence rows remain excluded even when hard
restrictions or penalties affect them: those terms may constrain or bound
component offsets, but they are not observational identification. Positive L2
regularization is the only currently supported additional objective reported as
guaranteed to select otherwise free component offsets. The compatibility
diagnostic ConnectivityDiagnostics.unconstrained_points retains its
established candidate-graph meaning.
The historical SeparatorFitProblem.offset_identifying_constraint_mask name
is preserved for compatibility. That mask includes rows touched by hard
restrictions or penalties because the numerical solver must keep coupled
variables in one subproblem; it does not define the informative observation
graph or claim unique offset selection. Exact hard equalities may fix offsets,
but the current identification view does not provide a general
constraint-identifiability classification.
global_representation_shift is a backend representation choice made by adding
one common constant, so it selects a representative within the global geometric
gauge. It is distinct from independent offsets between disconnected observation
components and is not inferred from observations.
component_alignment_policy is the canonical access to the policy string also
stored under the historical compatibility name ConnectivityDiagnostics.gauge_policy.
Problem-owned graph and quadratic views
SeparatorFitProblem owns two additional provisional inspection views. They do
not change its dataclass fields or bind the problem into a fit result.
| Problem access | Public view | Main contents |
|---|---|---|
.observation_graph |
SeparatorObservationGraphView |
n_sites, n_observations, site_i, site_j, observation_indices, requested_shifts, alpha, beta, z_obs, rho, informative_mask, components/connectivity, and incidence conversion |
.quadratic_operator |
SeparatorQuadraticOperatorView |
observation_rhs, regularized_normal_rhs, regularization/reference, hard-constraint metadata, matrix-free products, dense/optional-sparse matrices, and nullity/gauge metadata |
For m observation rows and n sites, graph.incidence_dense() returns
B.shape == (n, m). Column r is +1 at site_i[r] and -1 at
site_j[r], so B.T @ weights gives the oriented fitted differences. The
column order is the resolved observation row order;
graph.observation_indices retains the originating input indices. Repeated
rows and rows for different periodic images are never collapsed.
The informative mask is true only for positive-confidence separator rows.
Zero-confidence rows remain in every row array and in B, but have rho == 0,
contribute nothing to the operators or right-hand sides, and do not connect
informative components. Isolated sites are therefore singleton informative
components.
The explicit operator names distinguish
L_obs = B @ diag(rho) @ B.T
b_obs = B @ (rho * z_obs)
A = L_obs + regularization_strength * I
b = b_obs + regularization_strength * regularization_reference
Use observation_laplacian_matvec(...) and
regularized_normal_matvec(...) for matrix-free application,
observation_laplacian_dense() and
regularized_normal_matrix_dense() for NumPy matrices, and the corresponding
*_sparse(format=...) methods for optional SciPy conversion. SciPy is imported
lazily; requesting sparse conversion without it raises an actionable
ImportError. Matrix conversion alone does not select a solver.
The primary fixed quadratic fit additionally accepts solver='sparse' for an
optional SciPy sparse-direct solve. solver='auto' and solver='analytic'
retain the dense NumPy quadratic path; v0.7 does not choose a sparse backend
automatically. SeparatorFitResult.solver and
SeparatorFitResult.solver_termination.backend report the path actually
selected. Sparse execution is limited to unconstrained SquaredLoss with
optional L2 regularization and no scalar penalties. It is not exposed through
the experimental active-set outer solver or other inverse branches.
match_realized_pairs(...) accepts exactly one of mathematical weights= or
backend-compatible radii=. The weight-first route is preferred and uses the
same global representation conversion as forward compute(...); the selected
shift is not a scientific inverse result. Existing radius-based calls remain
compatible.
quadratic_operator is available only for SquaredLoss with no scalar
penalties. Optional L2 regularization is represented exactly. Hard interval or
equality restrictions may coexist, but remain in problem.bounds; when they
are present, normal_equations_characterize_fit is false because a constrained
optimum need not satisfy the unconstrained equation. Huber mismatch and models
with scalar penalties retain observation_graph but reject
quadratic_operator.
pyvoro2.inverse.separator
Separator-specific inverse fitting, diagnostics, and advanced workflows.
The fixed-observation solver is exact for its selected convex model. The realization-aware active-set workflow is a separate experimental outer algorithm and does not carry a universal convergence guarantee.
ActiveSetPathSummary
dataclass
Compact summary of transient active-set path diagnostics.
ActiveSetPathView
dataclass
Final active state and optional outer-loop path diagnostics.
ActiveSetTerminationView
dataclass
Termination state of the experimental active-set outer loop.
AlgebraicEdgeDiagnostics
dataclass
Edge-space diagnostics matching the paper-side algebraic formulas.
ConnectivityDiagnostics
dataclass
Structured connectivity diagnostics for the inverse-fit graph.
effective_graph and active_effective_graph are the informative
observation graphs induced only by positive-confidence rows. The
historical unconstrained_points field remains candidate-graph based.
offsets_identified_in_objective conservatively reports complete
relative-offset determination by informative data or positive L2
regularization; arbitrary penalties and hard restrictions do not set it.
ConnectivityDiagnosticsError
Bases: ValueError
Raised when connectivity_check='raise' detects a graph issue.
ConstraintGraphDiagnostics
dataclass
Connectivity summary for a graph induced by constraint rows.
ExponentialBoundaryPenalty
dataclass
Bases: ScalarPenalty
Repulsive penalty near the boundaries of an interval.
The penalty is based on exponentials measured from an inner interval
[lower + margin, upper - margin].
FitModel
dataclass
Complete objective definition for inverse power-weight fitting.
The objective consists of
- one required mismatch term,
- an optional hard feasibility set,
- zero or more extra penalties,
- optional L2 regularization on the weights.
FixedValue
dataclass
HardConstraintConflict
dataclass
Compact witness for inconsistent hard separator restrictions.
HardConstraintConflictTerm
dataclass
One bound relation participating in an infeasibility witness.
HuberLoss
dataclass
Bases: ScalarMismatch
Huber mismatch penalty in the chosen measurement space.
The penalty is quadratic near zero and linear for large residuals.
Interval
dataclass
L2Regularization
dataclass
Optional L2 regularization on the weight vector.
PairConstraintDiagnostics
dataclass
to_records(*, ids=None)
Return one plain-Python record per candidate pair.
RealizedGeometryView
dataclass
Optional realized geometry and tessellation-wide diagnostics.
RealizedPairDiagnostics
dataclass
Diagnostics for matching candidate constraints to realized boundaries.
geometry
property
Return optional boundary/cell geometry and tessellation diagnostics.
requested_image_matching
property
Return requested-pair and periodic-image matching diagnostics.
to_records(constraints, *, use_ids=False)
Return one plain-Python record per candidate pair.
to_report(constraints, *, use_ids=False)
Return a JSON-friendly report for realized-boundary matching.
unaccounted_records(*, ids=None)
Return one record per realized-but-unaccounted unordered pair.
ReciprocalBoundaryPenalty
dataclass
Bases: ScalarPenalty
Reciprocal repulsion near interval boundaries.
This penalty is intended to be used together with a hard interval or a
strong outside penalty. It penalizes separator positions that enter the
boundary layers [lower, lower + margin] and [upper - margin, upper].
RequestedImageMatchView
dataclass
Requested-pair and periodic-image matching results.
Arrays are shared with the owning :class:RealizedPairDiagnostics.
SelfConsistentPowerFitResult
dataclass
candidate_diagnostics
property
Return final diagnostics over every candidate observation.
final_realization
property
Return realization diagnostics for the final fitted state.
inner_fit
property
Return the final fixed-observation inner fit.
outer_termination
property
Return termination metadata for the experimental outer loop.
path
property
Return the final active state and optional path history.
to_records(*, use_ids=False)
Return one plain-Python record per candidate pair.
to_report(*, use_ids=False)
Return a JSON-friendly report for this active-set solve.
SeparatorAlgebraicView
dataclass
Existing difference-space and connectivity diagnostics.
Public incidence, Laplacian, and normal-operator representations are deliberately not part of this view.
SeparatorFitProblem
dataclass
Resolved fixed-observation separator fit problem.
offset_identifying_constraint_mask is the historical public name for
the row mask used to decompose the numerical problem. It includes rows
touched by hard restrictions or penalties because those terms can couple
solver variables. The mask does not claim that those rows identify
offsets from separator data or select them uniquely.
observation_graph
property
Return the oriented observation multigraph and its row data.
Every resolved observation remains a distinct incidence column. The view shares the problem's established read-only arrays; only the derived positive-confidence mask is newly allocated.
quadratic_operator
property
Return the exact fixed least-squares normal operator.
This view is intentionally limited to SquaredLoss models without
scalar penalties. Hard restrictions may coexist, but they remain in
bounds and are not folded into the unconstrained normal equation.
canonicalize_gauge(weights)
Apply the standalone component gauge convention to candidate weights.
SeparatorFitResult
dataclass
Bases: _ObservationBoundResult
Result of fitting power weights from separator observations.
algebraic
property
Return difference-space and connectivity diagnostics.
identification
property
Return data-identification and component-alignment metadata.
objective
property
Return the existing objective-contribution breakdown, if available.
solver_termination
property
Return termination metadata for the fixed-observation solver.
state
property
Return fitted weights and their backend-radius representation.
observation_view(observations)
Return diagnostics for the observations that produced this result.
Solver and problem-builder results retain a private reference to their resolved source observations. The supplied object may be that source or an independently resolved, fully equivalent observation set. The returned view shares arrays and does not copy them.
SeparatorFitStateView
dataclass
Fitted mathematical state and its backend representation.
global_representation_shift is the one common additive shift used to
convert mathematical_weights to non-negative backend_radii. It
selects a backend representation within the global geometric gauge; it is
distinct from component offsets and is not recovered from the separator
observations.
SeparatorIdentificationView
dataclass
Identification and component-alignment meaning of a separator fit.
The informative observation graph contains positive-confidence separator
rows only. relative_component_offsets_identified_by_data is true
exactly when that graph is connected. Hard restrictions and scalar
penalties may constrain offsets but are not separator-observation data.
component_offsets_selected_by_objective is conservative: it is true
only when otherwise free informative-component offsets are guaranteed to
be selected by a supported additional objective, currently positive L2
regularization. Exact hard equalities are not summarized by this view.
SeparatorObservationGraphView
dataclass
Oriented multigraph and row data of a separator-fit problem.
Obtain this provisional view from
:attr:SeparatorFitProblem.observation_graph. Each observation is one
distinct edge column, including zero-confidence rows, repeated rows, and
different periodic images of the same site pair. The incidence column is
+1 at site_i and -1 at site_j.
Array fields share the read-only arrays owned by the problem or its
resolved observations, except for the derived read-only
informative_mask.
effective_edge_weights
property
Alias for rho = confidence * alpha**2.
global_geometric_gauge_identified_by_data
property
Always false for separator observations of weight differences.
implied_difference_targets
property
Alias for the implied targets z_obs.
informative_components
property
Informative connected components, including isolated sites.
informative_graph
property
Connectivity induced only by positive-confidence rows.
isolated_sites
property
Sites isolated in the informative observation graph.
n_observations
property
Number of observation rows and incidence columns.
relative_component_offsets_identified_by_data
property
Whether informative data connect all sites into one component.
incidence_dense()
Return the oriented incidence matrix as a dense NumPy array.
The result has shape (n_sites, n_observations). Column r is
+1 at site_i[r] and -1 at site_j[r], so
B.T @ weights == weights[site_i] - weights[site_j].
incidence_sparse(*, format='csr')
Return the incidence matrix in a requested SciPy sparse format.
SciPy is imported lazily and remains optional. The sparse storage format is a conversion choice, not part of the mathematical contract.
SeparatorObservationView
dataclass
Observation-space targets, predictions, residuals, and confidence.
Arrays are references to the fit result or supplied resolved observations; constructing the view does not copy them.
SeparatorObservations
dataclass
Resolved pairwise separator observations.
This object is the public boundary between downstream pair-selection logic
and pyvoro2's inverse solver. Each row refers to a specific ordered pair
(i, j, shift) where shift is the lattice image applied to site j.
pair_labels(*, use_ids=False)
Return the left/right pair labels as indices or external ids.
subset(mask)
Return a subset with row order preserved.
to_records(*, use_ids=False)
Return one plain-Python record per constraint row.
SeparatorQuadraticOperatorView
dataclass
Least-squares normal operator for a quadratic separator problem.
Obtain this provisional view from
:attr:SeparatorFitProblem.quadratic_operator. It is available only for
SquaredLoss with no scalar penalties. Hard restrictions may still be
present; in that case the matrices describe the quadratic objective while
SeparatorFitProblem.bounds separately defines feasibility, and the
unconstrained normal equation need not hold at a constrained optimum.
component_alignment_policy
property
Policy used by the current solver for free component offsets.
normal_equations_characterize_fit
property
Whether an unconstrained solver result must satisfy A @ w == b.
observation_nullity
property
Nullity of the observation Laplacian.
regularization_removes_observation_nullspace
property
Whether positive L2 regularization removes Laplacian null modes.
regularized_normal_nullity
property
Nullity after adding the configured L2 regularization.
relative_component_offsets_identified_by_data
property
Whether separator data connect every site component.
represents_full_quadratic_objective
property
Whether this view represents every smooth objective term.
observation_laplacian_dense()
Return L_obs as a dense NumPy array.
observation_laplacian_matvec(vector)
Apply L_obs = B @ diag(rho) @ B.T without forming a matrix.
observation_laplacian_sparse(*, format='csr')
Return L_obs in a requested optional SciPy sparse format.
regularized_normal_matrix_dense()
Return A = L_obs + regularization_strength * I as NumPy.
regularized_normal_matrix_sparse(*, format='csr')
Return A in a requested optional SciPy sparse format.
regularized_normal_matvec(vector)
Apply A = L_obs + regularization_strength * I.
SeparatorSolverTerminationView
dataclass
Termination state of the fixed-observation separator solver.
SoftIntervalPenalty
dataclass
Bases: ScalarPenalty
Quadratic penalty for leaving a preferred interval.
The penalty is zero within [lower, upper] and quadratic outside.
SquaredLoss
dataclass
UnaccountedRealizedPair
dataclass
One realized internal boundary whose unordered pair was not supplied.
to_record(*, ids=None)
Return a plain-Python record for the unaccounted pair.
UnaccountedRealizedPairError
Bases: ValueError
Raised when unaccounted_pair_check='raise' finds absent pairs.
build_active_set_report(result, *, use_ids=False)
Return a JSON-friendly report for a self-consistent active-set result.
build_fit_report(result, constraints, *, use_ids=False)
Return a JSON-friendly report for a low-level fit result.
build_power_fit_problem(constraints, *, model=None)
Build a public separator-fit problem from resolved observations.
build_power_fit_result(problem, weights, *, solver='external', status='optimal', status_detail=None, converged=True, n_iter=0, warnings=(), canonicalize_gauge=True, r_min=0.0, weight_shift=None)
Package candidate weights into a standard power-fit result object.
build_realized_report(diagnostics, constraints, *, use_ids=False)
Return a JSON-friendly report for realized-face matching.
dumps_report_json(report, *, indent=2, sort_keys=False)
Serialize a powerfit report into a JSON string.
fit_weights_from_separators(points, constraints, *, measurement='fraction', domain=None, ids=None, index_mode='index', image='nearest', image_search=1, confidence=None, model=None, r_min=0.0, weight_shift=None, solver='auto', max_iter=2000, rho=1.0, tol_abs=1e-06, tol_rel=1e-05, connectivity_check='warn')
Fit power weights from resolved pairwise separator observations.
solver='auto' keeps the dense analytic quadratic default and selects
ADMM only when the model requires it. solver='sparse' explicitly uses
optional SciPy sparse-direct solving for unconstrained squared loss with
optional L2 regularization.
match_realized_pairs(points, *, domain, constraints, weights=None, radii=None, return_boundary_measure=False, return_cells=False, return_tessellation_diagnostics=False, tessellation_check='diagnose', unaccounted_pair_check='diagnose')
Determine which resolved pair constraints correspond to realized boundaries.
The matching is purely geometric: each requested ordered pair (i, j, shift)
is checked against the set of realized cell boundaries in the power
tessellation, including explicit periodic image shifts. Supply exactly one
of mathematical weights (preferred) or backend-compatible radii.
radii_to_weights(radii)
Convert radii to finite power weights (w = r^2).
Raises ValueError when the input or its squared result is non-finite.
resolve_separator_observations(points, constraints, *, measurement='fraction', domain=None, ids=None, index_mode='index', image='nearest', image_search=1, confidence=None, allow_empty=False)
Parse and resolve pairwise separator observations.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
points
|
ndarray
|
Site coordinates with shape |
required |
constraints
|
ConstraintInput
|
Raw constraint tuples |
required |
measurement
|
Literal['fraction', 'position']
|
Whether |
'fraction'
|
domain
|
DomainAny | None
|
Optional non-periodic or periodic domain. |
None
|
ids
|
Sequence[int] | None
|
External ids used when |
None
|
index_mode
|
Literal['index', 'id']
|
Interpret the first two tuple entries as internal indices or external ids. |
'index'
|
image
|
Literal['nearest', 'given_only']
|
Shift resolution policy for tuples that do not specify a shift. |
'nearest'
|
image_search
|
int
|
Search radius for nearest-image resolution in triclinic periodic 3D cells. It is ignored for the current planar backend. |
1
|
confidence
|
Sequence[float] | None
|
Optional non-negative per-constraint weights. |
None
|
allow_empty
|
bool
|
Allow zero constraints and return an empty resolved object. |
False
|
solve_self_consistent_power_weights(points, constraints, *, measurement='fraction', domain, ids=None, index_mode='index', image='nearest', image_search=1, confidence=None, model=None, active0=None, options=None, r_min=0.0, weight_shift=None, fit_solver='auto', fit_max_iter=2000, fit_rho=1.0, fit_tol_abs=1e-06, fit_tol_rel=1e-05, return_history=False, return_cells=False, return_boundary_measure=False, return_tessellation_diagnostics=False, tessellation_check='diagnose', connectivity_check='warn', unaccounted_pair_check='warn')
Iteratively refine an active pair set against realized power-diagram boundaries.
weights_to_radii(weights, *, r_min=0.0, weight_shift=None)
Convert power weights to finite radii using one global shift.
Raises ValueError when an input, intermediate value, or result is
non-finite.
write_report_json(report, path, *, indent=2, sort_keys=False)
Write a powerfit report to a JSON file.
:::