11.6. da.p7core.gtdoe

Generic Tool for Design of Experiments (GTDoE) module.

>>> from da.p7core import gtdoe

Submodules

da.p7core.gtdoe.measures Sample metrics.

Classes

da.p7core.gtdoe.Generator([backend]) DoE generator.
da.p7core.gtdoe.ProblemConstrained(*iargs, …) Simplified problem class for constrained problems.
da.p7core.gtdoe.ProblemCSP(*iargs, **ikwargs) Simplified problem class for constraint satisfaction problems (CSP).
da.p7core.gtdoe.ProblemGeneric(*iargs, **ikwargs) Base optimization problem class.
da.p7core.gtdoe.ProblemUnconstrained(*iargs, …) Simplified problem class for unconstrained problems.
da.p7core.gtdoe.Result(info, points, …[, …]) Generator result.
da.p7core.gtdoe.ValidationResult(status, details) Validation result and details.

11.6.1. Generator — sample generator

class da.p7core.gtdoe.Generator(backend=None)

DoE generator.

build_doe(blackbox, count, sample_x=None, sample_f=None, sample_c=None, options=None)

Generate a design of experiments (DoE), containing values of variables only, or run a sampling study — generate a DoE and run it, evaluating responses.

Parameters:
  • blackbox (ProblemGeneric or other GTDoE problem class, Blackbox, gtapprox.Model, gtdf.Model; or a pair of iterables containing floats) – DoE blackbox, or design space bounds (lower, upper)
  • count (int) – in space-filling techniques: the target size of DoE sample, 0 means default size; in Adaptive Design: the target number of feasible designs, 0 means continue generation until reaching a response evaluation limit
  • sample_x (array-like, 1D or 2D) – optional initial sample containing values of variables
  • sample_f (array-like, 1D or 2D) – optional initial sample of objective function values, requires sample_x
  • sample_c (array-like, 1D or 2D) – optional initial sample of constraint function values, requires sample_x
  • options (dict) – study options; not required, amends the options set through the options interface
Returns:

study result

Return type:

p7core.Result

New in version 6.14.

Changed in version 6.19: count now sets an aim for the number of feasible DoE points to generate, not the allowed number of evaluations; to set evaluation limits, use GTDoE/AdaptiveDesign/MaximumIterations and GTDoE/AdaptiveDesign/MaximumExpensiveIterations.

Changed in version 6.20: blackbox may be a gtapprox.Model or a gtdf.Model.

Changed in version 6.26: now supports space-filling as well as adaptive DoE techniques.

Changed in version 6.27: for space-filling techniques, count may be 0 to generate the default number of points if the technique supports it.

Changed in version 6.29: added stepped variables support.

Changed in version 6.29: space-filling techniques no longer raise an exception when it is not possible to generate count points; instead they issue a warning and return result, which contains all generated points.

Changed in version 6.33: space-filling techniques and Adaptive Design of Experiments now support constraints.

Changed in version 6.33: added categorical variables support in the Adaptive Design technique.

Changed in version 6.35: added the support for evaluation responses, minimization and maximization objectives — see the @GT/ObjectiveType hint.

Changed in version 6.35: DoE techniques now evaluate responses in all resulting DoE points (previously, only in feasible points).

Changed in version 6.35: to freeze a variable, you can now use the @GT/FixedValue hint; methods from previous versions are also supported for compatibility, but using them is not recommended.

Changed in version 6.36: for compatibility with Adaptive Design, most techniques now handle categorical variables in a similar manner — generate a DoE for each possible combination of categories, count and evaluation limits are split between those designs — so generation result may be used as an initial sample in Adaptive Design without issues; only the Full Factorial, Fractional Factorial and Orthogonal Array techniques do not change their behavior from 6.35 (to revert to old behavior in other techniques, you can redefine categorical variables as discrete).

Changed in version 6.45: added the support for mixed designs (include continuous and discrete variables) to the Adaptive Design of Experiments technique.

Changed in version 6.45: Adaptive Design of Experiments can run in space-filling mode.

Changed in version 6.45: all techniques support 0 as a valid count value, which means generating the default number of points (DoE size).

General DoE study method, which supports all GTDoE techniques and different types of variables and blackboxes, with certain limitations imposed by the selected technique.

To select a technique, use the GTDoE/Technique option. Technique requirements and limitations are outlined below.

Before you run a DoE study, validate your settings with validate() to avoid errors caused by incorrect study definition.

Types of variables

GTDoE recognizes the following types of variables:

  • Continuous (default type) — a generic continuous variable that can take any value within its lower and upper bounds.
  • Discrete — a discontinuous numeric variable that can take any value from the predefined set of allowed values (levels).
  • Stepped — a special kind of a continuous variable that is bound to a certain grid.
  • Categorical — a special type of variable that has a finite number of possible values (categories) and does not assume any numerical meaning, order or metrics. If your design includes categorical variables, most techniques generate all possible combinations of categories and run a DoE for each of those combinations. Notable exceptions are the Fractional Factorial and Orthogonal Array techniques, which generally handle categorical variables in the same way as discrete ones.

If blackbox is an instance of ProblemGeneric or another GTDoE problem class, specify types of variables when you add them to your problem, using the @GT/VariableType hint in add_variable(). In this case, variable bounds or levels are specified as arguments to add_variable().

If blackbox is a gtapprox.Model or gtdf.Model instance, types of variables are defined by the model (input descriptions, see Model Details).

Categorical variables and their levels may also be specified via the GTDoE/CategoricalVariables option, which may be useful in the following cases:

  • To define categorical variables when blackbox is a Blackbox instance or an array of design space bounds.
  • With other blackbox types — to change some variables of different types to categorical, or to narrow the set of levels for some categorical variable defined by the blackbox (model). In the latter case, GTDoE/CategoricalVariables may only select a subset from levels already defined by the blackbox (model), but may not add new levels.

Note that some techniques do not support certain types of variables — see section Types of Variables for details.

Constants

A variable of any type can be frozen, giving it a constant value in the generated sample. To freeze a variable, use the @GT/FixedValue hint. For a continuous variable, you may specify a constant value that is out of variable bounds. For other types of variables, the value you specify must be a valid level for that variable.

Space-filling techniques

Space-filling DoE techniques do not analyze blackbox responses although evaluate them, if defined. These techniques first generate the input DoE, then evaluate responses with that inputs. Constraints are recognized — resulting designs are sorted into feasible and infeasible, if blackbox defines constraints. If the blackbox defines any minimization or maximization objectives (see the @GT/ObjectiveType hint), GTDoE also finds optimal points among those appearing in the result.

For space-filling techniques, blackbox may be a pair of iterables (lower, upper) containing float values that specify the lower and upper bounds for each of the design variables. The length of each iterable must be equal to the number of variables. In this case you can use the GTDoE/CategoricalVariables option to set up categorical variables by specifying their indexes and levels. For categorical variables, bounds are ignored, so in blackbox the elements corresponding to categorical variables may have arbitrary float values (they are required only for correct indexing of variables).

With other types of blackboxes, properties of variables (types, bounds, levels) are read from the blackbox object or from model details, if blackbox is an approximation model. The GTDoE/CategoricalVariables option in this case may be used to change some variables of different types to categorical, or to narrow the set of levels for some categorical variable defined by the blackbox (model). Note that GTDoE/CategoricalVariables may only select a subset from levels defined by the blackbox (model), but may not add new levels.

The count argument sets the number of design points to generate. For the space-filling techniques, 0 is a valid count value, which means generating a sample of the default size:

  • Full Factorial — default is the minimum required to generate a sample that includes all possible combinations of variable levels or categories; continuous and stepped variables are assigned 2 levels — their lower and upper bounds.
  • Fractional Factorial — default size is defined by the generating string; if you do not specify the generating string or main factors, default is the minimum possible sample size for the given number of variables (dimension).
  • Parametric Study — default is the minimum possible sample size for the given number of variables (dimension), that includes all possible combinations produced by categorical variables.
  • Optimal Design — default is the minimum sample size suitable to train an RSM model of the target type (set by GTDoE/OptimalDesign/Model) for each possible combination produced by categorical variables.
  • Box-Behnken — has a fixed DoE size determined by the number of variables (dimension), multiplied by the number of possible combinations produced by categorical variables. For this technique, using default count is recommended.
  • Orthogonal Array — default is the minimum size of a proper orthogonal array for the given number of variables.
  • Other space-filling techniques — default is an internal estimate depending on the design space dimension (the number of variables).

