Skip to content

API Reference

vizopt.base

Base classes

Callback = Callable[[int, Array, Any, Any], bool | None] module-attribute

A per-iteration optimization callback.

Called as callback(i_iter, loss_value, optim_vars, grads). A callback may return a truthy value to request the optimizer stop after the current iteration; returning None (the common case — most callbacks just print or record a snapshot) means "keep going".

InputParams = dict[str, Any] module-attribute

OptimVars = dict[str, Any] module-attribute

ObjectiveTerm dataclass

A term in an objective function.

Attributes:

Name Type Description
name str

A name for the term, e.g. "total distance".

compute Callable[[Any, Any], Array]

A function that computes the value of the term with arguments optim_vars, input_parameters

multiplier float

A multiplicative factor for the term.

schedule Callable[[Array], Array] | None

Optional JAX-compatible callable (step: Array) -> Array that returns a scalar multiplier for the given iteration step. The effective weight is multiplier * schedule(step). Must use JAX ops (e.g. jnp.minimum, jnp.where) so that it can be traced through without recompilation. None means constant 1.0 (no scheduling).

OptimConfig dataclass

Configuration for the gradient-descent optimizer.

Attributes:

Name Type Description
n_iters int

Number of optimization iterations.

learning_rate float

Step size for the Adam optimizer.

b1 float

Adam exponential decay rate for the first moment. Default 0.9.

b2 float

Adam exponential decay rate for the second moment. Default 0.999.

n_restarts int

Number of random restarts. The run with the lowest final loss is returned. Default 1 (single run).

seed int

Base random seed passed to initialize. Restart i receives seed + i.

track_every int

Record per-term history every this many iterations.

early_stop_patience int | None

If set, stop once the (unscheduled) total loss hasn't improved by at least a relative early_stop_tol fraction over the last early_stop_patience iterations. Checked at track_every granularity (piggybacking on the history recording that already happens then, so this adds no extra device syncs); values smaller than track_every are rounded up to it. None (default) disables early stopping.

early_stop_tol float

Relative-improvement threshold for early stopping; see early_stop_patience. Ignored when early_stop_patience is None.

OptimizationProblem dataclass

An optimization problem.

Attributes:

Name Type Description
input_parameters InputParams

Fixed data for the problem (not optimized).

terms list[ObjectiveTerm]

Objective terms defining the loss function.

initialize Callable[[InputParams, int], OptimVars]

Callable that produces initial optimization variables from input_parameters.

plot_configuration Callable[[OptimVars, InputParams], None] | None

Optional callable to visualize a configuration. Signature: plot_configuration(optim_vars, input_parameters).

svg_configuration Callable[[list, InputParams, int], list[dict]] | None

Optional callable to produce SVG element specs for animation. Signature: svg_configuration(snapshots, input_parameters, size) -> list[dict].

var_scales dict | None

Optional per-variable scale factors. See :func:build_objective for details.

optimize(optim_config=None, callback=None)

Run gradient descent to minimize the objective.

When optim_config.n_restarts > 1, the optimization is run that many times with seeds seed, seed + 1, …. The result with the lowest final loss is returned.

Parameters:

Name Type Description Default
optim_config OptimConfig | None

Optimizer settings (iterations, learning rate, seeds, restarts, track_every). Uses OptimConfig defaults when None.

None
callback Callback | None

Optional callback called after each iteration with (iteration, loss, optim_vars, grads).

None

Returns:

Type Description
OptimizationResult

An OptimizationResult with the

OptimizationResult

optimized variables, per-term history, and final loss of the best run.

plot(**kwargs)

Plot the last optimization result using plot_configuration.

Keyword arguments are forwarded to plot_configuration, allowing optional display flags (e.g. show_arrows=True).

Raises:

Type Description
ValueError

If plot_configuration is not set or optimize() has not been called yet.

OptimizationProblemTemplate dataclass

A template for a class of optimization problems.

An instance represents a specific type of optimization problem (e.g. bubble layout optimization), independently of any particular input data. Call :meth:instantiate with concrete input parameters to obtain a runnable :class:OptimizationProblem.

If input_params_class is provided, it must be a Pydantic model class. instantiate will call model_validate on the supplied parameters, triggering Pydantic validation and coercion before the problem is created.

Attributes:

Name Type Description
terms list[ObjectiveTerm]

Objective terms defining the loss function.

