API reference¶
Everything below is importable from sdpb_python.
Problems¶
- class sdpb_python.PMP(objective, normalization=None, matrices=<factory>)[source]¶
Bases:
objectA polynomial matrix program (SDPB manual eq. 3.1):
maximize
a . zoverzinR^{N+1}such thatn . z = 1and, for every matrixj,sum_i z_i M^j_i(x)is positive semidefinite for allx >= 0.objectiveisa_0..a_N;normalizationisn_0..n_N(Nonemeans(1, 0, ..., 0), i.e.z_0 = 1andy = z_1..z_N); each matrix holdsN+1polynomials per entry.- Parameters:
- matrices: Sequence[PolynomialMatrix]¶
- to_sdp(precision=None, max_num_poles=None)[source]¶
Convert to SDP data, as
pmp2sdp --precisionwould.
- solver(options=None, *, max_num_poles=None, **overrides)[source]¶
A
Solverholding this problem’s state.- Parameters:
options (SolverOptions | None)
max_num_poles (int | None)
overrides (Any)
- solve(options=None, *, max_num_poles=None, **overrides)[source]¶
Solve with SDPB. Keyword arguments override
SolverOptionsfields.- Parameters:
options (SolverOptions | None)
max_num_poles (int | None)
overrides (Any)
- Return type:
- class sdpb_python.PolynomialMatrix(polynomials, prefactor=None, reduced_prefactor=None, max_num_poles=None, sample_points=None, sample_scalings=None, reduced_sample_scalings=None, bilinear_basis=None, label='')[source]¶
Bases:
objectOne positivity constraint:
sum_n z_n P^{rs}_n(x)is PSD forx >= 0.polynomials[r][s]is the list ofN+1polynomialsP^{rs}_0..P^{rs}_N(each aPolynomialor a coefficient list); the matrix must be symmetric. The optional fields mirror the keys ofpmp.json; anything omitted is computed by SDPB (seesampled()).- Variables:
polynomials (Sequence[Sequence[Sequence[Any]]]) –
dim x dimnested lists ofN+1polynomials each.prefactor (sdpb_python.problem.DampedRational | None) –
DampedRational; defaultexp(-x).reduced_prefactor (sdpb_python.problem.DampedRational | None) – Prefactor with fewer poles used for sampling; default derived from
prefactorandmax_num_poles.max_num_poles (int | None) – Keep at most this many poles of the prefactor when sampling (negative: no limit).
sample_points (Sequence[Any] | None) – Explicit sample points
x_k >= 0.sample_scalings (Sequence[Any] | None) – Explicit
prefactor(x_k).reduced_sample_scalings (Sequence[Any] | None) – Explicit
reduced_prefactor(x_k).bilinear_basis (tuple[Sequence[Any], Sequence[Any]] | None) – Explicit
(even, odd)lists of basis polynomials.label (str) – Free text, e.g. the source file; not used by the solver.
- Parameters:
prefactor (DampedRational | None)
reduced_prefactor (DampedRational | None)
max_num_poles (int | None)
label (str)
- prefactor: DampedRational | None = None¶
- reduced_prefactor: DampedRational | None = None¶
- class sdpb_python.Polynomial(coeffs=(0,))[source]¶
Bases:
objecta_0 + a_1 x + ... + a_n x^ngiven bycoeffs = [a_0, ..., a_n].
- class sdpb_python.DampedRational(constant=1, base=1, poles=())[source]¶
Bases:
objectA damped rational prefactor
constant * base**x / prod_i (x - poles[i]).Multiplying a polynomial matrix by a positive prefactor does not change the positivity constraint, but it tells SDPB where to place the sample points and how to scale them. SDPB’s default is
exp(-x);exp_minus_x()builds it (with optional poles) at full precision.
- class sdpb_python.LMI(b, blocks, f=0)[source]¶
Bases:
objectBlock-diagonal linear matrix inequality:
maximize
f + b . yoveryinR^Nsuch thatM_0 + sum_n y_n M_nis positive semidefinite, block by block.blocks[j]is the sequence(M_0, M_1, ..., M_N)of symmetric matrices for blockj(nested lists, numpy arrays ormpmath.matrix). To minimise, negatebandf. Internally this is a PMP whose polynomials are constants, so every block has a single sample point.- solver(options=None, **overrides)[source]¶
A
Solverholding this problem’s state.- Parameters:
options (SolverOptions | None)
overrides (Any)
- solve(options=None, **overrides)[source]¶
- Parameters:
options (SolverOptions | None)
overrides (Any)
- Return type:
- class sdpb_python.SampledMatrix(prefactor, reduced_prefactor, sample_points, sample_scalings, reduced_sample_scalings, bilinear_basis, bilinear_bases)[source]¶
Bases:
objectSampling data SDPB derived for one
PolynomialMatrix.- Variables:
prefactor (sdpb_python.problem.DampedRational) – The prefactor actually used (default
exp(-x)).reduced_prefactor (sdpb_python.problem.DampedRational) – The prefactor after
max_num_polestrimming.sample_points (list[mpmath.ctx_mp_python.mpf]) – The
num_pointspointsx_k >= 0.sample_scalings (list[mpmath.ctx_mp_python.mpf]) –
prefactor(x_k).reduced_sample_scalings (list[mpmath.ctx_mp_python.mpf]) –
reduced_prefactor(x_k).bilinear_basis (tuple[list[sdpb_python.problem.Polynomial], list[sdpb_python.problem.Polynomial]]) – Even and odd orthogonal polynomials
q_m(x).bilinear_bases (tuple[mpmath.matrices.matrices.matrix, mpmath.matrices.matrices.matrix]) – The bases sampled at the points (as stored in
block_datafiles): even and odd matrices.
- Parameters:
prefactor (DampedRational)
reduced_prefactor (DampedRational)
sample_points (list[mpf])
sample_scalings (list[mpf])
reduced_sample_scalings (list[mpf])
bilinear_basis (tuple[list[Polynomial], list[Polynomial]])
bilinear_bases (tuple[matrix, matrix])
- prefactor: DampedRational¶
- reduced_prefactor: DampedRational¶
- bilinear_basis: tuple[list[Polynomial], list[Polynomial]]¶
- class sdpb_python.SDPData(objective_const, b, normalization, blocks, precision)[source]¶
Bases:
objectWhat
pmp2sdpwrites to ansdp/directory (Manual eq. 2.2).The normalization of the PMP has been eliminated:
objective_constisb_0andbisb_1..b_N.- Variables:
objective_const (mpmath.ctx_mp_python.mpf) – The constant term
b_0.b (list[mpmath.ctx_mp_python.mpf]) – The dual objective vector.
normalization (list[mpmath.ctx_mp_python.mpf] | None) – The PMP’s normalization, kept for recovering
z.blocks (list[sdpb_python.problem.SDPBlock]) – One
SDPBlockper constraint.precision (int) – Bits used for the conversion.
- Parameters:
- objective_const: mpf¶
- class sdpb_python.problem.SDPBlock(block_index, dim, num_points, bilinear_bases, c, B)[source]¶
Bases:
objectOne block of an
SDPData(the content ofblock_data_<j>).- Variables:
block_index (int) – Global block index
j.dim (int) – Matrix dimension.
num_points (int) – Number of sample points.
bilinear_bases (tuple[mpmath.matrices.matrices.matrix, mpmath.matrices.matrices.matrix]) – Even and odd sampled bases.
c (list[mpmath.ctx_mp_python.mpf]) – Constraint constants, length
num_points * dim * (dim+1) / 2.B (mpmath.matrices.matrices.matrix) – Constraint matrix,
len(c)byN.
- Parameters:
- B: matrix¶
Solving¶
- class sdpb_python.SolverOptions(precision=None, max_iterations=500, max_runtime=9223372036854775807, duality_gap_threshold='1e-30', primal_error_threshold='1e-30', dual_error_threshold='1e-30', initial_matrix_scale_primal='1e20', initial_matrix_scale_dual='1e20', feasible_centering_parameter='0.1', infeasible_centering_parameter='0.3', step_length_reduction='0.7', max_complementarity='1e100', min_primal_step='0', min_dual_step='0', find_primal_feasible=False, find_dual_feasible=False, detect_primal_feasible_jump=False, detect_dual_feasible_jump=False, fast_step_length=False, max_shared_memory_bytes=0, checkpoint_dir=None, checkpoint_interval=3600, output_dir=None, verbosity='none', want=('y', 'z'))[source]¶
Bases:
objectSolver options. Defaults are SDPB’s own.
Names follow
sdpb’s command line options in snake_case, e.g.duality_gap_thresholdfor--dualityGapThreshold. Numeric thresholds accept anythingsdpb_python.numbersconverts (int,float,str,Fraction,mpf); strings such as"1e-30"are the safest way to write tiny numbers.- Variables:
precision (int | None) – Working precision in bits (
--precision).Nonemeans the precision already fixed for this process, or SDPB’s default 400 if none is fixed yet. See Precision.max_iterations (int) – Stop after this many iterations (
--maxIterations, 500).max_runtime (int) – Stop after this many seconds (
--maxRuntime, unlimited).duality_gap_threshold (Any) – Optimality test on the normalised duality gap
|primal - dual| / max(|primal| + |dual|, 1)(1e-30).primal_error_threshold (Any) – Optimality test on the primal residues (1e-30).
dual_error_threshold (Any) – Optimality test on the dual residues (1e-30).
initial_matrix_scale_primal (Any) –
Xstarts as this multiple of the identity (--initialMatrixScalePrimal, 1e20).initial_matrix_scale_dual (Any) – Same for
Y(1e20).feasible_centering_parameter (Any) – Centering parameter
betaused once primal and dual are feasible (0.1).infeasible_centering_parameter (Any) – Centering parameter while infeasible (0.3).
step_length_reduction (Any) – Fraction of the maximal step taken (0.7).
max_complementarity (Any) – Abort when
Tr(XY)/dimexceeds this (1e100).min_primal_step (Any) – Stop when the primal step length falls below this (0).
min_dual_step (Any) – Stop when the dual step length falls below this (0).
find_primal_feasible (bool) – Stop as soon as a primal feasible point is found.
find_dual_feasible (bool) – Stop as soon as a dual feasible point is found.
detect_primal_feasible_jump (bool) – Stop when the primal step length reaches 1.
detect_dual_feasible_jump (bool) – Stop when the dual step length reaches 1.
fast_step_length (bool) – Compute the step lengths from a double-precision smallest eigenvalue, verified by an arbitrary-precision Cholesky (SDPB’s
--fastStepLength); the exact eigensolver is used for blocks that fail the check. DefaultFalse.max_shared_memory_bytes (int) – Memory budget for the exact
Qcomputation (--maxSharedMemory);0lets SDPB choose about half of the free RAM. Accepts ints or strings such as"100K"/"64G".checkpoint_dir (str | os.PathLike | None) – Directory for SDPB’s binary checkpoints. When set, a checkpoint found there is loaded before solving and one is written at the end and every
checkpoint_intervalseconds.Nonedisables checkpointing.checkpoint_interval (int) – Seconds between checkpoints (3600).
output_dir (str | os.PathLike | None) – If set, SDPB writes
iterations.json(one record per iteration) andc_minus_By/c_minus_By.jsonthere, as thesdpbexecutable does in its--outDir.verbosity (str | int) –
"none"(default),"regular","debug"or"trace"(or 0-3). Anything above"none"prints SDPB’s iteration table to the C++ standard output.want (Iterable[str]) – Which parts of the solution to return besides the objectives and errors: any of
"x","y","z","X","Y","c_minus_By". Default("y", "z"). Large problems have largeX/Y; ask only for what you need.
- Parameters:
precision (int | None)
max_iterations (int)
max_runtime (int)
duality_gap_threshold (Any)
primal_error_threshold (Any)
dual_error_threshold (Any)
initial_matrix_scale_primal (Any)
initial_matrix_scale_dual (Any)
feasible_centering_parameter (Any)
infeasible_centering_parameter (Any)
step_length_reduction (Any)
max_complementarity (Any)
min_primal_step (Any)
min_dual_step (Any)
find_primal_feasible (bool)
find_dual_feasible (bool)
detect_primal_feasible_jump (bool)
detect_dual_feasible_jump (bool)
fast_step_length (bool)
max_shared_memory_bytes (int)
checkpoint_interval (int)
- class sdpb_python.Solution(status, primal_objective, dual_objective, duality_gap, primal_error, dual_error, y, z, x, X, Y, c_minus_By, iterations, runtime_seconds, precision, blocks=<factory>)[source]¶
Bases:
objectSolver output. Numbers are
mpmath.mpfatprecisionbits.See Background: what SDPB solves for the meaning of the variables.
- Variables:
status (sdpb_python.solution.TerminateReason) – Why the solver stopped;
optimalis the usual check.primal_objective (mpmath.ctx_mp_python.mpf) –
f + c . x.dual_objective (mpmath.ctx_mp_python.mpf) –
f + b . y; for a PMP this is the optimal value of the objectivea . z.duality_gap (mpmath.ctx_mp_python.mpf) –
|primal - dual| / max(|primal| + |dual|, 1).primal_error (mpmath.ctx_mp_python.mpf) – Largest primal residue.
dual_error (mpmath.ctx_mp_python.mpf) – Largest dual residue.
y (list[mpmath.ctx_mp_python.mpf]) – The dual variables, length
N.z (list[mpmath.ctx_mp_python.mpf] | None) – The PMP variables of Manual eq. (3.1), length
N + 1, when the problem has a normalization and"z"was requested; elseNone.x (list[list[mpmath.ctx_mp_python.mpf]] | None) – Per block, the primal variables (length
num_points * dim * (dim+1) / 2);Noneunless"x"was requested.X (list[tuple[mpmath.matrices.matrices.matrix, mpmath.matrices.matrices.matrix]] | None) – Per block, the pair
(even, odd)of positive semidefinite primal matrices;Noneunless"X"was requested.Y (list[tuple[mpmath.matrices.matrices.matrix, mpmath.matrices.matrices.matrix]] | None) – Per block, the pair
(even, odd)of positive semidefinite dual matrices; for an LMI blockY[j][0]isM_0 + sum_n y_n M_n.c_minus_By (list[list[mpmath.ctx_mp_python.mpf]] | None) – Per block,
c - B y: the extremal functional evaluated on the sampled constraints (whatspectrumconsumes).iterations (int) – Iterations completed by this run.
runtime_seconds (float) – Wall time of the run.
precision (int) – Bits of precision used.
blocks (list[sdpb_python.solution.BlockInfo]) –
BlockInfoper block.
- Parameters:
- status: TerminateReason¶
- primal_objective: mpf¶
- dual_objective: mpf¶
- duality_gap: mpf¶
- primal_error: mpf¶
- dual_error: mpf¶
- class sdpb_python.TerminateReason(*values)[source]¶
Bases:
EnumWhy SDPB stopped (
SDP_Solver_Terminate_Reason).The value of each member is the exact text SDPB writes to
out.txt. OnlyPRIMAL_DUAL_OPTIMALmeans the problem was solved to the requested thresholds; the*_FEASIBLEand*_JUMP_DETECTEDreasons are early stops requested throughSolverOptions.- PRIMAL_DUAL_OPTIMAL = 'found primal-dual optimal solution'¶
- PRIMAL_FEASIBLE = 'found primal feasible solution'¶
- DUAL_FEASIBLE = 'found dual feasible solution'¶
- PRIMAL_FEASIBLE_JUMP_DETECTED = 'primal feasible jump detected'¶
- DUAL_FEASIBLE_JUMP_DETECTED = 'dual feasible jump detected'¶
- MAX_COMPLEMENTARITY_EXCEEDED = 'maxComplementarity exceeded'¶
- MAX_ITERATIONS_EXCEEDED = 'maxIterations exceeded'¶
- MAX_RUNTIME_EXCEEDED = 'maxRuntime exceeded'¶
- PRIMAL_STEP_TOO_SMALL = 'primal step too small'¶
- DUAL_STEP_TOO_SMALL = 'dual step too small'¶
- SIGTERM_RECEIVED = 'SIGTERM signal received'¶
- class sdpb_python.BlockInfo(dim, num_points)[source]¶
Bases:
objectSize of one SDP block.
- Variables:
- Parameters:
- class sdpb_python.Solver(kind, spec, options)[source]¶
Bases:
objectOwns SDPB’s Block_Info, SDP and SDP_Solver for one problem.
Created by
PMP.solver()orLMI.solver().run()continues the interior-point iteration from the currentx, X, y, Yand may be called repeatedly, e.g. with tighter thresholds. Use as a context manager or callclose()to release the C++ objects.- Parameters:
kind (str)
spec (dict)
options (SolverOptions)
- property options: SolverOptions¶
- run(options=None, **overrides)[source]¶
Continue iterating. Raises
SolverInterruptedon Ctrl-C.- Parameters:
options (SolverOptions | None)
overrides (Any)
- Return type:
- state(want=('y', 'z', 'x', 'X', 'Y'))[source]¶
The current iterate without running (objectives are those of the last run).
- exception sdpb_python.SolverInterrupted(solution)[source]¶
Bases:
KeyboardInterruptCtrl-C during a run: SDPB stopped cleanly at the end of an iteration.
solutionholds the state at that point; theSolvercan be run again to continue.- Parameters:
solution (Solution)
- exception sdpb_python.SDPBError(details)[source]¶
Bases:
RuntimeErrorAn error raised inside SDPB’s C++ code.
str(error)is SDPB’s message, with the source location appended in brackets when SDPB reported one;detailskeeps the whole text as SDPB produced it, including its stack trace.- Parameters:
details (str)
Parallel solves¶
- class sdpb_python.SolverPool(workers=None, *, precision=None, env=None)[source]¶
Bases:
objectA pool of worker processes that solve
PMP/LMIproblems.with SolverPool(workers=4, precision=768) as pool: futures = [pool.submit(pmp, fast_step_length=True) for pmp in problems] solutions = [f.result() for f in futures]
- Parameters:
workers (int | None) – Number of processes; default
default_workers()(physical cores, capped by available memory).precision (int | None) – Working precision of every worker, in bits.
Nonemeans the precision fixed in this process, or SDPB’s default 400.env (Mapping[str, str] | None) – Extra environment variables for the workers (on top of
DEFAULT_WORKER_ENV), e.g.{"LD_PRELOAD": ...}.
submit()returns aconcurrent.futures.Futurewhose result is theSolution(or whose exception is theSDPBErrorthe solve raised). Results do not depend on the number of workers or the order in which solves run.- submit(problem, options=None, *, max_num_poles=None, **overrides)[source]¶
Queue one solve; keyword arguments override
SolverOptionsfields.- Parameters:
options (SolverOptions | None)
max_num_poles (int | None)
overrides (Any)
- Return type:
Future
- map(problems, options=None, **overrides)[source]¶
Solve every problem; the solutions in input order (raises the first error).
- Parameters:
problems (Iterable)
options (SolverOptions | None)
overrides (Any)
- Return type:
- cancel(future)[source]¶
Cancel a solve: drop it if it is still queued, or stop it at the end of its current iteration if it runs (its future then raises
SolveCancelled). Returns False when the solve already finished. A running solve that completes before the request arrives keeps its result.- Parameters:
future (Future)
- Return type:
- close(*, cancel=False)[source]¶
Finish the queued solves (or cancel them), then stop the workers.
- Parameters:
cancel (bool)
- Return type:
None
- terminate()[source]¶
Kill the workers now. Queued solves are cancelled; running ones raise
SolveCancelled.- Return type:
None
- sdpb_python.solve_many(problems, options=None, *, workers=None, precision=None, env=None, **overrides)[source]¶
Solve independent problems on a temporary
SolverPool; the solutions in input order.
- exception sdpb_python.SolveCancelled(message, solution=None)[source]¶
Bases:
CancelledErrorThe solve was cancelled with
SolverPool.cancel()while it ran.solutionis the state at the end of the last iteration (statusSIGTERM_RECEIVED, with itsiterationsandruntime_seconds), orNonewhen the worker was stopped another way.
Precision¶
- sdpb_python.set_precision(bits)[source]¶
Fix the working precision (bits) for this process.
SDPB’s Elemental allows setting it once per process; calling again with a different value raises
SDPBError. When not called, the first solve fixes it (to itsprecisionoption, default 400).- Parameters:
bits (int)
- Return type:
None
Files¶
- sdpb_python.read_pmp_json(*paths)[source]¶
Load one or more
pmp.jsonfiles (or.nsvlists) into aPMP.As in SDPB, every file may carry the objective and normalization; they must agree, and matrices are concatenated in file order.
Numbers¶
Conversions between Python numbers and the decimal strings SDPB exchanges.
Strings are printed with max_digits10 digits for the working precision, so
mpf -> str -> BigFloat -> str -> mpf is lossless.
- sdpb_python.numbers.digits_for(bits)[source]¶
Decimal digits that uniquely identify a binary float of
bitsbits.
- sdpb_python.numbers.to_str(value, bits)[source]¶
Render
valueas a decimal string exact tobitsof precision.
- sdpb_python.numbers.from_str(s, bits)[source]¶
Parse a decimal string without rounding below
bitsof precision.