If your design includes categorical variables, it is handled as follows:

  • If you use the Full Factorial technique, all possible combinations of categories are generated.
  • If you use the Fractional Factorial technique, combinations are generated as per the generating string (see Fractional Factorial for details).
  • If you use the Orthogonal Array technique, it produces the minimum number of combinations required to generate an array of the requested type and size (see Orthogonal Array for details).
  • If you use any other space-filling technique, GTDoE generates all possible combinations of categories, then for each of those combinations generates a DoE using the technique you have specified and splitting count between those sub-runs. If dividing count by the number of combinations leaves a remainder, that remainder is distributed between sub-runs so that each of them gets at most 1 extra point.

Note that in certain cases it is not possible to generate as many as count points — for example, if all variables are discrete, a full factorial DoE has fixed size. In such cases, only the possible number of points are generated and included in result, and GTDoE issues a warning.

Adaptive Design of Experiments

This technique analyzes blackbox responses though can also work in sample-based and space-filling modes, if response evaluations are not available. It selects the mode automatically based on the blackbox type, response properties, and availability of the initial sample. In the adaptive (main) mode, it analyzes behavior of adaptation objectives (see the @GT/ObjectiveType hint), and supports constraints but does not analyze them (treats constraints in the same way as the space-filling techniques). Minimization and maximization objectives are treated in the same way as in space-filling techniques — GTDoE finds optimal points in the final result. If your design includes categorical variables, GTDoE generates all possible combinations of categories, then runs an independent Adaptive Design of Experiments study for each combination, splitting count between those sub-runs.

In the adaptive (main) mode:

  • blackbox must be ProblemGeneric, ProblemUnconstrained, Blackbox, or an approximation model (GTApprox, GTDF). Models with categorical inputs are supported only if all inputs are categorical. Models with categorical outputs are not supported.
  • If blackbox is a GTDoE problem instance, it must define at least 1 adaptation objective; if a Blackbox instance, must define at least 1 response.
  • Properties of variables are defined by the blackbox. The GTDoE/CategoricalVariables option may be used to change some of the continuous variables to categorical, or to narrow the set of levels for some categorical variable defined by the blackbox (model). Note that GTDoE/CategoricalVariables may only select a subset from levels defined by the blackbox (model), but may not add new levels.
  • An initial sample is optional.
  • All adaptive DoE criteria are supported (see GTDoE/Adaptive/Criterion).

In the sample-based mode:

  • This mode is used when there are no adaptation objectives, and you provide an initial sample.
  • The blackbox argument may be a pair of iterables defining the lower and upper bounds of variables — for example, 2 lists of float values.
  • You can use the GTDoE/CategoricalVariables option to set up categorical variables. If blackbox is an array of bounds, you can set arbitrary values of bounds for categorical variables, since bounds for them are ignored.
  • If you provide an initial sample with response data (pass variable and response samples as sample_x and sample_f), all adaptive DoE criteria are supported (see GTDoE/Adaptive/Criterion). If you provide only sample_x, then only the uniform criterion is supported.

In the space-filling mode:

  • This mode is used when there are no adaptation objectives and no initial sample.
  • The blackbox argument may be a pair of iterables defining the lower and upper bounds of variables — for example, 2 lists of float values.
  • You can use the GTDoE/CategoricalVariables option to set up categorical variables. If blackbox is an array of bounds, you can set arbitrary values of bounds for categorical variables, since bounds for them are ignored.
  • Only the uniform criterion is supported (see GTDoE/Adaptive/Criterion).

In the adaptive mode, count sets the number of allowed response evaluations. In the space-filling mode, count sets the number of new points to generate. If your design includes categorical variables, GTDoE splits count between sub-runs done for each of the possible combinations of categories. If dividing count by the number of combinations leaves a remainder, that remainder is distributed between sub-runs so that each of them gets at most 1 extra point.

For Adaptive Design of Experiments, 0 is also a valid count value: the number of points to generate will be estimated internally, depending on the design space dimension (the number of variables).

Adaptive Design

The Adaptive Design technique supports constraint and objective responses and analyzes behavior of adaptation objectives (see the @GT/ObjectiveType hint), generating new designs with aims as follows:

  • If the blackbox defines any constraints, aim to generate points that satisfy those constraints (generate points in the feasibility domain).
  • If the blackbox defines any adaptation objectives, aim to generate more points in the design space areas where adaptation objective functions exhibit non-trivial behavior — for example, where a function is more sensitive to changes in inputs (variables).
  • If the blackbox does not define any adaptation objective, aim to distribute points uniformly in the feasibility domain (satisfy constraints).
  • If the blackbox defines adaptation objectives as well as constraints, aim to generate points in the feasibility domain but take into account the behavior of adaptation objectives when distributing points within that domain.
  • If the blackbox does not define any adaptation objectives or constraints, generate a uniformly distributed sample within the design space (variable) bounds.
  • Minimization and maximization objectives are treated in the same way as in space-filling techniques — GTDoE finds optimal points in the final result.

Internally, Adaptive Design trains approximation models of responses and uses them to predict response behavior when placing new points. If you pass an initial sample containing response data, that sample is used to obtain initial models, which are further updated when the Adaptive Design algorithm receives new response evaluations from the blackbox.

  • Requires blackbox to be an instance of your problem class inherited from ProblemGeneric or one of the simplified GTDoE problem classes, or an approximation model (GTApprox, GTDF). Models with categorical outputs are not supported.

    For a guide on how to implement your problem class, see descriptions of ProblemGeneric and other classes. In brief:

  • If you define categorical variables, Adaptive Design runs an independent subtask for each possible combination of categories.

  • If the blackbox does not define any adaptation objectives or constraints, Adaptive Design switches to space-filling mode where it generates a uniformly distributed sample. This mode may be used to update a non-uniform initial sample to a more uniform result sample.

  • Constraint and objective responses are processed as outlined above. Responses defined as computationally expensive (see the @GTOpt/EvaluationCostType hint) are modeled internally; Adaptive Design requests evaluations of such responses to update and improve their internal models. Computationally cheap responses are always evaluated directly and may be evaluated an unlimited number of times by default. Note that responses are considered cheap by default.

The distinction between computationally cheap and expensive responses is one of the key features in Adaptive Design.

Expensive responses are always expected to have a finite evaluation limit. This limit is set according to the GTDoE/AdaptiveDesign/MaximumExpensiveIterations option value. If this option does not set a specific limit, GTDoE determines it automatically. The automatic limit is finite but can vary depending on the problem properties. Adaptive Design generally aims to minimize the number of expensive response evaluations.

Cheap responses may be evaluated an unlimited number of times by default. Adaptive Design does not aim to limit the number of cheap response evaluations. This limit may be imposed manually, using the GTDoE/AdaptiveDesign/MaximumIterations, although its value should be relatively high (of order \(10^3\) or greater). Setting the evaluation limit for computationally cheap responses too low may cause an abrupt stop in the Adaptive Design algorithm, which does not raise an error but often decreases the result quality significantly. If your design includes categorical variables, Adaptive Design runs an independent subtask for each possible combination of categories, and evaluation limits are split between those subtasks. If dividing some limit by the number of subtasks leaves a remainder, that remainder is distributed between subtasks so that each of them gets at most 1 extra evaluation.

For the Adaptive Design technique, a non-zero count argument sets the target number of feasible points to generate. Feasible points are points that satisfy constraints defined by blackbox; if the blackbox defines no constraints, all generated points are considered feasible. The target number of feasible points cannot be greater than the evaluation limit for expensive responses (GTDoE/AdaptiveDesign/MaximumExpensiveIterations). If your design includes categorical variables, count sets the total target number of feasible points, which is split between the subtasks created by Adaptive Design. If dividing count by the number of subtasks leaves a remainder, that remainder is distributed between subtasks so that each of them gets at most 1 extra point.

