Example #1
0
def test_scale_samples_upper_eq_lower():
    '''
    Raise ValueError if upper bound lower equal to lower bound
    '''
    params = np.array([[0, 0], [0.1, 0.1], [0.2, 0.2]])
    bounds = [[10, 10], [-10, 10]]
    scale_samples(params, bounds)
def sample(problem,
           N,
           num_levels,
           grid_jump,
           optimal_trajectories=None,
           local_optimization=True,
           seed=None):
    """Generate model inputs using the Method of Morris
    Returns a NumPy matrix containing the model inputs required for Method of
    Morris.  The resulting matrix has :math:`(G+1)*T` rows and :math:`D`
    columns, where :math:`D` is the number of parameters, :math:`G` is the
    number of groups (if no groups are selected, the number of parameters).
    :math:`T` is the number of trajectories :math:`N`,
    or `optimal_trajectories` if selected.
    These model inputs  are intended to be used with
    :func:`SALib.analyze.morris.analyze`.
    Parameters
    ----------
    problem : dict
        The problem definition
    N : int
        The number of trajectories to generate
    num_levels : int
        The number of grid levels
    grid_jump : int
        The grid jump size
    optimal_trajectories : int
        The number of optimal trajectories to sample (between 2 and N)
    local_optimization : bool, default=True
        Flag whether to use local optimization according to Ruano et al. (2012)
        Speeds up the process tremendously for bigger N and num_levels.
        If set to ``False`` brute force method is used, unless ``gurobipy`` is
        available
    Returns
    -------
    sample : numpy.ndarray
        Returns a numpy.ndarray containing the model inputs required for Method
        of Morris. The resulting matrix has :math:`(G/D+1)*N/T` rows and
        :math:`D` columns, where :math:`D` is the number of parameters.
    """
    if seed:
        np.random.seed(seed)

    if grid_jump >= num_levels:
        raise ValueError("grid_jump must be less than num_levels")

    if problem.get('groups'):
        sample = _sample_groups(problem, N, num_levels, grid_jump)
    else:
        sample = _sample_oat(problem, N, num_levels, grid_jump)

    if optimal_trajectories:

        sample = _compute_optimised_trajectories(problem, sample, N,
                                                 optimal_trajectories,
                                                 local_optimization)

    scale_samples(sample, problem['bounds'])
    return sample
Example #3
0
def test_scale_samples_upper_lt_lower():
    '''
    Raise ValueError if upper bound lower than lower bound
    '''
    params = np.array([[0, 0], [0.1, 0.1], [0.2, 0.2]])
    bounds = [[10, 9], [-10, 10]]
    with raises(ValueError):
        scale_samples(params, bounds)
Example #4
0
def test_scale_samples_upper_eq_lower():
    '''
    Raise ValueError if upper bound lower equal to lower bound
    '''
    params = np.array([[0, 0], [0.1, 0.1], [0.2, 0.2]])
    bounds = [[10, 10], [-10, 10]]
    with raises(ValueError):
        scale_samples(params, bounds)
Example #5
0
def sample(problem: Dict,
           N: int,
           num_levels: int = 4,
           optimal_trajectories: int = None,
           local_optimization: bool = True,
           seed: int = None) -> np.ndarray:
    """Generate model inputs using the Method of Morris

    Returns a NumPy matrix containing the model inputs required for Method of
    Morris.  The resulting matrix has :math:`(G+1)*T` rows and :math:`D`
    columns, where :math:`D` is the number of parameters, :math:`G` is the
    number of groups (if no groups are selected, the number of parameters).
    :math:`T` is the number of trajectories :math:`N`,
    or `optimal_trajectories` if selected.
    These model inputs  are intended to be used with
    :func:`SALib.analyze.morris.analyze`.

    Parameters
    ----------
    problem : dict
        The problem definition
    N : int
        The number of trajectories to generate
    num_levels : int, default=4
        The number of grid levels (should be even)
    optimal_trajectories : int
        The number of optimal trajectories to sample (between 2 and N)
    local_optimization : bool, default=True
        Flag whether to use local optimization according to Ruano et al. (2012)
        Speeds up the process tremendously for bigger N and num_levels.
        If set to ``False`` brute force method is used, unless ``gurobipy`` is
        available
    seed : int
        Seed to generate a random number

    Returns
    -------
    sample_morris : numpy.ndarray
        Returns a numpy.ndarray containing the model inputs required for Method
        of Morris. The resulting matrix has :math:`(G/D+1)*N/T` rows and
        :math:`D` columns, where :math:`D` is the number of parameters.
    """
    if seed:
        np.random.seed(seed)

    _check_if_num_levels_is_even(num_levels)

    problem = _define_problem_with_groups(problem)

    sample_morris = _sample_morris(problem, N, num_levels)

    if optimal_trajectories:
        sample_morris = _compute_optimised_trajectories(
            problem, sample_morris, N, optimal_trajectories,
            local_optimization)

    scale_samples(sample_morris, problem['bounds'])
    return sample_morris
