11.1. General Notes¶
This page discusses some general concepts that are needed to work with pSeven Core.
11.1.1. Blackbox¶
Some of the pSeven Core tools feature techniques which obtain data from a blackbox —
an existing model (gtapprox.Model
, gtdf.Model
) or a generic function:
- Blackbox-based data fusion (see
da.p7core.gtdf.Builder.build_BB()
andda.p7core.gtdf.Model
). - Blackbox-based adaptive Design of Experiments (see
da.p7core.gtdoe.Generator.generate()
). - Adaptive design (see
da.p7core.gtdoe.Generator.build_doe()
). - Blackbox-based dimension reduction, the Feature Extraction method (see
da.p7core.gtdr.Builder.build()
). - Blackbox-based sensitivity analysis (see
da.p7core.gtsda.Analyzer.rank()
).
To use a function as a blackbox, you have to implement a blackbox class,
which works as a wrapper for external function calls.
Inherit your class from Blackbox
.
Note that GTOpt, due to its complexity, uses its own blackboxes —
see ProblemGeneric
and other GTOpt problem classes.
Adaptive design also supports ProblemGeneric
as a blackbox,
because the generic Blackbox
cannot define constraints.
11.1.2. Options Interface¶
pSeven Core provides a general options interface (the methods of the Options
class) for all tools, which may be used to setup a tool’s instance. For example, if configuring an instance of da.p7core.gtapprox.Builder
(GTApprox model builder):
>>> from da.p7core import gtapprox
>>> builder = gtapprox.Builder()
>>> print builder.options
GTApprox/Accelerator : 1
GTApprox/AccuracyEvaluation : 0
GTApprox/Componentwise : 0
... ...
>>> builder.options.info("GTApprox/Accelerator")
{'OptionDescription': {'Default': '1', 'Ranges': '[1, 5]', 'Type': 'unsigned', 'Name': 'GTApprox/Accelerator', 'Description': 'Five-position switch to control the trade-off between speed and accuracy. Possible values are from 1 (low speed, highest quality) to 5 (high speed, lower quality).'}}
>>> builder.options.get("GTApprox/Accelerator")
'1'
>>> builder.options.set("GTApprox/Accelerator", 5)
>>> builder.options.get("GTApprox/Accelerator")
'5'
Options may also be specified when calling the main processing method of the tool. Following the example above, it would be
da.p7core.gtapprox.Builder.build()
— see the options parameter in this method description.
Option values specified by the options parameter
override those set by da.p7core.Options.set()
. For example, here the effective value of
GTApprox/Accelerator is 3
, not 5
:
>>> builder.options.set("GTApprox/Accelerator", 5)
>>> new_options = {"GTApprox/Accelerator": 3}
>>> builder.build(x_sample, y_sample, options=new_options)
A few more general notes:
All option names are case-insensitive:
>>> builder.options.get("GTAPPROX/accelerator") '5'
Option values are not validated by
set()
— see the method description for details.Options imposing certain requirements (such as GTApprox/ExactFitRequired, GTApprox/LinearityRequired and others alike) only guarantee a specific behavior when the requirement is on. Setting the requirement off does not mean, in general, that the option will be interpreted as an opposite requirement. pSeven Core does not strictly specify the tool’s behavior in the latter case, and it may be changed without notice.
For example, setting GTApprox/ExactFitRequired to
True
guarantees an exact-fitting model. On the contrary, setting it toFalse
does not mean that GTApprox starts to prohibit the exact fit: it may still build an exact-fitting model though in general it is free not to do so.Integer and float option values are accepted as strings:
>>> builder.options.set("GTApprox/Accelerator", "5")
Boolean options, in addition to genuine Boolean values (
True
andFalse
), also accept the following synonyms:True
synonyms:"true"
,"yes"
,"y"
,"on"
(all strings are case-insensitive); any number that evaluates toTrue
following the common Python rules; any numeric literal for such number (a string).False
synonyms:"false"
,"no"
,"n"
,"off"
(all strings are case-insensitive); any number that evaluates toFalse
following the common Python rules; any numeric literal for such number (a string).
11.1.3. Loggers¶
A logger is an object that handles log messages from some process (for example, model training).
Custom loggers are classes implemented by user; by default, pSeven Core provides only a simple StreamLogger
implementation.
Every custom logger must implement CustomLogger.__call__()
:
-
CustomLogger.
__call__
(self, level, message)¶ Log message handler.
Parameters: - level (
int
) – log level - message (
str
) – log message
Returns: user-defined
Log levels are enumerated by
da.p7core.loggers.LogLevel
.- level (
Example:
class SimpleLogger(object):
"""Simple logger, just prints the received log message and log level."""
def __call__(self, level, message):
print '[%d]: %s' % (level, message)
11.1.4. Watchers¶
In pSeven Core a watcher is a callable object which
receives messages from the process it is connected to, such as
approximation model training (build()
, build_smart()
),
design of experiments generation (build_doe()
),
or optimization problem solving (solve()
).
You can use a watcher to
interrupt the watched process,
monitor its progress,
and get its intermediate results.
By default, pSeven Core provides only a placeholder DefaultWatcher
implementation.
To use the watcher features,
implement your custom watcher and process the report argument it receives from the watched process.
-
CustomWatcher.
__call__
(report=None)¶ Monitoring and interrupt callback.
Parameters: report – data, messages, and state information from the watched process Returns: interrupt flag Return type: bool
This method should return
True
when you want the watched process to continue, orFalse
when you want to interrupt.Changed in version 6.11: in optimization, the report argument is used to get an intermediate result.
Changed in version 2024.02: intermediate result is fully supported in DoE.
Note
Use report only in this method’s scope. Attributes of report are references to non-persistent C objects, so referencing them out of the scope will lead to errors or obtaining invalid data.
When a watcher is connected to a GTOpt
Solver
or GTDoEGenerator()
, the received report contains a result update flag and can be used to obtain an intermediate result. For usage, see the Intermediate result example.When interrupted by a watcher,
solve()
andbuild_doe()
return an intermediate result when possible. You can read the result’sstatus
to check whether the interrupt was received.GTOpt and GTDoE also call the watcher once they have the final result ready, right before they return the result. That final call ignores the watcher’s return value (never interrupts), since the process is actually finished at the moment. In this final call, if you get the intermediate result through the watcher, it is the same object that the main process (GTOpt, GTDoE) returns.
When a watcher is connected to a GTApprox
Builder
(seegtapprox.Builder.set_watcher()
), report is a dictionary that can contain any of the following (all keys are optional):- Training progress estimate (the
"progress"
key) — afloat
in range from 0 (just started) to 1 (completed). - Training details (the
"training phase"
key) — a dictionary with additional information about trained submodels. - If you run
build_smart()
, report also includes information on the current best model.
When interrupted by a watcher,
Builder
methods return an intermediate model when possible. Note that this model may miss certain features — for example, accuracy evaluation or internal validation may be not available even if they were required by your option settings. When it is not possible to return any model, these methods raise theUserTerminated
exception on interrupt.- Training progress estimate (the
11.1.5. Status¶
The statuses described in this section are used by pSeven Core Generic Tools both internally and in the public interface. In particular, gtdoe.Result
, and gtopt.Result
have a status attribute. This attribute is a Status
object — one of the statuses defined in the status
module.
Statuses can be tested for equiality, for example:
>>> result1.status == result2.status # True if both results have the same status
>>> from da.p7core import status
>>> result.status != status.NANINF_PROBLEM # True if result status is not "NaN/Inf problem"
A status has integer and string representations:
>>> s = status.INFEASIBLE_PROBLEM
>>> print "'%s' status ID is: %d" % (s, s)
'Infeasible problem' status ID is: 2
Integer representation is the same as Status.id
.
Note that due to Python’s peculiarities, a status compares to Boolean and numeric values:
>>> type(status.SUCCESS), status.SUCCESS.id
(da.p7core.status.Status, 0)
>>> status.SUCCESS == 0.0 # Do not use!
True
>>> status.SUCCESS == False # Do not use!
True
>>> status.SUCCESS == True # Do not use!
False
>>> result.status == status.SUCCESS # Correct
This should be avoided. Compare a status with a status only; if you absolutely need a numeric comparison, use id
.
11.1.6. License Usage¶
pSeven Core has a flexible licensing system where a license contains a pool of method-specific features. To users, this means that there is no need to get a full-featured license if you only use a few methods or solve problems of a certain type.
License features are requested when you create an object of a class that contains licensed methods. This object captures related features, if they are available, and holds them until destroyed. You can see which features were requested and captured using the general license information interface, for example:
>>> from da.p7core import gtopt # no license requests
>>> solver = gtopt.Solver() # requests features and captures them if available
>>> lic = solver.license.features() # get feature info
>>> lic
{'DA_MACROS_GTOPT_MO': True,
'DA_MACROS_GTOPT_RDO': False,
'DA_MACROS_GTOPT_SO': True}
>>> lic.keys() # all requested features
['DA_MACROS_GTOPT_SO', 'DA_MACROS_GTOPT_MO', 'DA_MACROS_GTOPT_RDO']
>>> [k for k in lic.keys() if lic[k]] # only available (captured) features
['DA_MACROS_GTOPT_SO', 'DA_MACROS_GTOPT_MO']
>>> del(solver) # releases features when the instance is garbage collected
Constructors do not test feature availability — for example, if the license is not available, you just get:
>>> solver = gtopt.Solver() # assume no license; creating instance is yet allowed
>>> solver.license.features() # shows no features found
{'DA_MACROS_GTOPT_MO': False,
'DA_MACROS_GTOPT_RDO': False,
'DA_MACROS_GTOPT_SO': False}
In the example above, feature availability would be tested only when you call solve()
:
>>> solver.solve(some_problem) # raises exception since there is no license
LicenseError: License feature DA_MACROS_GTOPT_SO not found!
Changed in version 3.4: features are counted on a per-process (instead of per-object) basis.
Since version 3.4, feature use count increases only once for every process that captures a feature. Most importantly, this means that if you create multiple models in the same script, related features are counted once, despite every model captures these features. For example:
>>> from da.p7core import gtapprox
>>> builder = gtapprox.Builder() # requests and captures the build feature
>>> m1 = builder.build(x1, f1) # captures available model features, increases count
>>> m2 = builder.build(x2, f2) # captures available model features, does not increase count
However, if the models are created by two different scripts running in parallel, each model increases the feature count.
Note
Simultaneously running a number of pSeven Core processes, which create many objects with licensed methods and request licenses from the same server, may sometimes cause license errors. See section License in Known Issues for details.
Tables below provide summary information on license features, related classes and methods.
GTApprox
Feature | Required by |
---|---|
gtapprox.Builder.license |
|
DA_MACROS_GTAPPROX_BUILD1 | build() and
build_smart() 2
to train any model |
gtapprox.Model.license |
|
DA_MACROS_GTAPPROX_AE3 | calc_ae() and
grad_ae() ;
GTApproxModelCalcAE() and GTApproxModelGradAE() ;
GTApproxModel.calcAE() and
GTApproxModel.calcGradAE() |
DA_MACROS_GTAPPROX_CALC1 | calc() and
grad() ;
GTApproxModelCalc() and GTApproxModelGrad() ;
GTApproxModel.calc() and
GTApproxModel.calcGrad() |
DA_MACROS_GTAPPROX_EXPORT_C | export_to() if format is
C99_PROGRAM ,
C99_HEADER , or
C99_SOURCE |
DA_MACROS_GTAPPROX_EXPORT_CS | export_to() if format is
CSHARP_SOURCE |
DA_MACROS_GTAPPROX_EXPORT_MEX | export_to() if format is
OCTAVE_MEX |
DA_MACROS_GTAPPROX_EXPORT_OCT | export_to() if format is
OCTAVE |
DA_MACROS_GTAPPROX_SMOOTH | smooth() ,
smooth_anisotropic() , and
smooth_errbased() |
1 DA_MACROS_GTAPPROX_BUILD and DA_MACROS_GTAPPROX_CALC are also required by GTSDA Analyzer
when you use a methods which train and evaluate a GTApprox model internally. These methods include:
rank()
if used in the sample-based mode with GTSDA/Ranker/Technique set to"Screening"
,rank()
if used in the sample-based mode with GTSDA/Ranker/Technique set to"Sobol"
and GTSDA/Ranker/Sobol/Method set to"CSTA"
or"FAST"
, andselect()
in all modes.
2 build_smart()
also requires the DA_MACROS_GTOPT_SO license feature
(see GTOpt license features).
3 DA_MACROS_GTAPPROX_AE is also required by GTSDA Analyzer
when you use any of the methods listed above and additionally set GTApprox/AccuracyEvaluation on,
using the approx_options argument to rank()
or select()
.
GTDF
Feature | Required by |
---|---|
gtdf.Builder.license |
|
DA_MACROS_GTDF_BUILD | build() to train any model |
gtdf.Model.license |
|
DA_MACROS_GTDF_AE | calc_ae() |
DA_MACROS_GTDF_CALC | calc() and
grad() |
GTDoE
Feature | Required by |
---|---|
gtdoe.Generator.license |
|
DA_MACROS_GTDOE_ADAPTIVE | generate()
and build_doe() 1
for all adaptive generation techniques |
DA_MACROS_GTDOE_GENERATE2 | generate()
and build_doe()
for all space-filling generation techniques |
1 build_doe()
also requires GTOpt license features
for the Adaptive Design technique (GTDoE/Technique set to "AdaptiveDesign"
).
This technique uses GTOpt internally in order to optimize the design point distribution,
based on the design response evaluations received from a blackbox.
Required GTOpt feature depends on the number of response functions (design outputs):
DA_MACROS_GTOPT_SO if there is a single response only,
and DA_MACROS_GTOPT_MO in the case of 2 or more responses.
2 DA_MACROS_GTDOE_GENERATE is also required by GTSDA Analyzer
when you use rank()
in the blackbox mode and specify a technique
which performs initial sampling of the blackbox.
These techniques include:
- the CSTA method for computing Sobol indices
(GTSDA/Ranker/Technique set to
"Sobol"
, GTSDA/Ranker/Sobol/Method set to"CSTA"
), and - Taguchi indices calculation
(GTSDA/Ranker/Technique set to
"Taguchi"
).
GTDR
Feature | Required by |
---|---|
gtdr.Builder.license |
|
DA_MACROS_GTDR_BUILD | build() to train any model (codec) |
gtdr.Model.license |
|
DA_MACROS_GTDR_COMPRESS | compress() and
gradCompress() |
DA_MACROS_GTDR_DECOMPRESS | decompress() and
gradDecompress() |
DA_MACROS_GTDR_EXPORT_C | compress_export_to() and
decompress_export_to() if format is
C99_PROGRAM ,
C99_HEADER , or
C99_SOURCE |
DA_MACROS_GTDR_EXPORT_MEX | compress_export_to() and
decompress_export_to() if format is
OCTAVE_MEX |
DA_MACROS_GTDR_EXPORT_OCT | compress_export_to() and
decompress_export_to() if format is
OCTAVE |
GTOpt
Feature | Required by |
---|---|
gtopt.Solver.license |
|
DA_MACROS_GTOPT_MO1 | solve() for multi-objective problems
(size_f() is 2 or more) |
DA_MACROS_GTOPT_RDO | solve() for robust optimization problems
(size_s() is not 0); |
DA_MACROS_GTOPT_SO1, 2 | solve() for single-objective problems
(size_f() is 1);
does not limit the number of problem variables and constraints |
1 GTOpt license features are also required by GTDoE Generator
for the Adaptive Design technique.
This technique uses GTOpt internally in order to optimize the design point distribution,
based on the design response evaluations received from a blackbox.
Required GTOpt feature depends on the number of response functions (design outputs):
DA_MACROS_GTOPT_SO if there is a single response only,
and DA_MACROS_GTOPT_MO in the case of 2 or more responses.
2 The DA_MACROS_GTOPT_SO feature is also required by GTApprox Builder
for build_smart()
(see Smart Training).
GTSDA
Feature | Required by |
---|---|
gtsda.Analyzer.license |
|
DA_MACROS_GTSDA_CHECK | check() |
DA_MACROS_GTSDA_RANK | rank() 1, 2 |
DA_MACROS_GTSDA_SELECT | select() 3 |
1 rank()
also requires the following GTApprox license features when using a technique that trains and evaluates a GTApprox model internally:
- DA_MACROS_GTAPPROX_BUILD and DA_MACROS_GTAPPROX_CALC in the sample-based mode with GTSDA/Ranker/Technique set to
"Screening"
, - DA_MACROS_GTAPPROX_BUILD and DA_MACROS_GTAPPROX_CALC in the sample-based mode with GTSDA/Ranker/Technique set to
"Sobol"
and GTSDA/Ranker/Sobol/Method set to"CSTA"
or"FAST"
, and - DA_MACROS_GTAPPROX_AE in the same cases as above, if you additionally set GTApprox/AccuracyEvaluation on, using the approx_options argument.
2 rank()
also requires the DA_MACROS_GTDOE_GENERATE feature
when you use it in the blackbox mode and specify a technique
which performs initial sampling of the blackbox.
These techniques include:
- the CSTA method for computing Sobol indices
(GTSDA/Ranker/Technique set to
"Sobol"
, GTSDA/Ranker/Sobol/Method set to"CSTA"
), and - Taguchi indices calculation
(GTSDA/Ranker/Technique set to
"Taguchi"
).
3 select()
also requires the following GTApprox license features:
- DA_MACROS_GTAPPROX_BUILD and DA_MACROS_GTAPPROX_CALC — in all modes, and
- DA_MACROS_GTAPPROX_AE if you additionally set GTApprox/AccuracyEvaluation on, using the approx_options argument.