initialize Callable[[InputParams, int], OptimVars]

Callable that produces initial optimization variables from input_parameters.

input_params_class type[BaseModel] | None

Optional Pydantic model class for input parameters. When set, validation is performed at instantiation time.

plot_configuration Callable[[OptimVars, InputParams], None] | None

Optional callable to visualize a configuration. Signature: plot_configuration(optim_vars, input_parameters).

svg_configuration Callable[[list, InputParams, int], list[dict]] | None

Optional callable to produce SVG element specs for animation. Signature: svg_configuration(snapshots, input_parameters, size) -> list[dict] where each dict has a "tag" key and SVG attribute keys; list values are animated per-frame, scalar values are static.

instantiate(input_parameters, weight_overrides=None, var_scales=None)

Create a runnable problem instance from concrete input parameters.

If input_params_class is set, validates input_parameters via model_validate before creating the problem. The plain dict is passed through to the problem unchanged (Pydantic is used for validation only, so that input_parameters remains a JAX-compatible pytree).

Parameters:

Name Type Description Default
input_parameters InputParams

Fixed data for this problem instance.

required
weight_overrides dict[str, float] | None

Optional mapping of term name to multiplier. Overrides the default multiplier for the named terms. Unknown names raise KeyError.

None
var_scales dict | None

Optional per-variable scale factors used to normalise optim_vars during optimisation. See :func:build_objective for details. Values may be scalars or arrays.

None

Returns:

Name Type Description
An OptimizationProblem

class:OptimizationProblem ready to optimize.

Raises:

Type Description
KeyError

If a name in weight_overrides does not match any term.

ValidationError

If input_params_class is set and validation fails.

OptimizationResult dataclass

Result returned by OptimizationProblem.optimize.

Attributes:

Name Type Description
optim_vars OptimVars

Optimized variables in physical (un-scaled) space.

history list[dict]

Per-iteration records. Each dict has keys "iteration", "total", "total_unscheduled" (sum of every term's end-weighted value; used for early_stop_patience plateau detection, since it isn't confounded by schedule ramping), one key per term name (schedule-weighted value), one per term name suffixed _unscheduled (end-weighted), and one per term name suffixed _unweighted (raw, un-multiplied value).

final_loss float

Scalar loss of the best run at the last iteration.

VizOptimizer

Bases: ABC

Base class for user-facing visualization optimizers.

Subclasses implement :meth:_build_problem to turn stored hyperparameters into a configured :class:OptimizationProblem. The base class handles the optimize → plot lifecycle and stores fitted state in problem_ and result_ after :meth:optimize is called.

animate(callback, **kwargs)

Create a matplotlib animation of the optimization progress.

Convenience wrapper around :func:~vizopt.animation.animate that renders each snapshot via this optimizer's plot_configuration. To save as a GIF, call .save(path, writer="pillow", fps=...) on the returned animation.

Parameters:

Name Type Description Default
callback

A :class:~vizopt.animation.SnapshotCallback passed to :meth:optimize, or a raw list of (iteration, optim_vars) tuples.

required
**kwargs

Forwarded to :func:~vizopt.animation.animate.

{}

Returns:

Type Description
Any

A matplotlib.animation.FuncAnimation.

Raises:

Type Description
ValueError

If :meth:optimize has not been called yet.

animate_svg(callback, **kwargs)

Create an animated SVG from a SnapshotCallback.

Convenience wrapper around :func:~vizopt.animation.snapshots_to_animated_svg that uses this optimizer's built problem and defaults history to the result from the last :meth:optimize call.

Parameters:

Name Type Description Default
callback

A :class:~vizopt.animation.SnapshotCallback passed to :meth:optimize, or a raw list of (iteration, optim_vars) tuples.

required
**kwargs

Forwarded to :func:~vizopt.animation.snapshots_to_animated_svg. history defaults to self.result_.history.

{}

Returns:

Type Description
str

An SVG string suitable for saving or displaying with

str

IPython.display.SVG.

Raises:

Type Description
ValueError

If :meth:optimize has not been called yet.

optimize(optim_config=None, callback=None)

Build the problem and run gradient descent.

Parameters:

Name Type Description Default
optim_config OptimConfig | None

Optimizer settings. Uses :class:OptimConfig defaults when None.

None
callback Callback | None

Optional callback (iteration, loss, optim_vars, grads).

None

Returns:

