qlinks.basis package#
Subpackages#
Submodules#
qlinks.basis.basis module#
- qlinks.basis.basis.full_basis_from_layout(layout, *, sort=True, max_states=None)[source]#
Generate the full Cartesian-product basis for an unconstrained layout.
This is faster and simpler than DFS when there are no constraints/sectors.
The output states have shape:
(prod_i dim_i, layout.n_variables)
where dim_i is the local-space dimension of variable i.
- class qlinks.basis.basis.Basis(layout, states, encoder, index)[source]#
Bases:
objectComputational basis represented by explicit configurations.
- states:
Integer array of shape (n_states, n_variables).
- index:
Map encoded configuration -> basis index.
- layout: VariableLayout#
- encoder: ConfigEncoder#
- __init__(layout, states, encoder, index)#
qlinks.basis.configs module#
- qlinks.basis.configs.basis_configs_from_basis(basis)[source]#
Return explicit basis configurations for ArrayBasis or BinaryEncodedBasis.
Sparse/array builders usually expose this as
basis.states. Bitmask builders may use BinaryEncodedBasis, which stores compact integer codes and exposesto_array_basis().
- qlinks.basis.configs.basis_configs_from_build_result(build_result)[source]#
Return physical basis configurations from a ModelBuildResult.
Bitmask builders may store basis states as local integer codes, e.g. 0/1 for a two-state local space. The classifier and visualizers need the physical variable values declared by build_result.layout, e.g. -1/+1.
- qlinks.basis.configs.decode_basis_configs_with_layout(basis_configs, layout)[source]#
Decode local integer codes into physical values using a VariableLayout.
If the configs already contain valid physical values, they are returned unchanged. Otherwise, values 0, 1, …, d-1 are interpreted as indices into each variable’s local space.
qlinks.basis.sectors module#
Module contents#
- class qlinks.basis.Basis(layout, states, encoder, index)[source]#
Bases:
objectComputational basis represented by explicit configurations.
- states:
Integer array of shape (n_states, n_variables).
- index:
Map encoded configuration -> basis index.
- layout: VariableLayout#
- encoder: ConfigEncoder#
- __init__(layout, states, encoder, index)#
- class qlinks.basis.BasisSolver(*args, **kwargs)[source]#
Bases:
ProtocolProtocol implemented by constrained-basis solvers.
Solvers enumerate configurations from a
VariableLayoutsubject to constraints and sector filters, then return aBasis.- __init__(*args, **kwargs)#
- class qlinks.basis.BruteForceBasisSolver(sort=False)[source]#
Bases:
objectExhaustive product-space basis solver.
This is simple and useful for tests, but it scales as
prod_i dim(local_space_i)
so it should only be used for small systems.
- __init__(sort=False)#
- class qlinks.basis.CPSATBasisSolver(max_solutions=None, num_workers=1, log_search_progress=False, sort=False)[source]#
Bases:
objectOR-Tools CP-SAT basis solver.
This solver is useful when the constraints are naturally integer/Boolean constraints. It currently supports:
FixedValueConstraint LocalSumConstraint GaussLawConstraint DimerCoveringConstraint NearestNeighborBlockadeConstraint TotalValueSector ParitySector SquareWindingSector
Unsupported custom constraints raise NotImplementedError.
OR-Tools is imported lazily so qlinks can still be installed without it.
- __init__(max_solutions=None, num_workers=1, log_search_progress=False, sort=False)#
- class qlinks.basis.DFSBasisSolver(sort=True, variable_order=None, variable_order_strategy='auto', value_order_strategy='layout')[source]#
Bases:
objectDepth-first constrained-basis enumerator.
The solver incrementally assigns variables, runs partial checks and propagators, and optionally notifies search observers. It is the default basis solver for model builds because it supports early stopping, dynamic ordering, propagation, and model-specific observer hooks.
- variable_order#
Optional explicit variable order.
- Type:
collections.abc.Buffer | numpy._typing._array_like._SupportsArray[numpy.dtype[Any]] | numpy._typing._nested_sequence._NestedSequence[numpy._typing._array_like._SupportsArray[numpy.dtype[Any]]] | complex | bytes | str | numpy._typing._nested_sequence._NestedSequence[complex | bytes | str] | None
- variable_order_strategy#
Heuristic used when
variable_orderis not supplied.- Type:
Literal[‘auto’, ‘layout’, ‘degree’, ‘weighted_degree’, ‘constraint_closure’, ‘dynamic’]
- value_order_strategy#
Heuristic used to order trial local values.
- Type:
Literal[‘layout’, ‘propagation’]
- variable_order: Buffer | _SupportsArray[dtype[Any]] | _NestedSequence[_SupportsArray[dtype[Any]]] | complex | bytes | str | _NestedSequence[complex | bytes | str] | None#
- variable_order_strategy: Literal['auto', 'layout', 'degree', 'weighted_degree', 'constraint_closure', 'dynamic']#
- solve_with_statistics(layout, constraints=(), sectors=(), *, max_states=None, observers=())[source]#
Solve and return lightweight DFS execution statistics.
- __init__(sort=True, variable_order=None, variable_order_strategy='auto', value_order_strategy='layout')#
- class qlinks.basis.DFSSearchObserver(*args, **kwargs)[source]#
Bases:
ProtocolRead-only branch/solution observer for
DFSBasisSolver.Observers are intended for search-specific pruning that is not naturally a model constraint. They may inspect the mutable DFS arrays but must not mutate them. Returning
Falsefromcan_continueprunes the current partial branch; returningFalsefromaccept_solutionfilters the complete configuration.Stateful observers may additionally implement any of these optional methods, which DFSBasisSolver discovers with
getattrso existing read-only observers remain valid:reset(config, assigned_mask) on_assignments(config, assigned_mask, changed_variables) on_unassignments(config, assigned_mask, changed_variables) on_assign(config, assigned_mask, variable_index, value, forced_assignment) on_unassign(config, assigned_mask, variable_index, value)
Assignment callbacks run after the DFS arrays have been updated; unassign callbacks run just before
assigned_mask[variable_index]is cleared. Batched callbacks are preferred for observers that maintain incremental state over many variables.- __init__(*args, **kwargs)#
- class qlinks.basis.DFSStatistics(branch_count=0, solution_count=0, contradiction_count=0, propagated_assignment_count=0, skipped_forced_variable_count=0, partial_check_count=0, propagation_round_count=0, propagator_call_count=0, dynamic_variable_selection_count=0, dynamic_value_ordering_count=0, observer_call_count=0, observer_update_count=0, observer_prune_count=0, observer_solution_reject_count=0, max_depth=0)[source]#
Bases:
objectExecution counters for
DFSBasisSolver.The counters are intentionally lightweight and solver-centric. They are meant for comparing pruning/order heuristics, not for proving exact search tree identities across implementation changes.
- __init__(branch_count=0, solution_count=0, contradiction_count=0, propagated_assignment_count=0, skipped_forced_variable_count=0, partial_check_count=0, propagation_round_count=0, propagator_call_count=0, dynamic_variable_selection_count=0, dynamic_value_ordering_count=0, observer_call_count=0, observer_update_count=0, observer_prune_count=0, observer_solution_reject_count=0, max_depth=0)#
- class qlinks.basis.SolverInput(layout, constraints, sectors)[source]#
Bases:
objectImmutable bundle of inputs shared by basis solvers.
- layout#
Variable layout defining local spaces.
- constraints#
Constraints all states must satisfy.
- Type:
- sectors#
Sector filters all states must satisfy.
- Type:
- layout: VariableLayout#
- constraints: tuple[Constraint, ...]#
- sectors: tuple[SectorCondition, ...]#
- __init__(layout, constraints, sectors)#
- qlinks.basis.basis_configs_from_basis(basis)[source]#
Return explicit basis configurations for ArrayBasis or BinaryEncodedBasis.
Sparse/array builders usually expose this as
basis.states. Bitmask builders may use BinaryEncodedBasis, which stores compact integer codes and exposesto_array_basis().
- qlinks.basis.basis_configs_from_build_result(build_result)[source]#
Return physical basis configurations from a ModelBuildResult.
Bitmask builders may store basis states as local integer codes, e.g. 0/1 for a two-state local space. The classifier and visualizers need the physical variable values declared by build_result.layout, e.g. -1/+1.
- qlinks.basis.decode_basis_configs_with_layout(basis_configs, layout)[source]#
Decode local integer codes into physical values using a VariableLayout.
If the configs already contain valid physical values, they are returned unchanged. Otherwise, values 0, 1, …, d-1 are interpreted as indices into each variable’s local space.
- qlinks.basis.full_basis_from_layout(layout, *, sort=True, max_states=None)[source]#
Generate the full Cartesian-product basis for an unconstrained layout.
This is faster and simpler than DFS when there are no constraints/sectors.
The output states have shape:
(prod_i dim_i, layout.n_variables)
where dim_i is the local-space dimension of variable i.