Source code for uncertainpy.uncertainty

from __future__ import absolute_import, division, print_function, unicode_literals

import os
import platform
import numpy as np

from .core.uncertainty_calculations import UncertaintyCalculations
from .plotting.plot_uncertainty import PlotUncertainty
from .utils.logger import get_logger, add_file_handler
from .data import Data
from .core.base import ParameterBase


[docs]class UncertaintyQuantification(ParameterBase): """ Perform an uncertainty quantification and sensitivity analysis of a model and features of the model. It implements both quasi-Monte Carlo methods and polynomial chaos expansions using either point collocation or the pseudo-spectral method. Both of the polynomial chaos expansion methods have support for the rosenblatt transformation to handle dependent input parameters. Parameters ---------- model : {None, Model or Model subclass instance, model function} Model to perform uncertainty quantification on. For requirements see Model.run. Default is None. parameters : {None, Parameters instance, list of Parameter instances, list with [[name, value, distribution], ...]} Either None, a Parameters instance or a list of the parameters that should be created. The two lists are similar to the arguments sent to Parameters. Default is None. features : {None, Features or Features subclass instance, list of feature functions}, optional Features to calculate from the model result. If None, no features are calculated. If list of feature functions, all will be calculated. Default is None. uncertainty_calculations : UncertaintyCalculations or UncertaintyCalculations subclass instance, optional An UncertaintyCalculations class or subclass that implements (custom) uncertainty quantification and sensitivity analysis methods. create_PCE_custom : callable, optional A custom method for calculating the polynomial chaos approximation. For the requirements of the function see ``UncertaintyCalculations.create_PCE_custom``. Overwrites existing ``create_PCE_custom`` method. Default is None. custom_uncertainty_quantification : callable, optional A custom method for calculating uncertainties. For the requirements of the function see ``UncertaintyCalculations.custom_uncertainty_quantification``. Overwrites existing ``custom_uncertainty_quantification`` method. Default is None. CPUs : {int, None, "max"}, optional The number of CPUs to use when calculating the model and features. If None, no multiprocessing is used. If "max", the maximum number of CPUs on the computer (multiprocess.cpu_count()) is used. Default is "max". logger_level : {"info", "debug", "warning", "error", "critical", None}, optional Set the threshold for the logging level. Logging messages less severe than this level is ignored. If None, no logging to file is performed Default logger level is "info". logger_filename : str Name of the logfile. If None, no logging to file is performed. Default is "uncertainpy.log". backend : {"auto", "hdf5", "exdir"}, optional The fileformat used to save and load data to/from file. "auto" assumes the filenames ends with either ".h5" for HDF5 files or ".exdir" for Exdir files. If unknown fileextension defaults to saving data as HDF5 files. "hdf5" saves and loads files from HDF5 files. "exdir" saves and loads files from Exdir files. Default is "auto". Attributes ---------- model : Model or Model subclass The model to perform uncertainty quantification on. parameters : Parameters The uncertain parameters. features : Features or Features subclass The features of the model to perform uncertainty quantification on. uncertainty_calculations : UncertaintyCalculations or UncertaintyCalculations subclass UncertaintyCalculations object responsible for performing the uncertainty quantification calculations. data : Data A data object that contains the results from the uncertainty quantification. Contains all model and feature evaluations, as well as all calculated statistical metrics. Raises ------ ValueError If unsupported backend is chosen. See Also -------- uncertainpy.features uncertainpy.Parameter uncertainpy.Parameters uncertainpy.models uncertainpy.core.UncertaintyCalculations uncertainpy.core.UncertaintyCalculations.create_PCE_custom : Requirements for create_PCE_custom uncertainpy.models.Model.run : Requirements for the model run function. """ def __init__(self, model, parameters, features=None, uncertainty_calculations=None, create_PCE_custom=None, custom_uncertainty_quantification=None, CPUs="max", logger_level="info", logger_filename="uncertainpy.log", backend="auto"): if backend not in ["auto", "hdf5", "exdir"]: raise ValueError("backend {} not supported. Supported backends are: auto, hdf5, and exdir".format(backend)) logger = get_logger(self) if platform.system().lower() == "windows": logger.info("On Windows machines everything in your script must be " "inside of an if __name__ == '__main__': block in order " "for multiprocess to work." ) if uncertainty_calculations is None: self._uncertainty_calculations = UncertaintyCalculations( model=model, parameters=parameters, features=features, create_PCE_custom=create_PCE_custom, custom_uncertainty_quantification=custom_uncertainty_quantification, CPUs=CPUs, logger_level=logger_level, ) else: self._uncertainty_calculations = uncertainty_calculations super(UncertaintyQuantification, self).__init__(parameters=parameters, model=model, features=features, logger_level=logger_level) self.data = None self.backend = backend self.plotting = PlotUncertainty(folder=None, logger_level=logger_level) add_file_handler(filename=logger_filename) @ParameterBase.features.setter def features(self, new_features): ParameterBase.features.fset(self, new_features) self.uncertainty_calculations.features = self.features @ParameterBase.model.setter def model(self, new_model): ParameterBase.model.fset(self, new_model) self.uncertainty_calculations.model = self.model @ParameterBase.parameters.setter def parameters(self, new_parameters): ParameterBase.parameters.fset(self, new_parameters) self.uncertainty_calculations.parameters = self.parameters @property def uncertainty_calculations(self): """ The class for performing the calculations for the uncertainty quantification and sensitivity analysis. Parameters ---------- new_uncertainty_calculations : UncertaintyCalculations or UncertaintyCalculations subclass instance New UncertaintyCalculations object responsible for performing the uncertainty quantification calculations. Returns ------- uncertainty_calculations : UncertaintyCalculations or UncertaintyCalculations subclass instance UncertaintyCalculations object responsible for performing the uncertainty quantification calculations. See Also -------- uncertainpy.core.UncertaintyCalculations """ return self._uncertainty_calculations @uncertainty_calculations.setter def uncertainty_calculations(self, new_uncertainty_calculations): self._uncertainty_calculations = new_uncertainty_calculations self.uncertainty_calculations.features = self.features self.uncertainty_calculations.model = self.model # TODO add features_to_run as argument to this function
[docs] def quantify(self, method="pc", pc_method="collocation", rosenblatt="auto", uncertain_parameters=None, polynomial_order=4, nr_collocation_nodes=None, quadrature_order=None, nr_pc_mc_samples=10**4, nr_mc_samples=10**4, allow_incomplete=True, seed=None, single=False, plot="condensed_first", figure_folder="figures", figureformat=".png", save=True, data_folder="data", filename=None, **custom_kwargs): """ Perform an uncertainty quantification and sensitivity analysis using polynomial chaos expansions or quasi-Monte Carlo methods. Parameters ---------- method : {"pc", "mc", "custom"}, optional The method to use when performing the uncertainty quantification and sensitivity analysis. "pc" is polynomial chaos method, "mc" is the quasi-Monte Carlo method and "custom" are custom uncertainty quantification methods. Default is "pc". pc_method : {"collocation", "spectral", "custom"}, optional The method to use when creating the polynomial chaos approximation, if the polynomial chaos method is chosen. "collocation" is the point collocation method "spectral" is pseudo-spectral projection, and "custom" is the custom polynomial method. Default is "collocation". rosenblatt : {"auto", bool}, optional If the Rosenblatt transformation should be used. The Rosenblatt transformation must be used if the uncertain parameters have dependent variables. If "auto" the Rosenblatt transformation is used if there are dependent parameters, and it is not used of the parameters have independent distributions. Default is "auto". uncertain_parameters : {None, str, list}, optional The uncertain parameter(s) to use when performing the uncertainty quantification. If None, all uncertain parameters are used. Default is None. polynomial_order : int, optional The polynomial order of the polynomial approximation. Default is 4. nr_collocation_nodes : {int, None}, optional The number of collocation nodes to choose, if polynomial chaos with point collocation is used. If None, `nr_collocation_nodes` = 2* number of expansion factors + 2. Default is None. quadrature_order : {int, None}, optional The order of the Leja quadrature method, if polynomial chaos with pseudo-spectral projection is used. If None, ``quadrature_order = polynomial_order + 2``. Default is None. nr_pc_mc_samples : int, optional Number of samples for the Monte Carlo sampling of the polynomial chaos approximation, if the polynomial chaos method is chosen. Default is 10**4. nr_mc_samples : int, optional Number of samples for the quasi-Monte Carlo sampling, if the quasi-Monte Carlo method is chosen. `nr_mc_samples` is used for the uncertainty quantification and ``(nr_mc_samples/2)*(nr_uncertain_parameters + 2)`` samples is used for the sensitivity analysis. Default `nr_mc_samples` is 10**4. allow_incomplete : bool, optional If the polynomial approximation should be performed for features or models with incomplete evaluations. Default is True. seed : int, optional Set a random seed. If None, no seed is set. Default is None. single : bool If an uncertainty quantification should be performed with only one uncertain parameter at the time. Requires that the values of each parameter is set. Default is False. plot : {"condensed_first", "condensed_total", "condensed_no_sensitivity", "all", "evaluations", None}, optional Type of plots to be created. "condensed_first" is a subset of the most important plots and only plots each result once, and contains plots of the first order Sobol indices. "condensed_total" is similar, but with the total order Sobol indices, and "condensed_no_sensitivity" is the same without any Sobol indices plotted. "all" creates every plot. "evaluations" plots the model and feature evaluations. None plots nothing. Default is "condensed_first". figure_folder : str, optional Name of the folder where to save all figures. Default is "figures". figureformat : str The figure format to save the plots in. Supports all formats in matplolib. Default is ".png". save : bool, optional If the data should be saved. Default is True. data_folder : str, optional Name of the folder where to save the data. Default is "data". filename : {None, str}, optional Name of the data file. If None the model name is used. Default is None. **custom_kwargs Any number of arguments for either the custom polynomial chaos method, ``create_PCE_custom``, or the custom uncertainty quantification, ``custom_uncertainty_quantification``. Returns ------- data : Data, dict containing data objects A data object that contains the results from the uncertainty quantification. Contains all model and feature evaluations, as well as all calculated statistical metrics. If `single` = True, then returns a dictionary that contains the data objects for each single parameter calculation. Raises ------ ValueError If a common multivariate distribution is given in Parameters.distribution and not all uncertain parameters are used. ValueError If `method` not one of "pc", "mc" or "custom". ValueError If `pc_method` not one of "collocation", "spectral" or "custom". NotImplementedError If custom method or custom pc method is chosen and have not been implemented. Notes ----- Which method to choose is problem dependent, but as long as the number of uncertain parameters is low (less than around 20 uncertain parameters) polynomial chaos methods are much faster than Monte Carlo methods. Above this Monte Carlo methods are the best. For polynomial chaos, the pseudo-spectral method is faster than point collocation, but has lower stability. We therefore generally recommend the point collocation method. The model and feature do not necessarily give results for each node. The collocation method and quasi-Monte Carlo methods are robust towards missing values as long as the number of results that remain is high enough. The pseudo-spectral method on the other hand, is sensitive to missing values, so `allow_incomplete` should be used with care in that case. In the quasi-Monte Carlo method we quasi-randomly draw ``(nr_mc_samples/2)*(nr_uncertain_parameters + 2)`` (nr_mc_samples=10**4 by default) parameter samples using Saltelli's sampling scheme. We require this number of samples to be able to calculate the Sobol indices. We evaluate the model for each of these parameter samples and calculate the features from each of the model results. This step is performed in parallel to speed up the calculations. Then we use `nr_mc_samples` of the model and feature results to calculate the mean, variance, and 5th and 95th percentile for the model and each feature. Lastly, we use all calculated model and each feature results to calculate the Sobol indices using Saltellie's approach. The plots created are intended as quick way to get an overview of the results, and not to create publication ready plots. Custom plots of the data can easily be created by retrieving the data from the Data class. Changing the parameters of the polynomial chaos methods should be done with care, and implementing custom methods is only recommended for experts. See also -------- uncertainpy.Parameters uncertainpy.Data uncertainpy.plotting.PlotUncertainty uncertainpy.core.UncertaintyCalculations.polynomial_chaos : Uncertainty quantification using polynomial chaos expansions uncertainpy.core.UncertaintyCalculations.monte_carlo : Uncertainty quantification using quasi-Monte Carlo methods uncertainpy.core.UncertaintyCalculations.create_PCE_custom : Requirements for create_PCE_custom uncertainpy.core.UncertaintyCalculations.custom_uncertainty_quantification : Requirements for custom_uncertainty_quantification """ uncertain_parameters = self.uncertainty_calculations.convert_uncertain_parameters(uncertain_parameters) if method.lower() == "pc": if single: data = self.polynomial_chaos_single(uncertain_parameters=uncertain_parameters, method=pc_method, rosenblatt=rosenblatt, polynomial_order=polynomial_order, nr_collocation_nodes=nr_collocation_nodes, quadrature_order=quadrature_order, nr_pc_mc_samples=nr_pc_mc_samples, allow_incomplete=allow_incomplete, seed=seed, plot=plot, figure_folder=figure_folder, figureformat=figureformat, save=save, data_folder=data_folder, filename=filename, **custom_kwargs) else: data = self.polynomial_chaos(uncertain_parameters=uncertain_parameters, method=pc_method, rosenblatt=rosenblatt, polynomial_order=polynomial_order, nr_collocation_nodes=nr_collocation_nodes, quadrature_order=quadrature_order, nr_pc_mc_samples=nr_pc_mc_samples, allow_incomplete=allow_incomplete, seed=seed, plot=plot, figure_folder=figure_folder, figureformat=figureformat, save=save, data_folder=data_folder, filename=filename, **custom_kwargs) elif method.lower() == "mc": if single: data = self.monte_carlo_single(uncertain_parameters=uncertain_parameters, nr_samples=nr_mc_samples, plot=plot, figure_folder=figure_folder, figureformat=figureformat, save=save, data_folder=data_folder, filename=filename, seed=seed) else: data = self.monte_carlo(uncertain_parameters=uncertain_parameters, nr_samples=nr_mc_samples, plot=plot, figure_folder=figure_folder, figureformat=figureformat, save=save, data_folder=data_folder, filename=filename, seed=seed) elif method.lower() == "custom": data = self.custom_uncertainty_quantification(plot=plot, figure_folder=figure_folder, figureformat=figureformat, save=save, data_folder=data_folder, filename=filename, **custom_kwargs) else: raise ValueError("No method with name {}".format(method)) return data
[docs] def custom_uncertainty_quantification(self, plot="condensed_first", figure_folder="figures", figureformat=".png", save=True, data_folder="data", filename=None, **custom_kwargs): """ Perform a custom uncertainty quantification and sensitivity analysis, implemented by the user. Parameters ---------- plot : {"condensed_first", "condensed_total", "condensed_no_sensitivity", "all", "evaluations", None}, optional Type of plots to be created. "condensed_first" is a subset of the most important plots and only plots each result once, and contains plots of the first order Sobol indices. "condensed_total" is similar, but with the total order Sobol indices, and "condensed_no_sensitivity" is the same without any Sobol indices plotted. "all" creates every plot. "evaluations" plots the model and feature evaluations. None plots nothing. Default is "condensed_first". figure_folder : str, optional Name of the folder where to save all figures. Default is "figures". figureformat : str The figure format to save the plots in. Supports all formats in matplolib. Default is ".png". save : bool, optional If the data should be saved. Default is True. data_folder : str, optional Name of the folder where to save the data. Default is "data". filename : {None, str}, optional Name of the data file. If None the model name is used. Default is None. **custom_kwargs Any number of arguments for the custom uncertainty quantification. Raises ------ NotImplementedError If the custom uncertainty quantification method have not been implemented. Notes ----- For details on how to implement the custom uncertainty quantification method see UncertaintyCalculations.custom_uncertainty_quantification. The plots created are intended as quick way to get an overview of the results, and not to create publication ready plots. Custom plots of the data can easily be created by retrieving the data from the Data class. See also -------- uncertainpy.plotting.PlotUncertainty uncertainpy.Parameters uncertainpy.core.UncertaintyCalculations.custom_uncertainty_quantification : Requirements for custom_uncertainty_quantification """ self.data = self.uncertainty_calculations.custom_uncertainty_quantification(**custom_kwargs) self.data.backend = self.backend if filename is None: filename = self.model.name if save: self.save(filename, folder=data_folder) self.plot(type=plot, folder=figure_folder, figureformat=figureformat) return self.data
[docs] def polynomial_chaos(self, method="collocation", rosenblatt="auto", uncertain_parameters=None, polynomial_order=4, nr_collocation_nodes=None, quadrature_order=None, nr_pc_mc_samples=10**4, allow_incomplete=True, seed=None, plot="condensed_first", figure_folder="figures", figureformat=".png", save=True, data_folder="data", filename=None, **custom_kwargs): """ Perform an uncertainty quantification and sensitivity analysis using polynomial chaos expansions. Parameters ---------- method : {"collocation", "spectral", "custom"}, optional The method to use when creating the polynomial chaos approximation, if the polynomial chaos method is chosen. "collocation" is the point collocation method "spectral" is pseudo-spectral projection, and "custom" is the custom polynomial method. Default is "collocation". rosenblatt : {"auto", bool}, optional If the Rosenblatt transformation should be used. The Rosenblatt transformation must be used if the uncertain parameters have dependent variables. If "auto" the Rosenblatt transformation is used if there are dependent parameters, and it is not used of the parameters have independent distributions. Default is "auto". uncertain_parameters : {None, str, list}, optional The uncertain parameter(s) to use when performing the uncertainty quantification. If None, all uncertain parameters are used. Default is None. polynomial_order : int, optional The polynomial order of the polynomial approximation. Default is 4. nr_collocation_nodes : {int, None}, optional The number of collocation nodes to choose, if polynomial chaos with point collocation is used. If None, `nr_collocation_nodes` = 2* number of expansion factors + 2. Default is None. quadrature_order : {int, None}, optional The order of the Leja quadrature method, if polynomial chaos with pseudo-spectral projection is used. If None, ``quadrature_order = polynomial_order + 2``. Default is None. nr_pc_mc_samples : int, optional Number of samples for the Monte Carlo sampling of the polynomial chaos approximation, if the polynomial chaos method is chosen. allow_incomplete : bool, optional If the polynomial approximation should be performed for features or models with incomplete evaluations. Default is True. seed : int, optional Set a random seed. If None, no seed is set. Default is None. plot : {"condensed_first", "condensed_total", "condensed_no_sensitivity", "all", "evaluations", None}, optional Type of plots to be created. "condensed_first" is a subset of the most important plots and only plots each result once, and contains plots of the first order Sobol indices. "condensed_total" is similar, but with the total order Sobol indices, and "condensed_no_sensitivity" is the same without any Sobol indices plotted. "all" creates every plot. "evaluations" plots the model and feature evaluations. None plots nothing. Default is "condensed_first". figure_folder : str, optional Name of the folder where to save all figures. Default is "figures". figureformat : str The figure format to save the plots in. Supports all formats in matplolib. Default is ".png". save : bool, optional If the data should be saved. Default is True. data_folder : str, optional Name of the folder where to save the data. Default is "data". filename : {None, str}, optional Name of the data file. If None the model name is used. Default is None. **custom_kwargs Any number of arguments for the custom polynomial chaos method, ``create_PCE_custom``. Returns ------- data : Data A data object that contains the results from the uncertainty quantification. Contains all model and feature evaluations, as well as all calculated statistical metrics. Raises ------ ValueError If a common multivariate distribution is given in Parameters.distribution and not all uncertain parameters are used. ValueError If `method` not one of "collocation", "spectral" or "custom". NotImplementedError If custom pc method is chosen and have not been implemented. Notes ----- Which method to choose is problem dependent, but as long as the number of uncertain parameters is low (less than around 20 uncertain parameters) polynomial chaos methods are much faster than Monte Carlo methods. Above this Monte Carlo methods are the best. For polynomial chaos, the pseudo-spectral method is faster than point collocation, but has lower stability. We therefore generally recommend the point collocation method. The model and feature do not necessarily give results for each node. The collocation method are robust towards missing values as long as the number of results that remain is high enough. The pseudo-spectral method on the other hand, is sensitive to missing values, so `allow_incomplete` should be used with care in that case. The plots created are intended as quick way to get an overview of the results, and not to create publication ready plots. Custom plots of the data can easily be created by retrieving the data from the Data class. Changing the parameters of the polynomial chaos methods should be done with care, and implementing custom methods is only recommended for experts. See also -------- uncertainpy.Data uncertainpy.Parameters uncertainpy.plotting.PlotUncertainty uncertainpy.core.UncertaintyCalculations.polynomial_chaos : Uncertainty quantification using polynomial chaos expansions uncertainpy.core.UncertaintyCalculations.create_PCE_custom : Requirements for create_PCE_custom """ uncertain_parameters = self.uncertainty_calculations.convert_uncertain_parameters(uncertain_parameters) if len(uncertain_parameters) > 20: raise RuntimeWarning("The number of uncertain parameters is high." + "The Monte-Carlo method might be faster.") self.data = self.uncertainty_calculations.polynomial_chaos( method=method, rosenblatt=rosenblatt, uncertain_parameters=uncertain_parameters, polynomial_order=polynomial_order, nr_collocation_nodes=nr_collocation_nodes, quadrature_order=quadrature_order, nr_pc_mc_samples=nr_pc_mc_samples, allow_incomplete=allow_incomplete, seed=seed, **custom_kwargs ) self.data.backend = self.backend if filename is None: filename = self.model.name if save: self.save(filename, folder=data_folder) self.plot(type=plot, folder=figure_folder, figureformat=figureformat) return self.data
[docs] def monte_carlo(self, uncertain_parameters=None, nr_samples=10**4, seed=None, plot="condensed_first", figure_folder="figures", figureformat=".png", save=True, data_folder="data", filename=None): """ Perform an uncertainty quantification using the quasi-Monte Carlo method. Parameters ---------- uncertain_parameters : {None, str, list}, optional The uncertain parameter(s) to use when performing the uncertainty quantification. If None, all uncertain parameters are used. Default is None. nr_samples : int, optional Number of samples for the quasi-Monte Carlo sampling. `nr_samples` is used for the uncertainty quantification and ``(nr_samples/2)*(nr_uncertain_parameters + 2)`` samples is used for the sensitivity analysis. Default `nr_samples` is 10**4. seed : int, optional Set a random seed. If None, no seed is set. Default is None. plot : {"condensed_first", "condensed_total", "condensed_no_sensitivity", "all", "evaluations", None}, optional Type of plots to be created. "condensed_first" is a subset of the most important plots and only plots each result once, and contains plots of the first order Sobol indices. "condensed_total" is similar, but with the total order Sobol indices, and "condensed_no_sensitivity" is the same without any Sobol indices plotted. "all" creates every plot. "evaluations" plots the model and feature evaluations. None plots nothing. Default is "condensed_first". figure_folder : str, optional Name of the folder where to save all figures. Default is "figures". figureformat : str The figure format to save the plots in. Supports all formats in matplolib. Default is ".png". save : bool, optional If the data should be saved. Default is True. data_folder : str, optional Name of the folder where to save the data. Default is "data". filename : {None, str}, optional Name of the data file. If None the model name is used. Default is None. Returns ------- data : Data A data object that contains the results from the uncertainty quantification. Contains all model and feature evaluations, as well as all calculated statistical metrics. Raises ------ ValueError If a common multivariate distribution is given in Parameters.distribution and not all uncertain parameters are used. Notes ----- Which method to choose is problem dependent, but as long as the number of uncertain parameters is low (less than around 20 uncertain parameters) polynomial chaos methods are much faster than Monte Carlo methods. Above this Monte Carlo methods are the best. In the quasi-Monte Carlo method we quasi-randomly draw ``(nr_samples/2)*(nr_uncertain_parameters + 2)`` (nr_samples=10**4 by default) parameter samples using Saltelli's sampling scheme. We require this number of samples to be able to calculate the Sobol indices. We evaluate the model for each of these parameter samples and calculate the features from each of the model results. This step is performed in parallel to speed up the calculations. Then we use `nr_samples` of the model and feature results to calculate the mean, variance, and 5th and 95th percentile for the model and each feature. Lastly, we use all calculated model and each feature results to calculate the Sobol indices using Saltellie's approach. The plots created are intended as quick way to get an overview of the results, and not to create publication ready plots. Custom plots of the data can easily be created by retrieving the data from the Data class. Sensitivity analysis is currently not yet available for the quasi-Monte Carlo method. See also -------- uncertainpy.Data uncertainpy.Parameters uncertainpy.plotting.PlotUncertainty uncertainpy.core.UncertaintyCalculations.monte_carlo : Uncertainty quantification using quasi-Monte Carlo methods """ uncertain_parameters = self.uncertainty_calculations.convert_uncertain_parameters(uncertain_parameters) self.data = self.uncertainty_calculations.monte_carlo(uncertain_parameters=uncertain_parameters, nr_samples=nr_samples, seed=seed) self.data.backend = self.backend if filename is None: filename = self.model.name if save: self.save(filename, folder=data_folder) self.plot(type=plot, folder=figure_folder, figureformat=figureformat) return self.data
[docs] def polynomial_chaos_single(self, method="collocation", rosenblatt="auto", polynomial_order=4, uncertain_parameters=None, nr_collocation_nodes=None, quadrature_order=None, nr_pc_mc_samples=10**4, allow_incomplete=True, seed=None, plot="condensed_first", figure_folder="figures", figureformat=".png", save=True, data_folder="data", filename=None): """ Perform an uncertainty quantification and sensitivity analysis for a single parameter at the time using polynomial chaos expansions. Parameters ---------- method : {"collocation", "spectral", "custom"}, optional The method to use when creating the polynomial chaos approximation, if the polynomial chaos method is chosen. "collocation" is the point collocation method "spectral" is pseudo-spectral projection, and "custom" is the custom polynomial method. Default is "collocation". rosenblatt : {"auto", bool}, optional If the Rosenblatt transformation should be used. The Rosenblatt transformation must be used if the uncertain parameters have dependent variables. If "auto" the Rosenblatt transformation is used if there are dependent parameters, and it is not used of the parameters have independent distributions. Default is "auto". uncertain_parameters : {None, str, list}, optional The uncertain parameter(s) to performing the uncertainty quantification for. If None, all uncertain parameters are used. Default is None. polynomial_order : int, optional The polynomial order of the polynomial approximation. Default is 4. nr_collocation_nodes : {int, None}, optional The number of collocation nodes to choose, if polynomial chaos with point collocation is used. If None, `nr_collocation_nodes` = 2* number of expansion factors + 2. Default is None. quadrature_order : {int, None}, optional The order of the Leja quadrature method, if polynomial chaos with pseudo-spectral projection is used. If None, ``quadrature_order = polynomial_order + 2``. Default is None. nr_pc_mc_samples : int, optional Number of samples for the Monte Carlo sampling of the polynomial chaos approximation, if the polynomial chaos method is chosen. allow_incomplete : bool, optional If the polynomial approximation should be performed for features or models with incomplete evaluations. Default is True. seed : int, optional Set a random seed. If None, no seed is set. Default is None. plot : {"condensed_first", "condensed_total", "condensed_no_sensitivity", "all", "evaluations", None}, optional Type of plots to be created. "condensed_first" is a subset of the most important plots and only plots each result once, and contains plots of the first order Sobol indices. "condensed_total" is similar, but with the total order Sobol indices, and "condensed_no_sensitivity" is the same without any Sobol indices plotted. "all" creates every plot. "evaluations" plots the model and feature evaluations. None plots nothing. Default is "condensed_first". figure_folder : str, optional Name of the folder where to save all figures. Default is "figures". figureformat : str The figure format to save the plots in. Supports all formats in matplolib. Default is ".png". save : bool, optional If the data should be saved. Default is True. data_folder : str, optional Name of the folder where to save the data. Default is "data". filename : {None, str}, optional Name of the data file. If None the model name is used. Default is None. **custom_kwargs Any number of arguments for the custom polynomial chaos method, ``create_PCE_custom``. Returns ------- data_dict : dict A dictionary that contains the data for each single parameter calculation. Raises ------ ValueError If a common multivariate distribution is given in Parameters.distribution and not all uncertain parameters are used. ValueError If `method` not one of "collocation", "spectral" or "custom". NotImplementedError If custom pc method is chosen and have not been implemented. Notes ----- Which method to choose is problem dependent, but as long as the number of uncertain parameters is low (less than around 20 uncertain parameters) polynomial chaos methods are much faster than Monte Carlo methods. Above this Monte Carlo methods are the best. For polynomial chaos, the pseudo-spectral method is faster than point collocation, but has lower stability. We therefore generally recommend the point collocation method. The model and feature do not necessarily give results for each node. The collocation method are robust towards missing values as long as the number of results that remain is high enough. The pseudo-spectral method on the other hand, is sensitive to missing values, so `allow_incomplete` should be used with care in that case. The plots created are intended as quick way to get an overview of the results, and not to create publication ready plots. Custom plots of the data can easily be created by retrieving the data from the Data class. Changing the parameters of the polynomial chaos methods should be done with care, and implementing custom methods is only recommended for experts. See also -------- uncertainpy.Data uncertainpy.Parameters uncertainpy.plotting.PlotUncertainty uncertainpy.core.UncertaintyCalculations.polynomial_chaos : Uncertainty quantification using polynomial chaos expansions uncertainpy.core.UncertaintyCalculations.create_PCE_custom : Requirements for create_PCE_custom """ logger = get_logger(self) uncertain_parameters = self.uncertainty_calculations.convert_uncertain_parameters(uncertain_parameters) for parameter in self.parameters: if parameter.value is None: raise ValueError("Parameter.value must be set for each parameter when using single=True.") if filename is None: filename = self.model.name if seed is not None: np.random.seed(seed) data_dict = {} for uncertain_parameter in uncertain_parameters: logger.info("Running for " + uncertain_parameter) data = self.uncertainty_calculations.polynomial_chaos( uncertain_parameters=uncertain_parameter, method=method, rosenblatt=rosenblatt, polynomial_order=polynomial_order, nr_collocation_nodes=nr_collocation_nodes, quadrature_order=quadrature_order, nr_pc_mc_samples=nr_pc_mc_samples, allow_incomplete=allow_incomplete, ) data.backend = self.backend data.seed = seed self.data = data data_dict[uncertain_parameter] = data self.data = data_dict if save: self.save(filename, folder=data_folder) self.plot(type=plot, folder=figure_folder, figureformat=figureformat) return data_dict
[docs] def monte_carlo_single(self, uncertain_parameters=None, nr_samples=10**4, seed=None, plot="condensed_first", save=True, data_folder="data", figure_folder="figures", figureformat=".png", filename=None): """ Perform an uncertainty quantification for a single parameter at the time using the quasi-Monte Carlo method. Parameters ---------- uncertain_parameters : {None, str, list}, optional The uncertain parameter(s) to use when performing the uncertainty quantification. If None, all uncertain parameters are used. Default is None. nr_samples : int, optional Number of samples for the quasi-Monte Carlo sampling. `nr_samples` is used for the uncertainty quantification and ``(nr_samples/2)*(nr_uncertain_parameters + 2)`` samples is used for the sensitivity analysis. Default `nr_samples` is 10**4. seed : int, optional Set a random seed. If None, no seed is set. Default is None. plot : {"condensed_first", "condensed_total", "condensed_no_sensitivity", "all", "evaluations", None}, optional Type of plots to be created. "condensed_first" is a subset of the most important plots and only plots each result once, and contains plots of the first order Sobol indices. "condensed_total" is similar, but with the total order Sobol indices, and "condensed_no_sensitivity" is the same without any Sobol indices plotted. "all" creates every plot. "evaluations" plots the model and feature evaluations. None plots nothing. Default is "condensed_first". figure_folder : str, optional Name of the folder where to save all figures. Default is "figures". figureformat : str The figure format to save the plots in. Supports all formats in matplolib. Default is ".png". save : bool, optional If the data should be saved. Default is True. data_folder : str, optional Name of the folder where to save the data. Default is "data". filename : {None, str}, optional Name of the data file. If None the model name is used. Default is None. Returns ------- data_dict : dict A dictionary that contains the data objects for each single parameter calculation. Raises ------ ValueError If a common multivariate distribution is given in Parameters.distribution and not all uncertain parameters are used. Notes ----- Which method to choose is problem dependent, but as long as the number of uncertain parameters is low (less than around 20 uncertain parameters) polynomial chaos methods are much faster than Monte Carlo methods. Above this Monte Carlo methods are the best. In the quasi-Monte Carlo method we quasi-randomly draw ``(nr_samples/2)*(nr_uncertain_parameters + 2)`` (nr_samples=10**4 by default) parameter samples using Saltelli's sampling scheme. We require this number of samples to be able to calculate the Sobol indices. We evaluate the model for each of these parameter samples and calculate the features from each of the model results. This step is performed in parallel to speed up the calculations. Then we use `nr_samples` of the model and feature results to calculate the mean, variance, and 5th and 95th percentile for the model and each feature. Lastly, we use all calculated model and each feature results to calculate the Sobol indices using Saltellie's approach. The plots created are intended as quick way to get an overview of the results, and not to create publication ready plots. Custom plots of the data can easily be created by retrieving the data from the Data class. Sensitivity analysis is currently not yet available for the quasi-Monte Carlo method. See also -------- uncertainpy.Data uncertainpy.plotting.PlotUncertainty uncertainpy.Parameters uncertainpy.core.UncertaintyCalculations.monte_carlo : Uncertainty quantification using quasi-Monte Carlo methods """ logger = get_logger(self) uncertain_parameters = self.uncertainty_calculations.convert_uncertain_parameters(uncertain_parameters) if filename is None: filename = self.model.name if seed is not None: np.random.seed(seed) data_dict = {} for uncertain_parameter in uncertain_parameters: logger.info("Running MC for " + uncertain_parameter) data = self.uncertainty_calculations.monte_carlo(uncertain_parameters=uncertain_parameter, nr_samples=nr_samples) data.backend = self.backend data.seed = seed data_dict[uncertain_parameter] = data self.data = data_dict if save: self.save(filename, folder=data_folder) self.plot(type=plot, folder=figure_folder, figureformat=figureformat) return data_dict
[docs] def save(self, filename, folder="data"): """ Save ``data`` to disk. Parameters ---------- filename : str Name of the data file. folder : str, optional The folder to store the data in. Creates the folder if it does not exist. Default is "/data". See also -------- uncertainpy.Data : Data class """ if not os.path.isdir(folder): os.makedirs(folder) logger = get_logger(self) fileextension = "" if self.backend == "auto": if filename.endswith(".h5"): fileextension = ".h5" filename = filename.strip(".h5") elif filename.endswith(".exdir"): fileextension = ".exdir" filename = filename.strip(".exdir") else: fileextension = ".h5" elif self.backend == "hdf5": fileextension = ".h5" filename = filename.strip(".h5") elif self.backend == "exdir": fileextension = ".exdir" filename = filename.strip(".exdir") # To save dict of single parameter runs if isinstance(self.data, dict): for uncertain_parameter in self.data: tmp_filename = "{}_{}".format( filename, uncertain_parameter ) save_path = os.path.join(folder, tmp_filename + fileextension) logger.info("Saving data as: {}".format(save_path)) self.data[uncertain_parameter].save(save_path) else: save_path = os.path.join(folder, filename + fileextension) logger.info("Saving data as: {}".format(save_path)) self.data.save(save_path)
[docs] def load(self, filename): """ Load data from disk. Parameters ---------- filename : str Name of the stored data file. See also -------- uncertainpy.Data : Data class """ self.data = Data(filename)
[docs] def plot(self, type="condensed_first", folder="figures", figureformat=".png"): """ Create plots for the results of the uncertainty quantification and sensitivity analysis. ``self.data`` must exist and contain the results. Parameters ---------- data : Data A data object that contains the results from the uncertainty quantification. type : {"condensed_first", "condensed_total", "condensed_no_sensitivity", "all", "evaluations", None}, optional Type of plots to be created. "condensed_first" is a subset of the most important plots and only plots each result once, and contains plots of the first order Sobol indices. "condensed_total" is similar, but with the total order Sobol indices, and "condensed_no_sensitivity" is the same without any Sobol indices plotted. "all" creates every plot. "evaluations" plots the model and feature evaluations. None plots nothing. Default is "condensed_first". folder : str Name of the folder where to save all figures. Default is "figures". figureformat : str The figure format to save the plots in. Supports all formats in matplolib. Default is ".png". Notes ----- These plots are intended as quick way to get an overview of the results, and not to create publication ready plots. Custom plots of the data can easily be created by retrieving the data from the Data class. See also -------- uncertainpy.Data uncertainpy.plotting.PlotUncertainty """ def plot(type): if type.lower() == "condensed_first": self.plotting.plot_condensed(sensitivity="sobol_first") elif type.lower() == "condensed_total": self.plotting.plot_condensed(sensitivity="sobol_total") elif type.lower() == "condensed_no_sensitivity": self.plotting.plot_condensed(sensitivity=None) elif type.lower() == "all": self.plotting.plot_all_sensitivities() self.plotting.all_evaluations() elif type.lower() == "evaluations": self.plotting.all_evaluations() else: raise ValueError('type must one of: "condensed_first", ' '"condensed_total", "condensed_no_sensitivity" ' '"all", "evaluations", None, not {}'.format(type)) if type is None: return else: self.plotting.figureformat = figureformat # To plot dict of single parameter runs if isinstance(self.data, dict): for uncertain_parameter in self.data: tmp_folder = os.path.join(folder, uncertain_parameter) self.plotting.folder = tmp_folder self.plotting.data = self.data[uncertain_parameter] plot(type) else: self.plotting.folder = folder self.plotting.data = self.data plot(type)