Evaluation limits and count may be used together — for example:

  • If count is 0, the technique continues generating new designs until it reaches one of the evaluation limits. Note that the number of expensive response evaluations is always finite — even if you do not set the GTDoE/AdaptiveDesign/MaximumExpensiveIterations option, GTDoE sets a finite limit automatically, based on problem properties (number of variables, responses, their types, and so on).
  • If you specify count only (greater than 0), the technique continues generating new designs until it finds count feasible points, aiming to minimize the number of expensive response evaluations.
  • If you specify count (greater than 0) and set GTDoE/AdaptiveDesign/MaximumExpensiveIterations, the technique continues generating new designs until it finds count feasible designs or reaches the expensive response evaluation limit, whichever happens first. It also aims to minimize the number of expensive response evaluations.
generate(bounds, **kwargs)

Generate a DoE.

Parameters:
  • blackbox (Blackbox, gtapprox.Model, or gtdf.Model) – adaptive DoE blackbox, optional
  • bounds (pair of iterables containing float values) – design space bounds (lower, upper)
  • budget (int, long) – blackbox budget (only for the blackbox-based adaptive DoE)
  • count (int, long) – the number of points to generate (not for the blackbox-based adaptive DoE; use budget), 0 means default
  • init_x (array-like, 1D or 2D) – optional initial sample for the adaptive DoE, input part (values of variables)
  • init_y (array-like, 1D or 2D) – optional initial sample for the adaptive DoE, response part (function values)
  • compatibility (bool) – keeps behavior compatible with versions 6.35 and below (added in 6.36)
Returns:

DoE sample or sequential generator

Return type:

gtdoe.Result by default, or p7core.Result if compatibility is False

New in version 2.0: sample-based adaptive DoE generation.

New in version 3.1: the support for functions with multidimensional output in adaptive DoE.

New in version 3.1: adaptive DoE can now handle NaN values in init_y and in blackbox output.

New in version 6.2: sample-based adaptive DoE can now work in property-preservation mode.

Changed in version 6.20: blackbox may be a gtapprox.Model or a gtdf.Model.

Changed in version 6.27: in batch space-filling mode, count may be 0 to generate the default number of points if the used technique supports it.

Changed in version 6.29: space-filling techniques no longer raise an exception when it is not possible to generate count points; instead they issue a warning and return result, which contains all generated points.

Changed in version 6.36: added the compatibility parameter used to switch between two modes: True (default) keeps behavior from prior versions (6.35 and earlier), False reproduces build_doe() behavior regarding categorical variables and changes return type to p7core.Result.

Deprecated since version 6.38: kept for compatibility only and may be removed in future versions; use build_doe() instead.

Generates a DoE sample within bounds or creates an infinite sequential generator which works in the domain specified by bounds. The bounds argument also implicitly specifies the DoE dimension: it is equal to len(bounds[0]) (naturally, len(bounds[0]) == len(bounds[1])).

This method has four call modes:

  1. sequential space-filling DoE,
  2. batch space-filling DoE,
  3. blackbox-based adaptive DoE, and
  4. sample-based adaptive DoE.

The optional compatibility argument added in 6.36 changes behavior as follows:

  • If compatibility is True, reproduces behavior of generate() from versions 6.35 and below:
    • Returns a gtdoe.Result instance.
    • DoE techniques that support categorical variables generate certain combinations of such variables, that depend on count and the technique you use.
    • The Parametric Study, Box-Behnken, and low-discrepancy sequence (Sobol, Halton, Faure) techniques cannot be used with categorical variables.
  • If compatibility is False, reproduces build_doe() behavior:
    • Returns a p7core.Result instance.
    • All techniques are compatible with categorical variables.
    • If your design includes categorical variables, all techniques except the ones listed below run an independent subtask for each possible combination of categories, count is split evenly between those subtasks and must be greater than the number of subtasks (but may be 0 to use the default).
    • The following techniques keep their behavior from 6.35, regarding categorical variables:
      • Full Factorial — generates all possible combinations of categories.
      • Fractional Factorial — generates combinations as per the generating string (see Fractional Factorial for details).
      • Orthogonal Array — selects certain combinations to generate an array of the required type (see Orthogonal Array for details).

Sequential

The sequential space-filling mode requires bounds only and is usable only if compatibility is True (default).

In this mode, returned result does not contain a data sample. Instead, it is used as an infinite points generator (see take()). This mode is supported only by sequential techniques:

  • sequential uniform random generation (random sequence)
  • Sobol sequence
  • Halton sequence
  • Faure sequence

Batch

For batch space-filling mode, specify bounds and count.

In this mode, GTDoE/Technique may specify any technique except "Adaptive", which switches to the sample-based adaptive DoE, and "AdaptiveDesign", which is supported only by build_doe().

For the space-filling techniques, 0 is a valid count value, which means generating a sample of the default size:

  • Full Factorial — default is the minimum required to generate a sample that includes all levels of variables, which have levels specified, and 2 levels for each variable, which has no specified levels.
  • Fractional Factorial — default size is defined by the generating string; if you do not specify the generating string or main factors, default is the minimum possible sample size for the given number of variables (dimension).
  • Parametric Study — default is the minimum possible sample size for the given number of variables (dimension).
  • Optimal Design — default is the minimum sample size suitable for the target RSM model type (set by GTDoE/OptimalDesign/Model).
  • Box-Behnken — generated sample size is defined by the number of variables, using default is recommended.
  • Orthogonal Array — default is the minimum size of a proper orthogonal array for the given number of variables.
  • Other space-filling techniques — default is an internal estimate depending on the design space dimension (the number of variables).

Note that in certain cases it is not possible to generate as many as count points — for example, if all variables are discrete, a full factorial DoE has fixed size. In such cases, only the possible number of points are generated and included in result, and GTDoE issues a warning.

Adaptive Blackbox-Based

For the blackbox-based adaptive DoE, specify blackbox, bounds and budget. The generator switches to the blackbox-based adaptive DoE mode automatically. The GTDoE/Technique option is ignored in the blackbox-based mode.

Optionally you can also specify an initial sample: either init_x only (in this case the generator requests response values from the blackbox), or both init_x and init_y. In general form, init_x and init_y are 2D array-likes. 1D samples are supported as a simplified form for the case of 1D input and/or response.

In this mode, bounds are intended to contract the point generation area. Due to this, the generator does not automatically apply the bounds set for blackbox variables (see da.p7core.blackbox.Blackbox.add_variable()). You have to ensure that the generator bounds at least intersect with the blackbox variable bounds, because DoE points are generated only in the area of intersection. If the areas of the generator and blackbox bounds do not intersect, the generate() raises an exception.

If you just want the same bounds for the generator and the blackbox, specify the variables_bounds() return value as the bounds argument.

Adaptive Sample-Based

The sample-based adaptive DoE works in two modes:

  1. Filling mode,
  2. Property-preservation mode.

The filling mode aims to add new points to the design according to the selected criterion. The property-preservation mode aims to preserve certain space-filling property of the given initial design.

Filling mode

Filling mode aims to add new points to the design according to the selected criterion.

To run the sample-based adaptive DoE in the filling mode, set GTDoE/Technique to "Adaptive" and specify bounds and count. Note that unlike the blackbox-based adaptive DoE, the generator does not switch to the sample-based adaptive DoE mode automatically.

The initial sample is optional in sample-based adaptive DoE, however the technique behavior depends on it. The initial sample may either include values of variables (init_x only), or include both variable and response values (init_x and init_y), or be empty. Running with an empty initial sample or with init_x only effectively limits adaptive DoE to uniform generation mode, and in this case valid settings for GTDoE/Adaptive/Criterion include only "Uniform" and "Auto" (and the latter defaults to "Uniform"). Other criteria are based on approximation models and require a response sample (init_y) for model training.

Note

To simplify, if you run sample-based adaptive DoE without an initial sample or with init_x only, leave GTDoE/Adaptive/Criterion default ("Auto").

Property-preservation mode

Property-preservation mode aims to preserve certain space-filling property of the given initial design. This mode is supported by the LHS, OLHS, and OA techniques. To run the sample-based adaptive DoE in the property-preservation mode, select one of the supported techniques with GTDoE/Technique and specify bounds, count and init_x.

In this mode, GTDoE preserves properties of the initial sample when possible:

  • For LHS: if the size of initial sample init_x is a factor of the additional sample size count, then the union of the initial design and generated design is also LHS.
  • For OA: if the initial sample is an orthogonal array with correct values of variables, the final sample is also an orthogonal array. The type of the final array (strict, balanced, or irregular) depends on count. With high enough count, it is possible that the final sample size exceeds the size of a full factorial sample. In this case, one or more full factorial samples are generated until the remaining count is less than the full factorial size, and the remainder is used to generate an orthogonal array. The final sample then is a union of one or more full factorial samples and an orthogonal array supplementing them to reach the requested sample size.

