Skip to content

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

Bases: HardConstraint

Hard equality restriction in the chosen measurement space.

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

Bases: HardConstraint

Hard interval restriction in the chosen measurement space.

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

Bases: ScalarMismatch

Quadratic mismatch penalty: (predicted - target)^2.

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 (n, d) where d is currently supported for planar (2D) and spatial (3D) workflows.

required
constraints ConstraintInput

Raw constraint tuples (i, j, value[, shift]).

required
measurement Literal['fraction', 'position']

Whether value is interpreted as a normalized fraction in [0, 1] or as an absolute position along the connector.

'fraction'
domain DomainAny | None

Optional non-periodic or periodic domain.

None
ids Sequence[int] | None

External ids used when index_mode='id'.

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.

:::