Autoscaler API#
By default, OpenMDAO uses manual specification for the scaling of design variables, constraints, and objectives in optimization.
These are either specified with scaler and adder or ref0 and ref when adding design variables, constraints, or objectives.
In some cases, users may want to apply automatic scaling algorithms of their own. For that purpose, we provide an Autoscaler API.
Presently, OpenMDAO only comes with a default Autoscaler, which is the default option for Drivers.
This uses the scaling provided by the user to specify an overall “total scaler” and “total adder” for each variable. User’s wishing to implement their own scaling algorithm with a diagonal, linear scaling approach can simply override the definitions of “total_scaler” and “total_adder”.
Otherwise, they are free to use the autoscaling methods to implement more advanced techniques.
Autoscaler#
In implementing their own Autoscaler methods, users may utilize the following API.
- Autoscaler.has_scaling
Return True if any scaling is applied to design variables, constraints, or objectives.
- Returns:
- bool
True if any scaling is applied, otherwise False.
- Autoscaler.setup_requires_run_model
Return True if this autoscaler requires that the model be in an executed state.
Some autoscaling methods may require computing totals or otherwise inspecting various inputs and outputs of the model.
This property is used to tell the driver that the run_model needs to be called before configuring the driver.
- Returns:
- bool
True if the driver must execute run_model before the autoscaler’s configure method.
- Autoscaler.setup(driver: Driver)[source]
Perform setup of autoscaler during final setup of the problem.
- Parameters:
- driverDriver
The driver associated with this autoscaler.
- model_has_run: bool
True if setup is being called after the model has been run. If not, and setup requires run model, it will be executed within setup.
- Autoscaler.report_after_setup
Return True if the scaling report should be generated after setup() is called.
When False (default), the scaling report is generated after the first nonlinear totals computation during optimization (the same timing as on master). This is appropriate for autoscalers whose configure() method is a no-op.
When True, the scaling report fires immediately after configure() completes. Subclasses whose configure() method modifies scaling parameters should override this property to return True so that the report reflects the post-configure scaling.
- Returns:
- bool
True if the scaling report should be generated after configure(), False otherwise.
- Autoscaler.get_bounds_scaling(voi_type)[source]
Return pre-computed scaled bounds vectors for the given variable type.
Returns bounds cached during setup() in driver (optimizer) units. The original metadata bounds remain in physical (model) units and are not modified.
Infinite bounds (abs value >= INF_BOUND in model space) are returned as ±INF_BOUND.
If scalers change after setup (e.g. in an adaptive autoscaler subclass), call _compute_scaled_bounds() again for each affected voi_type to refresh the cache.
- Parameters:
- voi_typestr
One of ‘design_var’ or ‘constraint’.
- Returns:
- lowerOptimizerVector
Scaled lower bounds. Unbounded entries contain -INF_BOUND.
- upperOptimizerVector
Scaled upper bounds. Unbounded entries contain INF_BOUND.
- equalsOptimizerVector or None
Scaled equality values. Non-equality constraint entries contain np.nan as a sentinel. None when voi_type=’design_var’.
- Autoscaler.apply_design_var_scaling(vec: OptimizerVector)[source]
Scale the design variables from the model space to the optimizer space.
- Parameters:
- vecOptimizerVector
An OptimizerVector with voi_type=’design_var’.
- Autoscaler.apply_design_var_unscaling(vec: OptimizerVector)[source]
Unscale the design variables from the optimizer space to the model space.
- Parameters:
- vecOptimizerVector
An OptimizerVector with voi_type=’design_var’.
- Autoscaler.apply_constraint_scaling(vec: OptimizerVector)[source]
Scale the constraints from the model space to the optimizer space.
- Parameters:
- vecOptimizerVector
An OptimizerVector with voi_type=’constraint’.
- Autoscaler.apply_objective_scaling(vec: OptimizerVector)[source]
Scale the objective from the model space to the optimizer space.
- Parameters:
- vecOptimizerVector
An OptimizerVector with voi_type=’objective’.
Notes
Use caution in the definition of this method. OpenMDAO always minimizes the objective, and negates the sign of the objective when maximizing (generally by setting scaler or ref to a negative value). If your implementation changes the sign of the objective, you may accidentally change an objective minimization to a maximization or vice-versa.
- Autoscaler.apply_mult_unscaling(desvar_multipliers, con_multipliers)[source]
Unscale the Lagrange multipliers from optimizer space to model space.
This method transforms Lagrange multipliers of active constraints (including active design variable bounds) from the scaled optimization space back to physical (model) space.
At optimality, we assume the KKT stationarity condition holds:
∇ₓf(x) + ∇ₓg(x)^T λ = 0
- where:
∇ₓf is the gradient of the objective
∇ₓg(x)^T is the Jacobian of all active constraints (each row is ∇ₓg_i^T)
λ is the vector of Lagrange multipliers (in optimizer-scaled)
- The constraint vector g(x) includes:
Active design variables (on their bounds, to within some tolerance)
Equality constraints (always active)
Active inequality constraints (on their bounds, to within some tolerance)
- Parameters:
- desvar_multipliersdict[str, np.ndarray]
A dict of optimizer-scaled Lagrange multipliers keyed by each active design variable.
- con_multipliersdict[str, np.ndarray]
A dict of optimizer-scaled Lagrange multipliers keyed by each active constraint.
- Returns:
- desvar_multipliersdict[str, np.ndarray]
A reference to the desvar_multipliers given on input. The values of the multipliers were unscaled in-place.
- con_multipliersdict[str, np.ndarray]
A reference to the con_multipliers given on input. The values of the multipliers were unscaled in-place.
- Autoscaler.apply_jac_scaling(jac_dict)[source]
Scale a Jacobian dictionary from model space to optimizer space.
Applies the scaling transformation to convert a Jacobian computed in the model’s coordinate system to the optimizer’s scaled coordinate system.
- The scaling transformation for the Jacobian is:
- J_scaled = (dT_f/df) * J_model * (dT_x/dx)^-1
= scaler_f * J_model / scaler_x
This accounts for how the scaling transformations affect the derivatives.
- Parameters:
- jac_dictdict
Dictionary of Jacobian blocks. Can be either: - Nested dict where jac_dict[output_name][input_name] = array - Flat dict where jac_dict[(output_name, input_name)] = array
Notes
The method modifies the Jacobian dictionary in-place, scaling each partial derivative block according to the output and input scalers.
When a scaler is None (identity transformation), it’s treated as 1.0 for multiplication and division.
In addition, more advanced methods may require overriding the following
- Autoscaler._compute_scaled_bounds(voi_type)[source]
Compute scaled bounds OptimizerVectors for design variables or constraints.
Called once during setup() to build and cache scaled bounds. Bounds are read from metadata in physical (model) units and transformed to driver (optimizer) units using the combined scaler and adder for each variable.
- Parameters:
- voi_typestr
One of ‘design_var’ or ‘constraint’.
- Returns:
- lowerOptimizerVector
Scaled lower bounds. Unbounded entries contain -INF_BOUND.
- upperOptimizerVector
Scaled upper bounds. Unbounded entries contain INF_BOUND.
- equalsOptimizerVector or None
Scaled equality values. Non-equality constraint entries contain np.nan. None when voi_type=’design_var’.
- Autoscaler._scale_bound(val, adder, scaler, size, is_lower)[source]
Apply scaling to a single bound value, preserving infinite bounds.
- Parameters:
- valfloat or ndarray
Bound value in physical (model) units.
- adderfloat, ndarray, or None
Combined additive scaling factor.
- scalerfloat, ndarray, or None
Combined multiplicative scaling factor.
- sizeint
Number of elements for the variable.
- is_lowerbool
True if this is a lower bound; controls which infinity sentinel is used.
- Returns:
- ndarray
Scaled bound array of length size.