QHD constrained problems and box refinement¶
Reference for the augmented-Lagrangian layer, which solves a ConstrainedOptimization by a sequence of QHD solves, and for box refinement, which repeats QHD on shrinking boxes, alone or inside each augmented-Lagrangian round. Import every name on this page from nwqlib.algorithms.qhd, for example from nwqlib.algorithms.qhd import solve_augmented_lagrangian, refine_box.
The guide's section on constrained problems gives the effective objective, the multiplier and penalty updates and the stopping test with their sources, Wu et al., arXiv:2605.12066v1, Eqs. (6)–(8), Rockafellar, doi:10.1007/BF01580138, and Birgin and Martínez, doi:10.1137/1.9781611973365, Algorithm 4.1 and Eqs. (4.7)–(4.9) and (10.6)–(10.8). Its slack-variable subsection explains inequality_form, the augmented inner problem, projected readout and the cap and error scope. The guide's section on box refinement explains how each level keeps its marginal intervals and forms the next box, what the search model solves and why its gain has no universal value, when the optional stall split applies and what it gives up, and the order of the stops. The QHD page documents the QHD configuration that every round and level uses. solve_augmented_lagrangian and refine_box each have a complete example below.
| Task | Entry |
|---|---|
| Solve a constrained problem | solve_augmented_lagrangian with AugmentedLagrangian options |
| Inspect round 0 and its cost before running | plan_augmented_lagrangian |
| Continue an interrupted run, or reopen a saved one | resume_augmented_lagrangian, load_augmented_lagrangian |
| Read the best point, its feasibility and the multipliers | ConstrainedQHDResult, ALEvaluation |
| Compare the best point with the evaluated grid minimum | constrained_grid_minimum |
| Refine the box of an unconstrained problem | refine_box with BoxRefinement options |
| Continue or reopen a refinement | resume_box_refinement, load_box_refinement |
| Read the levels of a refinement | BoxRefinementResult, RefinementLevel |
| Read selected region mass bounds from counts | print(result) or result.report() on either result type, with simultaneous coverage over the configured run |
Solve a constrained problem¶
solve_augmented_lagrangian ¶
solve_augmented_lagrangian(problem, *, qhd, options=AugmentedLagrangian(), refinement=None, backend=None, execution=None, shots=None, seed=None, limits=None, progress=None, directory=None)
Minimize a constrained objective by an augmented-Lagrangian sequence of QHD solves.
solve_augmented_lagrangian(problem, qhd=QHD(...)) solves a
ConstrainedOptimization, the box problem with equalities h_i(x) = 0 and
inequalities g_j(x) <= 0. Round k builds the normalized effective objective
L_k(x) = F + sum_i lambda_bar_i H_i + (rho/2) sum_i H_i**2 + sum_j ([mu_bar_j + rho G_j]_+**2 - mu_bar_j**2)/(2 rho)
with F = f/s_f, H_i = h_i/s_{h_i}, G_j = g_j/s_{g_j}, the round's multipliers
lambda_bar = lambda-bar^k, mu_bar = mu-bar^k and penalty rho = rho_k. The equality
part is Eq. (6) of Wu et al., arXiv:2605.12066v1, and the inequality part the
Powell-Hestenes-Rockafellar (PHR) term (Rockafellar, doi:10.1007/BF01580138). The
round plans
Optimization(objective=L_k, variables, bounds=the preprocessed box, unit=problem.unit)
with qhd, runs it with prepare and submit, reads a point x_{k+1} by
options.inner_point, evaluates f, h and g there with numerical functions formed
once for the run (SymPy lambdify), and updates the multipliers to
lambda+ = lambda + rho h and mu+ = max(0, mu + rho g) and the penalty (Birgin
and Martinez, doi:10.1137/1.9781611973365, Algorithm 4.1 and Eqs. (4.7)-(4.9)). The
guide's constrained problems section
explains each step.
The run stops when the normalized tests of options.termination hold. With
feasibility_and_complementarity these are complementarity <= epsilon_c and
infeasibility <= epsilon_f (Algencan's Eqs. (10.7)-(10.8)), and the status is
feasible_complementary. With feasibility the test is infeasibility <= epsilon_f,
and the status is feasible. Otherwise it stops after options.max_iterations
rounds, when an inner result has no valid point, when the cumulative limits cannot
fund a round, or when an inner planning, preparation or execution raises after the
first round
(AugmentedLagrangianRecord
lists the statuses). No round is retried. A stopping status does not assess
optimality. Like QHD itself, the layer is not a global optimizer. The rounds read
points of a finite grid of the box, except an off-grid mean under mode_or_mean,
and no status is a statement about the continuous problem. Read feasibility,
complementarity and termination alongside the objective. In the first round an
error propagates unchanged, because no round has completed and a configuration that
QHD rejects should surface at once. That includes a first round whose Run refuses
the limits, while limits that the layer's own test finds unable to fund the first
round's circuit or shots end the run with budget_exhausted after zero rounds.
Parameters:
-
problem(ConstrainedOptimization) –The problem, with live SymPy expressions.
-
qhd(QHD) –The QHD configuration of every round.
-
options(AugmentedLagrangian, default:AugmentedLagrangian()) –The layer's options. Default
AugmentedLagrangian(). -
refinement(BoxRefinement | None, default:None) –Box refinement of every round's inner objective, L_k or L(x, s), or None (the default) for one QHD solve per round, which leaves every result as without this argument.
-
backend(object | None, default:None) –Passed to every round's
prepare, as innwqlib.solve. -
execution(str | None, default:None) –"quantum"(the default) or"classical", as innwqlib.solve. -
shots(int | None, default:None) –Shots per round, or None for exact readout.
-
seed(int | None, default:None) –Nonnegative root seed of the run.
-
limits(ExecutionLimits | None, default:None) –Cumulative limits of the whole run, the defaults when None. Each round's Run, or each level's Run with refinement, gets the remaining circuits, shots, data bytes and synthesis work and the per-Run caps unchanged.
-
progress(object | None, default:None) –Passed to every round's Run, as in
nwqlib.solve. -
directory(str | Path | None, default:None) –A new directory for a saved run that
resume_augmented_lagrangiancan continue, or None to keep every inner Run in memory. It must not exist, and missing parents are created.
Returns:
-
result(ConstrainedQHDResult) –The run.
candidateandobjectivegive the best point and f there in original units,terminationthe stopping status,multipliers()the last round's multiplier estimates in original units, andrecordthe full record. The function never callsconstrained_grid_minimum.
Raises:
-
TypeError–If
optionsis not anAugmentedLagrangianorrefinementis neither aBoxRefinementnor None. -
ValueError–If
refinement.point_rulediffers fromoptions.inner_point, if the refinement options ask for what the QHD configuration cannot carry out, or if the first round fails as described above. -
FileExistsError–If
directoryexists. The message namesresume_augmented_lagrangian, which continues it.
Inequality representation
Under options.inequality_form="slack" or "auto" the round first fixes how
its kept inequalities enter (Proposition 54 of
the mathematics page). A converted inequality adds a
slack variable, after the problem's variables and with the box [0, U] of its
cap, and the round plans its inner objective L(x, s) instead, reads a joint
point and projects it to x, where the update above is unchanged
(ALIteration.representation).
Point selection with refinement
With refinement, round k instead runs box refinement
(refine_box) on its inner
problem, from the preprocessed box and the round's slack boxes, with qhd. This
is the order of the reproduction scripts of Wu et al., arXiv:2605.12066v1, which
refine inside each multiplier round. refinement.point_rule reads every level
and must equal options.inner_point, which has no second role, and two
different rules are rejected before any work, as are stall-split and level
initial-state options that the QHD configuration cannot carry out. A stall
split, when the options ask for one, acts within each round's refinement with
the options' budget.
The round takes as x_{k+1} the projection of the point of the level with the
least recorded relative value of the inner objective, the earlier level on ties.
The round compares its inner objective, L_k under the PHR policy and L(x, s)
with an inequality representation, by the point rules that the Point rules note
of AugmentedLagrangian
describes. The outer point is the projection onto the original variables, and
effective_value is the PHR value L_k evaluated at that projection when a
representation is present. The best and last points are chosen among rounds by
the rules above, not among levels.
f, h and g are then evaluated at the outer point in the original coordinates,
and the update is unchanged. The point is the level's reported point
(RefinementLevel.point), for the search model the image a + D u of the
level's unit point u rounded once to binary64, while the level evaluated its
objective at the exact image. f, h and g are evaluated at the rounded point
because it is the point that the round and the run return to the user, and the
recorded residuals and objective must describe that point.
Each refinement level checks the original objective and constraints at the
original-coordinate projection of every compared point. If an off-grid mean
makes an original function nonfinite or undefined, the level records
mean_unavailable and uses its valid grid point. The level's inner-value
comparison keeps its existing table and coordinate-transformation conventions.
Failures and stopping with refinement
When an original function is not finite and real at a level's grid point, or at
a point that a stall split scores, that level fails as a level whose Run raised
does, before a split or a next box is decided. In a round after the first, or
after a completed level, the refinement stops with inner_failed and the run
ends after the round, and in the first level of round 0 the error propagates.
Without refinement the round keeps the grid point when the mean fails, and a
failure at the grid point ends a round after the first with inner_failed and
propagates in round 0.
A refinement that completed a level always gives the round its point. After
budget_exhausted, inner_failed or no_valid_point the run records the round
and stops, with the success status when the round's point met the stopping test
and with the refinement's reason otherwise, and a refinement that completed no
level ends the run with its own reason.
An error of the first level of round 0 propagates. Any later error of a level
ends the run after keeping the completed rounds and levels, with inner_failed
or, when its round kept a point that met the stopping test, with the success
status.
Limits with refinement
limits stays cumulative over all rounds and levels, and each level's Run gets
what the earlier rounds and levels left. The configuration fixes before the
first round at most max_iterations * refinement.max_levels inner solves and the
host-work bound AugmentedLagrangianRecord.admitted_work_bound.
Random streams
Every round's random streams come from SeedSequence(seed).spawn, as
compare seeds its candidates, and the round
records its child's entropy and spawn key. With refinement, level z of round k
plans from the z-th child of the round's child, whose spawn key (k, z - 1) its
level record keeps.
Saved runs
With directory every inner Run is saved under iterations/<k>/run/, or
iterations/<k>/levels/<z>/run/ with refinement, and the outer record is
rewritten after each completed round or level and once more at the end, so that
resume_augmented_lagrangian can continue an interrupted run. The outer record
stores the configuration of the backend of every inner Run, and the model of a
noisy Aer backend is saved once in the directory. The rounds are the same as
without a directory, except that a saved Run also stores its run log and inputs,
which count against max_data_bytes, so a run whose data limit binds can stop
earlier, and that a round whose preparation raised reads its counts from its
closed Run folder.
Examples:
This is the unit-disk example of the guide. On the 4-point grid of each axis the first two rounds read the infeasible point (0.8, 0.8), raise the multiplier to 0.56 and the penalty to 2, and the third round reads (0.6, 0.8) on the circle, the least evaluated objective among the feasible grid points, so the gap to the explicit grid reference is 0.
>>> import sympy as sp
>>> from nwqlib.problems import ConstrainedOptimization
>>> from nwqlib.algorithms.qhd import (
... QHD, AugmentedLagrangian, constrained_grid_minimum,
... solve_augmented_lagrangian)
>>> x, y = sp.symbols("x y", real=True)
>>> problem = ConstrainedOptimization(
... objective=(x - 1)**2 + (y - 1)**2, variables=(x, y),
... bounds=((0.0, 1.0), (0.0, 1.0)), inequalities=(x**2 + y**2 - 1,))
>>> result = solve_augmented_lagrangian(
... problem, qhd=QHD(num_grid_points=4, num_steps=80, total_time=10.0),
... options=AugmentedLagrangian(stationarity=True),
... execution="classical", seed=7)
>>> print(result.termination, [round(v, 6) for v in result.candidate],
... round(result.objective, 6))
feasible_complementary [0.6, 0.8] 0.2
>>> print(len(result.iterations), round(result.penalty, 6))
3 2.0
>>> print(constrained_grid_minimum(result).gap)
0.0
AugmentedLagrangian ¶
Bases: Record
Options of solve_augmented_lagrangian: penalty schedule, scales, tolerances, point rule and stopping test.
Build it with keyword arguments, for example
AugmentedLagrangian(max_iterations=20, objective_scale=10.0), and pass it as
solve_augmented_lagrangian(..., options=...). Every argument is optional, but a
problem with equality constraints needs an explicit feasibility_tolerance. Every
tolerance, the penalty measure and the complementarity test act on the normalized
quantities f/s_f, h_i/s_{h_i} and g_j/s_{g_j}. The multipliers and their
bounds are those of this scaled problem. The defaults and their sources are
registered in the
engineering constants.
Attributes:
-
initial_penalty(PositiveReal) –Default
1.0, from Wu et al., arXiv:2605.12066v1, Sec. VI.B. Positive rho of the first round. -
penalty_growth(Real) –Default
2.0, from Wu et al., Sec. VI.B. The factor gamma > 1 that increases rho. -
reduction_ratio(Real) –Default
0.25, from the authors' prototype, strictly between 0 and 1. The tau of the penalty test, Birgin and Martinez Eq. (4.9). The book only requires 0 < tau < 1. -
max_penalty(PositiveReal) –Default
1e9, from Wu et al., Sec. VI.B. Upper bound of rho, at leastinitial_penalty. -
max_iterations(PositiveInt) –Default
15, from Wu et al., Sec. VI.B. Largest positive number of rounds, each one inner QHD solve or one box refinement. -
objective_scale(PositiveReal) –Default
1.0, which assumes a dimensionless objective. Positive s_f. The layer minimizesf/s_f. -
equality_scales(tuple[PositiveReal, ...] | None) –Default
None, which selects all ones. Positive s_{h_i} for every equality, in the problem's order. -
inequality_scales(tuple[PositiveReal, ...] | None) –Default
None, which selects all ones. Positive s_{g_j} for every inequality, in the problem's order. -
feasibility_tolerance(Nonnegative | None) –Default
None, which selects1e-9when the problem has only inequalities and is an error when it has an equality. The nonnegative epsilon_f of the normalized feasibility testmax(||h||_inf, ||g_+||_inf) <= epsilon_f. With equality constraints there is no default, because the residual that a finite grid can reach depends on the grid and the constraint. -
complementarity_tolerance(Nonnegative | None) –Default
None, which selects the resolvedfeasibility_tolerance. The nonnegative epsilon_c of the normalized complementarity test. The book uses one tolerance for Eqs. (10.7) and (10.8). -
multiplier_bounds(MultiplierBounds | None) –Default
None. Safeguard of Algorithm 4.1 Step 4, aMultiplierBounds. With None the next round uses the tentative multipliers and the result states that no safeguard was used. -
equality_multipliers(tuple[Real, ...] | None) –Default
None, which starts every equality multiplier at 0. Initial normalized lambda for every equality. Algorithm 4.1 starts the multipliers insidemultiplier_bounds, sosolve_augmented_lagrangianrefuses None for a problem with equalities when the bounds' equality interval excludes zero. -
inequality_multipliers(tuple[Nonnegative, ...] | None) –Default
None, which starts every inequality multiplier at 0. Initial normalized mu >= 0 for every inequality. -
absorb_bounds(StrictBool) –Default
False. Whether a one-variable linear inequalitya x_j + b <= 0tightens the box of x_j instead of entering the effective objective, when its cut-b/ais a binary64 number. A cut without one stays a constraint. Absorption changes the grid and the dynamics, so it is off by default. -
inner_point(Literal['most_probable', 'best_observed', 'mode_or_mean']) –Default
"most_probable". How each round reads its point from the inner QHD result:"most_probable", a joint mode,"best_observed", the least observed table value, or"mode_or_mean", the joint mode or the conditional mean, whichever has the smaller inner objective. With box refinement it must equalBoxRefinement.point_rule. The Point rules note below gives the details. -
termination(Literal['feasibility_and_complementarity', 'feasibility']) –Default
"feasibility_and_complementarity", which stops when both normalized tests of Algencan's Eqs. (10.7)-(10.8) hold, with statusfeasible_complementary."feasibility"stops on feasibility alone, with statusfeasible, the rule of Wu et al.'s code, which stops when the violation is strictly below the tolerance while this test accepts equality. Neither stop certifies stationarity or optimality. -
penalty_update(Literal['on_insufficient_decrease', 'every_iteration']) –Default
"on_insufficient_decrease", which applies the test of Algorithm 4.1 Step 3, Eq. (4.9)."every_iteration"multiplies rho bypenalty_growthafter every round, as Wu et al.'s code does. -
stationarity(StrictBool) –Default
False. Whether each round reports the projected-gradient diagnostic r_stat. It differentiates f, h and g symbolically and does not affect stopping. -
inequality_form(Literal['phr', 'slack', 'auto']) –Default
"phr". How each round represents its kept inequalities in the inner problem (Proposition 54):"phr", the PHR term,"slack", a slack variable per inequality with a positive cap, or"auto", chosen by planned cost on the quantum route. The outer update and the stopping tests are those of the PHR term in every case. The Inequality forms note below gives the rules.
Point rules
"most_probable" chooses a joint mode, the point that Wu et al. Sec. V read.
"best_observed" chooses the least observed table value. "mode_or_mean"
compares the joint mode with the joint conditional mean using the inner
objective, with a tie going to the grid point. This is the rule of the code
behind Wu et al.'s published results, whose code takes the mean on an exact tie.
The round compares its inner objective, L_k under the PHR policy and L(x, s)
with an inequality representation. A physical level solves this objective, and a
search-model level solves its positive normalization. The point rules act in the
inner coordinates. Refinement compares recorded relative values of the inner
objective across levels and takes the earlier level on a tie. The outer point is
the projection onto the original variables, and effective_value is the PHR value
L_k evaluated at that projection when a representation is present. With box
refinement (solve_augmented_lagrangian(refinement=...)) the rule reads every
level, so it must equal BoxRefinement.point_rule, which applies it, and a run
with two different rules is rejected before any work.
Inequality forms
"phr", the default, keeps the PHR term of every inequality, whose table spans
all of the inequality's variables. "slack" requests a slack variable for each
kept inequality with a positive cap after eligible quadratic or constant branch
tests. The normalized slack term is mu_j (G_j + s_j) + (rho/2) (G_j + s_j)**2.
A zero cap adds no axis and keeps PHR when the quadratic branch is ineligible.
Branch tests run only without refinement and with a grid-point rule. The
expansion has supports of at most two variables when G_j is additively
separable. In general, product supports are contained in unions of the original
supports, and QHD checks the expanded supports against its limits before
tabulating them.
"auto" keeps PHR without branch tests for classical execution or a user
GaussianState. Otherwise it applies the eligible branch tests and considers
slack conversions in constraint order. It accepts a trial that planning accepted
when planned host work and CX count are both no larger and at least one is
smaller, or when the current planning is refused and the trial is accepted with
a CX count. A missing CX count prevents the comparison. The comparison study's
quantum quality evidence for "auto" covers only the QHD guide's n = 3,
K = 4 cases with one affine inequality, KineticGroundState, joint-mode
readout, no refinement and exact noiseless readout under the study's fixed
schedule and outer settings. Classical execution uses a restricted state that
grows by a factor K per slack.
The outer update, the stopping tests and the stationarity diagnostic stay those of the PHR term at the round's point in the original coordinates.
Raises:
-
ValueError–If
max_penaltyis belowinitial_penalty, or the initial multipliers lie outsidemultiplier_bounds, where Birgin-Martinez Algorithm 4.1 starts them.
MultiplierBounds ¶
Bases: Record
Safeguard box for the multipliers, Algorithm 4.1 Step 4 of Birgin and Martinez, doi:10.1137/1.9781611973365.
Build it with keyword arguments, for example
MultiplierBounds(equality_lower=-10.0, equality_upper=10.0, inequality_upper=10.0),
and pass it as AugmentedLagrangian(multiplier_bounds=...). All three arguments are
required. The next round uses clip(lambda+, equality_lower, equality_upper) for
every equality and min(mu+, inequality_upper) for every inequality, where lambda+
and mu+ are the tentative multipliers of Eqs. (4.7)-(4.8). The bounds are in
normalized units, the units of the multipliers of the scaled problem.
Algorithm 4.1 requires lambda_min < lambda_max and mu_max > 0. Its Step 4 keeps
the multipliers of every round bounded, so that the shifts lambda-bar/rho and
mu-bar/rho tend to zero when rho grows (p. 35), and the book's convergence proofs
use that boundedness, for example the proof of Theorem 5.1 (pp. 41-42). The book's
analysis of the penalty in Chapter 7 also assumes that the true multipliers lie
inside the bounds, away from lambda_min, lambda_max and mu_max,
lambda* in (lambda_min, lambda_max) and mu* in [0, mu_max) (Assumption 7.7, Sec.
7.5, p. 64), which no default can know. Without that assumption the global
convergence results of Chapter 6 still hold, but the penalty may no longer stay
bounded (p. 64).
Attributes:
-
equality_lower(Real) –Required. lambda_min, the lower bound of every equality multiplier.
-
equality_upper(Real) –Required. lambda_max, greater than
equality_lower. -
inequality_upper(PositiveReal) –Required. mu_max, the positive upper bound of every inequality multiplier. The lower bound is zero.
Raises:
-
ValueError–If
equality_loweris not belowequality_upper.
plan_augmented_lagrangian ¶
plan_augmented_lagrangian(problem, *, qhd, options=AugmentedLagrangian(), execution=None, shots=None, seed=None)
Plan round 0 of solve_augmented_lagrangian without a Run, to inspect its preprocessing and cost.
The call does what solve_augmented_lagrangian does before its first inner Run,
with the same arguments: the checks and the support-wise preprocessing of the
problem, the representation of the kept inequalities in round 0 under
options.inequality_form, with its automatic selection when chosen, and the Plan of
round 0's inner problem, planned from the first child of SeedSequence(seed) as the
solve plans it. The returned Plan is therefore the Plan that the solve's round 0
would prepare, and nwqlib.estimate(plan) and
circuit_resources(plan) apply
to it. Its width, restricted dimension and CX count describe the inner problem with
its slack variables. Nothing is prepared, executed or measured, no state is evolved,
and neither a classical reference nor constrained_grid_minimum runs, so the call
also serves problems whose evolution cannot be simulated. A resource-only QHD with
initial_state_preparation="none" is accepted, since no round runs.
A planning-only call reports the first round only: the preprocessing, with the
inequality ranges on the grid, round 0's representation, with its slack caps and its
slack-grid error bound for the initial multipliers and penalty, and round 0's inner
Plan. Later rounds' multipliers and penalties depend on the points that executed
rounds read, so their representations, Plans and costs are not known here. The
structural bounds of a whole run, at most options.max_iterations rounds within the
work and byte bounds of AugmentedLagrangianRecord.admitted_work_bound, hold for
every round. They are upper bounds, not an executed trajectory or the exact costs of
later rounds. Box refinement is not planned here. A refined round keeps the PHR form
where the branch tests do not apply, and its first level plans the inner problem on
the same box with the physical scaling, or its unit-box normalization with the
search model.
Parameters:
-
problem(ConstrainedOptimization) –The problem, with live SymPy expressions.
-
qhd(QHD) –The QHD configuration of every round.
-
options(AugmentedLagrangian, default:AugmentedLagrangian()) –The layer's options. Default
AugmentedLagrangian(). -
execution(str | None, default:None) –"quantum"(the default) or"classical", as insolve_augmented_lagrangian. Automatic selection converts inequalities on the quantum route only. -
shots(int | None, default:None) –Shots per round, or None for exact readout.
-
seed(int | None, default:None) –Nonnegative root seed of the run.
Returns:
-
planned(tuple) –(preprocessing, representation, plan), theConstraintPreprocessingof the run, round 0'sInnerRepresentationor None underinequality_form="phr", and round 0's inner QHD Plan.
Raises:
-
ValueError–As
solve_augmented_lagrangianbefore its first Run, including a round-0 planning that QHD refuses, which a solve would raise from its first round.
resume_augmented_lagrangian ¶
resume_augmented_lagrangian(directory, *, backend, progress=None, end_at_unfinishable=False)
Continue an interrupted saved run of solve_augmented_lagrangian, or return it when it has ended.
Pass the directory and the backend of the original call. The directory's outer
record holds the run's problem, QHD configuration, options, refinement options,
execution, shots, root entropy, cumulative limits and backend configuration, and its
completed rounds and levels. The layer wrote every file of the directory, and resume
reads them as they are. A directory is read-only like a saved Run folder
(Saved folders are read-only),
and resume does not detect edits. Before any new work, backend must have the stored
configuration,
and for a noisy Aer run resume binds the noise model saved in the directory to its
own copy of backend, so that the Runs it creates run the original model in a new
process too. Another backend raises ValueError before anything is reopened, planned
or committed. The problem rebuilt from problem.pickle must have the content hash
of the stored problem record, or ValueError is raised before any completed Result is
read or the run advances, since an expression that the reader cannot reproduce would
otherwise continue the run as another problem. The completed rounds' and levels'
Results are read from their Runs with load_run, and the layer's preprocessing and
check counts are read from the setup that the first call saved, without recomputing
them to detect an edit.
The rounds then continue from the last completed round, with the state and the
random stream of the uninterrupted run. A round in progress reuses the inequality
representation that it committed before its first inner Run, after checking that it
rebuilds the committed inner objective, so automatic selection is not repeated, and
a completed round's Result must belong to its recorded inner Plan. A round or level
whose Run exists continues that Run with load_run(...).wait(), and none gets a
second Run, so completed work is read from the records and a continued Run is
counted once, by its own run log. When that Run cannot finish without new work,
because the interruption stopped a local preparation, measurement or classical
evolution whose outcome nothing can retrieve, its error propagates with a note, and
the outer record keeps its committed rounds and levels unchanged. With
end_at_unfinishable=True the run instead ends there with inner_failed, keeps its
completed rounds and records the Run's error as the failure. This option handles an
unfinishable continuation after a Run has reopened. A Run folder without a committed
run-log header fails during reopen and is not handled by end_at_unfinishable.
Reopen does not remove or recreate that folder automatically. Before a completed
round or level exists, an inner failure still propagates. Resume covers an
interrupted process, not a power loss.
A directory whose run has ended returns its result, with the inner Results read from their Runs, and plans, evaluates and measures nothing.
Resuming gives the records of an uninterrupted saved run with the same root entropy,
apart from the fields that differ between any two saved executions, namely the
identifiers of the Runs and Results, which every Run draws anew, the stored-data
byte counts, whose text of wall times and measured timings varies in length from run
to run, and the content hashes that include these fields. Those byte counts enter
the remainder of max_data_bytes, so a run whose data limit is almost spent can
stop at another round, as two uninterrupted saved runs can.
Parameters:
-
directory(str | Path) –The directory of
solve_augmented_lagrangian(..., directory=...). -
backend(object) –The backend of the original call, whose configuration the directory stores. None stands for
AerBackend()under quantum execution, as in the original call. For a noisy Aer run in a new process,AerBackend(noise_model_id=...)with the identifier of the original binding, which the error for another backend names. -
progress(object | None, default:None) –Progress callback of the inner Runs that this call creates or continues, as in
nwqlib.solve. -
end_at_unfinishable(bool, default:False) –Default
False, which raises the Run's error and leaves the directory as it is for a later resume. True ends the run withinner_failedat a round or level whose Run cannot finish without new work. It handles an unfinishable continuation after a Run has reopened, not a Run folder without a committed run-log header, which fails during reopen. Before a completed round or level exists, an inner failure still propagates.
Returns:
-
result(ConstrainedQHDResult) –The run, as
solve_augmented_lagrangianreturns it.
Raises:
-
TypeError–If
end_at_unfinishableis not a bool. -
ValueError–If
backenddiffers from the stored configuration, or the rebuilt problem differs from the stored record.
load_augmented_lagrangian ¶
load_augmented_lagrangian(path)
Load a saved augmented-Lagrangian run without planning, evaluating or measuring.
load_augmented_lagrangian(path) reads the directory that
ConstrainedQHDResult.save wrote and returns the ConstrainedQHDResult. The record
is validated with its content hashes. The SymPy objects come back through a reader
that resolves SymPy classes only, and the rebuilt problem must have the record's
problem hash. Each inner Result is loaded with load_result and must have the
recorded result and Plan hashes, and its Plan's objective the recorded hash of L_k,
or of the inner objective of the round's representation over the problem's variables
and the slack variables. With refinement each level's Result must have the result
and Plan hashes of its RefinementLevel. A level Plan solves the level's own
objective, for the search model the normalized one on the unit box, so it is checked
by these hashes and not against the hash of L_k. A saved standalone refinement is
refused with the name of load_box_refinement, and a saved-run directory of
solve_augmented_lagrangian(..., directory=...) with the name of
resume_augmented_lagrangian, which continues it.
Parameters:
-
path(str | Path) –The directory that
ConstrainedQHDResult.savewrote.
Returns:
-
result(ConstrainedQHDResult) –The saved run, with its problem and inner Results attached.
constrained_grid_minimum ¶
constrained_grid_minimum(result, *, max_work=GRID_MINIMUM_MAX_WORK, max_bytes=GRID_MINIMUM_MAX_BYTES)
Find the least evaluated feasible objective on the run's grid and its gap to the best point.
constrained_grid_minimum(result) evaluates f, h and g in binary64 at every point
of the preprocessed box's grid and returns a
ConstrainedGridMinimum.
Its gap is the run's stored best objective minus the least evaluated feasible
objective, in original units. The solver never calls it.
The explicit grid reference evaluates the original objective and required constraints on the declared original-variable grid. It chooses the lexicographically first point attaining the least computed feasible objective. Feasibility uses the normalized residual test at the stored tolerance. All reported reference values come from the same evaluated table. The result describes this finite numerical grid and supplies neither a continuous optimum nor an expression-evaluation error certificate.
The reference evaluates the original functions in C-order slabs, streams constraint values into the feasibility test and keeps the first feasible minimum. Its work counts every evaluated function and its byte allowance includes expression intermediates, coordinate arrays and masked-reduction buffers.
Selection. Given a finite reference objective array f and a Boolean feasible mask,
argmin(where(feasible, f, inf)) returns the first feasible minimum in C order,
which is the lexicographically first tuple. For each original equality value h and
inequality value g, the stored positive scale is applied before comparing with the
tolerance: the violation is max(max(abs(h/s_h)), max(max(g/s_g, 0))), with an
empty maximum zero. All raw values must be finite and real, even at infeasible
points. Division may overflow if a scale is tiny, which gives infinite infeasibility
and rejects that point as infeasible. Slabs are processed in increasing global C
order and the running minimum is updated only on a strictly smaller value, which
keeps the first tie across slab boundaries. Counts of feasible points use Python
integers across slabs. Vectorized expression evaluation may change the reference
table's entries relative to scalar evaluation and can change a minimum or
feasibility decision near a threshold, so this is one consistent array-evaluated
reference table, and re-evaluating only the chosen point scalarly would not restore
a scalar ranking.
The signed gap compares a stored objective with a fresh grid minimum and can be
negative. Let G be the nonempty grid subset passing this check's computed
feasibility test, and let the chosen point a lie in G. Suppose a finite E >= 0
bounds the absolute error of the stored objective at a and of every fresh objective
evaluation on G, relative to exact values at those same coordinates. For finite
reported gap r and u = 2**-53, the exact gap F(a) - min_G F is at most
r/(1-u) + 2*E when r >= 0, and r/(1+u) + 2*E when r < 0. These are
real-arithmetic inequalities under round-to-nearest binary64 with gradual underflow.
This function establishes neither E nor equality of G with the mathematically
feasible grid set.
The reference enumerates the original variables only, also for a run whose rounds added slack variables, and applies the original feasibility test. It evaluates f, h and g in their written form. This can raise ValueError at a grid point where the original binary64 evaluation fails, for example through intermediate overflow on a term whose initial check used only its support tables. Neither this reference nor the initial check certifies the exact real domain or bounds expression-evaluation error.
A run with box refinement is refused. Its rounds search nested grids that each run chooses from its own distributions, and the preprocessed box's grid is only the first of them, so a feasible minimum of that grid is not the finite-grid reference of the points the run compared, and the gap would mix points of different grids.
Before the first evaluation, the reference checks its work and slab bytes against
max_work and max_bytes by the laws in
Engineering constants.
It keeps no reference table of all K**d grid points.
Parameters:
-
result(ConstrainedQHDResult) –A run from
solve_augmented_lagrangianorload_augmented_lagrangian. -
max_work(int, default:GRID_MINIMUM_MAX_WORK) –Work limit of this reference. Default
1_000_000_000. -
max_bytes(int, default:GRID_MINIMUM_MAX_BYTES) –Byte limit of this reference. Default 10 GB (decimal,
10_000_000_000bytes).
Returns:
-
reference(ConstrainedGridMinimum) –The least evaluated feasible value in
objective, its point, the signed gap ingapand the checked work.
Raises:
-
TypeError–If
resultis not aConstrainedQHDResult. -
ValueError–If the run used box refinement, if the work or the bytes of a one-point slab exceed
max_workormax_bytes, or if the original binary64 evaluation fails at a grid point.
Read a constrained run¶
With counts and refinement, print(result) and result.report() include mass lower bounds for each level's backend-sampled distribution conditioned on valid decoding. The default 95% confidence covers all rounds and levels together. Both result types accept report(failure_probability=alpha) and explicit None to omit the statistical report. The method entries below give the parameter and returned fields.
ConstrainedQHDResult.record is an AugmentedLagrangianRecord, which keeps one ALIteration per round, with the round's point and update in ALEvaluation and its counts in ALResources. Under inequality_form="slack" or "auto", InnerRepresentation, SlackAxis and FormTrial record each round's resolved choice. Feasibility, complementarity and the stopping status describe the chosen point and its multipliers. A stopping status does not assess optimality.
ConstrainedQHDResult ¶
ConstrainedQHDResult(record: AugmentedLagrangianRecord, problem: ConstrainedOptimization, results: tuple)
Result of an augmented-Lagrangian run: its record, live problem and inner QHD results.
solve_augmented_lagrangian, resume_augmented_lagrangian and
load_augmented_lagrangian return it. The answer is candidate, the best point in
original coordinates, with objective, f there in original units, and
termination, the stopping status. Read the feasibility and complementarity of that
point in best.evaluation, and the multiplier estimates with multipliers(). A
stopping status does not assess optimality. best and last are separate rounds.
candidate and objective describe best. The multipliers and the penalty belong
to last. They are the tentative multipliers lambda+ and mu+ of the last round,
which are the run's multiplier estimates, next to the multipliers that round used,
and they do not form a KKT pair with best. print(result) summarizes the run,
report() returns it as JSON-ready data, and save(path) writes it to a new
directory.
Attributes:
-
record(AugmentedLagrangianRecord) –The portable
AugmentedLagrangianRecord. -
problem(ConstrainedOptimization) –The live ConstrainedOptimization.
-
results(tuple) –The inner QHDAnalysis of each round in
record.iterations, or None for a round whose inner solve raised. With refinement, each round's entry is the tuple of the QHDAnalysis of its completed levels, in level order.
termination ¶
termination
The run's stopping status, such as feasible_complementary.
AugmentedLagrangianRecord lists the statuses. A status does not assess
optimality.
best ¶
best
The ALIteration of the reported best point, or None when no round chose a point.
It is the feasible round with the least f, or the round with the least violation when no round is feasible.
multipliers ¶
multipliers(*, tentative=True)
Return the last round's (equality, inequality) multipliers in original units, or None.
The layer's multipliers belong to the scaled problem, and each is converted to
original units, lambda_i = (s_f/s_{h_i}) lambda~_i and
mu_j = (s_f/s_{g_j}) mu~_j, formed exactly and rounded once. A value outside the
normal binary64 range raises ValueError. tentative=True, the default, converts
lambda+ and mu+ of the last round, the run's estimates, and False the multipliers
that round used, the initial multipliers when it is round 0. The equality tuple
follows the problem's equalities, and the inequality tuple follows
record.preprocessing.inequalities, the problem positions of the inequalities that
the rounds use, so an inequality absorbed into the box has no entry. None when no
round chose a point.
report ¶
report(*, failure_probability=DEFAULT_FAILURE_PROBABILITY)
Return a JSON-ready report built only from the stored record and content hashes.
It performs no objective evaluation, planning or measurement. multipliers maps each constraint's
problem position, as a string, to its original-unit multiplier estimate
(multipliers()), separately for equalities and inequalities, and is None when no
round chose a point or a value lies outside the normal binary64 range, which a
statement then names. inner_results holds one content hash per round, or with
refinement one list of level hashes per round, and refinement the number of levels
and the stopping reason of each round's refinement, None without refinement.
inequality_forms holds, per round, the form of each kept inequality by problem
position, the round's slack-grid error bound and why the policy chose the forms
(InnerRepresentation), and is None under inequality_form="phr".
With counts and box refinement, confidence contains selected region mass lower
bounds for each level's backend-sampled distribution conditioned on valid decoding,
with simultaneous 95% confidence by default. The horizon is
max_iterations * max_levels for the whole run, including early termination.
Hoeffding and one-sided Clopper–Pearson bounds each use half the failure budget;
each level reports the larger available bound. The dimension includes its slack
coordinates. The sampling assumptions and binary64 evaluation are those of
Proposition 49. Exact readout, no refinement, no completed
counts levels, or explicit None gives confidence=None.
Parameters:
-
failure_probability(float | None, default:DEFAULT_FAILURE_PROBABILITY) –Default
0.05. Total failure probability alpha, strictly between 0 and 1 and fixed before inspecting the counts. Set toNoneto omit the statistical report.
Returns:
-
report(dict) –JSON-ready summary, interpretation statements, stored record, multipliers, inner Result hashes, refinement details, coverage bounds and inequality forms.
Raises:
-
ValueError–If
failure_probabilityis neitherNonenor a number strictly between 0 and 1.
Examples:
result.report() includes the default bounds.
result.report(failure_probability=0.01) uses a total failure probability of 0.01.
save ¶
save(path)
Write the run to a new directory and return its path.
The directory holds constrained.json (format qhd.constrained/4) with the record,
problem.pickle with the live SymPy objective, variables and constraints, and
iterations/<k>/result/, each inner Result saved by its own archive. With
refinement each completed level z of round k has its Result under
iterations/<k>/levels/<z>/result/ instead, and the record nests the refinement
records. One format, qhd.constrained/4, covers both shapes, because the record
itself says which shape a folder has. load_augmented_lagrangian reads it back. The
archive stores the problem itself, because no Plan holds a ConstrainedOptimization.
A failed save removes the directory.
Parameters:
-
path(str | Path) –A directory that does not exist yet. Its parent must exist.
Returns:
-
path(Path) –The written directory.
AugmentedLagrangianRecord ¶
Bases: Record
Record of a whole augmented-Lagrangian run: problem, settings, preprocessing, rounds and stopping status.
ConstrainedQHDResult.record holds it, and ConstrainedQHDResult reads
termination, best and last from it. The fields below are read-only.
Stopping statuses:
feasible_complementary: the last round meets the normalized complementarity and feasibility tests of Algencan's Eqs. (10.7)-(10.8). This is not convergence in Algencan's sense, because the projected stationarity of Eq. (10.6) is not a stopping condition, and it does not assess optimality.feasible: the last round meets the feasibility test alone (termination="feasibility").iteration_limit:max_iterationsrounds ran without stopping.no_valid_point: the last inner result had no valid grid point.budget_exhausted: the remaining cumulativelimitscould not fund another round, possibly after zero rounds.inner_failed: the inner planning, preparation or execution of the last round raised, for example because QHD planning refused a larger penalty or a Run refused the remaining limits. Before anything has completed, in the first round without refinement or the first level of the first round with refinement,solve_augmented_lagrangianraises the original exception instead. The status also ends the run when f, h or g is not finite and real at a round's point, which in the first round raises, or at a point that a refinement level compares, its grid point or a point that a stall split scores, which raises only before anything has completed, as above. A refined round whose point then meets the stopping test ends with that test's status instead. A resume withend_at_unfinishable=Truerecords it for a reopened Run that could not finish without new work, with that Run's error as the failure.flat_objective,unresolved_objective,width_floor: reachable only with refinement. The last round's refinement stopped before its first level, because the inner objective's tables on the initial augmented box show no variation, no variation it can resolve, or a side at its width floor (BoxRefinementResult), so the round has no point and no update.
These statuses update no multiplier in their last round and retry nothing, and the
completed rounds stay in iterations. With refinement, a round whose refinement
completed a level and then stopped with budget_exhausted, inner_failed or
no_valid_point keeps its point and update, and the run ends with
feasible_complementary or feasible when that point meets the stopping test and
with the refinement's reason otherwise.
Attributes:
-
problem(ConstrainedOptimization) –The portable form of the constrained problem.
-
qhd(QHD) –The QHD configuration every round uses.
-
options(AugmentedLagrangian) –The layer's options.
-
refinement(BoxRefinement | None) –The box-refinement options of every round, or None when each round is one QHD solve. With refinement,
options.inner_pointequalsrefinement.point_rule, the readout of every level. -
execution(Literal['quantum', 'classical']) –quantumorclassical, for every round. -
shots(PositiveInt | None) –Shots per round, or None for exact readout.
-
entropy(int | tuple[int, ...]) –Entropy of the run's root
SeedSequence. -
limits(ExecutionLimits) –Cumulative execution limits of the whole run.
-
preprocessing(ConstraintPreprocessing) –The box and constraints the rounds use.
-
equality_scales(tuple[PositiveReal, ...]) –s_{h_i} of the equalities the rounds use.
-
inequality_scales(tuple[PositiveReal, ...]) –s_{g_j} of the inequalities the rounds use.
-
feasibility_tolerance(Nonnegative) –Resolved epsilon_f on normalized residuals.
-
complementarity_tolerance(Nonnegative) –Resolved epsilon_c.
-
admitted_work_bound(PositiveInt) –Upper bound on the run's counted planning work,
(a * M * L + t * M + 1) * qhd.max_work, fixed before the first round. The Work and byte bounds note below defines a, t, M and L and what the bound covers. -
admitted_bytes_bound(PositiveInt) –(a * M * L + t * M) * qhd.max_bytes, the sum of the byte allowances over the attempted Plans, levels and trials. It bounds neither process memory nor the outer records' content-hash JSON. The Work and byte bounds note below gives the details. -
iterations(tuple[ALIteration, ...]) –Every started round, in order, each an
ALIteration. -
termination(Literal['feasible_complementary', 'feasible', 'iteration_limit', 'no_valid_point', 'budget_exhausted', 'inner_failed', 'flat_objective', 'unresolved_objective', 'width_floor']) –One of the statuses above.
-
failure(Text | None) –Exception type and message for
inner_failed, the reason forbudget_exhausted, otherwise None. When the last round's refinement caused either status, itsfailuretext. -
best(Count | None) –Round of the reported best point, the round with the least f among rounds whose normalized infeasibility is at most
feasibility_tolerance, ties to the earliest. Without such a round, the round with the least infeasibility, then f, then round number. None when no round chose a point. -
last(Count | None) –The last round that chose a point, which holds the reported multipliers and penalty, or None.
-
resources(ALResources) –Totals of the rounds plus the layer's preprocessing evaluations.
Work and byte bounds
admitted_work_bound is fixed before the first round and bounds the counted QHD
work categories and the layer's own counted work. Write M for
options.max_iterations, L for refinement.max_levels, and a = 6 for
search-model or a = 4 for physical refinement. The bound is
(a * M * L + t * M + 1) * qhd.max_work. Without refinement, L = 1 and a = 4.
An ordinary Plan has at most four category bounds: the symbolic expansion, the
running total of the initial state's evaluation and the table, compiled-block
and schedule-integral work, whose first part, the initial state, planning checks
alone before evaluating it, the optional kept state, and the classical evolution
or circuit construction. A search-model level adds the symbolic and
running-total bounds of its unscaled table stage. Intermediate checks of one
category are not counted separately. The trials of automatic inequality
selection on the quantum route add t = 6 (m + 1) - 4 bounds per round without
refinement and t = 6 (m + 1) with it, for m kept inequalities, and t = 0
otherwise. The layer counts the work of its support-table check of f, h and g,
which also gives the inequality ranges, and of its evaluations once for the
whole run. At most M L levels are attempted, an attempted level that stops or
fails included. Refinement geometry, marginal and joint-mass processing, the
refinement's repeated objective decomposition and point evaluation, the symbolic
construction of the inner objectives, and library internals such as SymPy, SciPy
and the simulators lie outside these limit checks.
admitted_bytes_bound is (a * M * L + t * M) * qhd.max_bytes, with a, t, M
and L as above. It sums the byte allowances of the QHD categories over the
attempted Plans, levels and trials, each at most qhd.max_bytes while its
operation runs. It bounds neither process memory, nor the content-hash JSON of
the outer records, nor the further allocations of refinement itself.
Record size
The bounds on the scalar JSON leaves of this record, with their derivation, are in Engineering constants.
safeguard_used ¶
safeguard_used
Whether options.multiplier_bounds applied Algorithm 4.1 Step 4.
The truncation flags of each round show which values changed.
ALIteration ¶
Bases: Record
One augmented-Lagrangian round: its multipliers and penalty, the inner QHD solve or box refinement, and the chosen point.
ConstrainedQHDResult.iterations lists every started round, and best and last
name two of them. The fields below are read-only. Without refinement the round's
single inner QHD solve is named by plan_id, result_id and run_id. With
refinement those fields, the masses and the range bound are None, and refinement
holds the round's whole refinement: its levels with their boxes, masses, Plans,
Results and Runs, its best point and level, its stopping reason and its resources.
Each level's random stream is the child
SeedSequence(entropy, spawn_key=level.spawn_key) with
level.spawn_key = spawn_key + (z - 1,) for level z.
Attributes:
-
iteration(Count) –Round number k, from 0.
-
penalty(PositiveReal) –rho_k of this round.
-
equality_multipliers(tuple[Real, ...]) –lambda-bar^k, the normalized equality multipliers in L_k.
-
inequality_multipliers(tuple[Nonnegative, ...]) –mu-bar^k, nonnegative.
-
effective_objective(Text) –Content hash of L_k, the SHA-256 of its
srepr, the variable order and the box. -
entropy(int | tuple[int, ...]) –Entropy of the round's child
SeedSequence. -
spawn_key(tuple[Count, ...]) –Its spawn key under the run's root seed.
-
plan_id(ContentID | None) –Content hash of the inner QHD Plan, None when planning raised or with refinement.
-
result_id(ContentID | None) –Content hash of the inner QHDAnalysis, None when no result was returned or with refinement.
-
run_id(Text | None) –Identifier of the inner Run, None with refinement and when preparation raised without a saved Run whose run log names it.
-
valid_mass(Nonnegative | None) –Valid mass of the inner result, None without one.
-
invalid_mass(Nonnegative | None) –Invalid mass of the inner result, None without one.
-
missing(tuple[Text, ...]) –The inner result's reasons for missing data.
-
effective_range_bound(Nonnegative | None) –Upper bound on
max L_k - min L_kover the grid, the sum of the ranges of the inner Plan's support tables. None without a Plan, with refinement (each level records its ownenergy_scale), with a representation, whose Plan solves the inner objective instead, or when that sum exceeds binary64. -
representation(InnerRepresentation | None) –How the round represents its kept inequalities and which inner objective its Plans solve, or None under
inequality_form="phr", where the inner objective is L_k. -
inner_range_bound(Nonnegative | None) –For a round with a representation, the same sum of table ranges for the inner objective L(x, s) over the inner Plan's grid, and None otherwise, as for
effective_range_bound. -
refinement(BoxRefinementResult | None) –The round's box refinement of its inner objective from the preprocessed box and the round's slack boxes, or None without refinement.
-
evaluation(ALEvaluation | None) –The chosen point and its update, an
ALEvaluation, or None when the round produced no point. That happens with no valid point, an inner solve that raised, a refinement that completed no level, or f, h or g not finite and real at the round's point. -
resources(ALResources) –This round's resources, including work spent before a failure.
ALEvaluation ¶
Bases: Record
The point a round chose, its residuals and the multiplier and penalty update it implies.
ALIteration.evaluation holds it, for example result.best.evaluation for the best
point of a ConstrainedQHDResult. The fields below are read-only. infeasibility
and complementarity are the left sides of the stopping tests, and objective is f
at point in original units. Normalized values divide by the scales of the run.
Multipliers are normalized, and ConstrainedQHDResult.multipliers converts the last
round's multipliers to original units with lambda_i = (s_f/s_{h_i}) lambda~_i and
mu_j = (s_f/s_{g_j}) mu~_j.
The round reads its point by the rule of AugmentedLagrangian.inner_point, in the
inner coordinates of its inner objective, L_k under the PHR policy and L(x, s) with
an inequality representation. The Point rules note of
AugmentedLagrangian
describes the rules. The outer point is the projection onto the original variables,
and effective_value is the PHR value L_k evaluated at that projection when a
representation is present.
With box refinement the point is that of the level with the least recorded relative
value of the inner objective (ALIteration.refinement), and the grid and the
probability are that level's. f, h and g are evaluated at its reported point in the
original coordinates. For the search model that point is a + D u rounded once to
binary64 while the level's objective is evaluated at the exact image a + D u, so
the two can differ by the rounding of the point (RefinementLevel.point).
With an InnerRepresentation the indices, probability, tie deficit, tie window and
mode status belong to the joint inner grid point, not to the marginal of x summed
over the slacks, inner_value holds L(x, s) and effective_value the PHR objective
L_k evaluated at x (Proposition 54). A joint mode need
not project to the mode of the marginal distribution of x. A joint probability table
with rows indexed by x and entries [[0.30, 0.29], [0.31, 0.10]] has its unique
joint maximum in the second row but its marginal maximum in the first row, and two
tied joint points can have the same x. An unresolved joint status therefore does not
imply competing projected x values, and a resolved joint status does not certify a
unique projected marginal mode.
Attributes:
-
rule(Literal['most_probable', 'best_observed', 'mode_or_mean']) –The inner-point rule (
AugmentedLagrangian.inner_point). -
kind(Literal['grid_point', 'valid_mean']) –grid_pointorvalid_mean, the valid-mass mean position thatmode_or_meancan choose. -
indices(tuple[Count, ...] | None) –Grid index per original variable, None for
valid_mean. With refinement, on the grid of the best level. -
point(tuple[Real, ...]) –The point in the original coordinates, the projection of a joint inner point.
-
probability(Nonnegative | None) –Unconditional probability of the inner grid point in the inner result, or in the best level's result with refinement, None for
valid_mean. With slack variables it is the probability of the joint point. -
tie_deficit(Nonnegative | None) –For a most probable grid point (
most_probable, andmode_or_meanwhen it takes the grid point), the computed maximum probability minus the chosen point's probability, positive when a point within the tie window was preferred by the lexicographic rule. None otherwise. With slack variables it is that of the joint point. -
tie_window(Nonnegative | None) –The inner readout's tie window for such a point, or None when there is none or the window was unavailable.
-
mode_status(ModeStatus | None) –Mode-resolution status of the inner grid representative when this evaluation chooses it. With refinement it is copied from the best level's QHD Result. None for best_observed or a chosen valid-mass mean. For a slack representation it describes the joint inner point before projection onto the original variables.
-
mean_unavailable(Text | None) –For
mode_or_mean, why the valid-mass mean was not compared, so that the round took the grid point. That happens when f, h or g was not finite and real there, or with refinement the best level's inner objective (RefinementLevel.mean_unavailable). None otherwise. -
effective_value(Real) –L_k at the point in normalized units. Without a representation it is the inner value, with refinement the best level's recorded objective (
RefinementLevel.objective). With a representation it is the PHR objective L_k evaluated atpointfrom f, h and g, also at a grid point. -
effective_value_source(Literal['table', 'evaluated']) –tablewhen read from the inner Plan's support tables, or with refinement when the level read L_k at its grid point from its stored tables.evaluatedwhen L_k was evaluated at an off-grid mean, from f, h and g by the layer or, with refinement, by the level, and in every round with a representation. -
inner_value(Real | None) –For a round with a representation, the inner objective L(x, s) at the chosen joint point in normalized units, None otherwise. In exact arithmetic the slack objective is at least the PHR objective for nonnegative slacks. The recorded values can have different evaluation and coordinate-transformation errors, which this field does not bound.
-
inner_value_source(Literal['table', 'evaluated'] | None) –tableorevaluatedforinner_value, by the rules ofeffective_value_source, None without it. -
slack_indices(tuple[Count, ...] | None) –Grid index per slack variable of the joint grid point, None for
valid_meanand without slack variables. -
slack_point(tuple[Real, ...] | None) –The slack coordinates of the joint point, in the order of
InnerRepresentation.slacks, None without slack variables. -
objective(Real) –f at the point in original units.
-
objective_normalized(Real) –f/s_f.
-
equality_residuals(tuple[Real, ...]) –h_i at the point in original units.
-
equality_residuals_normalized(tuple[Real, ...]) –h_i/s_{h_i}.
-
inequality_residuals(tuple[Real, ...]) –g_j at the point in original units.
-
inequality_residuals_normalized(tuple[Real, ...]) –g_j/s_{g_j}.
-
infeasibility(Nonnegative) –max(||h~||_inf, ||g~_+||_inf), the left side of Eq. (10.8) on normalized residuals. -
complementarity(Nonnegative) –max(||h~||_inf, max_j |min(-g~_j, mu+_j)|), the left side of Eq. (10.7). -
measure(Nonnegative) –max(||h~||_inf, ||V||_inf)withV_j = min(-g~_j, mu-bar_j/rho), Eq. (4.9). -
tentative_equality_multipliers(tuple[Real, ...]) –lambda+ of Eq. (4.7).
-
tentative_inequality_multipliers(tuple[Nonnegative, ...]) –mu+ of Eq. (4.8), nonnegative.
-
next_equality_multipliers(tuple[Real, ...]) –The equality multipliers a next round uses, lambda+ clipped by
multiplier_boundswhen given. -
next_inequality_multipliers(tuple[Nonnegative, ...]) –The inequality multipliers a next round uses, nonnegative.
-
equality_truncated(tuple[StrictBool, ...]) –Whether the safeguard changed each lambda+.
-
inequality_truncated(tuple[StrictBool, ...]) –Whether the safeguard changed each mu+.
-
next_penalty(PositiveReal) –The rho a next round uses. A round that stops the run still records it.
-
stationarity(Nonnegative | None) –The projected-gradient diagnostic r_stat, or None.
-
stationarity_unavailable(Text | None) –Why r_stat is None: not requested, a nondifferentiable function, or a nonfinite gradient at the point.
ALResources ¶
Bases: Record
Resources of one augmented-Lagrangian round, or of a whole run, with measurement kept apart from host work.
ALIteration.resources holds a round's, and ConstrainedQHDResult.resources the
run's totals. The fields below are read-only. A count is None when it is unknown,
and unavailable names each such field with its reason. Unknown is never replaced
by zero. A total sums each count over the rounds, except width and
restricted_dimension, which take the largest round, and is unknown when any
round's count is unknown. Measurement counts are what the inner Runs set aside,
including failed and uncertain attempts, as ExecutionTrace counts them. A round
with box refinement counts every level of its refinement, completed or stopping
(BoxRefinementResult.resources), and a count is unknown when the refinement's is.
The counts are the work of the algorithm, each counted once as in an uninterrupted
run, and not the host time spent across the calls of a saved run
(resume_augmented_lagrangian). A resumed run reads the counts of its completed
rounds and levels from their records, and a Run that it continues keeps the counts
of its own run log. Host work that resume repeats, the layer's preprocessing and the
unscaled table stage of a reopened search-model level, is deterministic and not
counted again.
Attributes:
-
width(PositiveInt | None) –Register width of the inner Plan,
D Kone-hot orD log2 Kbinary for its D variables, slack variables included, or of the refinement's completed levels. -
restricted_dimension(PositiveInt | None) –Valid grid size
K**Dof the inner Plan, or of the refinement's completed levels. -
cx(Count | None) –CX upper bound of the circuit that each round or refinement level prepared (
ResourceLawwith metriccx), summed over rounds and levels and not multiplied by shots. The Circuit counts note below says when a round counts 0 and when the value is unknown. -
arbitrary_rotations(Count | None) –Arbitrary rotations of the same circuits, counted as
cxis, an upper bound for the binary encoding. For quantum execution it equals the body totalarbitrary_rotationsofrun_resources. -
circuit_preparations(Count | None) –Circuit preparations.
-
circuit_attempts(Count | None) –Circuit attempts of every status.
-
completed_circuit_attempts(Count | None) –Those of them that completed with an observation. The rest are attempts that are reserved, uncertain or failed.
-
shots(Count | None) –Raw shots set aside by every attempt.
-
completed_shots(Count | None) –Raw shots of the completed attempts.
-
data_bytes(Count | None) –Recorded Run data bytes.
-
table_evaluations(Count | None) –Objective-table grid tuples evaluated by QHD planning, including discarded automatic-selection candidates and, with refinement, every level's planning. The Circuit counts note below gives what each round adds and when the count is unavailable.
-
evolution_work(Count | None) –Classical-kernel work that the inner Run counted before the classical evolution, in QHD's work units.
-
construction_work(Count | None) –Circuit construction and host preparation work that the inner Run counted.
-
synthesis_work(Count | None) –Exact dense synthesis work that the inner Run set aside.
-
layer_evaluations(Count) –Scalar expression evaluations by the augmented-Lagrangian layer itself (f, h, g, their gradients and the mean-position value), with refinement also the checks of f, h and g at every point that a level compares. A run's total also counts the support-table entries and any original-expression numerical scans of the grid check before the first round.
-
layer_work(Count) –Their work, one unit per expression-tree node and per coordinate of each evaluation, and in a run's total one unit per monomial of the grid check's expansions.
-
refinement_evaluations(Count) –Evaluations of the round's inner objective by box refinement at its level points (
RefinementResources.objective_evaluations), zero without refinement. The refinement does not count their work. -
joint_mass_reads(Count) –Joint-observation read count of box refinement, summed over its levels, zero without refinement (
RefinementResources.joint_mass_readsdefines it). -
unavailable(tuple[tuple[Text, Text], ...]) –(field, reason)for every count that is None.
Circuit counts
A round or level that prepared no circuit, including every round of classical
execution and one whose Run's creation raised before its run-log header,
contributes 0 to cx and arbitrary_rotations, and one whose preparation
raised after that header or whose preparation count is unknown makes the value
unknown. A Run prepares at most one circuit, so for quantum execution
arbitrary_rotations equals the body total of run_resources, which also
multiplies each circuit by its shots and adds T estimates.
table_evaluations includes automatic-selection candidates that were discarded.
An unrefined round counts its reused Plan once. A refined round also counts
every level's planning and each search-model level's unscaled table stage. The
count is unavailable when a failed planning attempt's partial evaluations are
unknown. The candidates' count is InnerRepresentation.table_evaluations, and
the level counts are RefinementResources table_evaluations plus
support_evaluations.
ConstraintPreprocessing ¶
Bases: Record
The box and constraints that the rounds use, derived from the problem once, in original coordinates.
AugmentedLagrangianRecord.preprocessing holds it, and plan_augmented_lagrangian
returns it first. The fields below are read-only.
Attributes:
-
original_bounds(tuple[tuple[Real, Real], ...]) –The problem's box.
-
bounds(tuple[tuple[Real, Real], ...]) –The box after bound absorption, which every inner QHD Plan and the stationarity diagnostic use for the original variables.
-
absorbed(tuple[AbsorbedBound, ...]) –Inequalities replaced by box bounds, in problem order.
-
equalities(tuple[Count, ...]) –Problem positions of the equalities the rounds use (all).
-
inequalities(tuple[Count, ...]) –Problem positions of the inequalities the rounds use, those not absorbed.
-
inequality_lower(tuple[Real | None, ...]) –For each entry of
inequalities, the lower bound ell =(c0 + sum_A min T_A)/s_gof the normalized inequality on the grid ofboundsfrom its support tables, rounded downward, or None outside the binary64 range (Proposition 54). It bounds the tabulated representation on that grid, not the continuous box or a refinement level's grid. -
inequality_upper(tuple[Real | None, ...]) –The upper bound M =
(c0 + sum_A max T_A)/s_gon the same grid, rounded upward, or None outside the binary64 range.
AbsorbedBound ¶
Bases: Record
One inequality a x_j + b <= 0 replaced by the box bound x_j <= -b/a or x_j >= -b/a.
AugmentedLagrangian(absorb_bounds=True) produces it, and
ConstraintPreprocessing.absorbed lists it. The fields below are read-only.
Attributes:
-
inequality(Count) –Position of the inequality in the problem.
-
variable(Count) –Position of x_j among the variables.
-
side(Literal['lower', 'upper']) –upperfor a > 0 andlowerfor a < 0. -
value(Real) –-b/a, which bounds x_j and equals this binary64 number exactly.
InnerRepresentation ¶
Bases: Record
How one round represents its kept inequalities in the inner problem that its QHD Plans solve.
ALIteration.representation holds it under inequality_form="slack" or "auto",
and plan_augmented_lagrangian returns round 0's. The fields below are read-only.
The round's inner objective is L(x, s) = A(x) + sum_j T_j of
Proposition 54, with the equality part A of the
effective objective L_k and one term T_j per kept inequality. T_j is the PHR term,
the slack term mu_j (G_j + s_j) + (rho/2) (G_j + s_j)**2, the quadratic
mu_j G_j + (rho/2) G_j**2 when ell_j + mu_j/rho >= 0, or the constant
-mu_j**2/(2 rho) when M_j + mu_j/rho <= 0. On the grid of the preprocessed box
the last two equal the PHR term for the tabulated representation of G_j, and
min_s L(x, s) is the PHR objective L_k. The outer update, the stopping tests and
the stationarity diagnostic use the PHR term at the projected point x.
Attributes:
-
policy(Literal['phr', 'slack', 'auto']) –AugmentedLagrangian.inequality_form. -
forms(tuple[Literal['phr', 'slack', 'quadratic', 'constant'], ...]) –One of
phr,slack,quadraticandconstantper kept inequality, in the order ofConstraintPreprocessing.inequalities. -
slacks(tuple[SlackAxis, ...]) –One
SlackAxisperslackform, in the same order. -
variables(tuple[Text, ...]) –Names of the inner problem's variables, the problem's variables followed by the slack variables.
-
grid(Literal['dirichlet_interior', 'dirichlet_endpoints', 'periodic']) –The slack grid's convention, from the Method's
boundaryandinclude_boundary_points:dirichlet_interior,dirichlet_endpointsorperiodic. -
grid_points(PositiveInt) –Points of each slack grid, the Method's
num_grid_points. -
cap_scope(Literal['grid']) –grid. The caps and branch tests hold on the grid of the preprocessed box, not on the continuous box or on the nested grids of later refinement levels. -
error_bound(Nonnegative) –The sum of the slacks' error bounds, rounded upward, a bound on
E_maxof Proposition 54 for the round's multipliers and penalty. Zero without slacks. -
trials(tuple[FormTrial, ...]) –The trial conversions of automatic selection, in constraint order, empty for the other policies.
-
selection(Text) –Why the policy chose these forms.
-
table_evaluations(Count | None) –Objective-table grid tuples that QHD planning evaluated for the candidates of automatic selection, each planned candidate once, the current representation and every trial, whether kept or discarded. Zero for the other policies and when selection planned nothing. The round adds the candidates that its Plans do not reuse to
ALResources.table_evaluations. None when a candidate's planning raised after its tables were accepted, so that its partial evaluations are unknown. -
table_evaluations_unavailable(Text | None) –Why
table_evaluationsis None, or None. -
inner_objective(Text) –Content hash of the inner objective, the SHA-256 of its
srepr, the inner variables'sreprand the inner box, which the inner Plans solve.
SlackAxis ¶
Bases: Record
The slack variable of one converted inequality in a round's inner problem (Proposition 54).
InnerRepresentation.slacks lists one per converted inequality. The fields below
are read-only. The inequality g_j <= 0 enters the round as
mu_j (G_j + s_j) + (rho/2) (G_j + s_j)**2 with G_j = g_j/s_{g_j} and
s_j in [0, upper], whose minimum over s_j >= 0 is the PHR term of the effective
objective L_k whenever the box contains the minimizer [-G_j - mu_j/rho]_+. The
slack has the units of the normalized G_j.
Attributes:
-
inequality(Count) –Problem position of the converted inequality.
-
variable(Text) –Name of the slack variable in the inner problem.
-
cap(PositiveReal) –U_0 = [-ell_j]_+with ell_j the recorded lower bound ofConstraintPreprocessing.inequality_lower, positive. It contains[-G_j - mu/rho]_+for every nonnegative multiplier and positive penalty on the grid of the preprocessed box, for the tabulated representation of G_j (scopegrid). -
upper(PositiveReal) –The upper end U of the slack box
[0, U]. It is U_0 on a Dirichlet grid, and on a periodic gridK/(K-1) U_0rounded upward, so that the slack grid0, h, ..., U - hcovers[0, U_0]withU - h >= U_0. -
spacing(PositiveReal) –The slack grid's spacing h.
-
error_bound(Nonnegative) –Upper bound, rounded upward, on the slack-grid excess
min_s phi_j(x, s) - P_j(G_j(x))over the grid points x of the preprocessed box, for the round's entering multiplier and penalty. The Slack-grid bound note below gives its formula and the conditions under which it is a bound.
Slack-grid bound
error_bound is r h + rho h**2/2 with r = [mu + rho M_j]_+ on the Dirichlet
interior grid, and rho h**2/8 on the endpoint grid and on the periodic grid
with its margin. It assumes the exact mesh of spacing h and the assumptions of
the cap. Interpreting the formula as a slack-grid excess bound requires the cap
and table-arithmetic assumptions and the node coverage used in Proposition 54.
The interior formula requires a first node no larger than h and distance at most
h from every required slack to the grid. The endpoint and covered periodic
formulas require zero and distance at most h/2. Rounding the spacing and
coordinates can affect these conditions. This field supplies no separate
allowance for that effect.
FormTrial ¶
Bases: Record
One trial conversion of automatic selection, AugmentedLagrangian(inequality_form="auto").
InnerRepresentation.trials lists one per trial. The fields below are read-only.
The current representation and the trial with one more slack variable are compared
by their planned host work, the work that QHD's symbolic and table check counts plus
the chosen circuit construction's work, and by the CX count of that construction.
Attributes:
-
inequality(Count) –Problem position of the inequality the trial converts.
-
current_work(Count | None) –Planned host work of the current representation, or None when its planning was refused.
-
current_cx(Count | None) –Its CX count per circuit, or None when its planning was refused or the construction has no CX count.
-
trial_work(Count | None) –Planned host work of the trial, or None when refused.
-
trial_cx(Count | None) –CX count of the trial, or None as for
current_cx. -
accepted(StrictBool) –Whether the round keeps the trial. It does when both counts are no larger and one is strictly smaller, or when the current planning was refused and the trial was accepted with a CX count. A missing CX count keeps the current representation.
-
reason(Text) –Why the trial was accepted or kept out.
ConstrainedGridMinimum ¶
Bases: Record
Evaluated finite-grid reference of constrained_grid_minimum.
constrained_grid_minimum
returns it. The fields below are read-only. The answer is gap, the run's stored
best objective minus the least evaluated feasible objective objective, in original
units. Computed feasibility uses the run's scales and feasibility_tolerance on the
normalized residuals. The reference covers the preprocessed box's grid. It bounds
neither objective nor constraint evaluation error and does not establish equality of
the computed and mathematical feasible sets. A large objective constant can make
distinct exact values tie in binary64.
Attributes:
-
record_id(ContentID) –Content hash of the AugmentedLagrangianRecord of the run.
-
grid_points(PositiveInt) –K**dpoints evaluated. -
feasible_points(Count) –Points whose computed normalized infeasibility is at most the tolerance.
-
indices(tuple[Count, ...] | None) –Grid index per variable of the point passing the computed feasibility test with the least evaluated binary64 objective, ties to the lexicographically smallest index, or None when no grid point passes.
-
point(tuple[Real, ...] | None) –That point in the original coordinates, or None.
-
objective(Real | None) –Its evaluated f in original units, including the constant, or None.
-
best_objective(Real | None) –Stored evaluated f at the run's reported best point, or None when the run chose no point.
-
best_feasible(StrictBool | None) –Whether that best point passes the same computed tolerance test, or None. This does not state objective optimality.
-
gap(Real | None) –best_objective - objectivein original units, or None when either is None. It compares a stored value with a fresh grid minimum and can be negative, including when the point is infeasible or is an off-grid mean chosen bymode_or_mean. The Gap note below bounds the exact gap. -
feasibility_tolerance(Nonnegative) –The tolerance used.
-
work(Count) –Work checked against
max_workbefore the first evaluation.
Gap
Let G be the nonempty grid subset passing this check's computed feasibility
test, and let the reported point a lie in G. Suppose a finite E >= 0 bounds the
absolute error of the stored objective at a and every fresh objective on G,
relative to exact values at the same coordinates. For finite reported gap r and
u = 2**-53, the exact gap F(a) - min_G F is at most r/(1-u) + 2*E if r >= 0,
and r/(1+u) + 2*E if r < 0. These are real-arithmetic inequalities under
round-to-nearest binary64 with gradual underflow. The check establishes neither
E nor equality of G with the mathematically feasible grid set.
Refine the box¶
refine_box ¶
refine_box(problem, *, qhd, options, execution=None, shots=None, backend=None, seed=None, limits=None, progress=None, directory=None)
Refine the box of an optimization problem by repeated QHD solves, following Wu et al. arXiv:2605.12066v1, Sec. V.
refine_box(problem, qhd=QHD(...), options=BoxRefinement()) solves level z as one
QHD Plan on its box B_z, as options.scaling maps the box to a QHD problem. Each
level reports a point by options.point_rule and records the original objective
evaluated in the level's coordinates. For the search model this is the transformed
expression F(a + D u) evaluated at the chosen unit point, before rounding its
affine image for display. From the level's marginals it keeps an index interval on
every axis that holds the conditional mass options.mass_threshold, records the
joint mass bound and, when the result has joint observations, the directly computed
joint mass, and forms B_{z+1} from the cells of the kept intervals. The best point
is the reported point with the least recorded relative objective F - C, the earlier
level on ties, where C is one exact constant for the whole refinement. It is the
best of the reported finite-grid points, not a continuous or global optimum. The
guide's box refinement section explains
each rule and its evidence.
Parameters:
-
problem(Optimization) –Objective, ordered variables and the initial box.
-
qhd(QHD) –QHD configuration of every level. With
options.level_initial_state="best_point_gaussian"a best-point Gaussian replaces its initial state after the first level. -
options(BoxRefinement) –Refinement options, including the scaling.
-
execution(str | None, default:None) –"quantum"(the default) or"classical", as fornwqlib.solve. -
shots(int | None, default:None) –Shots per level, or None for exact readout.
-
backend(object | None, default:None) –Backend of every level Run, as for
nwqlib.solve. -
seed(int | None, default:None) –Nonnegative seed of a
numpy.random.SeedSequence. Each level plans with its own spawned child, asnwqlib.compareseeds its candidates. -
limits(ExecutionLimits | None, default:None) –Cumulative limits of the whole refinement. Each level Run receives what the earlier levels left. None uses the ExecutionLimits defaults.
-
progress(object | None, default:None) –Progress callback of every level Run, as for
nwqlib.solve. -
directory(str | Path | None, default:None) –A new directory for a saved refinement that
resume_box_refinementcan continue, or None to keep every level Run in memory. It must not exist, and missing parents are created.
Returns:
-
result(BoxRefinementResult) –The refinement.
candidateandobjectivegive the best point and the original objective there,terminationwhy it stopped,levelsthe completed levels,resultstheir QHD results andproblemthe original problem, whichsavestores.
Raises:
-
ValueError–If the options ask for what the QHD configuration cannot carry out, such as a split budget on a periodic grid, or if the first level fails as described above.
-
FileExistsError–If
directoryexists. The message namesresume_box_refinement, which continues it.
Stops
Before each level, refinement stops at max_levels levels, an unchanged box, a
box at its width floor (for the physical model also a box that the grid
rejects), max_no_improve levels without a strict decrease of the best relative
objective, or remaining limits that cannot fund a level, checked in this order.
With options.stall_split="best_region" a level whose next box equals its box,
and which is not the last of max_levels, is split instead of stopping the
refinement while fewer than max_splits splits have been made, and the next
level solves the chosen region. A split is made only when the next level could
run, decided before any score or read for it. When the no-improvement count
after this level reaches max_no_improve, or the limits left after this level
cannot fund one, the level records no split and the refinement stops with
no_improvement or budget_exhausted, without a valley search. Otherwise the
level looks for a resolved valley. Without one it stops with box_unchanged,
and when neither region that a split at the valley can keep passes the width
floor it stops with width_floor. When only one of the two regions fails the
width floor and the split keeps it, the refinement stops with width_floor
after the split. The no-improvement count continues across a split. An unchanged
box after the last split stops with split_limit. A stalled level that does not
split records why in RefinementLevel.split_declined. A split budget on a
periodic grid raises ValueError before the first level, since one cut does not
divide a periodic axis into two regions. A level whose tables show no variation
or no resolvable variation, whose planning or Run raises, or whose result has no
valid point also stops it, and completed levels are kept for every one of these
stops. These stops end the refinement and never lead to a split. When the grid
rejects the first box, or the planning or Run of the first level raises, nothing
has completed, and the original exception propagates. An exception from the
refinement's own evaluation of a solved level, such as a nonreal objective value
at the reported grid point, propagates.
Point rules
Each level reads the rule's grid point. For mode_or_mean it compares F at that
point with F at the valid-mass mean position of the level's own coordinates.
Refinement compares its points by F - C and reports F, both of which each level
reads from its stored tables at a grid point and evaluates term by term at an
off-grid mean. C is the constant term of the first level's decomposition, so an
additive constant of F leaves every comparison unchanged when the constant and
every coefficient of F are exact SymPy numbers, while F itself can round the
objective's variation away next to a large constant. A physical level takes F at
its grid coordinate or mean. A search-model level takes F(a + D u) at the unit
point u, for exact coefficients F at the exact affine image of u, and records u
as RefinementLevel.unit_point. Its reported point is that image rounded once,
a display value.
Initial state
Every level plans its level problem with qhd, so QHD.initial_state is read
in the coordinates of the level problem. For the search model these are the unit
coordinates u, so the center and widths of a GaussianState there are unit
coordinates, fixed relative to every level box, and not original ones. With
options.level_initial_state="best_point_gaussian" every level after the first
instead starts from a Gaussian at the best point so far, written in the same
coordinates.
Levels and seeds
Each level plans from its own child of SeedSequence(seed) and runs its Plan
with prepare and submit, as solve runs a Plan. This is an orchestration of
QHD Plans, not a Method. It never retries a level.
Saved refinements
With directory every level Run is saved under levels/<z>/run/, each level
writes its table-stage data once to levels/<z>/tables.json, and the outer
record is rewritten after each completed level and once more at the end, so that
resume_box_refinement can continue an interrupted refinement. The outer record
stores the configuration of the backend of every level Run, and the model of a
noisy Aer backend is saved once in the directory.
Examples:
The minimizer of (x - 3/10)**2 on [-1, 1] is not a grid point of the first
level. Three levels shrink the box around it, and the best point lies within
0.015 of 0.3.
>>> import sympy as sp
>>> from nwqlib.problems import Optimization
>>> from nwqlib.algorithms.qhd import QHD, BoxRefinement, refine_box
>>> x = sp.Symbol("x", real=True)
>>> problem = Optimization(objective=(x - sp.Rational(3, 10))**2,
... variables=(x,), bounds=((-1.0, 1.0),))
>>> result = refine_box(
... problem, qhd=QHD(num_grid_points=8, num_steps=80, total_time=10.0,
... theory_flavor="split_step"),
... options=BoxRefinement(), execution="classical", seed=7)
>>> print(result.termination, len(result.levels))
level_limit 3
>>> print([[round(v, 4) for v in level.box[0]] for level in result.levels])
[[-1.0, 1.0], [0.0, 1.0], [0.1667, 0.6111]]
>>> print([round(v, 6) for v in result.candidate])
[0.314815]
BoxRefinement ¶
Bases: Record
Options of a box refinement, the finite-grid search of Wu et al. arXiv:2605.12066v1, Sec. V.
Build it with keyword arguments, for example
BoxRefinement(max_levels=6, mass_threshold=0.9), and pass it to
refine_box(..., options=...) or solve_augmented_lagrangian(..., refinement=...).
Every argument is optional. Every level solves QHD on its box, keeps on each axis
the index interval that holds the conditional marginal mass mass_threshold, and
solves the next level on the box those intervals represent. The defaults are
registered as "Box refinement defaults", "Box refinement scaling and potential_gain"
and "Box refinement stall split" in the
engineering constants,
and the guide's box refinement section
gives the evidence behind them.
Attributes:
-
scaling(Literal['search_model', 'physical']) –Default
"search_model". How a level box becomes a QHD problem:"search_model", the normalized objective(F(a + D u) - c)/Eon the unit box, the same dimensionless model at every level, or"physical", the original objective on the level box. The Scaling note below gives the details. -
max_levels(PositiveInt) –Default
3. Largest number of levels solved, a positive integer. -
mass_threshold(Real) –Default
0.99, in (0, 1]. Conditional marginal mass eta that each axis interval must reach. Marginal masses at least eta imply joint mass at leastmax(0, 1 - d(1 - eta))in exact arithmetic. The Masses note below says what this does and does not bound. -
box_rule(Literal['centered']) –Default
"centered", the only accepted value. Each kept grid point represents the cell between the midpoints to its neighbors, of width h centered on it on a uniform grid, and an interval that reaches an end of its axis keeps that face of the box. -
max_no_improve(PositiveInt) –Default
2. Positive number of consecutive levels without a strict decrease of the best relative objective (RefinementLevel.relative_objective) after which refinement stops. -
point_rule(Literal['most_probable', 'best_observed', 'mode_or_mean']) –Default
"most_probable". Point each level reports:"most_probable", the most probable valid grid point,"best_observed", the QHD candidate, or"mode_or_mean", the conditional mean position when its relative objective is strictly smaller, and the most probable point otherwise. The Point rules note below gives the details. -
potential_gain(Real | None) –Default
None, which selects 8 for the search model. kappa > 0, the dimensionless strength of the search model's normalized potential. The physical model has no gain and rejects any explicit value.gainresolves the value each level solves. The Scaling note below gives the level Hamiltonian. -
stall_split(Literal['none', 'best_region']) –Default
"none", which stops the refinement withbox_unchangedwhen a level's next box equals its box."best_region"instead splits the level at a resolved valley of an axis marginal and continues on one side, giving up the other side's probability. The Stall split note below gives the rule and its requirements. -
max_splits(Count) –Default
1. Largest number of stall splits in one refinement, a nonnegative integer. A stall after the last one stops withsplit_limit, whether or not its level has a valley, and withmax_splits=0the first stall does. It keeps its default withstall_split="none". In the augmented-Lagrangian layer the budget holds for each round's refinement. -
level_initial_state(Literal['configured', 'best_point_gaussian']) –Default
"configured", which plans every level withQHD.initial_state."best_point_gaussian"starts every level after the first from aGaussianStateat the refinement's best point so far, each such level recording it inRefinementLevel.initial_state. The Level initial state note below gives the details. -
level_gaussian_width(Real | None) –Default
None, which selects 1/6 withlevel_initial_state="best_point_gaussian". Width sigma of the best-point Gaussian as a fraction of each side of the level box, which is its width in the search model's unit coordinates."configured"rejects any value.gaussian_widthresolves it.
Scaling
"search_model" solves on the unit box u in [0, 1]^d the normalized objective
(F(a + D u) - c)/E, the same dimensionless model at every level, with a the
lower corner and D the diagonal matrix of side lengths of the level box. Each
level solves a(t) T_u + kappa b(t) V_z with V_z = (F - c_z)/E_z, so kappa
(potential_gain) multiplies V_z after E_z is formed. "physical" solves the
original objective on the level box in original coordinates, the same physical
Hamiltonian on a smaller box. Every level plans its problem with the QHD
configuration, so under the search model the center and widths of a
GaussianState given as QHD.initial_state are unit coordinates of each level
box, not original ones.
Masses
The reported union-bound formula is max(0, 1 - sum_j(1 - m_j)) for the
observed conditional marginal masses m_j (RefinementLevel.joint_mass_bound).
In exact arithmetic, marginal masses at least eta imply joint mass at least
max(0, 1 - d(1 - eta)). With counts these are empirical masses conditional on
a valid outcome, not a confidence bound for the underlying population.
Point rules
"most_probable" is the most probable valid grid point of the level's QHD
result. "best_observed" is the observed valid point with positive weight and
the least evaluated binary64 value of the objective solved by that level
(QHDAnalysis.candidate). "mode_or_mean" is the conditional mean position
when its relative objective is strictly smaller than the most probable point's,
and that point otherwise. In the augmented-Lagrangian layer
(solve_augmented_lagrangian(refinement=...)) the objective is the round's L_k,
this rule reads every level of the round, and it must equal
AugmentedLagrangian.inner_point, so that one rule describes every point of the
run.
Stall split
"best_region" finds the resolved valley with the largest smaller-peak/valley
ratio of an axis marginal, scores each strict side of it by the objective at the
side's most probable joint grid point, and continues on the lower-scoring side
only, together with the valley cell. A level without a resolved valley still
stops with box_unchanged. A periodic grid with a positive split budget is
refused. The other side's probability is given up, so the kept box no longer
holds mass_threshold of that level's distribution. Classical execution needs
QHD(keep_state=True) for it, since the scores read the joint distribution. The
guide states the rule's cost and risk.
Level initial state
"best_point_gaussian" plans the first level with QHD.initial_state and every
later level with a GaussianState centered at the refinement's best point so
far, with width gaussian_width times each side of the level box. The guide
states when it helped and when it hurt. Each such level records its Gaussian
(RefinementLevel.initial_state). In the augmented-Lagrangian layer the first
level of every round uses QHD.initial_state.
Raises:
-
ValueError–If
potential_gainis set withscaling="physical",max_splitsdiffers from 1 withstall_split="none", orlevel_gaussian_widthis set withlevel_initial_state="configured".
gaussian_width ¶
gaussian_width
Return the width fraction w of the best-point Gaussian, or None with level_initial_state="configured".
It is level_gaussian_width, or 1/6 when that is None.
gain ¶
gain
Return kappa, the gain that each level solves, or None for the physical model.
It is potential_gain, or 8 when that is None. refine_box solves and records this
value (RefinementLevel.potential_gain).
resume_box_refinement ¶
resume_box_refinement(directory, *, backend, progress=None, end_at_unfinishable=False)
Continue an interrupted refinement of refine_box(..., directory=...), or return it when it has ended.
Pass the directory and the backend of the original call. The directory's outer
record names the problem, the QHD configuration, the options, execution, shots, root
entropy, cumulative limits and backend configuration of the refinement, and holds
its completed levels. As in resume_augmented_lagrangian, backend must have the
stored configuration, a noisy Aer run gets the noise model saved in the directory
bound to a copy of backend, and another backend raises ValueError before any work.
The problem comes back from problem.pickle and must have the content hash of the
stored problem record, as in resume_augmented_lagrangian, or ValueError is raised
before any level Result is read or the refinement advances. Each completed level's
Result is read from its Run with load_run. The directory is read as the layer
wrote it, and edits are not detected
(Saved folders are read-only).
The refinement then continues from its last completed level with the state that the
uninterrupted
run had there. The level in progress reads its saved unscaled tables and their
evaluation count instead of evaluating its tables again, and the refinement's
constant C comes from the first level's saved data when it is rational. A level
whose Run exists continues that Run with load_run(...).wait(), and no level gets a
second Run. When that Run cannot finish without new work, because the interruption
stopped a local preparation, measurement or classical evolution whose outcome
nothing can retrieve, its error propagates with a note, and the outer record keeps
its committed levels unchanged. With end_at_unfinishable=True the refinement
instead ends there with inner_failed, keeps its completed levels and records the
Run's error as the failure. This option handles an unfinishable continuation after a
Run has reopened. A Run folder without a committed run-log header fails during
reopen and is not handled by end_at_unfinishable. Reopen does not remove or
recreate that folder automatically. Before a completed round or level exists, an
inner failure still propagates.
A directory whose refinement has ended returns its result, with the level Results
read from their Runs and the problem from problem.pickle attached, and plans,
evaluates and measures nothing. Either returned result can be saved to a separate
result archive (BoxRefinementResult.save).
Resuming gives the records of an uninterrupted saved refinement with the same root
entropy, apart from the fields that differ between any two saved executions, which
resume_augmented_lagrangian lists with their reasons.
Parameters:
-
directory(str | Path) –The directory of
refine_box(..., directory=...). -
backend(object) –The backend of the original call, whose configuration the directory stores. None stands for
AerBackend()under quantum execution, as in the original call. For a noisy Aer refinement in a new process,AerBackend(noise_model_id=...)with the identifier of the original binding, which the error for another backend names. -
progress(object | None, default:None) –Progress callback of the level Runs that this call creates or continues, as for
nwqlib.solve. -
end_at_unfinishable(bool, default:False) –Default
False, which raises the Run's error and leaves the directory as it is for a later resume. True ends the refinement withinner_failedat a level whose Run cannot finish without new work. It handles an unfinishable continuation after a Run has reopened, not a Run folder without a committed run-log header, which fails during reopen. Before a completed level exists, an inner failure still propagates.
Returns:
-
result(BoxRefinementResult) –The refinement, as
refine_boxreturns it.
load_box_refinement ¶
load_box_refinement(path)
Load a saved standalone refinement without planning, objective evaluation or measurement.
load_box_refinement(path) reads the directory that BoxRefinementResult.save
wrote. It validates the original problem's content hash and each completed level's
Result and Plan hashes, and returns a BoxRefinementResult with its original
problem and level Results attached. Each Plan describes that level's own objective
and coordinate box. The record is validated with its content hashes and its own
checks, the SymPy objects come back through a reader that resolves SymPy classes
only, and the rebuilt problem must have the hash of the stored problem record and of
the refinement record. Each level Result is loaded with load_result, which
validates it with its own Plan and archive. No backend is needed. A saved-refinement
directory of refine_box(..., directory=...) is refused with the name of
resume_box_refinement, which continues it, and a saved augmented-Lagrangian result
with the name of load_augmented_lagrangian.
Parameters:
-
path(str | Path) –The directory that
BoxRefinementResult.savewrote.
Returns:
-
result(BoxRefinementResult) –The saved refinement, with
problemandresultsattached.
Read a refinement¶
BoxRefinementResult ¶
Bases: Record
Result of a box refinement: completed levels, best point and stopping reason.
refine_box, resume_box_refinement and load_box_refinement return it, and
ALIteration.refinement holds the refinement of an augmented-Lagrangian round. The
answer is candidate, the best point in original coordinates, with objective, the
original objective there, and termination, why the refinement stopped.
print(result) summarizes it, report() returns it as JSON-ready data, and
save(path) writes it with its level Results. The fields below are read-only.
best_level is the completed level with the least recorded relative objective
(RefinementLevel.relative_objective), the earlier level on ties. objective
reports its original objective. Levels completed before a stop stay in levels.
resources adds the work of every completed level and of the level that stopped
the refinement (stopped_resources), so what a failed level's tables and Run
counted is included. A planning that raises reports no work, so its partial work is
not counted. results gives the QHD results of the completed levels. They are
live objects, outside the record's content hash.
The reported points are finite-grid search results. Neither the joint mass bound nor a small box certifies that the global minimizer lies in the box or that the best point is a continuous or global optimum.
str(result) and report read the stored fields only. They plan, evaluate,
measure and load nothing, reconstruct no state and call no resource estimate, so a
record validated from JSON alone can be summarized too.
Attributes:
-
problem_id(ContentID) –Content hash of the refined Optimization.
-
qhd(QHD) –QHD configuration used at every level.
-
options(BoxRefinement) –Refinement options.
-
execution(Literal['quantum', 'classical']) –"quantum"or"classical", as fornwqlib.solve. -
shots(PositiveInt | None) –Shots per level, or None for exact readout.
-
seed_entropy(Count) –Entropy of the
numpy.random.SeedSequencewhose children seed the levels. -
levels(tuple[RefinementLevel, ...]) –Completed levels in order.
-
best_level(PositiveInt | None) –Level number of the best point, or None without a completed level.
-
termination(Termination) –Why refinement stopped, such as
level_limit,box_unchangedorno_improvement. The Stopping reasons note below lists every reason in the order of the checks. -
failure(Text | None) –Exception type and message for
inner_failed, the result's missing-data reasons forno_valid_point, the limits that fell short forbudget_exhausted, otherwise None. -
stopped_resources(RefinementResources | None) –Work spent on the level that stopped the refinement, or None when it stopped before that level began.
-
resources(RefinementResources) –Work of all levels, completed and stopped.
-
max_plannings(PositiveInt) –Largest number of QHD plannings that
optionsallows, two per search-model level and one per physical level, known before the first level. The Planning bound note below gives the bound it implies.
Stopping reasons
Before each level the refinement checks, in this order, level_limit
(max_levels levels completed), box_unchanged (the next box equals the
last box, which with stall_split="best_region" means that no axis of the
last level had a resolved valley), split_limit (the next box equals the last
box after max_splits stall splits), width_floor (the box to solve has a
side at or below its width floor, or for the physical model a box that the grid
rejects), no_improvement (max_no_improve consecutive levels without a
strict decrease of the best relative objective) and budget_exhausted (the
remaining cumulative limits cannot fund a level), and reports the first that
holds. With stall_split="best_region" a stalled last level whose next level
could not run records no split and reports no_improvement or
budget_exhausted, or width_floor when neither region of its resolved
valley passes the width floor. Within a level, flat_objective means that the
level objective's tables show no variation (E = 0), unresolved_objective
that their ranges sum to a positive value at most the units in the last place of
the tables' largest values, too small to tell from evaluation error, a
resolution rule, inner_failed that planning or solving a level after the
first raised (the first level's error propagates), and no_valid_point that
the level's QHD result has no valid grid point.
Planning bound
max_plannings is the largest number of QHD plannings that options allows,
two per search-model level (the table stage and the solved objective) and one
per physical level, known before the first level. Each operation that one
planning checks, namely the symbolic expansion, the running total of the initial
state and tables, a kept state, a classical kernel and a circuit construction,
is at most qhd.max_work units and qhd.max_bytes bytes, so the table,
support, kernel and construction work fields of resources are each at most
max_plannings * qhd.max_work. The refinement's own objective evaluations and
joint-mass reads, and the second expansion of each level objective that those
evaluations use, are outside this bound.
Record size
The bounds on the scalar JSON leaves of this record, with their derivation, are in Engineering constants.
problem ¶
problem
The refined Optimization with its live SymPy objects, or None for a record validated from JSON alone.
refine_box, both paths of resume_box_refinement and load_box_refinement attach
it. A refinement nested in an augmented-Lagrangian record has neither this problem
nor its level Results, which ConstrainedQHDResult holds and saves with its run. A
search-model level Plan solves a transformed objective on the unit box and cannot
stand in for the original problem.
candidate ¶
candidate
Best point in original coordinates, or None.
For the search model it is a display value, the image of the best level's unit point
rounded once (RefinementLevel.point).
objective ¶
objective
Original objective at the best point, or None, evaluated as RefinementLevel.objective states.
report ¶
report(*, failure_probability=DEFAULT_FAILURE_PROBABILITY)
Return a JSON-ready report of the refinement built only from its stored fields.
It performs no planning, objective evaluation, measurement or loading, reconstructs
no state and calls no resource estimate. levels gives each level's readout kind, counts, intervals,
masses and the event they describe, its chosen split-region mass and its readout
mode status. resources gives each count with its unavailable reason and its
meaning. By default, confidence gives a population-mass lower bound for each
selected region in the level's backend-sampled distribution conditioned on valid
decoding, with simultaneous 95% confidence over the configured maximum
number of levels. Hoeffding and one-sided Clopper–Pearson bounds each receive
half the failure budget, and the larger available bound is reported. A split
uses its chosen side including the valley. The bounds use stored integer counts
and the sampling assumptions of Proposition 49.
They are binary64 evaluations, not directed-rounding enclosures. Exact readout,
no completed counts levels, or explicit None gives confidence=None.
Parameters:
-
failure_probability(float | None, default:DEFAULT_FAILURE_PROBABILITY) –Default
0.05. Total failure probability alpha, strictly between 0 and 1 and fixed before inspecting the counts. Set toNoneto omit the statistical report.
Returns:
-
report(dict) –JSON-ready data with the
summarytext, itsstatements, therecord, thelevels,confidence, theresourcesand the level Results' content hashes ininner_results.
Raises:
-
ValueError–If
failure_probabilityis neitherNonenor a number strictly between 0 and 1.
Examples:
result.report() includes the default bounds.
result.report(failure_probability=None) omits them.
save ¶
save(path)
Write this refinement and its completed level Results to a new directory.
The directory holds refinement.json (format qhd.refinement/4) with the portable
refinement record and the problem record, which keeps the bounds, units and content
hash of the original problem, and problem.pickle with its live SymPy objective and
variables. Each completed level z keeps its Result, saved by its own archive with
its own Plan, under levels/<z>/result/. A refinement without a completed level has
no levels/ folder. Saving requires the live problem and the level Results named by
the record, and a record without them is refused before the directory is created. It
performs no planning, objective evaluation or measurement. A failed save removes the
directory. This is a result archive, which load_box_refinement reads back, not a
directory that resume_box_refinement continues.
Parameters:
-
path(str | Path) –A directory that does not exist yet.
Returns:
-
path(Path) –The written directory.
RefinementLevel ¶
Bases: Record
One completed refinement level: its box, QHD solve, reported point and next box.
BoxRefinementResult.levels lists the completed levels in order, and best names
the best one. The fields below are read-only. Masses are conditional on a valid
outcome, which is every outcome of the binary encoding and a one-hot outcome with
one excitation per variable. Coordinates are in the original variables, taken from
the level's grid, except unit_point, which is in the search model's unit
coordinates. The guide's box refinement
section defines the intervals, axis masses, joint bound and next box.
Attributes:
-
level(PositiveInt) –Level number, starting at 1.
-
box(Box) –The level's box, one
(lower, upper)pair per variable. -
spacing(tuple[Real, ...]) –Grid spacing h of each variable in original coordinates, the level grid's spacing for the physical model and the side length times the unit grid's spacing, rounded once, for the search model.
-
energy_scale(Real) –E, the sum of the ranges of the unscaled level objective's stored support tables, rounded up, an upper bound on the objective's range over the level grid. The search model divides by it, and the physical model records it for
conditioning. -
potential_gain(Real | None) –kappa, the factor of the normalized potential that the level solved (
BoxRefinement.gain). None for the physical model. -
energy_shift(Real | None) –c, the constant term of the unscaled level objective plus the minima of its stored support tables, summed exactly and rounded once to binary64. None for the physical model. The Points and objectives note below says how the search model uses it.
-
table_magnitude(Nonnegative) –Sum over those support tables of their largest absolute value. The ratio to
energy_scaleisconditioning. -
spawn_key(tuple[Count, ...]) –Spawn key of the level's child of the refinement's
numpy.random.SeedSequence. -
plan_id(ContentID) –Content hash of the level's QHD Plan.
-
result_id(ContentID) –Content hash of the level's QHD result.
-
run_id(Text) –Identifier of the Run that produced it.
-
logical_width(PositiveInt) –Register width of the level's Plan,
d*Kfor the one-hot encoding andd*bwithK = 2**bfor the binary one. -
restricted_dimension(PositiveInt) –Valid grid size
K**d. -
valid_mass(Nonnegative) –Unconditional valid mass of the level's result.
-
valid_count(Count | None) –The result's
valid_countfor counts, the integer number S_z of valid decoded outcomes of the finite-shot statement of Proposition 49, or None for exact readout. -
returned_shots(Count | None) –The result's
returned_shotsfor counts, the raw number of returned draws among whichvalid_countdecoded to a grid point, or None for exact readout. -
region_axis_counts(tuple[Count, ...] | None) –Integer counts of valid draws in each axis interval of the selected region, or None for exact readout. For a split, the selected axis keeps its chosen side including the valley. Every other axis is whole.
-
region_count(Count | None) –Integer count of valid draws in the intersection of those axis intervals, or None for exact readout. These counts describe the selected split region when a split replaces the ordinary interval box.
-
mode_status(ModeStatus) –Mode-resolution status of this level's QHD readout among its positive observed valid points. Copied from the inner Result regardless of point_rule. It describes the readout's tie representative, including when this level reports a best-observed point or a mean instead. It does not certify the choice of marginal intervals or a stall-split region.
-
point_indices(tuple[Count, ...] | None) –Grid indices of the reported point, or None when
mode_or_meanreported the mean position. -
point(tuple[Real, ...]) –Reported point in original coordinates, the evaluation point for the physical model and a display value for the search model, where it is the image
a + D uofunit_pointrounded once. F at this rounded point can differ fromobjectiveor be undefined. -
unit_point(tuple[Real, ...] | None) –Search model only: the unit coordinates u of the reported grid point or mean position, at which the level objective
F(a + D u)was evaluated and whose grid point carriespoint_probability. None for the physical model. -
point_probability(Nonnegative | None) –Unconditional probability of the reported grid point, or None for the mean position.
-
objective(Real) –Original objective F at the reported location, read from the level's stored tables at a grid point and evaluated term by term at an off-grid mean. The Points and objectives note below gives the location and its rounding.
-
relative_objective(Real) –F - C at the same location, the value by which the refinement compares points, with C one exact constant for the whole refinement. The Points and objectives note below defines C.
-
mean_unavailable(Text | None) –Why
mode_or_meankept the grid point because the objective at the mean position was not finite and real, or None. -
intervals(tuple[tuple[Count, Count], ...]) –Kept index interval
(first, last)of each variable. -
axis_masses(tuple[Nonnegative, ...]) –Conditional marginal mass m_j of each interval.
-
joint_mass_bound(Nonnegative) –max(0, 1 - sum_j (1 - m_j)), a lower bound on the conditional mass of the joint box that holds for every joint distribution with these marginals. -
joint_mass(Nonnegative | None) –Conditional mass of the joint box computed from the joint observations, or None when the result keeps only marginals. The joint box and both masses are those of the intervals, so at a split level they describe the level box, and
split.region_massesgives the chosen region's probability. -
joint_mass_kind(Literal['exact', 'empirical'] | None) –"exact"for exact probabilities or amplitudes,"empirical"for counts, or None withjoint_mass. -
next_box(Box) –Box of the next level under the box rule, or the region that
splitchose. -
split(StallSplit | None) –The stall split of this level, or None. A level splits only when its box rule returned the level box itself.
-
split_declined(Text | None) –With
stall_split="best_region", why a level whose box rule returned the level box itself did not split: the level is the last ofmax_levels, the split budget is spent, the next level cannot run, the readout has no tie window, or no valley passes the resolution screen. None otherwise, and always None withstall_split="none". It explains the stop and does not replaceBoxRefinementResult.termination. -
initial_state(GaussianState | None) –With
level_initial_state="best_point_gaussian", theGaussianStatethat this level's Plan started from, in the coordinates of the level problem, the unit coordinates for the search model. None for the first level and with"configured", where the level started fromQHD.initial_state. -
resources(RefinementResources) –Counted work of this level, including the two objective evaluations of a split.
Points and objectives
For the physical model point is the grid coordinate or mean at which
objective was evaluated. For the search model it is a + D u for
u = unit_point, rounded once to binary64, a display value. F at this rounded
point can differ from objective or be undefined.
objective is F at point for the physical model and at the exact affine image
a + D u of unit_point for the search model, up to the evaluation's rounding
and, for a Float coefficient, SymPy's rounding in the substitution. At a grid
point both are read from the level's stored tables, and at an off-grid mean both
are evaluated term by term.
relative_objective is F - C. C is one exact constant for the whole refinement,
the constant term of the first level's decomposition of the objective. Each
level forms its own constant term minus C exactly and adds it to the term values
once, so a large constant of F, which can round the objective's variation out of
objective, does not reach this value when every coefficient of F is an exact
SymPy number. A binary64 Float coefficient makes SymPy round each constant
term at the size of that constant first.
The search model subtracts the exact value of energy_shift, so that
(F - c)/E lies in [0, 1] on the grid and the solved potential
kappa (F - c)/E in [0, kappa], up to the rounding of the tables. For tables
rounded once and simple expressions that rounding is about 4 u kappa times
conditioning, with u = 2**-53, an estimate and not a bound.
conditioning ¶
conditioning
Return table_magnitude / energy_scale, the factor by which table rounding reaches the model.
The search model divides tables of size up to table_magnitude by energy_scale,
so an evaluation error of a few u relative to the table values becomes an error of
about 4 u times this factor in its normalized potential, with u = 2**-53. That
estimate illustrates simple expressions and is not a bound. The resolution stop does
not bound this factor either, so a level can pass it with a factor near 1/u. For
the physical model it measures how much of the level's potential variation can be
rounding.
RefinementResources ¶
Bases: Record
Counted work of one refinement level, or of a whole refinement.
RefinementLevel.resources holds a level's, and BoxRefinementResult.resources the
refinement's totals. The fields below are read-only. Measurement (circuit
preparations and attempts, shots, stored Run data) and host work (planning tables,
classical kernel runs, construction, exact synthesis and the refinement's own
evaluations) are separate counts and are never added to each other. Each work field
has its own unit, so the host-work fields are not summed either. A search-model
level plans twice: once for the unscaled level objective, whose support tables give
E and c (table_evaluations), and once for the normalized objective it solves
(support_evaluations). A physical level plans once. A count is None when it is
unknown, and unavailable names each such field with its reason. Unknown is never
replaced by zero, so a total is None when any level's count is. The counts are the
work of the algorithm, each counted once as in an uninterrupted refinement, and not
the host time spent across the calls of a saved refinement
(resume_box_refinement), whose completed levels keep their recorded counts and
whose continued Run keeps the counts of its own run log. The unscaled table stage of
a reopened search-model level, which resume repeats, is not counted again.
Attributes:
-
circuit_preparations(Count | None) –Circuit preparations of the level Runs.
-
circuit_attempts(Count | None) –Circuit attempts, of any status.
-
completed_circuit_attempts(Count | None) –Those of them that completed with an observation.
-
shots(Count | None) –Raw shots set aside by the attempts of every status.
-
completed_shots(Count | None) –Raw shots of the completed attempts.
-
data_bytes(Count | None) –Run data bytes recorded by the level Runs.
-
evolution_work(Count | None) –Work units that the level Runs counted for classical kernel runs (restricted evolution and readout summary), zero for quantum execution.
-
construction_work(Count | None) –Construction work that the level Runs counted, for a quantum circuit or for the classical kernel's setup.
-
synthesis_work(Count | None) –Exact dense synthesis work set aside by the level Runs.
-
table_evaluations(Count | None) –Grid tuples evaluated for the unscaled level objective's support tables, the extra planning of the search model. Zero for the physical model.
-
support_evaluations(Count | None) –Grid tuples evaluated for the support tables of the solved level objective.
-
objective_evaluations(Count) –Evaluations of the original objective by the refinement itself, at the level's own coordinates (
RefinementLevel.objective), including the two scores of a stall split. -
joint_mass_reads(Count) –Joint-observation read count, in full-state-equivalent units, not measured memory traffic. The Read and circuit counts note below gives what each readout adds.
-
cx(Count | None) –Sum of the CX upper bounds of the circuits that the level Runs prepared, one circuit per level Run at most, not multiplied by shots. The Read and circuit counts note below says when a level counts 0 and when the value is unknown.
-
arbitrary_rotations(Count | None) –Sum of the arbitrary rotations of the same circuits, an upper bound for the binary encoding, counted as
cxis. For quantum execution it equals the body totalarbitrary_rotationsofrun_resources. -
unavailable(tuple[tuple[Text, Text], ...]) –(field, reason)for every count that is None.
Read and circuit counts
joint_mass_reads counts count and exact-bin entries when the observations are
decoded, and their decoded data are reused. A kept-state dense grid is counted
once by the kept-state length. A streamed kept-state readout counts that length
for each started probability pass, one per joint request and two for the paired
split modes, even when only valid one-hot entries are gathered or the final pass
stops early. These kept-state units are full-state-equivalent counts, not
measured memory traffic.
A level that prepared no circuit, such as one that stopped before its
preparation, whose Run's creation raised before its run-log header or that ran
classically, contributes 0 to cx and arbitrary_rotations, and one whose
preparation raised after that header or whose preparation count is unknown makes
the value unknown. run_resources also multiplies each level's circuit by its
shots and adds T estimates.
StallSplit ¶
Bases: Record
One stall split of BoxRefinement(stall_split="best_region").
RefinementLevel.split holds it for a level that split. The fields below are
read-only. Masses are conditional on a valid one-hot outcome of the stalled level's
distribution. Index 0 of each pair is the lower region, whose side on axis ends at
coordinate, and index 1 the upper region, whose side starts there. Every other
side of both regions is the level box's side.
Attributes:
-
axis(Count) –Variable index of the split axis.
-
valley(Count) –Grid index of the valley minimum on that axis.
-
coordinate(Real) –Original coordinate of the split, the face of the valley's centered cell toward the discarded side, so that the valley cell stays in the chosen region.
-
regions(tuple[Box, Box]) –The lower and the upper region.
-
point_indices(tuple[tuple[Count, ...], tuple[Count, ...]]) –Grid indices of the most probable joint grid point of each strict side of the valley, the indices below it and those above it on
axis, in the level's distribution. The chosen region also holds the valley column, so its most probable point can lie there instead. -
points(tuple[tuple[Real, ...], tuple[Real, ...]]) –Those grid points in original coordinates, given as
RefinementLevel.pointgives a grid point, so for the search model the rounded imagea + D uof the unit point, a display value. -
scores(tuple[Real, Real]) –Original objective F at each grid point, evaluated in the level's own coordinates as the level's reported grid point is (
RefinementLevel.objective). -
relative_scores(tuple[Real, Real]) –The relative objective F - C at each grid point (
RefinementLevel.relative_objective), the values the split compares. -
region_masses(tuple[Nonnegative, Nonnegative]) –Conditional probability each region held.
-
chosen(Literal[0, 1]) –0 or 1, the region the refinement continues in. It is the one whose side has the lower relative score, on equal relative scores the one whose side holds more probability, then the lower one.
-
discarded_mass(Nonnegative) –Conditional probability of the other region, which the refinement gives up.
Limits¶
- Neither layer is a global optimizer. Their points are points of finite grids, except an off-grid mean under
mode_or_mean, and no stopping status is a statement about the continuous problem. - A stopping status does not assess optimality.
feasible_complementaryis not convergence in Algencan's sense, because projected stationarity is not a stopping condition. - Finite-grid multipliers are dual iterates of the grid problem, not the continuous KKT multipliers, and the reported multipliers belong to the last round, not to the best point.
- Neither the joint mass bound of a refinement level nor a small box certifies that the global minimizer lies in the box.
constrained_grid_minimumcovers the preprocessed box's grid only and refuses a run with box refinement. Its gap is an evaluated-value diagnostic, not a bound for the mathematical objective.- The work and byte bounds of the record sum per-category limits. They are not runtime or peak-memory bounds.