amisc.component
A Component
is an amisc
wrapper around a single discipline model. It manages surrogate construction and
a hierarchy of modeling fidelities.
Multi-indices in the MISC approximation
A multi-index is a tuple of natural numbers, each specifying a level of fidelity. You will frequently see two
multi-indices: alpha
and beta
. The alpha
(or \(\alpha\)) indices specify physical model fidelity and get
passed to the model as an additional argument (e.g. things like discretization level, time step size, etc.).
The beta
(or \(\beta\)) indices specify surrogate refinement level, so typically an indication of the amount of
training data used or the complexity of the surrogate model. We divide \(\beta\) into data_fidelity
and
surrogate_fidelity
for specifying training data and surrogate model complexity, respectively.
Includes:
ModelKwargs
— a dataclass for storing model keyword argumentsStringKwargs
— a dataclass for storing model keyword arguments as a stringIndexSet
— a dataclass that maintains a list of multi-indicesMiscTree
— a dataclass that maintains MISC data in adict
tree, indexed byalpha
andbeta
Component
— a class that manages a single discipline model and its surrogate hierarchy
Component(model, *args, inputs=None, outputs=None, name=None, **kwargs)
Bases: BaseModel
, Serializable
A Component
wrapper around a single discipline model. It manages MISC surrogate construction and a hierarchy of
modeling fidelities.
A Component
can be constructed by specifying a model, input and output variables, and additional configurations
such as the maximum fidelity levels, the interpolator type, and the training data type. If model_fidelity
,
data_fidelity
, and surrogate_fidelity
are all left empty, then the Component
will not use a surrogate model,
instead calling the underlying model directly. The Component
can be serialized to a YAML file and deserialized
back into a Python object.
A simple Component
Each fidelity index in \(\alpha\) increases in refinement from \(0\) up to model_fidelity
. Each fidelity index
in \(\beta\) increases from \(0\) up to (data_fidelity, surrogate_fidelity)
. From the Component's
perspective,
the concatenation of \((\alpha, \beta)\) fully specifies a single fidelity "level". The Component
forms an approximation of the model by summing up over many of these concatenated sets of \((\alpha, \beta)\).
ATTRIBUTE | DESCRIPTION |
---|---|
name |
the name of the
TYPE:
|
model |
the model or function that is to be approximated, callable as |
inputs |
the input variables to the model
TYPE:
|
outputs |
the output variables from the model
TYPE:
|
model_kwargs |
extra keyword arguments to pass to the model
TYPE:
|
model_fidelity |
the maximum level of refinement for each fidelity index in \(\alpha\) for model fidelity
TYPE:
|
data_fidelity |
the maximum level of refinement for each fidelity index in \(\beta\) for training data
TYPE:
|
surrogate_fidelity |
the max level of refinement for each fidelity index in \(\beta\) for the surrogate
TYPE:
|
interpolator |
the interpolator to use as the underlying surrogate model
TYPE:
|
vectorized |
whether the model supports vectorized input/output (i.e. datasets with arbitrary shape
TYPE:
|
call_unpacked |
whether the model expects unpacked input arguments (i.e.
TYPE:
|
ret_unpacked |
whether the model returns unpacked output arguments (i.e.
TYPE:
|
active_set |
the current active set of multi-indices in the MISC approximation
TYPE:
|
candidate_set |
all neighboring multi-indices that are candidates for inclusion in
TYPE:
|
misc_states |
the interpolator states for each multi-index in the MISC approximation
TYPE:
|
misc_costs |
the computational cost associated with each multi-index in the MISC approximation
TYPE:
|
misc_coeff_train |
the combination technique coefficients for the active set multi-indices
TYPE:
|
misc_coeff_test |
the combination technique coefficients for the active and candidate set multi-indices
TYPE:
|
model_costs |
the average single fidelity model costs for each \(\alpha\)
TYPE:
|
training_data |
the training data storage structure for the surrogate model
TYPE:
|
serializers |
the custom serializers for the
TYPE:
|
_logger |
the logger for the
TYPE:
|
Source code in src/amisc/component.py
has_surrogate: bool
property
The component has no surrogate model if there are no fidelity indices.
max_alpha: MultiIndex
property
The maximum model fidelity multi-index (alias for model_fidelity
).
max_beta: MultiIndex
property
The maximum surrogate fidelity multi-index is a combination of training and interpolator indices.
activate_index(alpha, beta, model_dir=None, executor=None)
Add a multi-index to the active set and all neighbors to the candidate set.
Warning
The user of this function is responsible for ensuring that the index set maintains downward-closedness. That is, only activate indices that are neighbors of the current active set.
PARAMETER | DESCRIPTION |
---|---|
alpha |
A multi-index specifying model fidelity
TYPE:
|
beta |
A multi-index specifying surrogate fidelity
TYPE:
|
model_dir |
Directory to save model output files
TYPE:
|
executor |
Executor for parallel execution of model on training data if the model is not vectorized
TYPE:
|
Source code in src/amisc/component.py
1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 1125 1126 1127 1128 1129 1130 1131 1132 1133 1134 1135 1136 1137 1138 1139 1140 1141 1142 1143 1144 1145 1146 1147 1148 1149 1150 1151 1152 1153 1154 1155 1156 1157 1158 1159 1160 1161 1162 1163 1164 1165 1166 1167 1168 1169 1170 1171 1172 1173 1174 1175 1176 1177 1178 1179 1180 1181 1182 1183 1184 1185 1186 1187 1188 1189 1190 1191 1192 1193 1194 1195 1196 1197 1198 1199 1200 1201 1202 1203 1204 1205 1206 1207 1208 1209 1210 1211 1212 1213 1214 1215 1216 1217 1218 1219 1220 |
|
call_model(inputs, model_fidelity=None, output_path=None, executor=None, **kwds)
Wrapper function for calling the underlying component model.
This function formats the input data, calls the model, and processes the output data.
It supports vectorized calls, parallel execution using an executor, or serial execution. These options are
checked in that order, with the first available method used. Must set Component.vectorized=True
if the
model supports input arrays of the form (N,)
or even arbitrary shape (...,)
.
Parallel Execution
The underlying model must be defined in a global module scope if pickle
is the serialization method for
the provided Executor
.
Additional return values
The model can return additional items that are not part of Component.outputs
. These items are returned
as object arrays in the output dict
. Two special return values are model_cost
and output_path
.
Returning model_cost
will store the computational cost of a single model evaluation (which is used by
amisc
adaptive surrogate training). Returning output_path
will store the output file name if the model
wrote any files to disk.
Handling errors
If the underlying component model raises an exception, the error is stored in output_dict['errors']
with
the index of the input data that caused the error. The output data for that index is set to np.nan
for each output variable.
PARAMETER | DESCRIPTION |
---|---|
inputs |
The input data for the model, formatted as a
TYPE:
|
model_fidelity |
Fidelity indices to tune the model fidelity (model must request this in its keyword arguments).
TYPE:
|
output_path |
Directory to save model output files (model must request this in its keyword arguments).
TYPE:
|
executor |
Executor for parallel execution if the model is not vectorized (optional).
TYPE:
|
kwds |
Additional keyword arguments to pass to the model (model must request these in its keyword args).
DEFAULT:
|
RETURNS | DESCRIPTION |
---|---|
Dataset
|
The output data from the model, formatted as a |
Source code in src/amisc/component.py
766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 |
|
clear()
Clear the component of all training data, index sets, and MISC states.
Source code in src/amisc/component.py
deserialize(serialized_data, search_paths=None, search_keys=None)
classmethod
Return a Component
from data
. Let pydantic handle field validation and conversion. If any component
data has been saved to file and the save file doesn't exist, then the loader will search for the file
in the current working directory and any additional search paths provided.
PARAMETER | DESCRIPTION |
---|---|
serialized_data |
the serialized data to construct the object from
TYPE:
|
search_paths |
paths to try and find any save files (i.e. if they moved since they were serialized), will always search in the current working directory by default
TYPE:
|
search_keys |
keys to search for save files in each component (default is all keys in
TYPE:
|
Source code in src/amisc/component.py
get_cost(alpha, beta)
Return the total cost (wall time s) required to add \((\alpha, \beta)\) to the MISC approximation.
PARAMETER | DESCRIPTION |
---|---|
alpha |
A multi-index specifying model fidelity
TYPE:
|
beta |
A multi-index specifying surrogate fidelity
TYPE:
|
RETURNS | DESCRIPTION |
---|---|
float
|
the total cost of adding this multi-index pair to the MISC approximation |
Source code in src/amisc/component.py
get_training_data(alpha='best', beta='best', y_vars=None)
Get all training data for a given multi-index pair (alpha, beta)
.
PARAMETER | DESCRIPTION |
---|---|
alpha |
the model fidelity index (defaults to the maximum available model fidelity)
TYPE:
|
beta |
the surrogate fidelity index (defaults to the maximum available surrogate fidelity)
TYPE:
|
y_vars |
the training data to return (defaults to all stored data)
TYPE:
|
RETURNS | DESCRIPTION |
---|---|
tuple[Dataset, Dataset]
|
|
Source code in src/amisc/component.py
gradient(inputs, index_set='test', misc_coeff=None, derivative='first', executor=None)
Evaluate the Jacobian or Hessian of the MISC surrogate approximation at new inputs
, i.e.
the first or second derivatives, respectively.
PARAMETER | DESCRIPTION |
---|---|
inputs |
TYPE:
|
index_set |
the active index set, defaults to
TYPE:
|
misc_coeff |
the data structure holding the MISC coefficients to use, which defaults to the training or testing coefficients depending on the
TYPE:
|
derivative |
whether to compute the first or second derivative (i.e. Jacobian or Hessian)
TYPE:
|
executor |
executor for looping over MISC coefficients (optional)
TYPE:
|
RETURNS | DESCRIPTION |
---|---|
Dataset
|
a |
Source code in src/amisc/component.py
hessian(*args, **kwargs)
is_downward_closed(indices)
staticmethod
Return if a list of \((\alpha, \beta)\) multi-indices is downward-closed.
MISC approximations require a downward-closed set in order to use the combination-technique formula for the
coefficients (as implemented by Component.update_misc_coeff()
).
Example
The list [( (0,), (0,) ), ( (1,), (0,) ), ( (1,), (1,) )]
is downward-closed. You can visualize this as
building a stack of cubes: in order to place a cube, all adjacent cubes must be present (does the logo
make sense now?).
PARAMETER | DESCRIPTION |
---|---|
indices |
TYPE:
|
RETURNS | DESCRIPTION |
---|---|
bool
|
whether the set of indices is downward-closed |
Source code in src/amisc/component.py
model_kwarg_requested(kwarg_name)
Return whether the underlying component model requested this kwarg_name
. Special kwargs include:
output_path
— a save directory created byamisc
will be passed to the model for saving model output files.alpha
— a tuple or list of model fidelity indices will be passed to the model to adjust fidelity.input_vars
— a list ofVariable
objects will be passed to the model for input variable information.output_vars
— a list ofVariable
objects will be passed to the model for output variable information.
PARAMETER | DESCRIPTION |
---|---|
kwarg_name |
the argument to check for in the underlying component model's function signature kwargs
TYPE:
|
RETURNS | DESCRIPTION |
---|---|
bool
|
whether the component model requests this |
Source code in src/amisc/component.py
predict(inputs, use_model=None, model_dir=None, index_set='test', misc_coeff=None, incremental=False, executor=None, **kwds)
Evaluate the MISC surrogate approximation at new inputs x
.
Using the underlying model
By default this will predict the MISC surrogate approximation; all inputs are assumed to be in a compressed
and normalized form. If the component does not have a surrogate (i.e. it is analytical), then the inputs
will be converted to model form and the underlying model will be called in place. If you instead want to
override the surrogate, passing use_model
will call the underlying model directly. In that case, the
inputs should be passed in already in model form (i.e. full fields, denormalized).
PARAMETER | DESCRIPTION |
---|---|
inputs |
TYPE:
|
use_model |
'best'=high-fidelity, 'worst'=low-fidelity, tuple=a specific
TYPE:
|
model_dir |
directory to save output files if
TYPE:
|
index_set |
the active index set, defaults to
TYPE:
|
misc_coeff |
the data structure holding the MISC coefficients to use, which defaults to the training or testing coefficients depending on the
TYPE:
|
incremental |
a special flag to use if the provided
TYPE:
|
executor |
executor for parallel execution if the model is not vectorized (optional), will use the executor for looping over MISC coefficients if evaluating the surrogate rather than the model
TYPE:
|
kwds |
additional keyword arguments to pass to the model (if using the underlying model)
DEFAULT:
|
RETURNS | DESCRIPTION |
---|---|
Dataset
|
the surrogate approximation of the model (or the model return itself if |
Source code in src/amisc/component.py
973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 |
|
serialize(keep_yaml_objects=False, serialize_args=None, serialize_kwargs=None)
Convert to a dict
with only standard Python types as fields and values.
PARAMETER | DESCRIPTION |
---|---|
keep_yaml_objects |
whether to keep
TYPE:
|
serialize_args |
additional arguments to pass to the
TYPE:
|
serialize_kwargs |
additional keyword arguments to pass to the
TYPE:
|
RETURNS | DESCRIPTION |
---|---|
dict
|
a |
Source code in src/amisc/component.py
set_logger(log_file=None, stdout=None, logger=None, level=logging.INFO)
Set a new logging.Logger
object.
PARAMETER | DESCRIPTION |
---|---|
log_file |
log to file (if provided)
TYPE:
|
stdout |
whether to connect the logger to console (defaults to whatever is currently set or False)
TYPE:
|
logger |
the logging object to use (if None, then a new logger is created; this will override the
TYPE:
|
level |
the logging level to set (default is
TYPE:
|
Source code in src/amisc/component.py
update_misc_coeff(new_indices, index_set='train', misc_coeff=None)
Update MISC coefficients incrementally resulting from the addition of new indices to an index set.
Incremental updates
This function is used to update the MISC coefficients stored in misc_coeff
after adding new indices
to the given index_set
. If a custom index_set
or misc_coeff
are provided, the user is responsible
for ensuring the data structures are consistent. Since this is an incremental update, this means all
existing coefficients for every index in index_set
should be precomputed and stored in misc_coeff
.
PARAMETER | DESCRIPTION |
---|---|
new_indices |
a set of \((\alpha, \beta)\) tuples that are being added to the
TYPE:
|
index_set |
the active index set, defaults to
TYPE:
|
misc_coeff |
the data structure holding the MISC coefficients to update, which defaults to the training or testing coefficients depending on the
TYPE:
|
Source code in src/amisc/component.py
update_model(new_model=None, model_kwargs=None, **kwargs)
Update the underlying component model or its kwargs.
Source code in src/amisc/component.py
ComponentSerializers
Bases: TypedDict
Type hint for the Component
class data serializers.
ATTRIBUTE | DESCRIPTION |
---|---|
model_kwargs |
the model kwarg object class
TYPE:
|
interpolator |
the interpolator object class
TYPE:
|
training_data |
the training data object class
TYPE:
|
IndexSet(s=())
Bases: set
, Serializable
Dataclass that maintains a list of multi-indices. Overrides basic set
functionality to ensure
elements are formatted correctly as (alpha, beta)
; that is, as a tuple of alpha
and
beta
, which are themselves instances of a MultiIndex
tuple.
An example index set
\(\mathcal{I} = [(\alpha, \beta)_1 , (\alpha, \beta)_2, (\alpha, \beta)_3 , ...]\) would be specified
as I = [((0, 0), (0, 0, 0)) , ((0, 1), (0, 1, 0)), ...]
.
Source code in src/amisc/component.py
deserialize(serialized_data)
classmethod
MiscTree(data=None, **kwargs)
Bases: UserDict
, Serializable
Dataclass that maintains MISC data in a dict
tree, indexed by alpha
and beta
. Overrides
basic dict
functionality to ensure elements are formatted correctly as (alpha, beta) -> data
.
Used to store MISC coefficients, model costs, and interpolator states.
The underlying data structure is: dict[MultiIndex, dict[MultiIndex, float | InterpolatorState]]
.
Source code in src/amisc/component.py
clear()
deserialize(serialized_data)
classmethod
Deserialize a dict
to a MiscTree
.
PARAMETER | DESCRIPTION |
---|---|
serialized_data |
the data to deserialize to a
TYPE:
|
serialize(*args, keep_yaml_objects=False, **kwargs)
Serialize alpha, beta
indices to string and return a dict
of internal data.
PARAMETER | DESCRIPTION |
---|---|
args |
extra serialization arguments for internal
DEFAULT:
|
keep_yaml_objects |
whether to keep
DEFAULT:
|
kwargs |
extra serialization keyword arguments for internal
DEFAULT:
|
Source code in src/amisc/component.py
state_serializer(data)
classmethod
Infer and return the interpolator state serializer from the MiscTree
data (if possible). If no
InterpolatorState
instance could be found, return None
.
Source code in src/amisc/component.py
update(data_dict=None, **kwargs)
Force dict.update()
through the validator.
ModelKwargs
Bases: UserDict
, Serializable
Default dataclass for storing model keyword arguments in a dict
. If you have kwargs that require
more complicated serialization/specification than a plain dict
, then you can subclass from here.
from_dict(config)
classmethod
Create a ModelKwargs
object from a dict
configuration.