Name Type Description
An OptimizationResult

class:OptimizationResult with optimized variables, per-term

OptimizationResult

history, and final loss.

plot(**kwargs)

Plot the last optimization result.

Raises:

Type Description
ValueError

If :meth:optimize has not been called yet.

build_objective(terms, input_parameters, var_scales=None)

Build a composite objective function from a list of terms.

Parameters:

Name Type Description Default
terms list[ObjectiveTerm]

Objective terms to sum, each weighted by its multiplier.

required
input_parameters Any

Fixed data passed to each term's compute function.

required
var_scales dict | None

Optional per-variable scale factors. When provided, each optim_vars[k] is multiplied by var_scales[k] before being passed to any term's compute function, so the optimizer works in a normalised space while loss terms always receive physical values. Values may be scalars or arrays (broadcast over the variable's shape). Keys absent from var_scales are left unscaled.

None

Returns:

Type Description
Callable[[OptimVars, Array], Array]

A callable fun(optim_vars, step) -> scalar suitable for gradient

Callable[[OptimVars, Array], Array]

descent. step is the current iteration as a JAX int32 array and

Callable[[OptimVars, Array], Array]

is passed to each term's schedule (if any).

default_print_callback(i_iter, loss_value, *_)

Print the loss value after every nth optimization iteration


vizopt.animation

Animation utilities for visualizing optimization progress.

OptimizationProblem dataclass

An optimization problem.

Attributes:

Name Type Description
input_parameters InputParams

Fixed data for the problem (not optimized).

terms list[ObjectiveTerm]

Objective terms defining the loss function.

initialize Callable[[InputParams, int], OptimVars]

Callable that produces initial optimization variables from input_parameters.

plot_configuration Callable[[OptimVars, InputParams], None] | None

Optional callable to visualize a configuration. Signature: plot_configuration(optim_vars, input_parameters).

svg_configuration Callable[[list, InputParams, int], list[dict]] | None

Optional callable to produce SVG element specs for animation. Signature: svg_configuration(snapshots, input_parameters, size) -> list[dict].

var_scales dict | None

Optional per-variable scale factors. See :func:build_objective for details.

optimize(optim_config=None, callback=None)

Run gradient descent to minimize the objective.

When optim_config.n_restarts > 1, the optimization is run that many times with seeds seed, seed + 1, …. The result with the lowest final loss is returned.

Parameters:

Name Type Description Default
optim_config OptimConfig | None

Optimizer settings (iterations, learning rate, seeds, restarts, track_every). Uses OptimConfig defaults when None.

None
callback Callback | None

Optional callback called after each iteration with (iteration, loss, optim_vars, grads).

None

Returns:

Type Description
OptimizationResult

An OptimizationResult with the

OptimizationResult

optimized variables, per-term history, and final loss of the best run.

plot(**kwargs)

Plot the last optimization result using plot_configuration.

Keyword arguments are forwarded to plot_configuration, allowing optional display flags (e.g. show_arrows=True).

Raises:

Type Description
ValueError

If plot_configuration is not set or optimize() has not been called yet.

SnapshotCallback

Callback that saves a numpy copy of optim_vars at regular intervals.

Pass an instance as the callback argument to :meth:OptimizationProblem.optimize. Snapshots accumulate in :attr:snapshots and can be passed to :func:animate.

Parameters:

Name Type Description Default
every int

Save a snapshot every this many iterations.

10

Attributes:

Name Type Description
snapshots list[tuple[int, Any]]

List of (iteration, optim_vars) tuples, one per recorded step.

Example::

cb = SnapshotCallback(every=100)
result = problem.optimize(n_iters=2000, callback=cb)
anim = animate(problem, cb.snapshots)

_loss_curve_svg_lines(history, snapshots, size, panel_height, n_frames, total_dur, calc_mode, log_scale=False)

Build SVG lines for a loss curve panel placed below the main animation.

Parameters:

Name Type Description Default
history list[dict]

List of history dicts with "iteration" and "total" keys.

required
snapshots list[tuple[int, Any]]

List of (iteration, optim_vars) tuples.

required
size int

Width of the SVG (same as the animation width).

required
panel_height int

Height of the loss curve panel in pixels.

required
n_frames int

Number of animation frames.

required
total_dur float

Total animation duration in seconds.

required
calc_mode str

SMIL calcMode ("linear" or "discrete").