Modes Summary

Call modes and valid argument combinations:

Mode Arguments
Sequential space-filling DoE bounds
Batch space-filling DoE bounds, count
Blackbox-based adaptive DoE, no initial sample blackbox, bounds, budget
Blackbox-based adaptive DoE with an initial DoE only blackbox, bounds, budget, init_x
Blackbox-based adaptive DoE with an input/response sample blackbox, bounds, budget, init_x, init_y
Sample-based adaptive DoE with a training sample bounds, count, init_x, init_y
Sample-based adaptive DoE with an initial DoE only bounds, count, init_x
Adaptive DoE in uniform sampling mode bounds, count
license

Generator license.

Type:License

General license information interface. See section License Usage for details.

options

Generator options.

Type:Options

General options interface for the generator. See section Options Interface for usage and the GTDoE Option Reference.

report_ignore_ig(problem, technique, logger)
set_logger(logger)

Set logger.

Parameters:logger – logger object
Returns:None

Used to set up a logger for the DoE generation process. See section Loggers for details.

set_watcher(watcher)

Set watcher.

Parameters:watcher – watcher object
Returns:None

Used to set up a watcher for the DoE generation process. See section Watchers for details.

validate(blackbox, count, sample_x=None, sample_f=None, sample_c=None, options=None)

Validate a DoE study definition.

Parameters:
  • blackbox (ProblemGeneric or other GTDoE problem class, Blackbox, gtapprox.Model, gtdf.Model; or a pair of iterables containing floats) – DoE blackbox, or design space bounds (lower, upper)
  • count (int) – in space-filling techniques: sample size, 0 means default; in Adaptive Design: the target number of feasible designs, 0 means no target
  • sample_x (array-like, 1D or 2D) – optional initial sample of variables
  • sample_f (array-like, 1D or 2D) – optional initial sample of objectives
  • sample_c (array-like, 1D or 2D) – optional initial sample of constraints
  • options (dict) – study options
Returns:

validation outcome

Return type:

gtdoe.ValidationResult

New in version 6.33.

Validates your study settings and returns a ValidationResult object providing general validation status (status, True if validation passed, False otherwise) and details, if any (details).

Test your study definition before running build_doe() to avoid errors caused by incorrect study settings. When calling validate(), pass the same arguments as you would pass to build_doe(), including option settings and initial samples. All validate() parameters have the same meaning as build_doe() parameters.

11.6.2. ProblemConstrained — constrained problem

class da.p7core.gtdoe.ProblemConstrained(*iargs, **ikwargs)

Simplified problem class for constrained problems. Inherits from ProblemGeneric.

This class does not support the usage of analytical objective and constraint gradients.

To define a constrained optimization problem, create your own problem class, inheriting from ProblemConstrained. This class must implement the following methods:

define_constraints(x)

An abstract method to define problem constraints.

Parameters:x (ndarray, 1D) – point to evaluate
Returns:evaluation results
Return type:array-like, 1D

Changed in version 3.0 Release Candidate 1: the x argument is ndarray.

Changed in version 6.24: evaluation results may contain None values to indicate skipped evaluations.

This method does not support the batch mode (evaluates single point only). May be implemented by user instead of define_constraints_batch() (which uses this method by default).

The shape of x is the same as in define_objectives().

The returned array may contain NaN and None values, which have the following meaning:

  • NaN value of some constraint indicates that evaluation of a constraint failed.
  • None value indicates that evaluation of a constraint was skipped.

Note that skipped and failed evaluations may stop optimization prematurely.

define_constraints_batch(x)

Default implementation of the method defining problem constraints. Supports non-batch and batch modes.

Parameters:x (ndarray, 2D) – points batch
Returns:evaluation results
Return type:ndarray, 2D

Changed in version 3.0 Release Candidate 1: the x argument is ndarray; default implementation also returns ndarray.

Changed in version 6.24: evaluation results may contain None values to indicate skipped evaluations.

This method is used by ProblemConstrained.evaluate() to calculate constraints. Default implementation simply loops over the points batch x, calling define_constraints() for each point. May be reimplemented by user to support parallel calculations. Such implementation may return any 2D array-like.

The shape of x is the same as in define_objectives_batch().

The returned array may contain NaN and None values, which have the following meaning:

  • NaN value of some constraint indicates that evaluation of a constraint failed.
  • None value indicates that evaluation of a constraint was skipped.

Note that skipped and failed evaluations may stop optimization prematurely.

define_objectives(x)

An abstract method to define problem objectives.

Parameters:x (ndarray, 1D) – point to evaluate
Returns:evaluation results
Return type:ndarray, 1D

Changed in version 3.0 Release Candidate 1: the x argument is ndarray.

Changed in version 6.24: evaluation results may contain None values to indicate skipped evaluations.

This method does not support the batch mode (evaluates single point only). May be implemented by user instead of define_objectives_batch() (which uses this method by default).

The shape of x is (1, m) where m is the input dimension (size_x() + size_s()). The first size_x() values are classic variables (see add_variable()), while the following size_s() values are stochastic variables (see set_stochastic()).

The returned array may contain NaN and None values, which have the following meaning:

  • NaN value of some objective indicates that evaluation of an objective failed.
  • None value indicates that evaluation of an objective was skipped.

Note that skipped and failed evaluations may stop optimization prematurely.

define_objectives_batch(x)

Default implementation of the method defining problem objectives. Supports non-batch and batch modes.

Parameters:x (ndarray, 2D) – points batch
Returns:evaluation results
Return type:ndarray, 2D

Changed in version 3.0 Release Candidate 1: the x argument is ndarray; default implementation also returns ndarray.

Changed in version 6.24: evaluation results may contain None values to indicate skipped evaluations.

This method is used by ProblemConstrained.evaluate() to calculate objectives. Default implementation simply loops over the points batch x, calling define_objectives() for each point. May be reimplemented to support parallel calculations. Such implementation may return any 2D array-like.

The shape of x is (n, m) where n is the number of points to evaluate (at most GTOpt/BatchSize) and m is the input dimension ( size_x() + size_s() ). For each row, the first size_x() values are classic variables (see add_variable()), while the following size_s() values are stochastic variables (see set_stochastic()).

The returned array may contain NaN and None values, which have the following meaning:

  • NaN value of some constraint indicates that evaluation of an objective failed.
  • None value indicates that evaluation of an objective was skipped.

Note that skipped and failed evaluations may stop optimization prematurely.

evaluate(queryx, querymask)

Default implementation of the evaluate() method inherited from the base class ProblemGeneric. Should not be reimplemented; use define_objectives() and define_constraints().

11.6.3. ProblemCSP — constraint satisfaction problem

class da.p7core.gtdoe.ProblemCSP(*iargs, **ikwargs)

Simplified problem class for constraint satisfaction problems (CSP). Inherits from ProblemConstrained.

This class does not support the usage of analytical constraint gradients, and should not add any problem objectives.

To define a constraint satisfaction problem, create your own problem class, inheriting from ProblemCSP. This class must implement the following methods:

Note that this class should not implement evaluate().

define_objectives(x)

Empty definition of objectives. Does nothing. Should not be reimplemented (CSP must not define any objectives).

11.6.4. ProblemGeneric — base problem

class da.p7core.gtdoe.ProblemGeneric(*iargs, **ikwargs)

Base optimization problem class.

To define an optimization problem, create your own problem class, inheriting from ProblemGeneric or its descendants.

All problem properties are defined in the prepare_problem() method of the derived class. Inside prepare_problem(), use these inherited methods:

In all classes derived directly from ProblemGeneric, you also have to implement the evaluate() method that calculates values of objectives and constraints. This method is the only one that supports all optimizer features, but due to its complexity it may be difficult to use (see code sample). Because of that, GTOpt module includes a number of simplified problem classes:

A problem object can be converted to a string to obtain a short human-readable problem description, for example:

>>> import da.p7core.gtopt
>>> class MyProblem(da.p7core.gtopt.ProblemGeneric):
>>>   def prepare_problem(self):
>>>     self.add_variable((0, 1), 0.5)
>>>     self.add_variable((0, 2), 0.5)
>>>     self.add_objective()
>>>   def evaluate(self, xquery, maskquery):
>>>     return [[x[0]**2] for x in xquery], [[1] for x in xquery]
>>> problem = MyProblem()
>>> print problem
da.p7core GTOpt problem:
    Type: MyProblem
    Number of variables: 2
    Number of objectives: 1
    Number of constraints: 0
    Analytical objectives gradients: False
    Analytical constraints gradients: False
    Variables bounds:
    x1: 0.000000 1.000000
    x2: 0.000000 2.000000
    Initial guess:
    [0.500000,0.500000]
>>> result = da.p7core.gtopt.Solver().solve(problem)
>>> print result.optimal.x
[[7.116129095440896e-07, 0.5050600736179194]]
>>> print result.optimal.f
[[5.063929330298047e-13]]
add_constraint(bounds, name=None, hints=None)

Add a new problem constraint.

Parameters:
  • bounds (array-like) – low and high bounds
  • name (str) – the name of the constraint
  • hints (dict) – optimization hints

Initializes a new constraint in the problem.

The bounds argument is a tuple of two values: (lower, upper). One of the bounds can be None, meaning that there is no respective bound for the constraint.

The name argument is optional; if you do not provide a name, it is generated automatically. Auto names are "c1", "c2", "c3", and so on, in the order of adding constraints to a problem.

Changed in version 3.0 Release Candidate 1: names of constraints are no longer required to be valid Python identifiers.

The hints argument sets constraint-specific options that may direct optimizer to use alternative internal algorithms to increase performance (see Hint Reference). It is a dictionary {hint name: value}, for example {"@GTOpt/LinearityType": "Quadratic"}.

If you implement evaluate(), constraints in querymask are indexed after objectives and in the order of adding constraints to a problem. This indexing order is also kept in Result attributes.

Changed in version 3.0 Release Candidate 1: name indexing for constraints is no longer supported.

This method should be called from prepare_problem().

add_objective(name=None, hints=None)

Add a new problem objective.

Parameters:
  • name (str) – the name of the objective
  • hints (dict) – optimization hints

Initializes a new objective in the problem.

The name argument is optional; if you do not provide a name, it is generated automatically. Auto names are "f1", "f2", "f3", and so on, in the order of adding objectives to a problem.

Changed in version 3.0 Release Candidate 1: names of objectives are no longer required to be valid Python identifiers.

The hints argument sets objective-specific options that may direct optimizer to use alternative internal algorithms to increase performance (see Hint Reference). It is a dictionary {hint name: value}, for example {"@GTOpt/LinearityType": "Quadratic"}.

If you implement evaluate(), objectives in querymask are indexed in the order of adding them to a problem. This indexing order is also kept in Result attributes.

Changed in version 3.0 Release Candidate 1: name indexing for objectives is no longer supported.

This method should be called from prepare_problem().

add_variable(bounds, initial_guess=None, name=None, hints=None)

Add a new problem variable.

Parameters:
  • bounds (tuple(float)) – bounds or levels
  • initial_guess (float) – initial guess
  • name (str) – the name of the variable
  • hints (dict) – additional hints

Changed in version 6.14: added discrete and categorical variables support when using the class with GTDoE only.

Changed in version 6.15: added discrete variables support to GTOpt.

Changed in version 6.29: added stepped variables support.

Changed in version 6.33: added categorical variables support to GTOpt.

Declares a new variable in the problem.

For continuous and integer variables, bounds is a tuple of two float values: (lower, upper). The initial_guess, if specified, must be within bounds.

For discrete, stepped, and categorical variables, bounds is a tuple specifying allowed values (levels) of the variable. The sorting order of those values does not matter, the list of levels may be unsorted. All values must be float — for example, if your problem includes a categorical variable with string values, you should denote its categories with arbitrary float numbers. The initial_guess, if specified, must be one of the level values specified by bounds.

For continuous variables only, None is valid as the lower or upper bound, meaning that the variable is unbound in the respective direction. Your problem may declare continuous variables that are unbound in one or both directions, given that the problem satisfies the following:

  • All responses are computationally cheap, that is, you do not set the @GTOpt/EvaluationCostType hint to "Expensive" for any response.
  • There are no integer or discrete variables in the problem.
  • There are no stochastic variables in the problem.

In other kinds of problems, each variable requires numeric bounds or levels, and using unbound variables leads to an InvalidProblemError exception when solving.

The name argument is optional; if you do not provide a name, it is generated automatically. Auto names are "x1", "x2", "x3", and so on, in the order of adding variables to a problem.

Changed in version 3.0 Release Candidate 1: names of variables are no longer required to be valid Python identifiers.

The hints parameter can be used to specify type of the variable — see Hint Reference for details. It is a dictionary {hint name: value}, for example {"@GT/VariableType": "Integer"}.

Variables are always indexed in the order of adding them to a problem. This indexing is kept in the queryx parameter to ProblemGeneric.evaluate(), in the x parameter to problem definition methods of the simplified problem classes (such as ProblemConstrained.define_objectives(), ProblemConstrained.define_constraints() and the like), and in Result attributes.

Changed in version 3.0 Release Candidate 1: name indexing for variables (as in x["name"] or x.name) is no longer supported.

This method should be called from prepare_problem().

clear_history()

Clear history.

New in version 4.0.

Removes all evaluations currently stored in the memory history, but does not disable it. For disabling, see disable_history() or set_history().

constraints_bounds()

Get constraints bounds.

Returns:constraints bounds as tuple of two iterable objects
Return type:tuple
constraints_gradient()

Get constraint gradient info.

Returns:constraint gradient info
Return type:tuple(bool, bool, tuple, tuple)

This method returns a tuple of four elements (enabled, sparse, non-zero rows, non-zero columns).

First boolean element (enabled) is True if analytical constraint gradients are enabled in the problem. If enabled is False, all other elements should be ignored as meaningless.

Second boolean (sparse) has a meaning only if enabled is True. Value of sparse is True if the gradients are sparse. If sparse is False (gradients are dense), all other elements in the returned tuple should be ignored as meaningless.

Tuple elements provide the lists of non-zero rows and columns for sparse gradients. Naturally, these lists only have a meaning when both enabled and sparse are True; in all other cases the tuples are empty.

constraints_names()

Get names of constraints.

Returns:name list
Return type:list[str]
designs

Compacted history of problem evaluations.

Type:array-like

New in version 5.1.

Similar to history, but ensures that each evaluated point appears only once by combining all evaluation results available for this point. Can still contain None values (meaning that some function was never evaluated) and NaN (meaning that a function was evaluated but calculation failed). For more details on the array structure and the meaning of None and NaN values see history.

disable_constraints_gradient()

Disable using analytical constraint gradients.

New in version 2.0 Release Candidate 1.

Disables analytical gradients for constraints and switches back to using numerical differentiation (see enable_constraints_gradient()).

This method should be called from prepare_problem(). It is intended to cancel analytical constraint gradients in a new problem class inherited from a problem with enabled analytical gradients.

disable_history()

Disable saving objective and constraint evaluations completely.

New in version 2.0 Release Candidate 1.

Disables both memory and file history. Objective and constraint evaluation results will no longer be stored in history or the configured history file (see file in set_history()).

Disabling does not clear current contents of history (see clear_history()).

disable_objectives_gradient()

Disable using analytical objective gradients.

New in version 2.0 Release Candidate 1.

Disables analytical gradients for objectives and switches back to using numerical differentiation (see enable_objectives_gradient()).

This method should be called from prepare_problem(). It is intended to cancel analytical objective gradients in a new problem class inherited from a problem with enabled analytical gradients.

elements_hint(indexElement, nameHint)

Get current hints for problem element.

Parameters:
  • indexElement (int) – index of element in order: variables, objectives, constraints
  • nameHint (str) – name of hint
Returns:

hint value

Return type:

str or None

This method returns current value of hint nameHint for an element of the problem (variable, objective function or constraint) with the given indexElement index, or None if the hint with given name is not available for the element.

For the list of available hints, see Hint Reference.

enable_constraints_gradient(sparse=None)

Enable using analytical constraint gradients.

Parameters:sparse (array-like) – non-zero rows and columns