Example #6
0
def sample(problem, N, num_levels, grid_jump, optimal_trajectories=None,
           local_optimization=True):
    """Generate model inputs using the Method of Morris

    Returns a NumPy matrix containing the model inputs required for Method of
    Morris.  The resulting matrix has :math:`(G+1)*T` rows and :math:`D`
    columns, where :math:`D` is the number of parameters, :math:`G` is the
    number of groups (if no groups are selected, the number of parameters).
    :math:`T` is the number of trajectories :math:`N`,
    or `optimal_trajectories` if selected.
    These model inputs  are intended to be used with
    :func:`SALib.analyze.morris.analyze`.

    Parameters
    ----------
    problem : dict
        The problem definition
    N : int
        The number of trajectories to generate
    num_levels : int
        The number of grid levels
    grid_jump : int
        The grid jump size
    optimal_trajectories : int
        The number of optimal trajectories to sample (between 2 and N)
    local_optimization : bool, default=True
        Flag whether to use local optimization according to Ruano et al. (2012)
        Speeds up the process tremendously for bigger N and num_levels.
        If set to ``False`` brute force method is used, unless ``gurobipy`` is
        available

    Returns
    -------
    sample : numpy.ndarray
        Returns a numpy.ndarray containing the model inputs required for Method
        of Morris. The resulting matrix has :math:`(G/D+1)*N/T` rows and
        :math:`D` columns, where :math:`D` is the number of parameters.
    """
    if grid_jump >= num_levels:
        raise ValueError("grid_jump must be less than num_levels")

    if problem.get('groups'):
        sample = _sample_groups(problem, N, num_levels, grid_jump)
    else:
        sample = _sample_oat(problem, N, num_levels, grid_jump)

    if optimal_trajectories:

        sample = _compute_optimised_trajectories(problem,
                                                 sample,
                                                 N,
                                                 optimal_trajectories,
                                                 local_optimization)

    scale_samples(sample, problem['bounds'])
    return sample
Example #7
0
 def _generate_lhs(cls, parameter_bounds, n_samples, seed=1):
     """
     Generates a latin hypercube array.
     """
     num_vars = len(parameter_bounds)
     lhs_array = lhs(n=num_vars,
                     samples=n_samples,
                     criterion="maximin",
                     random_state=seed)
     # scale to the bounds
     scale_samples(lhs_array, parameter_bounds)
     return lhs_array
Example #8
0
def test_scale_samples():
    '''
    Simple test to ensure that samples are correctly scaled
    '''

    params = np.arange(0, 1.1, 0.1).repeat(2).reshape((11, 2))

    bounds = [[10, 20], [-10, 10]]

    desired = np.array(
        [np.arange(10, 21, 1), np.arange(-10, 12, 2)], dtype=np.float).T
    scale_samples(params, bounds)
    assert_allclose(params, desired, atol=1e-03, rtol=1e-03)
Example #9
0
def test_scale_samples():
    '''
    Simple test to ensure that samples are correctly scaled
    '''

    params = np.arange(0, 1.1, 0.1).repeat(2).reshape((11, 2))

    bounds = [[10, 20], [-10, 10]]

    desired = np.array(
        [np.arange(10, 21, 1), np.arange(-10, 12, 2)], dtype=np.float).T
    scale_samples(params, bounds)
    assert_allclose(params, desired, atol=1e-03, rtol=1e-03)
Example #10
0
def Create_LHS_parameter_set(nsamples):

 from SALib.sample import latin_hypercube
 from SALib.util import scale_samples, read_param_file
 import random as rd

 # Set random seed (does not affect quasi-random Sobol sampling)
 seed = 1
 np.random.seed(seed)
 rd.seed(seed)

 #Define parameters and ranges
 parameters = ordereddict.OrderedDict()
 parameters['log10m'] = [np.log10(0.001),np.log10(0.1)]
 parameters['lnTe'] = [np.log(np.exp(-8.0)/3600.0),np.log(np.exp(8.0)/3600.0)]
 parameters['log10soil'] = [np.log10(1.0),np.log10(2.00)]
 parameters['sdmax'] = [0.1,2.0] #dtopmodel

 #Make directory
 if os.path.exists('LHS') == False:
  os.mkdir('LHS')

 #Prepare file with parameter range
 fp = open('LHS/parameters.txt','w')
 vars = []
 for var in parameters:
  vars.append(var)
  fp.write('%s %f %f\n' % (var,parameters[var][0],parameters[var][1]))
 fp.close()

 #Read the parameter range file and generate samples
 param_file = 'LHS/parameters.txt'
 pf = read_param_file(param_file)

 #Generate samples (choose method here)
 param_values = latin_hypercube.sample(nsamples, pf['num_vars'])

 #Samples are given in range [0, 1] by default. Rescale them to your parameter bounds.
 scale_samples(param_values, pf['bounds'])

 #Save parameters to file         
 np.savetxt('LHS/LHS_sampling.txt', param_values, delimiter=' ',header=" ".join(vars))

 return