required
log_scale bool

If True, the loss axis uses a log10 scale.

False

Returns:

Type Description
list[str]

A list of SVG element strings to append before the closing </svg>.

_optim_vars_spaghetti_svg_lines(snapshots, panel_y, size, panel_height, n_frames, total_dur, calc_mode)

Build SVG lines for a spaghetti-plot panel of optimization variables.

Each scalar component of optim_vars becomes one polyline traced across all snapshot iterations. Variables that share the same pytree leaf are drawn in the same colour. An animated vertical marker tracks the current animation frame, consistent with the loss curve panel.

Parameters:

Name Type Description Default
snapshots list[tuple[int, Any]]

List of (iteration, optim_vars) tuples.

required
panel_y int

Y-offset of this panel inside the SVG.

required
size int

Width of the SVG (same as the animation width).

required
panel_height int

Height of this panel in pixels.

required
n_frames int

Number of animation frames.

required
total_dur float

Total animation duration in seconds.

required
calc_mode str

SMIL calcMode ("linear" or "discrete").

required

Returns:

Type Description
list[str]

A list of SVG element strings to append before the closing </svg>.

animate(problem, snapshots, interval=200)

Create an animation of the optimization process.

Renders each optim_vars snapshot via problem.plot_configuration and assembles the frames into a FuncAnimation.

Parameters:

Name Type Description Default
problem OptimizationProblem

The optimization problem; must have plot_configuration set.

required
snapshots list[tuple[int, Any]]

List of (iteration, optim_vars) tuples as produced by :class:SnapshotCallback.

required
interval int

Delay between frames in milliseconds.

200

Returns:

Type Description
Any

A matplotlib.animation.FuncAnimation. In a Jupyter notebook,

Any

display with IPython.display.HTML(anim.to_jshtml()).

Raises:

Type Description
ValueError

If problem.plot_configuration is not set or snapshots is empty.

chronophotograph(problem, snapshots, n_frames=8, alpha_start=0.15, alpha_end=1.0)

Create a static chronophotography composite of the optimization process.

Renders a selection of evenly-spaced snapshots and overlays them into a single static figure. Earlier frames are faint ghosts; the latest frame is fully opaque, so the eye reads the trajectory at a glance.

Parameters:

Name Type Description Default
problem OptimizationProblem

The optimization problem; must have plot_configuration set.

required
snapshots list[tuple[int, Any]]

List of (iteration, optim_vars) tuples as produced by :class:SnapshotCallback.

required
n_frames int

Number of evenly-spaced frames to overlay. Clamped to len(snapshots).

8
alpha_start float

Blend weight of the earliest selected frame (0–1).

0.15
alpha_end float

Blend weight of the latest selected frame (0–1).

1.0

Returns:

Type Description
Any

A matplotlib Figure containing the composite image.

Raises:

Type Description
ValueError

If problem.plot_configuration is not set or snapshots is empty.

default_print_callback(i_iter, loss_value, *_)

Print the loss value after every nth optimization iteration

smil_animate(attr_name, per_frame_values, n_frames, total_dur, calc_mode='linear')

Build a SMIL <animate> element string for a numeric SVG attribute.

Parameters:

Name Type Description Default
attr_name str

SVG attribute to animate (e.g. "cx", "opacity").

required
per_frame_values list[str]

Stringified values, one per frame.

required
n_frames int

Total number of frames, used to space keyTimes evenly.

required
total_dur float

Animation duration in seconds.

required
calc_mode str

"linear" or "discrete". Linear appends the first value at keyTime 1.0 to close the loop smoothly.

'linear'

Returns:

Type Description
str

An SVG <animate> element string.

snapshots_to_animated_svg(problem, snapshots, fps=10, size=500, calc_mode='linear', history=None, loss_curve_height=120, log_scale=False, optim_vars_panel_height=0, margin=None)

Create an animated SVG from optimization snapshots.

Uses problem.svg_configuration to obtain per-element SVG specs, then builds SMIL <animate> elements for attributes that vary across frames.

Parameters:

Name Type Description Default
problem OptimizationProblem

The optimization problem; must have svg_configuration set.

required
snapshots list[tuple[int, Any]]

List of (iteration, optim_vars) tuples as produced by :class:SnapshotCallback.

required
fps int

Frames per second.

10
size int

Width and height of the output SVG in pixels.

500
calc_mode str