By default, the problem automatically uses numerical differentiation to provide constraint gradient values to Solver. Alternatively, you may provide gradients in evaluate() — see its description for more details. Before that, the problem has to be switched to analytical constraint gradients mode by calling enable_constraints_gradient() once upon initialization. This method should be called from prepare_problem(). Note that not all problem classes support analytical gradients.

Gradients may be set sparse using the sparse argument. This is a tuple of two lists of the same length where the first list contains the indices of non-zero rows in the gradient, and the second list contains the indices of non-zero columns. None (default) means that constraint gradient is dense.

For example, consider a problem with two variables and two constraints:

\[\begin{split}\begin{array}{cc} (x_1 - 1)^2 &\le 0\\ x_2 &\le 0 \end{array}\end{split}\]

The Jacobian matrix for this problem is

\[\begin{split}\left(\begin{array}{cc} 2x_1 - 2 & 0\\ 0 & 1 \end{array}\right)\end{split}\]

Non-zero elements in the Jacobian are (0, 0) and (1, 1), so the sparse argument should be ([0, 1], [0, 1]). The problem can be defined as follows:

from da.p7core import gtopt

class MyProblem(gtopt.ProblemGeneric):

  def prepare_problem(self):
    self.add_variable((None,None))
    self.add_variable((None,None))
    self.add_constraint((None, 0))
    self.add_constraint((None, 0))
    self.enable_constraints_gradient(([0, 1], [0, 1]))

  def evaluate(self, x_batch, mask_batch):
    c_batch = []
    # mask_batch is ignored for brevity
    for x in x_batch:
      c_batch.append([(x[0] - 1)**2, x[1], 2*(x[0] - 1), 1])
    # since all responses were calculated, extend the mask to [1, 1, 1, 1]
    mask_batch = [1, 1, 1, 1] * len(mask_batch)
    return c_batch, mask_batch

There are four elements in the list of evaluations in c_batch.append, while in the case of dense gradients it would be c_batch.append([(x[0] - 1)**2, x[1], 2*(x[0] - 1), 0, 0, 1]).

enable_history(inmemory=True, file_arg=None, header=True)

Enable saving objective and constraint evaluations.

Parameters:
  • file_arg (str or file) – write history to file
  • header (bool) – add a header to the history file
  • inmemory (bool) – store history in memory (on by default)

New in version 1.11.0.

Deprecated since version 4.0: use set_history() instead.

Since version 4.0, replaced by a more convenient set_history() method. See also clear_history() and disable_history().

enable_objectives_gradient(sparse=None)

Enable using analytical objective gradients.

Parameters:sparse (array-like) – non-zero rows and columns

By default, the problem automatically uses numerical differentiation to provide objective gradient values to Solver. Alternatively, you may provide gradients in evaluate() — see its description for more details. Before that, the problem has to be switched to analytical objective gradients mode by calling enable_objectives_gradient() once upon initialization.

Gradients may be set sparse using the sparse argument. This is a tuple of two integer arrays of same length where first array contains indices of non-zero rows in objective gradient, and second array contains indices of non-zero columns. None (default) means that objective gradient is dense.

This method should be called from prepare_problem(). Note that not all problem classes support analytical gradients.

For an example of using sparse gradients, see enable_constraints_gradient().

evaluate(queryx, querymask)

Calculates values of objective functions and constraints. This method must be implemented by user.

Parameters:
  • queryx (ndarray, 2D float) – points to evaluate
  • querymask (ndarray, 2D bool) – evaluation requests mask
Returns:

evaluation results (array-like, 2D) and masks (array-like, 2D, Boolean)

Return type:

tuple(array-like, array-like)

Changed in version 3.0 Release Candidate 1: the queryx argument is ndarray.

Changed in version 6.19: it is now possible to skip some evaluations requested by Solver.

Changed in version 6.24: skipped evaluations may be indicated with None response values, regardless of the response flag in the output mask.

When Solver requests values of problem objectives and constraints, it sends the queryx sample to evaluate(). The shape of this array is (n, m) where n is the number of points to evaluate (at most GTOpt/BatchSize) and m is the input dimension (size_x() + size_s()). For each row, the first size_x() values are classic variables (see add_variable()), while the following size_s() values are stochastic variables (see set_stochastic()).

evaluate() has to process queryx and return values of objectives and constraints (and gradients, if they are enabled in the problem) according to the querymask.

The querymask contains a mask of responses requested by Solver for each point. It is a 2D ndarray (bool) of shape (n, l) where n is the number of points in queryx (a mask for each point; note that each point may have a different mask), and l is the mask length equal to size_full().

Mask order is [objectives, constraints, objective gradients, constraint gradients]: for example, if three variables, one objective and two constraints were defined in the problem, and all gradients are dense, mask length is 12 (1 + 2 + 1 \(\cdot\) 3 + 2 \(\cdot\) 3). Masks are used to perform evaluations selectively — that is, if GTOpt requests only one gradient value, there is no need to evaluate all other gradients, as well as objectives and constraints. To take advantage of this feature, the evaluation method should be implemented in such a way that supports selective evaluation by mask.

An implementation of this method must return both evaluation results and evaluation masks as 2D arrays. Indexing order for both is the same as in the input querymask: [objectives, constraints, objective gradients, constraint gradients], and array shape is determined by the length of the input batch, the number of objectives and constraints, and the number of gradient values (see size_full() for more details).

Returned evaluation mask informs Solver what responses (objectives, constraints, gradients) were evaluated. For mask flags, use either bool or 0 and 1.

  • A response flagged True in the input mask should be evaluated. However, Solver can handle failed evaluations to some extent, so there are several possibilities:
    • Evaluate the response, add its value to results, and flag it True in the output mask. If response evaluation fails, set its value to NaN and flag it True.
    • Skip evaluation, flag the response False, and put any value into results (Solver discards this value; in designs and history, the value is replaced with None).
    • Skip evaluation and set the response value to None. In this case, the response flag in the returned mask is disregarded (you may set it True for simplicity).
  • A response flagged False in the input mask is optional. You may choose to:
    • Skip evaluation, flag it False, and put any value into results (Solver discards it; in designs and history, the value will be None).
    • Skip evaluation and set the response value to None. In this case, the response flag in the returned mask is disregarded (you may set it True for simplicity).
    • Evaluate the response, add it to results, and flag it True. Despite Solver did not request this value, it may still be useful in optimization. If response evaluation fails, set its value to NaN and flag it True.

Note that skipped (None or flagged False) and failed (NaN but flagged True) evaluations may stop optimization prematurely.

General advice is to evaluate responses selectively, separating those requested frequently from the ones requested rarely, for example:

  • Cheap and expensive functions (see Hint Reference).
  • Response values and gradient values.
  • Generic, linear and quadratic response functions (see Hint Reference).
  • In some cases you may prefer to evaluate objectives and constraints separately.

Other separations mostly make sense only if they do not complicate the code.

See the example_gtopt_generic.py code sample for an example implementation of this method.

history

Exact history of problem evaluations stored in memory.

Type:array-like

New in version 1.11.0.

Stores values of variables and evaluation results. Each element of the top-level list is one evaluated point. Nested list structure is [variables, objectives, constraints, objective gradients, constraint gradients]. Gradients are added only if analytical gradients are enabled, see enable_objectives_gradient() and enable_constraints_gradient()).

Changed in version 5.1: missing evaluation results are stored as None values, not NaN (float).

Often Solver requests only a partial evaluation of the problem (see the querymask argument to evaluate()). For such points, non-evaluated functions (objectives, constraints, gradients) are noted with None values to distinguish them from a float NaN value. NaN in history specifically indicates that a function was evaluated but calculation failed (for example, the point to evaluate for was out of the function’s domain).

The history stores all inputs and outputs exactly as they were evaluated, which may be unconvenient in some cases. For example, Solver can request objective and constraint values for the same point on different iterations, and in this case the point will appear in history two or more times. This is useful for tracing the optimization process, but when you want to re-use evaluation data, a more convenient representation can be found in designs.

Note

Memory history is enabled by default, which increases memory consumption. If you implement your own way to save the history of evaluations, always use disable_history(). If there are a lot of evaluations in your problem, consider reconfiguring history to only write it to a file (see set_history()).

initial_guess()

Get initial guess for all variables.

Returns:initial guess iterable (if present)
Return type:list[float] or None
objectives_gradient()