Example #11
0
# Set random seed (does not affect quasi-random Sobol sampling)
seed = 1
np.random.seed(seed)
rd.seed(seed)

# Read the parameter range file and generate samples
param_file = './SALib/test_functions/params/Sobol_G.txt'
pf = read_param_file(param_file)

# Generate samples (choose method here)
param_values = saltelli.sample(100, pf['num_vars'], calc_second_order = True)
# param_values = morris_oat.sample(100, pf['num_vars'], num_levels = 10, grid_jump = 5)
# param_values = fast_sampler.sample(100, pf['num_vars'])

# Samples are given in range [0, 1] by default. Rescale them to your parameter bounds. (If using normal distributions, use "scale_samples_normal" instead)
scale_samples(param_values, pf['bounds'])

# For Method of Morris, save the parameter values in a file (they are needed in the analysis)
# FAST and Sobol do not require this step, unless you want to save samples to input into an external model
np.savetxt('SGInput.txt', param_values, delimiter=' ')

# Run the "model" and save the output in a text file
# This will happen offline for external models
Y = Sobol_G.evaluate(param_values)
np.savetxt("SGOutput.txt", Y, delimiter=' ')

# Perform the sensitivity analysis using the model output
# Specify which column of the output file to analyze (zero-indexed)
sobol.analyze(param_file, 'SGOutput.txt', column = 0, calc_second_order = True)
# morris.analyze(param_file, 'SGInput.txt', 'SGOutput.txt', column = 0)
# extended_fast.analyze(param_file, 'SGOutput.txt', column = 0)
Example #12
0
def sample(problem: Dict, N: int, num_levels: int = 4,
           optimal_trajectories: int = None, local_optimization: bool = True,
           seed: int = None) -> np.ndarray:
    """Generate model inputs using the Method of Morris

    Returns a NumPy matrix containing the model inputs required for Method of
    Morris.  The resulting matrix has :math:`(G+1)*T` rows and :math:`D`
    columns, where :math:`D` is the number of parameters, :math:`G` is the
    number of groups (if no groups are selected, the number of parameters).
    :math:`T` is the number of trajectories :math:`N`,
    or `optimal_trajectories` if selected.
    These model inputs  are intended to be used with
    :func:`SALib.analyze.morris.analyze`.

    Parameters
    ----------
    problem : dict
        The problem definition
    N : int
        The number of trajectories to generate
    num_levels : int, default=4
        The number of grid levels (should be even)
    optimal_trajectories : int
        The number of optimal trajectories to sample (between 2 and N)
    local_optimization : bool, default=True
        Flag whether to use local optimization according to Ruano et al. (2012)
        Speeds up the process tremendously for bigger N and num_levels.
        If set to ``False`` brute force method is used, unless ``gurobipy`` is
        available
    seed : int
        Seed to generate a random number

    Returns
    -------
    sample_morris : numpy.ndarray
        Returns a numpy.ndarray containing the model inputs required for Method
        of Morris. The resulting matrix has :math:`(G/D+1)*N/T` rows and
        :math:`D` columns, where :math:`D` is the number of parameters.

    References
    ----------
    .. [1] Ruano, M.V., Ribes, J., Seco, A., Ferrer, J., 2012. 
           An improved sampling strategy based on trajectory design for 
           application of the Morris method to systems with many input factors. 
           Environmental Modelling & Software 37, 103–109. 
           https://doi.org/10.1016/j.envsoft.2012.03.008

    .. [2] Morris, M.D., 1991. 
           Factorial Sampling Plans for Preliminary Computational Experiments. 
           Technometrics 33, 161–174. 
           https://doi.org/10.1080/00401706.1991.10484804

    .. [3] Campolongo, F., Cariboni, J., Saltelli, A., 2007. 
           An effective screening design for sensitivity analysis of large models. 
           Environmental Modelling & Software, Modelling, computer-assisted 
           simulations, and mapping of dangerous phenomena for 
           hazard assessment 22, 1509–1518. 
           https://doi.org/10.1016/j.envsoft.2006.10.004
    """
    if seed:
        np.random.seed(seed)

    _check_if_num_levels_is_even(num_levels)

    problem = _define_problem_with_groups(problem)

    sample_morris = _sample_morris(problem, N, num_levels)

    if optimal_trajectories:
        sample_morris = _compute_optimised_trajectories(problem, sample_morris,
                                                        N,
                                                        optimal_trajectories,
                                                        local_optimization)

    sample_morris = scale_samples(sample_morris, problem)

    return sample_morris