"linear" for smooth interpolation or "discrete" for instant jumps between frames.

'linear'
history list[dict] | None

Optional list of history dicts as returned by :meth:OptimizationProblem.optimize (each dict has an "iteration" key and a "total" key with the aggregate loss). When provided, a loss curve is rendered below the animation with an animated marker tracking the current frame.

None
loss_curve_height int

Height in pixels of the loss curve panel, used only when history is provided.

120
log_scale bool

If True, the loss axis uses a log10 scale.

False
optim_vars_panel_height int

Height in pixels of the spaghetti-plot panel for optimization variables. When greater than zero, a panel is appended below the animation (and below the loss curve, if shown) with one polyline per scalar optimization variable, so you can see all variable trajectories across iterations at a glance. An animated vertical marker tracks the current frame, matching the style of the loss curve panel.

0
margin float | None

Empty border around the content, as a fraction of the content's span. Only forwarded to problem.svg_configuration if that function accepts a margin keyword (e.g. one built by StarRepresentation.make_svg_configuration); left at None (the underlying function's own default) otherwise.

None

Returns:

Type Description
str

An SVG string. Save with Path("out.svg").write_text(svg) or

str

display in Jupyter with IPython.display.SVG(data=svg).

Raises:

Type Description
ValueError

If problem.svg_configuration is not set, snapshots is empty, or margin is given but problem.svg_configuration does not accept a margin keyword.


vizopt.components.common

calculate_collision_penalty(node_xys, node_radii, collision_pairs, offset=1.0)

Vectorized collision penalty for node pairs that should not overlap.

Parameters:

Name Type Description Default
node_xys

Array of node positions with shape (n, 2).

required
node_radii

Array of node radii with shape (n,).

required
collision_pairs

Integer array of shape (k, 2) with index pairs to check.

required
offset

Minimum required gap between circle boundaries.

1.0

Returns:

Type Description

Scalar penalty value.

calculate_total_width_penalty_for_circular_layout(node_xys, node_radii)

A penalty for the overall width and height of the drawing with circular nodes.

Parameters:

Name Type Description Default
node_xys ndarray | Array

Array of node positions with shape (n, 2).

required
node_radii ndarray | Array

Array of node radii with shape (n,).

required

calculate_total_width_penalty_ignoring_radii(node_xys)

A penalty for the overall width and height of the drawing.

Parameters:

Name Type Description Default
node_xys ndarray

Array of node positions with shape (n, 2).

required

multiple_bbox_intersections(bbox_matrix, other_bbox_matrix)

Calculate the pairwise intersections of two sets of bounding boxes

This vectorized implementation is more efficient than the avoided double for loop

Parameters:

Name Type Description Default
bbox_matrix Array

array of shape (n, 2, 2) dimensions: points, min and max, xy coordinates

required
other_bbox_matrix Array

array of shape (m, 2, 2) dimensions: points, min and max, xy coordinates

required

Returns:

Type Description

array of shape (n, m)

should_be_positive_activation(x_value, factor=100.0)

A penalty for negative values.


vizopt.components.bands

Reusable JAX loss terms and helpers for convex vertical-band domains.

A convex region is exactly the area between a concave upper boundary y2(x) and a convex lower boundary y1(x) over x in [x_min, x_max]. Here each region is represented by x_bounds = [x_min, x_max] plus upper and lower arrays of K values sampled at K uniformly-spaced columns:

x_k = x_min + k/(K-1) * (x_max - x_min),  k = 0, ..., K-1

Unlike the star-shaped representation in :mod:vizopt.components.stars, x_bounds is itself an optimization variable (not a fixed input parameter), since a band's horizontal extent is generally not known in advance.

_MIN_THICKNESS = 0.1 module-attribute

_MIN_WIDTH = 0.1 module-attribute

_SVG_SET_COLORS = ['#e05252', '#4472c4', '#9966cc', '#339966', '#e07d39', '#3cbfcf', '#c05e88', '#888888'] module-attribute

BandRepresentation dataclass

Bases: ABC

Base class for convex vertical-band boundary representations.