Get objective gradient info.

Returns:objective gradient info
Return type:tuple(bool, bool, tuple, tuple)

This method returns a tuple of four elements (enabled, sparse, non-zero rows, non-zero columns).

First boolean element (enabled) is True if analytical objective gradients are enabled in the problem. If enabled is False, all other elements should be ignored as meaningless.

Second boolean (sparse) has a meaning only if enabled is True. Value of sparse is True if the gradients are sparse. If sparse is False (gradients are dense), all other elements in the returned tuple should be ignored as meaningless.

Tuple elements provide the lists of non-zero rows and columns for sparse gradients. Naturally, these lists only have a meaning when both enabled and sparse are True; in all other cases the tuples are empty.

For an example of using sparse gradients, see enable_constraints_gradient().

objectives_names()

Get names of objectives.

Returns:name list
Return type:list[str]
prepare_problem()

The problem initialization method, has to be implemented by user. Use the following methods for problem definition:

See the usage in example_gtopt_generic.py.

set_constraint_bounds(index, bounds)

Set bounds for a constraint.

Parameters:
  • index (int) – index of the constraint in the list of problem constraints
  • bounds (array-like) – lower and upper bounds
set_constraint_hints(index, hints)

Set hints for a constraint.

Parameters:
  • index (int) – index of the constraint in the list of problem constraints
  • hints (dict) – hint settings

Resets all hints previously set for the constraint, replacing all existing settings with the new settings from hints. To update hint settings without resetting them, use update_constraint_hints().

set_history(**kwargs)

Configure saving objective and constraint evaluations.

Parameters:
  • add_header (bool) – add a header to the history file
  • file (str, file or None) – write history to file
  • memory (bool) – store history in memory

New in version 4.0.

Return values of evaluate() can be saved to memory or to a file on disk. History saving modes are independent: both can be enabled simultaneously so history is saved in memory while also writing to a file. Default configuration is to save history to memory only.

Note

Default configuration increases memory consumption. If you implement your own way to save the history of evaluations, always use disable_history(). If there are a lot of evaluations in your problem, consider reconfiguring history to only write it to a file.

If memory is True, evaluations are saved to history. If False, disables updating history but does not clear it. Re-enabling in case history is not empty appends to existing history; if it is not wanted, call clear_history() first.

The file argument can be a path string or a file-like object (enables writing history to file). Note that the file is opened in append mode. To disable the file history, set file to None. Values in a history file are comma-separated.

If add_header is True, the first line appended to file is a header containing the names of problem variables, objectives and constraints set by add_variable(), add_objective(), and add_constraint(). The header is enabled by default, and can be disabled by setting add_header to False.

set_objective_hints(index, hints)

Set hints for an objective.

Parameters:
  • index (int) – index of the objective in the list of problem objectives
  • hints (dict) – hint settings

Resets all hints previously set for the objective, replacing all existing settings with the new settings from hints. To update hint settings without resetting them, use update_objective_hints().

set_stochastic(distribution, generator=None, name=None, seed=0)

Set stochastic distribution for a robust optimization problem.

Parameters:distribution – a stochastic distribution object

Changed in version 6.15: the generator, name, and seed arguments are no longer used.

This method is essential for robust optimization problems. It adds stochastic variables \(\xi_i\) (see section Robust Problem Formulation) and sets the stochastic distribution used in generating random values for these variables.

The distribution is implemented by user, see section Using Stochastic Variables for details. The number of stochastic variables added is equal to the distribution dimension (see getDimension()). Stochastic variables are always added and indexed after normal variables. For example, in prepare_problem() you can do something like:

bounds = (0, 1)
add_variable(bounds)  # indexed 0
add_variable(bounds)  # indexed 1
set_stochastic(my_distr)  # assuming the distribution is 2-dimensional,
                          # adds 2 variables indexed (!) 3 and 4
add_variable(bounds)  # indexed 2 despite here it is called after set_stochastic()

Then, when you process queryx in evaluate(), the variables are indexed as noted above. The fact that you call set_stochastic() before the final add_variable() call does not matter.

This method should be called from prepare_problem(). See Using Stochastic Variables for a guide.

set_variable_bounds(index, bounds)

Set bounds for a variable.

Parameters:
  • index (int) – index of the variable in the list of problem variables
  • bounds (array-like) – bounds or levels for the variable

Changed in version 6.14: added the support for discrete and categorical variables.

See add_variable() for details on how to use bounds for discrete and categorical variables.

set_variable_hints(index, hints)

Set hints for a variable.

Parameters:
  • index (int) – index of the variable in the list of problem variables
  • hints (dict) – hint settings

Resets all hints previously set for the variable, replacing all existing settings with the new settings from hints. To update hint settings without resetting them, use update_variable_hints().

set_variable_initial_guess(index, initial_guess)

Set initial guess to a given problem variable.

Parameters:
  • index (int) – variable index in the list of problem variables.
  • initial_guess (None, float) – initial guess for variable
size_c()

Get number of constraints in problem.

Returns:number of constraints
Return type:int
size_f()

Get number of objectives in problem.

Returns:number of objectives
Return type:int
size_full()

Get full size of evaluated data (including gradients)

Returns:total number of objectives, constraints, gradients, and noise components
Return type:int

If gradients are not enabled (see enable_objectives_gradient(), enable_constraints_gradient()), the full size is equal to size_f() + size_c().

If all gradients are enabled and all gradients are dense, full size is (size_f() + size_c()) × (1 + size_x()).

In the case of using sparse gradients, full size depends on the number of non-zero elements in the gradient (see the sparse argument to enable_objectives_gradient() and enable_constraints_gradient()). You can also get the number of gradient values from objectives_gradient() and constraints_gradient(), for example:

enabled, sparse, rows, columns = problem.objectives_gradient()
if sparse:
  size_obj_grad = len(rows)  # the number of objective gradient values
                             # len(rows) and len(columns) are equal
size_s()

Get number of stochastic variables in problem.

Returns:number of stochastic variables
Return type:int

For adding stochastic variables, see set_stochastic().

size_x()

Get number of variables in problem.

Returns:number of variables
Return type:int
variables_bounds(index=None)

Get bounds and levels of variables.

Parameters:index (int) – index of a categorical or discrete variable
Returns:bounds of variables or levels for a variable specified by index
Return type:numpy.ndarray

Changed in version 6.14: added the index parameter

If index is None, returns a tuple of two lists containing values of the lower and upper bounds for all problem variables. For continuous and integer variables, these values are the same as those specified by the bounds parameter to add_variable(). For discrete and categorical variables, the bounds are the minimum and maximum values from the set of their levels specified by the bounds parameter. Note that bounds are generally nonsensical for a categorical variable, since categorical values cannot be compared by magnitude.

If index is int, returns a tuple of two values (lower and upper bound) if the variable under this index is continuous or integer, and a tuple containing all level values if this variable is discrete or categorical.

variables_names()

Get names of variables.

Returns:name list
Return type:list[str]
open_history_file(*args, **kwds)
size_nc()

Get number of blackboxed constraint noise in problem.

Returns:dimensionality of the constraint noise
Return type:int

New in version 6.14.

size_nf()

Get number of blackboxed objective noise in problem.

Returns:dimensionality of the objective noise
Return type:int

New in version 6.14.

update_constraint_hints(index, hints)

Update hints for a constraint.

Parameters:
  • index (int) – index of the constraint in the list of problem constraints
  • hints (dict) – hint settings

New in version 6.35.

Updates hint settings for the constraint: if hints sets some hint, the new setting replaces the existing one, but hints not found in hints keep existing settings. To reset all existing hint settings, use set_constraint_hints().

update_objective_hints(index, hints)

Update hints for an objective.

Parameters:
  • index (int) – index of the objective in the list of problem objectives
  • hints (dict) – hint settings

New in version 6.35.

Updates hint settings for the objective: if hints sets some hint, the new setting replaces the existing one, but hints not found in hints keep existing settings. To reset all existing hint settings, use set_objective_hints().

update_variable_hints(index, hints)

Update hints for a variable.

Parameters:
  • index (int) – index of the variable in the list of problem variables
  • hints (dict) – hint settings

New in version 6.35.

Updates hint settings for the variable: if hints sets some hint, the new setting replaces the existing one, but hints not found in hints keep existing settings. To reset all existing hint settings, use set_variable_hints().

