Cost Functions¶
Base Classes¶
- class ionworkspipeline.data_fits.objective_functions.costs.ObjectiveFunction(objective_weights: dict[str, float] | None = None, variable_weights: dict[str, float] | None = None)¶
Base class for all objective/cost functions.
Parameters¶
- objective_weightsdict[str, float], optional
Per-objective weights. Keys are objective names, values are weights. Missing objectives default to weight 1.0.
- variable_weightsdict[str, float], optional
Per-variable weights. Keys are variable names, values are weights. Missing variables default to weight 1.0.
Notes¶
Objective/variable scoping is configured after construction via
set_calculation_structure()(the source of truth), or the convenience wrappersset_objective_names()andset_variable_names(). The structure maps each objective name to the variables to compute for it, orNonefor all; an empty list computes none. It round-trips throughto_config()under thecalculation_structurekey.Extends:
ionworkspipeline.controllers.ConfigMixin- __call__(**kwargs)¶
Call self as a function.
- property calculation_structure: dict[str, list[str] | None] | None¶
The configured calculation structure, or None to compute everything.
Maps each objective name to the explicit list of variable names to compute for it. A value of
Nonefor an objective computes all of that objective’s variables; an empty list computes none of them. A value ofNonefor the whole structure computes every objective and every variable present in the outputs.
- check_output_shapes(outputs: dict) None¶
Validate the model/data shapes this cost will score. No-op by default.
Element-wise costs override this to warn on length mismatches; it is called once at fit setup so the check stays out of the evaluation loop.
- combine(accumulator: ScalarAccumulator | ResidualAccumulator, other: ScalarAccumulator | ResidualAccumulator | float | ndarray[Any, dtype[_ScalarType_co]]) ScalarAccumulator | ResidualAccumulator¶
Combine accumulator values.
Parameters¶
- accumulator
The accumulator to add to.
- other
Another accumulator, or a raw value to add with weight 1.0.
Returns¶
- Accumulator
The updated accumulator (same object, mutated in place).
- finalize_output(accumulator: ScalarAccumulator | ResidualAccumulator) float | ndarray[Any, dtype[_ScalarType_co]]¶
Finalize an accumulator to its output value.
- get_objective_names(outputs: dict) list[str]¶
Get the names of objectives to evaluate over.
Returns the calculation structure’s keys when a structure is set, otherwise every objective name present in
outputs.
- get_variable_names(objective_name: str, outputs: dict, model: dict | None = None) list[str]¶
Get the variable names to compute for a single objective.
Resolves the calculation structure for
objective_name: an explicit variable list is returned as-is (an empty list meaning “no variables”), whileNone— or an unset structure — returns every variable present in that objective’s model output.Parameters¶
- objective_namestr
Name of the objective whose variables to resolve.
- outputsdict
Objective-name -> output container, as passed to
__call__.- modeldict, optional
The already-unpacked model mapping for
objective_name, passed by callers that have it to avoid re-unpackingoutputs. Unpacked fromoutputswhen omitted.
Returns¶
- list[str]
The variable names to compute for
objective_name.
- property objective_names: list[str] | None¶
The configured objective names (structure keys), or None for all.
- property residual_scale_factor: float¶
Scaling factor for regularizer residuals to match scalar semantics.
Regularizers contribute
w * f(x)²in scalar mode. In residual mode they outputsqrt(w) * f(x), which after scalarization becomesscalarize_factor * w * f(x)²wherescalarize_factoris 1.0 for most costs but 0.5 for GaussianLogLikelihood. To preserve the scalar contribution, regularizer residuals are scaled bysqrt(residual_scale_factor)before accumulation, whereresidual_scale_factor = 1 / scalarize_factor.
- scalarize(value: float | ndarray[Any, dtype[_ScalarType_co]], mode: Literal['scalar', 'residuals'] = 'scalar') float¶
Convert a cost value to a scalar.
For scalar mode, returns the value unchanged. For residual mode, computes the sum of squares.
- set_calculation_structure(structure: dict[str, list[str] | None] | None) None¶
Set the exact objective/variable structure this cost computes over.
This is the single source of truth for both objective-level and variable-level scoping;
set_objective_names()andset_variable_names()are thin wrappers over it.Parameters¶
- structuredict[str, list[str] | None] | None
Maps each objective name to the variable names to compute for it, referring to the
outputs[objective]model structure.Nonefor an objective computes all of its variables; an empty list computes none of them. PassingNonefor the whole structure restores the default of computing every objective and variable.
- set_objective_names(objective_names: list[str]) None¶
Restrict this cost to the given objectives (all variables of each).
Convenience wrapper over
set_calculation_structure()that maps every name toNone(compute all of that objective’s variables).
- set_variable_names(objective_name: str, variable_names: list[str] | None) None¶
Set which variables to compute for a single objective.
Updates (or creates) the calculation structure entry for
objective_name.Nonecomputes all of that objective’s variables; an empty list computes none. Other objectives already in the structure are left unchanged.Notes¶
Inside a
DataFit, scoping a subset of objectives is safe: binding fills in the other fit objectives with all variables. Evaluated directly, the structure is the full scope — only the objectives it names are computed.
- class ionworkspipeline.data_fits.objective_functions.costs.ErrorFunction(normalization: Normalization | str | float | None = None, nan_values=None, objective_weights: dict[str, float] | None = None, variable_weights: dict[str, float] | None = None, *, scale: str | float | None = None)¶
Base class for error-based cost functions.
Parameters¶
- normalizationNormalization | str | float, optional
How to normalize weights across variables with different magnitudes. Options: “mean” (default), “identity”, “range”, “sum_squares”, “mean_squares”, “root_mean_squares”, or a float constant. Legacy names “sse”, “mse”, “rmse” are mapped to new names.
- nan_valuesstr | float, optional
How to handle NaN values in model output. Defaults to 1e6. Options: float value, “mean”, “min”, or “raise”.
- objective_weightsdict[str, float], optional
Per-objective weights.
- variable_weightsdict[str, float], optional
Per-variable weights.
- scalestr | float, optional
Deprecated. Use
normalizationinstead.
Extends:
ionworkspipeline.data_fits.objective_functions.costs.costs.ObjectiveFunction- check_output_shapes(outputs: dict) None¶
Warn on mismatched-length model/data variables this cost scores.
Element-wise costs (SSE/MSE/RMSE/MAE/Max) combine
modelanddatapoint-by-point, so differing shapes silently produce a meaningless result — a common footgun when a single cost is applied to an objective exposing both a model-axis variable and a shorter data-axis one. This mirrors the objective/variable iteration of__call__()but only inspects shapes; it is run once at fit setup (not in the evaluation hot path) because a mismatch is a one-time configuration problem. Distribution metrics (Wasserstein) setrequires_equal_length = Falseand are skipped, since unequal-length sample sets are expected there.Parameters¶
- outputsdict
Mapping of objective name to its
(model, data)output container, as built byDataFit.evaluate_inputs_and_outputs.
Error Functions¶
- class ionworkspipeline.data_fits.objective_functions.costs.Max(normalization: Normalization | str | float | None = None, nan_values=None, objective_weights: dict[str, float] | None = None, variable_weights: dict[str, float] | None = None, *, scale: str | float | None = None)¶
Maximum error cost function.
Returns the maximum absolute difference between model and data: Max = max|model - data|
Extends:
ionworkspipeline.data_fits.objective_functions.costs.costs.ErrorFunction
- class ionworkspipeline.data_fits.objective_functions.costs.SSE(normalization: Normalization | str | float | None = None, nan_values=None, objective_weights: dict[str, float] | None = None, variable_weights: dict[str, float] | None = None, *, scale: str | float | None = None)¶
Sum-of-squared-errors cost function.
Calculates the sum of squared differences between model and data: SSE = Σ(model - data)²
Extends:
ionworkspipeline.data_fits.objective_functions.costs.costs.ErrorFunction
- class ionworkspipeline.data_fits.objective_functions.costs.MSE(normalization: Normalization | str | float | None = None, nan_values=None, objective_weights: dict[str, float] | None = None, variable_weights: dict[str, float] | None = None, *, scale: str | float | None = None)¶
Mean-squared-error cost function.
Calculates the mean of squared differences: MSE = Σ(model - data)² / n
Extends:
ionworkspipeline.data_fits.objective_functions.costs.costs.ErrorFunction
- class ionworkspipeline.data_fits.objective_functions.costs.RMSE(normalization: Normalization | str | float | None = None, nan_values=None, objective_weights: dict[str, float] | None = None, variable_weights: dict[str, float] | None = None, *, scale: str | float | None = None)¶
Root-mean-squared-error cost function.
Calculates the square root of MSE: RMSE = √(Σ(model - data)² / n)
This cost function only supports scalar output.
Extends:
ionworkspipeline.data_fits.objective_functions.costs.costs.ErrorFunction
- class ionworkspipeline.data_fits.objective_functions.costs.MAE(normalization: Normalization | str | float | None = None, nan_values=None, objective_weights: dict[str, float] | None = None, variable_weights: dict[str, float] | None = None, *, scale: str | float | None = None)¶
Mean-absolute-error cost function.
Calculates the mean of absolute differences: MAE = Σ|model - data| / n
Extends:
ionworkspipeline.data_fits.objective_functions.costs.costs.ErrorFunction
- class ionworkspipeline.data_fits.objective_functions.costs.ChiSquare(variable_standard_deviations: dict[str, float], nan_values=None)¶
Chi-square cost function with per-variable standard deviations.
Calculates chi² = Σ((model - data) / σ)² where σ is the standard deviation for each variable.
Parameters¶
- variable_standard_deviationsdict[str, float]
Dictionary mapping variable names to their standard deviations.
- nan_valuesstr | float, optional
How to handle NaN values.
Extends:
ionworkspipeline.data_fits.objective_functions.costs.costs.ErrorFunction
Multi-Cost Functions¶
- class ionworkspipeline.data_fits.objective_functions.costs.MultiCost(costs: dict, normalization: Normalization | str | float | None = None, nan_values=None, objective_weights: dict[str, float] | None = None, variable_weights: dict[str, float] | None = None, *, scale: str | float | None = None)¶
Cost function combining multiple costs with weights.
Parameters¶
- costsdict[ObjectiveFunction, float]
Dictionary mapping cost functions to their weights.
- normalization, nan_values, objective_weights, variable_weights
Passed to ErrorFunction base class.
- scalestr | float, optional
Deprecated. Use
normalizationinstead.
Extends:
ionworkspipeline.data_fits.objective_functions.costs.costs.ErrorFunction- check_output_shapes(outputs: dict) None¶
Delegate to each sub-cost (each has its own metric and scoping).
- scalarize(value: float | ndarray[Any, dtype[_ScalarType_co]], mode: Literal['scalar', 'residuals'] = 'scalar') float¶
Convert the finalized cost value to a scalar.
Uses the passed-in value directly, which includes any regularization terms added after MultiCost.__call__ returns. This ensures Evaluation.value_scalarized reflects the true total cost.
Design Functions¶
- class ionworkspipeline.data_fits.objective_functions.costs.DesignFunction(objective_weights: dict[str, float] | None = None)¶
Cost function for design optimization problems.
Used for optimization objectives where the goal is to maximize or minimize design metrics (energy density, power density, etc.) rather than fit to data.
Parameters¶
- objective_weightsdict[str, float], optional
Per-objective weights.
Extends:
ionworkspipeline.data_fits.objective_functions.costs.costs.ObjectiveFunction