A representation determines how the boundary of each band domain is parametrised during optimisation. Unlike :class:~vizopt.components.stars.StarRepresentation, x_bounds (the domain's horizontal extent) is itself an optimisation variable, so wrap/to_bounds need no fixed external grid argument.

Attributes:

Name Type Description
k_columns int

number of uniformly-spaced columns used to sample the boundary. For Discrete this is also the number of optimised (upper, lower) pairs.

extra_results(s, optim_vars)

Representation-specific extras added to the result dict of set s.

Empty by default (Discrete has no extras).

initialize_vars(n_sets, initial_x_bounds, initial_upper, initial_lower) abstractmethod

Return the initial optimisation-variable dict.

Parameters:

Name Type Description Default
n_sets int

number of band domains.

required
initial_x_bounds ndarray

(n_sets, 2) initial [x_min, x_max].

required
initial_upper ndarray

(n_sets, k_columns) initial upper boundary values.

required
initial_lower ndarray

(n_sets, k_columns) initial lower boundary values.

required

make_svg_configuration(base_svg_fn=None)

Return an svg_configuration function compatible with the animation helper.

Converts representation-specific vars to upper/lower on each snapshot so any base SVG renderer that reads those keys can be reused for all representations.

Parameters:

Name Type Description Default
base_svg_fn

the underlying (snapshots, input_params, size) → elements function to delegate to after conversion. Defaults to :func:_svg_configuration_band_only.

None

to_bounds(optim_vars) abstractmethod

Convert optimisation variables to (upper, lower) arrays of shape (n_sets, k_columns).

wrap(fn)

Adapt a loss term expecting optim_vars["upper"/"lower"] to this representation.

The default identity is correct for Discrete, which already stores upper/lower directly.

Discrete dataclass

Bases: BandRepresentation

One (upper, lower) pair per column, linearly interpolated.

The optimisation variables are x_bounds of shape (n_sets, 2) and upper/lower of shape (n_sets, k_columns). This is the only representation for now — the simplest and the default.

_band_areas(x_bounds, upper, lower)

Per-set band area via the trapezoid rule over K uniformly-spaced columns.

Parameters:

Name Type Description Default
x_bounds ndarray

(S, 2) [x_min, x_max] per set.

required
upper ndarray

(S, K) upper boundary values.

required
lower ndarray

(S, K) lower boundary values.

required

Returns:

Type Description

(S,) array of areas.

_column_positions(x_bounds, K)

Uniformly-spaced x positions for each set's K boundary columns.

Parameters:

Name Type Description Default
x_bounds

(S, 2) [x_min, x_max] per set.

required
K

number of columns.

required

Returns:

Type Description

(S, K) array of x positions.

_init_rectangle(initial_centers, half_width, half_height, k_columns)

Initial axis-aligned rectangle per set.

Mirrors the star convention of initializing as a regular polygon of constant radius: here the initial band is a rectangle of constant height across all columns.

Parameters:

Name Type Description Default
initial_centers

(S, 2) [cx, cy] per set.

required
half_width

(S,) initial half-width per set.

required
half_height

(S,) initial half-height per set.

required
k_columns

number of columns K.

required

Returns:

Type Description

Tuple (x_bounds, upper, lower) with shapes (S, 2), (S, K),

(S, K).

_interp_band_bounds(x_bounds, upper, lower, px)

Interpolate target bands' upper/lower boundaries at given x positions.

Parameters:

Name Type Description Default
x_bounds

(T, 2) target domains' [x_min, x_max].

required
upper

(T, K) target domains' upper boundary values.

required
lower

(T, K) target domains' lower boundary values.

required
px

(S, 1, P) or (S, T, P) query x positions, broadcast against the T target domains (axis 1).

required

Returns:

Type Description

Tuple (upper_interp, lower_interp, x_min, x_max). The first two

are shaped (S, T, P); the last two are (1, T, 1) and

broadcastable against px. Query points outside [x_min, x_max]

get the boundary column's value (clamped extrapolation) — callers

combine this with an explicit x-range violation.

_multi_term_band_area(optim_vars, input_params)

Sum of band areas over all sets.

_multi_term_band_convexity(optim_vars, input_params)

Penalty for non-convex band shapes.

Convexity requires the upper boundary to be concave and the lower boundary to be convex. Uses the discrete second difference at each interior column, normalised by squared column spacing (analogous to the edge-length normalisation in stars._multi_term_convexity), and the same max(0, violation)**2 + alpha * max(0, violation) penalty shape.

_multi_term_band_enclosure(optim_vars, input_params)

Band-vs-band enclosure: boundary of inner sets must stay inside outer sets.

For each (inner, outer) pair indicated by input_params["enclosure_mask"], penalises boundary points (upper and lower chains) of the inner set that lie outside the interpolated boundary of the outer set, in x or in y.

optim_vars keys: "x_bounds" (S, 2), "upper" (S, K), "lower" (S, K) input_params keys: "enclosure_mask" (S, S) bool — [inner, outer] Optional: "enclosure_offset" (float), minimum inset from the outer boundary.

_multi_term_band_exclusion(optim_vars, input_params)

Band-vs-band exclusion: boundary and interior of each set must not enter another.

For each pair (s, t) where exclusion_mask[s, t] is True, penalises boundary and interior points of s that lie inside the band domain of t, using an AABB-style penetration depth (minimum distance to the nearest of the four bounding sides), the same style as stars._multi_term_label_label_collision.

optim_vars keys: "x_bounds" (S, 2), "upper" (S, K), "lower" (S, K) input_params keys: "exclusion_mask" (S, S) bool Optional: "exclusion_offset" (float), minimum required gap. Optional: "exclusion_interior_fracs" (list[float]), height fractions in (0, 1) at which to sample interior points at each column. Defaults to [0.5].

_multi_term_band_perimeter(optim_vars, input_params)

Sum of band perimeters over all sets (upper + lower chains + end caps).

_multi_term_band_smoothness(optim_vars, input_params)

Penalty for sharp changes between adjacent columns of upper/lower.

_multi_term_min_thickness(optim_vars, input_params)

Penalty for band thickness (upper - lower) falling below the minimum.

_multi_term_min_width(optim_vars, input_params)

Penalty for band width (x_max - x_min) falling below the minimum.

_multi_term_target_area(optim_vars, input_params)

Penalises deviation of each set's area from its target.

Sets with target_areas[s] = nan are ignored.

_svg_configuration_band_only(snapshots, input_params, size, margin=0.05)

SVG configuration for pure band domains (no underlying circles).

Parameters:

Name Type Description Default
margin float

Empty border around the content, as a fraction of the content's span.

0.05

vizopt.schedules

Schedule factory functions for loss term weight scheduling.

Schedules are JAX-compatible callables (step: Array) -> Array that scale a term's effective weight over the course of optimization. They must use JAX ops (e.g. jnp.clip) so they can be traced through without recompilation.

TermSchedules dataclass

Per-term weight schedules with warmup/cooldown categorization.

Attributes:

Name Type Description
schedules dict

Dict mapping term name to a JAX-compatible schedule callable, ready to pass as term_schedules to any optimizer.

quality_terms set

Term names whose schedules end at 1 (warmup). Use these when computing a quality score from the final loss history.

relaxation_terms set

Term names whose schedules end at 0 (cooldown). These are expected to fade out and should be excluded from quality scoring.

cooldown(peak_frac, ramp_frac, n_iters)

Linear cooldown: ramps from 1.0 down to 0.01 over a window of the run.

Parameters:

Name Type Description Default
peak_frac float

Fraction of n_iters at which the weight is still 1.0.

required
ramp_frac float

Fraction of n_iters over which to ramp down.

required
n_iters int

Total number of optimization iterations.

required

Returns:

Type Description

JAX-compatible callable (step: Array) -> Array.

make_term_schedules(params, n_iters)

Build a :class:TermSchedules from a flat parameter dict.

Term names and schedule types are inferred from param key suffixes:

  • {term}_delay + {term}_ramp → :func:warmup for term
  • {term}_peak + {term}_ramp → :func:cooldown for term

Parameters:

Name Type Description Default
params dict

Flat dict whose keys follow the naming convention above. All values are fractions of n_iters in [0, 1].

required
n_iters int

Total number of optimization iterations. Schedules scale automatically — the same params work for any run length.

required

Returns:

Type Description
TermSchedules

class:TermSchedules with schedules, quality_terms, and

TermSchedules

relaxation_terms populated from params.

warmup(delay_frac, ramp_frac, n_iters)

Linear warmup: ramps from 0.01 to 1.0 over a window of the run.

Parameters:

Name Type Description Default
delay_frac float

Fraction of n_iters before ramping starts.

required
ramp_frac float

Fraction of n_iters over which to ramp up.

required
n_iters int

Total number of optimization iterations.

required

Returns:

Type Description

JAX-compatible callable (step: Array) -> Array.