variable_indexes_by_type(var_type)

Return list of indexes of variables of the given type.

Parameters:var_type (str) – type name
Returns:indexes of variables which have the var_type type
Return type:list

New in version 6.14.

Types are: "continuous", "integer", "stepped", "discrete", "categorical". Type names are case-insensitive.

11.6.5. ProblemUnconstrained — unconstrained problem

class da.p7core.gtdoe.ProblemUnconstrained(*iargs, **ikwargs)

Simplified problem class for unconstrained problems. Inherits from ProblemConstrained.

This class does not support the usage of analytical objective gradients, and should not add any problem constraints.

To define an unconstrained optimization problem, create your own problem class, inheriting from ProblemUnconstrained. This class must implement the following methods:

Note that this class should not implement evaluate().

define_constraints(x)

Empty definition of constraints for an unconstrained problem. Does nothing. Should not be reimplemented (an unconstrained problem must not define any constraints).

11.6.6. Result — DoE study result

class da.p7core.gtdoe.Result(info, points, pointsY, status, model=None)

Generator result.

An object of this class is only returned by generate(), and the class should never be instantiated by user.

Different attributes are available depending on the mode of generate() call that returned the result:

Also provides DoE generation info and the generator finish status.

info

Result info.

Type:dict
model

Internal model trained by the Adaptive Design of Experiments technique.

Type:gtapprox.Model

This attribute is None in results generated by any GTDoE technique other than the Adaptive Design of Experiments. May also be None in an Adaptive Design of Experiments result, if the internal model never reached the minimum accuracy specified by the GTDoE/Adaptive/InitialModelQualityLevel option.

points

All generated points.

Type:ndarray, 2D
Raise:GTException if the result was returned from sequential generate()

Changed in version 3.0 Release Candidate 1: attribute type is ndarray.

This attribute is not available from a result of a sequential space-filling generator.

responses

All blackbox responses for generated points.

Type:ndarray, 2D
Raise:GTException if the result was returned from sequential generate()

Changed in version 3.0 Release Candidate 1: attribute type is ndarray.

If the result was obtained from a generator working in adaptive mode, contains all responses that the generator got from calls to blackbox used in the adaptive DoE process (that is, the blackbox evaluations for generated points and the points of the initial sample). This attribute is empty in the case of a batch space-filling generator, and not available from a result of a sequential space-filling generator.

status

Finish status.

Type:Status

Changed in version 3.0 Beta 2: attribute type is Status.

For details, see section Status.

take(count)

Get generated points.

Parameters:count (int) – the number of points
Returns:sample
Return type:ndarray, 2D

Changed in version 3.0 Release Candidate 1: returns ndarray.

Returns an array of count points. If the result was obtained from a batch generate() and contains less points that count, take() returns all available points.

11.6.7. ValidationResult — validation data

class da.p7core.gtdoe.ValidationResult

Validation result and details. An object of this class is only returned by validate() and should never be instantiated by user.

status

Validation status.

Type:bool

General result of validation: pass (True) or fail (False).

For validation details or failure reasons, see details.

details

Validation messages.

Type:list of DiagnosticRecord objects

Contains validation errors, warnings, and other messages as DiagnosticRecord objects, which provide message text, severity level, string and integer representations, and equality comparison.

valres = gtdoe.Generator().validate(problem)
for rec in valres.details:
  print('{level}: {msg}'.format(level=rec.severity, msg=rec.message))

11.7. da.p7core.gtdoe.measures

Sample metrics.

Functions

da.p7core.gtdoe.measures.discrepancy(bounds, …) Evaluate the discrepancy metric.
da.p7core.gtdoe.measures.minimax_distance(…) Evaluate the minimax interpoint distance.
da.p7core.gtdoe.measures.phi_p(bounds, points) Evaluate the \(\phi_p\) metric.
da.p7core.gtdoe.measures.potential(bounds, …) Evaluate the potential metric.
da.p7core.gtdoe.measures.discrepancy(bounds, points)

Evaluate the discrepancy metric.

Parameters:
  • bounds (tuple(list[float], list[float])) – design space bounds (lower, upper)
  • points (array-like) – point set
Returns:

normalized discrepancy value

Return type:

float

Raise:

ValueError if the points array contains a point out of bounds

New in version 6.18.

Evaluates the discrepancy metric (see section Uniformity).

The design space (both point coordinates and bounds) is normalized before calculation: the function applies a linear transform so that all points are contained into a unit hypercube.

Note that the bounds should be equal to the bounds of the DoE generator that was used to obtain the points set (see bounds in generate()). Setting different bounds makes the normalization incorrect; this issue can not be resolved automatically, so this function only checks if all points are within bounds.

Note

Return value is the discrepancy metric in the normalized space, not in the original design space.

da.p7core.gtdoe.measures.minimax_distance(bounds, points, normalize=True)

Evaluate the minimax interpoint distance.

Parameters:
  • bounds (tuple(list[float], list[float])) – design space bounds (lower, upper)
  • points (array-like, 2D) – sample
  • normalize (bool) – indicates coordinate transform into a unit hypercube
Returns:

minimax distance in the original or normalized space

Return type:

float

Raise:

ValueError if points contain a point out of bounds

Evaluates the minimax interpoint distance \(d = \max _i \min _j d_{ij}\) (the maximum distance to the nearest neighbor in the array), where \(d_{ij}\) is the Euclidean distance between two points.

If normalize is True (default), the design space (point coordinates and bounds) is normalized before calculation:

  • Normalization applies a linear coordinate transform, so that all points are contained into a unit hypercube.
  • Return value becomes the minimax distance in this normalized space (in the unit hypercube), not in the original design space (the bounding box specified by bounds).

Note that the bounds should be equal to the bounds of the DoE generator that was used to obtain the points set (see bounds in generate()). Setting different bounds makes the normalization incorrect; this issue can not be resolved automatically, so this function only checks that all points are within bounds.

da.p7core.gtdoe.measures.phi_p(bounds, points, p=50, normalize=True)

Evaluate the \(\phi_p\) metric.

Parameters:
  • bounds (tuple(list[float], list[float])) – design space bounds (lower, upper)
  • points (array-like, 2D) – sample
  • p (int, long, or float) – metric parameter
  • normalize (bool) – indicates coordinate transform into a unit hypercube
Returns:

\(\phi_p\) value in the original or normalized space

Return type:

float

Raise:

ValueError if the points array contains a point out of bounds

Evaluates the \(\phi_p = \sqrt[p]{\sum_{i=1}^N \sum_{j=1}^{i-1} \frac{1}{d_{ij}^p}}\) metric, where \(d_{ij}\) is the Euclidean distance between two points.

If normalize is True (default), the design space (point coordinates and bounds) is normalized before calculation:

  • Normalization applies a linear coordinate transform, so that all points are contained into a unit hypercube.
  • Return value becomes the metric value in this normalized space (in the unit hypercube), not in the original design space (the bounding box specified by bounds).

Note that the bounds should be equal to the bounds of the DoE generator that was used to obtain the points set (see bounds in generate()). Setting different bounds makes the normalization incorrect; this issue can not be resolved automatically, so this function only checks if all points are within bounds.

da.p7core.gtdoe.measures.potential(bounds, points, normalize=True)

Evaluate the potential metric.

Parameters:
  • bounds (tuple(list[float], list[float])) – design space bounds (lower, upper)
  • points (array-like) – point set
  • normalize (bool) – indicates coordinate transform into a unit hypercube
Returns:

potential value in the original or normalized space

Return type:

float

Raise:

ValueError if the points array contains a point out of bounds

Evaluates the \(U = \sum_{i=1}^N \sum_{j=1}^{i-1} \frac{1}{d_{ij}^2}\) metric, where \(d_{ij}\) is the Euclidean distance between two points.

If normalize is True (default), the design space (point coordinates and bounds) is normalized before calculation:

  • Normalization applies a linear coordinate transform, so that all points are contained into a unit hypercube.
  • Return value becomes the metric value in this normalized space (in the unit hypercube), not in the original design space (the bounding box specified by bounds).

Note that the bounds should be equal to the bounds of the DoE generator that was used to obtain the points set (see bounds in generate()). Setting different bounds makes the normalization incorrect; this issue can not be resolved automatically, so this function only checks if all points are within bounds.