sktopt.tools
- class sktopt.tools.HistoryCollection(dst_path: str)
Bases:
objectManager for multiple
HistorySeriesinstances.This class provides a convenient interface to:
Register multiple named histories
Append new data to any history
Print the latest values for all histories
Export progress plots to image files
Export/import histories to/from a
.npzfileConvert all histories to NumPy arrays or attribute-style objects
- Parameters:
dst_path (str) – Destination directory where exported figures and
.npzfiles will be written.
- add(name: str, constants: list[float] | None = None, constant_names: list[str] | None = None, plot_type: Literal['value', 'min-max-mean', 'min-max-mean-std'] = 'value', ylog: bool = False, data: list | None = None)
Register a new history under the given name.
- Parameters:
name (str) – Name of the history to create.
constants (list of float, optional) – Optional constant values associated with this history (e.g. target volume fraction, penalty parameters). Currently stored but not used in the internal logic.
constant_names (list of str, optional) – Names corresponding to
constants.plot_type ({"value", "min-max-mean", "min-max-mean-std"}, optional) –
Type of aggregation for array inputs:
"value": store scalar values directly. Array inputs are aggregated as inHistorySeries.add()for the chosen plot_type inHistorySeries."min-max-mean": seeHistorySeries."min-max-mean-std": seeHistorySeries.
Default is
"value".ylog (bool, optional) – If
True, the history is intended to be plotted on a logarithmic y-axis inexport_progress().data (list, optional) – Initial data for the history. If provided, it is passed directly to
HistorySeriesand stored as a list.
- as_object()
Return all histories as an attribute-style object.
Each history is exposed as an attribute whose value is the full NumPy array returned by
HistorySeries.data_np_array.- Returns:
obj – An anonymous object such that
obj.<name>is the array corresponding to history<name>.- Return type:
object
- as_object_latest()
Return the latest value of all histories as an attribute-style object.
Each attribute corresponds to a history name and stores the last entry of
HistorySeries.data_np_array.- Returns:
obj – An anonymous object such that
obj.<name>is the latest value of history<name>.- Return type:
object
- export_histories(fname: str | None = None)
Save all histories to a
.npzfile and reload them.This method:
Collects all histories via
histories_to_array()Saves them to
dst_path / fnameusingnumpy.savez()Calls
import_histories()to reload the data and reconstructHistorySeriesinstances
- Parameters:
fname (str, optional) – Output file name (without path). Defaults to
"histories.npz".
- export_progress(fname: str | None = None)
Generate and save progress plots for all histories.
Histories are plotted in a grid of subplots, with up to eight graphs per page (2 rows × 4 columns). If there are more than eight histories, multiple pages are created.
For aggregated histories (min/mean/max[/std]), the following are plotted against iteration index:
min(line + markers)mean(line + markers)max(line + markers)optional shaded region
mean ± stdifplot_type == "min-max-mean-std"
For scalar histories, a single curve is plotted.
The y-axis is logarithmic if
ylog=Truefor that history.- Parameters:
fname (str, optional) – Base file name of the output image(s). If multiple pages are required, an index is prepended (e.g.
"0progress.jpg"). Default is"progress.jpg".
- feed_data(name: str, data: ndarray | float)
Append a new data point to an existing history.
- Parameters:
name (str) – Name of the history (must already exist in
histories).data (float or numpy.ndarray) – Data to be passed to
HistorySeries.add().
- histories_to_array() dict[str, ndarray]
Convert all histories into a dictionary of NumPy arrays.
For each history
name, two entries may be created:name: main data array returned byHistorySeries.data_to_array()f"{name}_header": header array containing metadata such as name and plot_type
Histories with no data are skipped.
- Returns:
Mapping from keys to data/header arrays, suitable for saving via
numpy.savez().- Return type:
dict[str, numpy.ndarray]
- import_histories(fname: str | None = None)
Load histories from a
.npzfile and rebuild the loggers.For each data array stored under key
name, this method:Looks for a corresponding
f"{name}_header"entry to recover the original history name and plot_typeConverts the array back into the internal list format used by
HistorySeriesReuses
constants,constant_namesandylogfrom any existing logger with the same name (if present)Populates a new
HistorySeriesand replaceshistorieswith the reconstructed dictionary
- Parameters:
fname (str, optional) – Input file name (without path). Defaults to
"histories.npz".
- latest(name: str)
Return the latest value of a specific history.
- Parameters:
name (str) – Name of the history to query.
- Returns:
Latest value stored in the specified history.
- Return type:
float or numpy.ndarray
- Raises:
KeyError – If the history
namedoes not exist.ValueError – If the history exists but has no data.
- class sktopt.tools.SchedulerConfig(name: str | None = None, init_value: float | None = None, target_value: float | None = None, num_steps: int | None = None, iters_max: int | None = None, curvature: float | None = None, scheduler_type: Literal['Constant', 'ConstantOne', 'Step', 'StepAccelerating', 'StepDecelerating', 'SawtoothDecay', 'StepToOne', 'StepAcceleratingToOne', 'StepDeceleratingToOne', 'None'] = 'Constant')
Bases:
objectConfiguration for continuation and parameter scheduling.
Defines how a scalar parameter (e.g., penalization
p, projection sharpnessbeta, or volume fractionvol_frac) evolves across optimization iterations. Supports several scheduling strategies.- name
Identifier for the schedule (e.g., “p”, “vol_frac”).
- Type:
str, optional
- init_value
Starting value of the parameter. - Required for Step, StepAccelerating, StepDecelerating, SawtoothDecay. - Automatically inferred for StepToOne. - Ignored if Constant.
- Type:
float, optional
- target_value
Final value of the parameter. - Required for Step, StepAccelerating, StepDecelerating, SawtoothDecay. - Fixed to 1.0 for StepToOne. - Used as fixed value if Constant.
- Type:
float, optional
- num_steps
Number of continuation steps or cycles. - Step / StepAccelerating / StepDecelerating / StepToOne: number of increments between init and target. - SawtoothDecay: number of sawtooth cycles (restarts). - Ignored for Constant.
- Type:
int, optional
- iters_max
Maximum total number of iterations for which the schedule is defined. - Used in SawtoothDecay to partition iterations into cycles. - Typically equals the outer optimizer’s max_iters.
- Type:
int, optional
- curvature
Shape parameter used in StepAccelerating / StepDecelerating. - Example: curvature=2.0 accelerates change near the end. - Ignored in other schedulers.
- Type:
float, optional
- scheduler_type
- Scheduling strategy:
Constant: fixed at
target_value.ConstantOne: fixed at
1.0(alias of Constant with target 1).Step: discrete continuation from
init_value→target_valueinnum_stepsincrements.StepAccelerating: like Step but transition rate controlled by
curvature.StepDecelerating: mirror of StepAccelerating (fast early changes, slows later).
SawtoothDecay: parameter decays linearly from
init_value→target_valuewithin each cycle (cycle length = iters_max/num_steps), then resets toinit_valueat the start of the next cycle.StepToOne: like Step but automatically fixes
target_valueto1.0and infersinit_valuefromnum_steps(1.0 / num_steps).StepAcceleratingToOne: accelerating variant with fixed target 1.0 and inferred
init_value(1.0 / num_steps).StepDeceleratingToOne: decelerating variant with fixed target 1.0 and inferred
init_value(1.0 / num_steps).
- Type:
{“Constant”, “ConstantOne”, “Step”, “StepAccelerating”, “StepDecelerating”, “SawtoothDecay”, “StepToOne”, “StepAcceleratingToOne”, “StepDeceleratingToOne”}
- classmethod constant(name: str | None = None, target_value: float = 1.0) SchedulerConfig
Factory for a Constant scheduler (always returns the same value).
- classmethod constant_one(name: str | None = None) SchedulerConfig
Factory for a Constant scheduler fixed at 1.0.
- classmethod from_defaults(name: str | None = None, init_value: float | None = None, target_value: float | None = None, num_steps: int | None = None, iters_max: int | None = None, curvature: float | None = None, scheduler_type: Literal['Constant', 'ConstantOne', 'Step', 'StepAccelerating', 'StepDecelerating', 'SawtoothDecay', 'StepToOne', 'StepAcceleratingToOne', 'StepDeceleratingToOne', 'None'] = 'Constant') SchedulerConfig
Construct a
SchedulerConfigwith validated defaults.This helper ensures that each scheduler type receives the proper parameters and fills in sensible defaults where possible.
- Parameters:
name (str, optional) – Identifier for the schedule (e.g., “p”, “vol_frac”).
init_value (float, optional) – Starting value of the parameter. - Required for Step, StepAccelerating, StepDecelerating, SawtoothDecay. - Computed automatically for StepToOne. - Ignored if Constant.
target_value (float, optional) – Final value of the parameter. - Required for Step, StepAccelerating, StepDecelerating, SawtoothDecay. - Forced to 1.0 for StepToOne. - Used as fixed value if Constant.
num_steps (int, optional) –
Number of continuation steps or cycles. - Step / StepAccelerating / StepDecelerating / StepToOne:
number of increments from init → target.
SawtoothDecay: number of sawtooth cycles.
Ignored if Constant.
iters_max (int, optional) – Maximum number of iterations over which the schedule is defined. - Used in SawtoothDecay to split iterations into cycles. - Ignored otherwise.
curvature (float, optional) – Shape parameter for StepAccelerating (default ≈ 2.0). Controls acceleration of the step transition. Ignored in other schedulers.
scheduler_type ({"Constant", "ConstantOne", "Step", "StepAccelerating", "StepDecelerating", "SawtoothDecay", "StepToOne", "StepAcceleratingToOne", "StepDeceleratingToOne"}, default="Constant") –
- Which scheduling strategy to use:
Constant: fixed value at
target_value.ConstantOne: fixed to 1.0 regardless of provided values.
Step: discrete continuation from
init_value→target_valueovernum_stepsstages.StepAccelerating: like Step, but interpolation biased by
curvature.StepDecelerating: front-loaded change that slows down over time.
SawtoothDecay: linear decay from
init_value→target_valuewithin each cycle, resetting each time;iters_maxdefines total length.StepToOne: fixed target of 1.0 with the starting point inferred from the number of steps (
1.0 / num_steps).StepAcceleratingToOne / StepDeceleratingToOne: accelerating / decelerating variants with fixed target 1.0.
- Returns:
A validated configuration object ready to be used by the scheduler functions.
- Return type:
- Raises:
ValueError – If required parameters are missing or inconsistent with the chosen
scheduler_type.
Notes
Iteration indices are assumed to be 1-based (
it=1is the first).For Constant,
init_valueis overridden bytarget_value.Defaults may be auto-filled (e.g., curvature=2.0 if omitted).
- classmethod sawtooth_decay(name: str | None = None, init_value: float = 0.1, target_value: float = 0.05, iters_max: int = 100, num_steps: int = 6) SchedulerConfig
Factory for a SawtoothDecay scheduler.
Parameter decays linearly from init_value to target_value within each cycle, then resets. Total iterations = iters_max, cycles = num_steps.
- classmethod step(name: str | None = None, init_value: float | None = None, target_value: float | None = None, num_steps: int | None = None, iters_max: int | None = None) SchedulerConfig
Factory for a Step scheduler (discrete continuation).
- classmethod step_accelerating(name: str | None = None, init_value: float | None = None, target_value: float | None = None, num_steps: int | None = None, iters_max: int | None = None, curvature=None) SchedulerConfig
Factory for a StepAccelerating scheduler (nonlinear continuation with curvature).
- classmethod step_accelerating_to_one(name: str | None = None, num_steps: int | None = None, iters_max: int | None = None, curvature=None) SchedulerConfig
Factory for an accelerating Step scheduler with fixed target 1.0.
- classmethod step_decelerating(name: str | None = None, init_value: float | None = None, target_value: float | None = None, num_steps: int | None = None, iters_max: int | None = None, curvature=None) SchedulerConfig
Factory for a StepDecelerating scheduler (nonlinear continuation that slows down).
- classmethod step_decelerating_to_one(name: str | None = None, num_steps: int | None = None, iters_max: int | None = None, curvature=None) SchedulerConfig
Factory for a decelerating Step scheduler with fixed target 1.0.
- classmethod step_to_one(name: str | None = None, num_steps: int | None = None, iters_max: int | None = None) SchedulerConfig
Factory for a Step scheduler that always targets 1.0.
- class sktopt.tools.SchedulerSawtoothDecay(name: str, init_value: float, target_value: float, num_steps: float, iters_max: int | None = None)
Bases:
SchedulerSawtooth-style cyclic decay scheduler.
This scheduler repeatedly decays a parameter from
init_valuetotarget_valueover each cycle, then resets sharply toinit_value. The full optimization window ofiters_maxiterations is divided intonum_stepscycles.This pattern is useful for: - oscillatory move-limit control, - alternating aggressive and conservative update phases, - maintaining exploration ability in early cycles while enforcing
stability in later cycles.
- Parameters:
name (str) – Name of the scheduled parameter (e.g.,
"move_limit").init_value (float) – Starting value at the beginning of each cycle.
target_value (float) – Final (lowest) value reached at the end of each cycle.
num_steps (int) – Number of decay cycles (sawtooth teeth).
iters_max (int, optional) – Total iterations across which cycles are distributed.
Notes
Scheduling logic is delegated to
schedule_sawtooth_decay().Commonly used for move-limit modulation in OC/MOC updates.
The value evolves linearly within each cycle.
Examples
>>> cfg = SchedulerConfig.sawtooth_decay( ... name="move", init_value=0.3, target_value=0.1, ... iters_max=120, num_steps=4 ... ) >>> sched = Scheduler.from_config(cfg) >>> sched.value(1) 0.3 >>> sched.value(30) 0.2 >>> sched.value(60) # end of second cycle 0.1 >>> sched.value(61) # reset at cycle 3 0.3
- class sktopt.tools.SchedulerStep(name: str, init_value: float, target_value: float, num_steps: float, iters_max: int)
Bases:
SchedulerStep-based continuation scheduler.
This scheduler implements a discrete continuation strategy in which the parameter value (e.g., SIMP exponent
por projection sharpnessbeta) transitions frominit_valuetotarget_valueacrossnum_stepsequally sized stages. Each stage is active for approximatelyiters_max / num_stepsiterations.Unlike gradual exponential schedules, this method produces distinct “plateaus” in which the parameter remains constant for a block of iterations before jumping to the next value. This is one of the common continuation techniques used in density-based topology optimization.
- Parameters:
name (str) – Identifier for the parameter being scheduled (e.g.,
"p"or"vol_frac").init_value (float) – Starting value of the scheduled parameter.
target_value (float) – Final value of the scheduled parameter.
num_steps (int) – Number of continuation steps (including both endpoints).
iters_max (int) – Total number of iterations for the optimization process.
Notes
The actual scheduling logic is delegated to
schedule_step().The value transitions linearly in
num_stepsdiscrete increments.
Examples
>>> cfg = SchedulerConfig.step( ... name="p", init_value=1.0, target_value=3.0, num_steps=5, iters_max=100 ... ) >>> sched = Scheduler.from_config(cfg) >>> sched.value(1) 1.0 >>> sched.value(50) 2.0 >>> sched.value(100) 3.0
- class sktopt.tools.SchedulerStepAccelerating(name: str, init_value: float, target_value: float, num_steps: float, iters_max: int | None = None, curvature: float | None = None)
Bases:
SchedulerNonlinear step-based continuation scheduler with acceleration.
This scheduler extends
SchedulerStepby introducing a curvature-controlled nonlinear interpolation. Earlier stages change slowly, while later stages accelerate more aggressively towardtarget_valueas determined by thecurvatureparameter.Compared to the uniform Step schedule, this variant is useful when early iterations require stability (small changes) and later iterations benefit from rapid parameter adjustments.
- Parameters:
name (str) – Identifier for the parameter being scheduled.
init_value (float) – Starting value of the scheduled parameter.
target_value (float) – Final value of the scheduled parameter.
num_steps (int) – Number of discrete continuation steps.
iters_max (int, optional) – Total number of optimization iterations.
curvature (float, optional) – Nonlinearity exponent controlling acceleration. Higher values → stronger acceleration near the final iterations.
Notes
Scheduling logic is delegated to
schedule_step_accelerating().Behaves similarly to a “power-law continuation”.
Typically configured via
SchedulerConfig.step_accelerating().
Examples
>>> cfg = SchedulerConfig.step_accelerating( ... name="beta", init_value=1.0, target_value=8.0, ... num_steps=6, iters_max=120, curvature=3.0 ... ) >>> sched = Scheduler.from_config(cfg) >>> sched.value(1) 1.0 >>> sched.value(100) # accelerated toward the target 7.2
- class sktopt.tools.SchedulerStepAcceleratingToOne(name: str, num_steps: float, iters_max: int | None = None, curvature: float | None = None)
Bases:
SchedulerAccelerating Step scheduler with fixed target 1.0.
- class sktopt.tools.SchedulerStepDecelerating(name: str, init_value: float, target_value: float, num_steps: float, iters_max: int | None = None, curvature: float | None = None)
Bases:
SchedulerNonlinear step-based continuation scheduler with deceleration.
This is the mirror of
SchedulerStepAccelerating: the schedule changes quickly at the beginning and gradually flattens as iterations progress. Useful when you want aggressive early updates that stabilize over time.
- class sktopt.tools.SchedulerStepDeceleratingToOne(name: str, num_steps: float, iters_max: int | None = None, curvature: float | None = None)
Bases:
SchedulerDecelerating Step scheduler with fixed target 1.0.
- class sktopt.tools.SchedulerStepToOne(name: str, num_steps: float, iters_max: int)
Bases:
SchedulerStep-based scheduler with a fixed target of
1.0.The schedule mirrors
SchedulerStepbut automatically setstarget_value=1.0and infersinit_valuefromnum_steps(1.0 / num_steps). This is handy for ratios or blending factors that should eventually reach one without explicitly specifying both endpoints.
- class sktopt.tools.SectionTimer(clock: Callable[[], float] | None = None, hierarchical: bool = False, sep: str = '>')
Bases:
objectLightweight helper to measure how long named sections take.
Examples
>>> timer = SectionTimer() >>> with timer.section("assemble"): ... ... >>> with timer.section("solve"): ... ... >>> timer.report()
To track nested calls, enable
hierarchicalso section names are recorded with their call stack (e.g.,outer>inner):timer = SectionTimer(hierarchical=True) with timer.section("outer"): with timer.section("inner"): ...
- plot(ax=None, sort_by: str = 'total', value: str = 'total', descending: bool = True, color: str = 'C0', format_nested: bool | None = None, stacked_nested: bool = False, kind: str = 'pie', moving_average: bool = False, use_self_time: bool = False, **kwargs)
Plot timing results choosing between pie (default) or bar chart.
- Parameters:
kind ({"pie", "bar"}) – Chart type.
"pie"usesplot_pie()and is the default,"bar"usesplot_bar().parameters (Other) – Passed through to the selected plotting function.
- plot_bar(ax=None, sort_by: str = 'total', value: str = 'total', descending: bool = True, color: str = 'C0', format_nested: bool | None = None, stacked_nested: bool = False, moving_average: bool = False, use_self_time: bool = False)
Plot timing results as a horizontal bar chart without relying on pyplot state.
- Parameters:
ax (matplotlib.axes.Axes, optional) – Target axes. If omitted, a new Figure/Axes is created.
sort_by ({"total", "avg", "max", "count", "name"}) – Sorting key used before plotting.
value ({"total", "avg", "max", "count"}) – Metric plotted on the x-axis.
descending (bool) – Sort order for
sort_by.color (str) – Bar color passed to Matplotlib.
format_nested (bool, optional) – If
Trueand the timer is hierarchical, indent nested section labels usingsepfor readability. Defaults tohierarchicalflag used at construction time (ignored whenstacked_nestedisTrue).stacked_nested (bool) – If
Trueand hierarchical data are present, render a stacked bar for every section that has children: self-time (parent minus sum(children)) plus one segment per direct child. Sections without children are drawn as regular bars alongside the stacked groups.moving_average (bool) – If
True, plot exponential-free running averages using the incremental mean update (no full history stored).
- Returns:
Figure/Axes containing the plot. If
axwas provided, its parent figure is returned.- Return type:
(matplotlib.figure.Figure, matplotlib.axes.Axes)
- plot_pie(ax=None, sort_by: str = 'total', value: str = 'total', descending: bool = True, colors: List[str] | None = None, autopct: str = '%.1f%%', label_threshold: float = 0.05, min_pct_to_label: float = 1.0, show_legend: bool = True, legend_kwargs: dict | None = None, show_total: bool = True, moving_average: bool = False, use_self_time: bool = False)
Plot timing results as a pie chart to show relative time share.
- Parameters:
ax (matplotlib.axes.Axes, optional) – Target axes. If omitted, a new Figure/Axes is created.
sort_by ({"total", "avg", "max", "count", "name"}) – Sorting key used before plotting.
value ({"total", "avg", "max", "count"}) – Metric used to size the wedges.
descending (bool) – Sort order for
sort_by.colors (list of str, optional) – Colors passed to Matplotlib
pie.autopct (str) –
autopctstring passed to Matplotlibpie.label_threshold (float) – Minimum fraction (0-1) required to draw a text label on the wedge. Smaller slices omit the label to reduce clutter.
min_pct_to_label (float) – Minimum percent value to render
autopcttext. UseNoneto always show.show_legend (bool) – If
True, draw a legend with all section names.legend_kwargs (dict, optional) – Extra kwargs forwarded to
Axes.legendwhenshow_legendisTrue.show_total (bool) – If
True, append total runtime text to the title.moving_average (bool) – If
True, plot exponential-free running averages using the incremental mean update (no full history stored).
- Returns:
Figure/Axes containing the plot. If
axwas provided, its parent figure is returned.- Return type:
(matplotlib.figure.Figure, matplotlib.axes.Axes)
- save_plot(filepath: str, sort_by: str = 'total', value: str = 'total', descending: bool = True, color: str = 'C0', dpi: int = 150, format_nested: bool | None = None, stacked_nested: bool = False, kind: str = 'pie', use_self_time: bool = False, moving_average: bool = False, **kwargs) None
Render and save the timing plot to
filepath.This helper builds its own Figure/Axes (no pyplot state), so it can be used safely inside loops.
- wrap(name: str)
Decorator form of
section().This is convenient for quickly instrumenting functions without rewriting call sites:
@timer.wrap("my_step") def my_step(...): ...