Example #1
0
    def _generate_samples(self, problemdef, savefile = None):
        """
            Generate a set of evenly-spaced Saltelli samples to use for variance analysis.
        """
        # Generate evenly-distributed samples within the defined parameter bounds using Saltelli Sampling
        if self.second_order == True:
            k = 2
        else:
            k = 1

        if savefile is not None:
            if os.path.isfile(savefile) is True:
                with open(savefile, 'w') as pf:
                    sample_list = pickle.load(savefile)
            else:
                # Generate the samples
                sample_list = saltelli.sample(problemdef, int(round(float(self.nsamples)/(k * problem['num_vars'] + 2))), calc_second_order = self.second_order)
                # Save the generated samples to a pickle file for later use
                with open(savefile, 'w') as pf:
                    pickle.dump(param_list, pf)
        else:
            # Generate the samples
                sample_list = saltelli.sample(problemdef, int(round(float(self.nsamples)/(k * problem['num_vars'] + 2))), calc_second_order = self.second_order)

        return sample_list
Example #2
0
def _hyper_params_create(second_order=True):
    problem = {'num_vars': 1, 'names': ['alpha'], 'bounds': [[0, 2]]}

    if second_order:  # includes second-order indices
        return saltelli.sample(problem,
                               1000)  # N * (2D + 2); here, N = 10, D = 3

    # excludes second-order indices
    return saltelli.sample(
        problem, 1000,
        calc_second_order=False)  # N * (D + 2); here, N = 10, D = 3
Example #3
0
def test_saltelli_sample_seed():

    N, problem = problem_setup()

    sample1 = saltelli.sample(problem,
                              N,
                              calc_second_order=False,
                              skip_values=1000)
    sample2 = saltelli.sample(problem,
                              N,
                              calc_second_order=False,
                              skip_values=1001)

    np.testing.assert_equal(np.any(np.not_equal(sample1, sample2)), True)
Example #4
0
 def _gen_muestrea(símismo, n, ops):
     if símismo.método == 'sobol':
         return saltelli.sample(problem=símismo.problema, N=n, **ops)
     elif símismo.método == 'fast':
         return fast_sampler.sample(problem=símismo.problema, N=n, **ops)
     elif símismo.método == 'morris':
         return morris_muestra.sample(problem=símismo.problema, N=n, **ops)
     elif símismo.método == 'dmim':
         return latin.sample(problem=símismo.problema, N=n)
     elif símismo.método == 'dgsm':
         return saltelli.sample(problem=símismo.problema, N=n)
     elif símismo.método == 'ff':
         return ff_muestra.sample(problem=símismo.problema)
     else:
         raise ValueError('Método de análisis de sensibilidad "{}" no reconocido.'.format(símismo.método))
Example #5
0
def sobol_analyze(model, X, logger, N=500000, **kwargs):
    ''' INPUT:
            ::model::  the NN that takes X as input,
            ::X:: a 2D vector of input [batch_size, feature_length] 
            ::N:: the analyze point size, see more detail in SALib
            ::**kwargs:: specify optional kwargs for 'sobel.analyze(**kwargs)'
        RETURN:  
            a dict of sobol importance analysis
        '''
    upper = X.max(axis=0)
    lower = X.min(axis=0)
    bounds = [[i, j] for i, j in zip(lower, upper)]
    for i in range(len(bounds)):
        if bounds[i][1] == 0:
            bounds[i][1] = 0.01
            break
    # print(bounds)
    all_feature_problem = {
        'num_vars': X.shape[1],
        'names': ['x' + str(i) for i in range(X.shape[1])],
        'bounds': bounds
    }
    logger.info("Generate feature samples")
    params_value = saltelli.sample(all_feature_problem, N)
    y_est = model.predict_batch(params_value).flatten()
    logger.info("Start analyze")
    result = sobol.analyze(all_feature_problem, y_est, **kwargs)

    return result
Example #6
0
def scatter_plot():
    n = 100
    mod = models['adequate']
    for param in param_bounds.keys():
        prob = {
            'num_vars': 1,
            'names': [param],
            'bounds': [param_bounds[param]]
        }
        par_sets = [p[0] for p in sampling_method.sample(prob, n)]
        solver = Solver(mod, t)
        res_sets = {out: [] for out in outputs['adequate']}
        for par_set in par_sets:
            pars = {p.name: p.value for p in mod.parameters}
            pars[param] = par_set
            solver.run(pars)
            for out in outputs['adequate']:
                res_sets[out].append(solver.yobs[out][-1])  # last result
        # Plot simulation results for the observables in the model
        pl.ion()
        pl.figure(figsize=(8, 8))
        for res in res_sets.keys():
            pl.scatter(par_sets, res_sets[res], label=res)
        pl.legend()
        pl.xlabel(param)
        pl.ylabel("Outputs")
        pl.savefig('scatterplots/' + param + '.png', dpi=300)
        pl.clf()
def SALib(result_title, input_title, bounds):
    num_vars = len(bounds[1]) + 1
    for i in range(len(result_title)):
        input_title.insert(0, result_title[i])
        print(input_title)
        new_bounds = bounds[1]
        new_bounds.insert(0, bounds[0][i])

        problem = {
            'num_vars': num_vars,
            'names': input_title,
            'bounds': new_bounds
        }

        # Generate samples
        param_values = saltelli.sample(problem, 1000)

        # Run model (example)
        Y = Ishigami.evaluate(param_values)

        # Perform analysis
        _ = sobol.analyze(problem, Y, print_to_console=True)

        del(input_title[0])
        del(new_bounds[0])
Example #8
0
def make_saltelli_samples(model,
                          salib_problem,
                          num_samples,
                          second_order=False,
                          log=[]):
    """
    Use SALib to make saltelli samples

    Args:
        model (Model): The model object
        salib_problem (dict): An SALib Problem
        num_samples (int): number of samples to take
        second_order (bool): look at second order interactions

    Returns:
        Samples from salib which have been parsed into a set of samples which run_all_models can take.

    """

    saltelli_samples = saltelli.sample(salib_problem,
                                       num_samples,
                                       calc_second_order=second_order)
    saltelli_samples = samples_to_normal_space(saltelli_samples, salib_problem,
                                               log)

    samples = parse_samples(saltelli_samples,
                            list(model.parameter_distributions.keys()),
                            list(model.species_distributions.keys()))

    return samples
Example #9
0
def get_saltelli_sample(
    problem: dict, n_saltelli: int, calc_second_order: bool = False
) -> pd.DataFrame:
    """Encapsulates Saltelli sampling function from SALib

    Parameters
    ----------
    problem: dict
        problem definition in SALib format (see problem.py)
    n_saltelli: int
        'N' parameter of SALib.sample.saltelli: The number of samples to
        generate
    calc_second_order: bool
        'calc_second_order' parameter of SALib.sample.saltelli:
        Option to compute second order Sobol indices

    Returns
    -------
    df_sample: pd.DataFrame
        dataframe of Saltelli samples
    """
    param_values = saltelli.sample(
        problem, n_saltelli, calc_second_order=calc_second_order
    )

    # Replace column names
    df_sample = pd.DataFrame(param_values, columns=problem["names"])

    return df_sample
def sample_parameters(problem: dict, seed: int, method: str):
    if method == "FAST":
        return fast_sampler.sample(problem, seed)
    if method == "sobol":
        return saltelli.sample(problem, seed)
    if (method == "RBD_FAST") or (method == "DMIM"):
        return latin.sample(problem, seed)
def d_analysis(d_eff_on=False):

    if d_eff_on:
        problem = {
            'num_vars': 4,
            'names': ['D', 'x', 'l', 'q'],
            'bounds': [[gfp, sa], [0, 50], [50, 100], [0, 10]]
        }

        def analytical(x, D, q, l):
            D = D_eff(D, q, l)
            t = 60
            return ((1 / np.sqrt(4 * np.pi * D * t)) *
                    np.exp(-((np.square(x)) / (4 * D * t))))
    else:

        problem = {
            'num_vars': 3,
            'names': ['D', 'q', 'l'],
            'bounds': [[gfp // 10, sa * 10], [0.001, 10], [25, 200]]
        }

        def analytical(x, D, t):
            return ((1 / np.sqrt(4 * np.pi * D * t)) *
                    np.exp(-((np.square(x)) / (4 * D * t))))

    param_values = saltelli.sample(problem, 10000)

    Y = np.array([analytical(*pv) for pv in param_values])

    return sobol.analyze(problem, Y, print_to_console=True)
Example #12
0
def _saltelli_sampling(n, doe_variables, seed):
    dim = len(doe_variables)
    N = int(n / (2 * dim + 2))
    problem = _define_salib_problem(doe_variables)
    points = saltelli.sample(problem, N, seed=seed)

    return points
Example #13
0
def main():
    problem = {
        'num_vars': 2,
        'names': ['a', 'b'],
        'bounds': [
            [0.0, 3.0],  #'bounds':[a,b], a<b
            [0.0, 1.0]
        ]
    }
    param_values = saltelli.sample(problem, 1, calc_second_order=True)
    #run model

    print param_values
    #Y = run_model(param_values)
    #Si = sobol.analyze(problem, Y, print_to_console=True)

    Y = np.empty([param_values.shape[0]])
    for i, XX in enumerate(param_values):
        #print i, XX[0],XX[1],1,0
        Y[i] = run_model(XX[0], XX[1], 1, 0)  #parallel run on HPC
        #Y[i] = run_model(XX(i,0), XX(i,1), 1, 0)

        print Y[i]
    Si = sobol.analyze(problem, Y, print_to_console=False)
    print Si['S1'], Si['ST']
def get_sampling_df(nr_samples=160):

    # STEP 1: Create samples with Sobol sequence using SALib
    parameter = problem_definition()

    param_values = saltelli.sample(parameter,
                                   int(nr_samples / 8),
                                   calc_second_order=True,
                                   seed=111)

    # Step 2: Make samples readable for suqc
    param_values = pd.DataFrame(param_values,
                                columns=["number_of_agents_mean", "p1", "p2"])
    param_values["number_of_agents_mean"] = round(
        param_values["number_of_agents_mean"], 0)

    # Step 2.1: Distribute number of agents at four sources and determine number of agents/(1 second)
    for x in [1, 2, 5, 6]:
        param_values[
            f"sources.[id=={x}].distributionParameters"] = param_values.apply(
                lambda row: [row.number_of_agents_mean * 0.01 / 4], axis=1)

    # Step 2.2: Add units
    param_values["*.hostMobile[*].app[1].messageLength"] = param_values.apply(
        lambda row: f"{int(row.p1)}B", axis=1)
    param_values["**wlan[*].radio.transmitter.power"] = param_values.apply(
        lambda row: f"{round(row.p2,2)}mW", axis=1)

    param_values = param_values.drop(columns=["p1", "p2"])
    return param_values
Example #15
0
    def sensitivity_analysis(self):
        female, relation, factors = self.sensitivity_analysis_detect_intervals(
            [15, 40, 90])
        factors_names = list(
            sorted(map(lambda k: 'factor_{}'.format(k), factors),
                   key=lambda k: int(k[7])))
        problem = {
            'num_vars':
            len(factors) + 2,
            'names': ['female', 'relation'] + factors_names,
            'bounds':
            [[female['min'], female['max']],
             [relation['min'], relation['max']]] + list(
                 map(lambda k: [factors[k]['min'], factors[k]['max']],
                     sorted(factors.keys())))
        }

        param_values = saltelli.sample(problem, 100)
        for year in [2010, 2020, 2050, 2100]:
            Y = self.sensitivity_analysis_evaluate(param_values, year)

            Si = sobol.analyze(problem, Y, print_to_console=False)
            print("__________________ {} __________________".format(year))
            print("")
            print(Si['S1'])
            print("")
Example #16
0
def generate_samples(problem, params, project_dir, method):
    """
    The Saltelli sampler generated 8000 samples. The Saltelli sampler generates N*(2D+2) samples, where in this
    example N is 1000 (the argument we supplied) and D is 3 (the number of model inputs).
    """

    if method == 'Saltelli':
        param_values = saltelli.sample(problem, params['samples'])
    elif method == 'FAST':
        param_values = fast_sampler.sample(problem, params['samples'])

    count = 0

    for i, X in enumerate(param_values):
        count += 1
        p, w, pred_fle = par.get_params(innate, X)
        _numpoints = 100
        t = [
            par._stoptime * float(i) / (_numpoints - 1)
            for i in range(_numpoints)
        ]
        w0 = innate.get_init(w, params)
        t, wsol = innate.solve(p, w0, t, params)
        APE_blood = []
        CH = []
        ACH = []
        for t1, w1 in zip(t, wsol):
            APE_blood.append(w1[1])
            CH.append(w1[10])
            ACH.append(w1[13])
        # Y_list.append(APE_blood)
        write_file(project_dir, method, APE_blood, 'AP')
        write_file(project_dir, method, CH, 'CH')
        write_file(project_dir, method, ACH, 'ACH')
        print(count, ' of ', len(param_values))
Example #17
0
def test_sobol_to_df():
    params = ['x1', 'x2', 'x3']
    problem = {'num_vars': 3, 'names': params, 'bounds': [[-np.pi, np.pi]] * 3}

    X = saltelli.sample(problem, 1000)
    Y = Ishigami.evaluate(X)
    Si = sobol.analyze(problem, Y, print_to_console=False)
    total, first, second = Si.to_df()

    assert isinstance(total, pd.DataFrame), \
        "Total Si: Expected DataFrame, got {}".format(type(total))
    assert isinstance(first, pd.DataFrame), \
        "First Si: Expected DataFrame, got {}".format(type(first))
    assert isinstance(second, pd.DataFrame), \
        "Second Si: Expected DataFrame, got {}".format(type(second))

    expected_index = set(params)
    assert set(total.index) == expected_index, \
        "Index for Total Si are incorrect"
    assert set(first.index) == expected_index, \
        "Index for first order Si are incorrect"
    assert set(second.index) == set([('x1', 'x2'),
                                     ('x1', 'x3'),
                                     ('x2', 'x3')]), \
        "Index for second order Si are incorrect"
Example #18
0
def setup_samples(N=500, calc_second_order=True):
    param_file = 'src/SALib/test_functions/params/Ishigami.txt'
    problem = read_param_file(param_file)
    param_values = saltelli.sample(problem,
                                   N=N,
                                   calc_second_order=calc_second_order)
    return problem, param_values
Example #19
0
def test_sample_saltelli_second():
    parameters = {
        'a': ap.IntRange(1, 2),
        'b': ap.Range(3, 3.5),
        'c': ap.Values(*'xyz'),
        'd': True
    }
    sample = ap.Sample(parameters,
                       n=2,
                       method='saltelli',
                       calc_second_order=True)

    problem = {
        'num_vars': 3,
        'names': ['a', 'b', 'c'],
        'bounds': [
            [1., 3.],
            [3., 3.5],
            [0., 3.],
        ]
    }
    param_values = saltelli.sample(problem, 2, calc_second_order=True)

    for s1, s2 in zip(sample, param_values):
        assert s1['a'] == int(s2[0])
        assert s1['b'] == s2[1]
        assert s1['c'] == parameters['c'].values[int(s2[2])]
        assert s1['d'] == parameters['d']
Example #20
0
    def redraw(self, random_method: str):
        """Redraw the random number with the given method

        :param random_method: the random method to use

        """
        problem = {
            "num_vars": self.num_dim,
            "names": list(range(self.num_dim)),
            "bounds": [[0, 1]] * self.num_dim,
        }
        if random_method == "pseudo_random":
            seq = np.random.random((self.bucket_size, 2))
        elif random_method == "sobol_sequence":
            seq = sobol_sequence.sample(self.bucket_size, 2)
        elif random_method == "saltelli":
            seq = saltelli.sample(problem, self.bucket_size, calc_second_order=False)
        elif random_method == "latin_hypercube":
            seq = latin.sample(problem, self.bucket_size)
        elif random_method == "finite_differences":
            seq = finite_diff.sample(problem, self.bucket_size)
        elif random_method == "fast":
            seq = fast_sampler.sample(problem, self.bucket_size, M=45)
        else:
            raise ValueError(f"Unknown random method {random_method}")
        self.random_draws[random_method] = seq
Example #21
0
    def sensitivityAnalysis(model, mlKind, dfInputData, config):
        problem = {
            'num_vars': len(config._featureList),
            'names': config._featureList,
            'bounds': []
        }
        for xcol in config._featureList:
            problem['bounds'].append([
                dfInputData[xcol].min() - 0.01, dfInputData[xcol].max() + 0.01
            ])
        # Generate samples
        XSample = saltelli.sample(problem, 1000)
        # Run model (example)
        Y = model.predict(XSample)
        Y = Y.reshape((Y.shape[0], ))
        print('Sensitivity_' + mlKind, XSample.shape, Y.shape)
        Si = sobol.analyze(problem, Y, print_to_console=False)

        from pandas import DataFrame
        feature_importances = [
            (feature, round(importance, 3))
            for feature, importance in zip(config._featureList, Si['ST'])
        ]
        # Sort the feature importances by most important first
        feature_importances = sorted(feature_importances,
                                     key=lambda x: x[1],
                                     reverse=True)
        df_feature_importances = DataFrame(feature_importances)
        df_feature_importances.columns = ['Feature', '敏感度' + mlKind]

        return df_feature_importances
Example #22
0
def analyse(model,n_samples):
    problem = {
        'num_vars': 5,
        'names': ['flow1', 'flow2', 'flow3', 'flow4', 'lost_time'],
        'bounds': [[0.0, 1.0],
                   [0.0, 1.0],
                   [0.0, 1.0],
                   [0.0, 1.0],
                   [0.0, 1.0],]
    }
    param_values = saltelli.sample(problem, n_samples)
    Y1 = np.zeros([param_values.shape[0]])
    Y2 = np.zeros([param_values.shape[0]])
    Y3 = np.zeros([param_values.shape[0]])
    Y4 = np.zeros([param_values.shape[0]])
    for i, X in enumerate(param_values):
        X = np.column_stack((X[0],X[1],X[2],X[3],X[4]))
        temp = model.predict(X)
        Y1[i] = temp[0][0]
        Y2[i] = temp[0][1]
        Y3[i] = temp[0][2]
        Y4[i] = temp[0][3]

    Si = sobol.analyze(problem, Y1)
    print('sensitivity analysis for phase split 1')
    print(Si['S1'])
    print(Si['ST'])
    print("x1-x2:", Si['S2'][0, 1])
    print("x1-x3:", Si['S2'][0, 2])
    print("x2-x3:", Si['S2'][1, 2])
    print("x3-x4:", Si['S2'][2, 3])

    Si = sobol.analyze(problem, Y2)
    print('sensitivity analysis for phase split 2')
    print(Si['S1'])
    print(Si['ST'])
    print("x1-x2:", Si['S2'][0, 1])
    print("x1-x3:", Si['S2'][0, 2])
    print("x2-x3:", Si['S2'][1, 2])
    print("x3-x4:", Si['S2'][2, 3])

    Si = sobol.analyze(problem, Y3)
    print('sensitivity analysis for phase split 3')
    print(Si['S1'])
    print(Si['ST'])
    print("x1-x2:", Si['S2'][0, 1])
    print("x1-x3:", Si['S2'][0, 2])
    print("x2-x3:", Si['S2'][1, 2])
    print("x3-x4:", Si['S2'][2, 3])

    Si = sobol.analyze(problem, Y4)
    print('sensitivity analysis for phase split 4')
    print(Si['S1'])
    print(Si['ST'])
    print("x1-x2:", Si['S2'][0, 1])
    print("x1-x3:", Si['S2'][0, 2])
    print("x2-x3:", Si['S2'][1, 2])
    print("x3-x4:", Si['S2'][2, 3])

    return True
Example #23
0
    def __init__(self):
        self.simulation = oc.simulation()
        self.simulation.data().setStartingPoint(0)
        self.simulation.data().setEndingPoint(3900)
        self.simulation.data().setPointInterval(1)
        self.constants = self.simulation.data().constants()
        self.constant_parameter_names = sorted(list(self.constants.keys()))

        for i in range(0, len(fit_parameters_exclude)):
            self.constant_parameter_names.remove(fit_parameters_exclude[i])

        self.model_constants = OrderedDict(
            {k: self.constants[k]
             for k in self.constant_parameter_names})

        # default the parameter bounds to something sensible, needs to be set directly
        bounds = []
        for c in self.constant_parameter_names:
            v = self.constants[c]
            bounds.append([bounds_dictionary[c][0], bounds_dictionary[c][1]])
        # define our sensitivity analysis problem
        self.problem = {
            'num_vars': len(self.constant_parameter_names),
            'names': self.constant_parameter_names,
            'bounds': bounds
        }
        self.samples = saltelli.sample(self.problem, num_samples)
        #print(self.samples)
        np.savetxt("self.samples.txt", self.samples)
Example #24
0
def test_sobol_to_df():
    params = ['x1', 'x2', 'x3']
    problem = {
        'num_vars': 3,
        'names': params,
        'bounds': [[-np.pi, np.pi]]*3
    }

    X = saltelli.sample(problem, 1000)
    Y = Ishigami.evaluate(X)
    Si = sobol.analyze(problem, Y, print_to_console=False)
    total, first, second = Si.to_df()

    assert isinstance(total, pd.DataFrame), \
        "Total Si: Expected DataFrame, got {}".format(type(total))
    assert isinstance(first, pd.DataFrame), \
        "First Si: Expected DataFrame, got {}".format(type(first))
    assert isinstance(second, pd.DataFrame), \
        "Second Si: Expected DataFrame, got {}".format(type(second))

    expected_index = set(params)
    assert set(total.index) == expected_index, \
        "Index for Total Si are incorrect"
    assert set(first.index) == expected_index, \
        "Index for first order Si are incorrect"
    assert set(second.index) == set([('x1', 'x2'),
                                     ('x1', 'x3'),
                                     ('x2', 'x3')]), \
        "Index for second order Si are incorrect"
Example #25
0
    def _generate_sample(self, n, sample_type, generate_pars):
        # create the array using the spacing method of choice
        raw_sample = None
        if sample_type == "sobol":
            from sobol_seq import i4_sobol_generate

            raw_sample = i4_sobol_generate(len(generate_pars), n)
        elif sample_type == "saltelli":
            from SALib.sample import saltelli

            problem = {
                "names": generate_pars,
                "bounds": [[0, 1] for x in generate_pars],
                "num_vars": len(generate_pars),
            }
            raw_sample = saltelli.sample(problem, n, True)

        elif sample_type == "grid":
            from sklearn.utils.extmath import cartesian

            temp = np.linspace(0, 1, n)
            raw_sample = cartesian([temp for i in range(len(generate_pars))])

        elif sample_type == "random":
            raw_sample = np.random.random((n, len(generate_pars)))
        assert raw_sample is not None, "something went wrong - check that type is correct"
        print("expected shape is {}".format(raw_sample.shape))
        # map the raw array to bounds, adhering to log scaling rules
        scaled_sample = self.log_scale_matrix(raw_sample)
        return scaled_sample
Example #26
0
    def sample(self, nobs, method='saltelli', seed=933090936):
        """
        Generate the random parameter values using SALib

        Parameters
        ----------
        nobs: int, required 
            Number of sample realizations 
        method: string, optional 
            The sampling method, default saltelli
        seed : int, optional
            The random seed

        Returns
        -------
        A NumPy matrix containing the model inputs using Saltelli's sampling
        scheme. The resulting matrix has size of N * D, where D is the 
        number of parameters.  
        """    
        
        sampling_methods_allowed = ['saltelli']
        if method.lower() not in sampling_methods_allowed:
            raise ValueError('Sampling method not supported: choose one of %s' 
                             %', '.join(sampling_methods_allowed))
            
        nvars = len(self.pars['names'])
        problem = self.pars.copy()
        problem['num_vars'] = nvars
        
        if method.lower()=='saltelli':
            from SALib.sample import saltelli
            values = saltelli.sample(problem, nobs, seed=seed, 
                                     calc_second_order=False)[::nvars + 2, :]
        
        return values
Example #27
0
def generate_samples(sp, n_runs, VPD=2.0, tmax=180):
    var_vals = [traits[sp][get_part(v)][v] for v in var_names[:-1]]
    var_vals.extend([Rmax])
    problem_bounds = [[min(0.5 * v, 2.0 * v),
                       max(0.5 * v, 2.0 * v)] for v in var_vals]
    #     problem_bounds = [[min(0.25*v,4.0*v), max(0.25*v,4.0*v)] for v in var_vals]
    problem = {
        'num_vars': n_vars,
        'names': var_names,
        'bounds': problem_bounds
    }
    # generate samples
    param_values = saltelli.sample(problem, n_runs, calc_second_order=False)
    print len(param_values)
    ''' parallel processing '''
    ncores = mp.cpu_count()
    print('There are %s cores on this machine ' % (str(ncores), ))
    pool = mp.Pool()
    param_cores = np.array_split(param_values, ncores, axis=0)
    param_augmented = [(p, VPD, tmax) for p in param_cores]
    Y_pooled = pool.map(evaluate_model, param_augmented)
    Y = np.vstack(Y_pooled)  # output shape (len(param_values), 2)

    with open(
            '/Users/xuefeng/Dropbox/Projects/Isohydricity/Sobol/Si_' + sp +
            '_vpd' + str(int(VPD)) + '_tmax' + str(tmax) + '_outcomes.pickle',
            'wb') as handle:
        pickle.dump(Y, handle)
    with open(
            '/Users/xuefeng/Dropbox/Projects/Isohydricity/Sobol/Si_' + sp +
            '_vpd' + str(int(VPD)) + '_tmax' + str(tmax) + '_params.pickle',
            'wb') as handle:
        pickle.dump(param_values, handle)
    return Y, param_values
 def ranges_adjust(Nsamples=Nsamples):
     sample_range_change = np.round(
         saltelli.sample(problem_adjust,
                         N=Nsamples,
                         calc_second_order=False,
                         seed=121), 4)
     return sample_range_change
Example #29
0
def generate_spectra(sample_number=10000,
                     bounds='../assets/prosail_param_bounds.txt',
                     save_to_npy=False,
                     spectra_save='../data/spectra.npy',
                     params_save='../data/params.npy',
                     params_norm_save='../data/params_norm.npy'):
    param_dimension = 15
    wavelength_start = 400
    wavelength_end = 2500
    wavelength_num = wavelength_end - wavelength_start + 1

    problem = read_param_file(bounds)
    params = saltelli.sample(problem, sample_number)
    params_norm = params.copy()

    num = sample_number * (param_dimension + 1) * 2
    cores = multiprocessing.cpu_count()
    pool = multiprocessing.Pool(processes=cores)
    spec = pool.map(generate_spectrum, params)
    spec = np.array(spec).reshape(num, 2101)

    for i in range(num):
        p = params[i]
        for j in range(param_dimension):
            params_norm[i][j] = (p[j] - problem['bounds'][j][0]) / (
                problem['bounds'][j][1] - problem['bounds'][j][0])

    if save_to_npy:
        np.save(spectra_save, spec)
        np.save(params_save, params)

    return spec, params, params_norm
def runModelManyTimes(parameters, scaling_factor):
    # Collect problem parameters, names, and bounds
    problem = problemParameters(parameters, scaling_factor)

    # Generate samples
    param_values = saltelli.sample(problem, 100)

    # Create empty array of same shape to store values
    Y = np.zeros([param_values.shape[0]])

    print(Y.shape)

    # Store results of model in Y array
    for i, option in enumerate(param_values):

        # Put parameters back into dictionary needed for duct model function
        option = dict()
        for j, parameter in enumerate(problem['names']):
            var_dict = dict()
            var_dict[parameter] = dict()
            var_dict[parameter]['Value'] = param_values[i][j]
            option[parameter] = var_dict[parameter]

        # Store peak bicarbonate secretion as measure of model performance
        Y[i] = np.max(runBaseModel(option)['bl'])

        print(i, Y[i])

    return problem, Y
Example #31
0
File: sens.py Project: ngc436/DMM
def sensitivity(fertility, ratio, x1, x14, x18, x28, x41):
    model = init_model()
    problem = {
        'num_vars':
        7,
        'names':
        ['fertility', 'babies_fraction', 'x1', 'x14', 'x18', 'x28', 'x41'],
        'bounds': [[fertility["min"], fertility["max"]],
                   [ratio['min'], ratio['max']], [x1['min'], x1['max']],
                   [x14['min'], x14['max']], [x18['min'], x18['max']],
                   [x28['min'], x28['max']], [x41['min'], x41['max']]]
    }

    params = sample(problem, 10)
    years = [i for i in range(2005, 2106, 5)]

    simulated_population = []

    for year in years:
        print("YEAR: ", year)
        population = eval(model, params, year)
        population = population.flatten()
        simulated_population.append(population)
        # si = sobol.analyze(problem, population, print_to_console=False)
        # vis.sensitivity_analysis(si, problem['names'], year)
        # vis.sensitivity_analysis(si, problem['names'], year, num=1)
    max_population = [max(i) for i in simulated_population]
    min_population = [min(i) for i in simulated_population]
    avg_population = [np.mean(i) for i in simulated_population]
    vis.uncertainty_plot(min_population, max_population, avg_population, years)
Example #32
0
def create_data(problem, new_path):
    """
    problem : dict with specified input variables and range instead of discrete values otherwise saltelli will not work

    Run each batch iterations with all the samples obtained from saltelli and save at the end of the run

    Saves data with time stamp as .csv and .pickle
    """

    # Set the repetitions, the amount of steps, and the amount of distinct values per variable
    replicates = 10
    max_steps = 100
    distinct_samples= 10

    # Define output parameters
    model_reporters = {
        'step_data': lambda m: m.datacollector.get_model_vars_dataframe(),
        'obstacle_density': lambda m: m.obstacle_density,
        'food_density': lambda m: m.food_density,
        'nr_hives': lambda m: m.nr_hives
    }

    data = {}

    # Sample from data with every interactions, computationally expensive but gives all combinations
    params_values = saltelli.sample(problem,N=distinct_samples)


    #transform to int value and overwrite array if copy needed set flag to True
    params_values = params_values.astype(int, copy=False)


    batch = BatchRunnerMP(BeeForagingModel,
                        nr_processes=os.cpu_count(),
                        max_steps=max_steps,
                        variable_parameters={val:[] for val in problem['names']},
                        model_reporters=model_reporters,
                         display_progress=True)
    counter = 0

    # progress bar
    pbar = tqdm(total=len(params_values))
    for _  in range(replicates):
        for values in params_values:
            var_parameters = {}

            # #collect all data samples from salteli sampling
            for n, v, in zip(problem['names'],values):

                var_parameters[n] = v
            batch.run_iteration(var_parameters, tuple(values),counter)
            counter +=1
            pbar.update(counter)
    pbar.close()
    data = batch.get_model_vars_dataframe()

    data.to_csv(f'pickles/analysis_{new_path}.csv')
    data.to_pickle(f'pickles/analysis_{new_path}.p')
    return data
Example #33
0
def test_regression_sobol():
    param_file = 'SALib/test_functions/params/Ishigami.txt'
    problem = read_param_file(param_file)
    param_values = saltelli.sample(problem, 10000, calc_second_order=True)

    Y = Ishigami.evaluate(param_values)

    Si = sobol.analyze(problem, Y,
                       calc_second_order=True, conf_level=0.95, print_to_console=False)

    assert_allclose(Si['S1'], [0.31, 0.44, 0.00], atol=5e-2, rtol=1e-1)
    assert_allclose(Si['ST'], [0.55, 0.44, 0.24], atol=5e-2, rtol=1e-1)
    assert_allclose([Si['S2'][0][1], Si['S2'][0][2], Si['S2'][1][2]], [0.00, 0.25, 0.00], atol=5e-2, rtol=1e-1)
Example #34
0
def test_regression_sobol_groups():
    problem = {
      'num_vars': 3, 
      'names': ['x1', 'x2', 'x3'], 
      'bounds': [[-np.pi, np.pi]]*3,
      'groups': ['G1', 'G2', 'G1']
    }
    param_values = saltelli.sample(problem, 10000, calc_second_order=True)

    Y = Ishigami.evaluate(param_values)
    Si = sobol.analyze(problem, Y,
                       calc_second_order=True, parallel=True, conf_level=0.95, print_to_console=False)

    assert_allclose(Si['S1'], [0.55, 0.44], atol=5e-2, rtol=1e-1)
    assert_allclose(Si['ST'], [0.55, 0.44], atol=5e-2, rtol=1e-1)
    assert_allclose(Si['S2'][0][1], [0.00], atol=5e-2, rtol=1e-1)
 def perform_analsis(self, n=10, **kwds):
     """Perform Sobol sensitivity analysis with SALib methods
     
     **Arguments**:
         - *n* = int : number of sobol iterations (default: 10)
         
     **Optional keywords**:
         - *calc_second_order* = bool : second order stats (default: True)
     """
     calc_second_order = kwds.get("calc_second_order", True)
     # freeze base stats
     self.freeze()
     # import SALib method
     from SALib.sample import saltelli
     from SALib.analyze import sobol
     # create temporary parameter file
     param_file = "params_file_tmp.txt"
     self.create_params_file(filename = param_file)
     # perform sampling
     self.param_values = saltelli.sample(10, param_file, calc_second_order = calc_second_order)
     # calculate distances - compute intensive step!
     self.distances = self.determine_distances()
     # save results
     results_file = 'dist_tmp.txt'
     np.savetxt(results_file, self.distances, delimiter=' ')
     # perform sobol analysis
     Si = sobol.analyze(param_file, results_file, 
                        column = 0, 
                        conf_level = 0.95,
                        calc_second_order = calc_second_order, 
                        print_to_console=False)
     # create composite matrix for sensitivities
     n_params = len(self.param_stats)
     self.comp_matrix = np.ndarray(shape = (n_params,n_params))
     for j in range(n_params):
         for i in range(n_params):
             if i == j:
                 self.comp_matrix[i,j] = Si['S1'][i]
             else:
                 self.comp_matrix[i,j] = Si['S2'][i,j]
                 self.comp_matrix[j,i] = Si['S2'][i,j]
                 
     # remove temporary files
     import os
     os.remove(results_file)
     os.remove(param_file)
Example #36
0
def test_Sobol_G_using_sobol():
    '''
    Tests the accuracy of the Sobol/Saltelli procedure using the Sobol_G
    test function, comparing the results from the Sobol/Saltelli analysis
    against the analytically computed sensitivity index from the Sobol_G
    function.
    '''
    problem = {'num_vars': 6,
               'names': ['x1', 'x2', 'x3', 'x4', 'x5', 'x6'],
               'bounds': [[0, 1], [0, 1], [0, 1], [0, 1],[0, 1], [0, 1]]}
    N = 5000
    a = np.array([78, 12, 0.5, 2, 97, 33])
    param_values = saltelli.sample(problem, N, calc_second_order=False)
    model_results = Sobol_G.evaluate(param_values, a)
    Si = sobol.analyze(problem, model_results, calc_second_order=False)
#     expected = Sobol_G.total_sensitivity_index(a)
#     assert_allclose(Si['ST'], expected)
    expected = Sobol_G.sensitivity_index(a)
    assert_allclose(Si['S1'], expected, atol=1e-2, rtol=1e-6)
Example #37
0
def setup_samples(N = 500, calc_second_order = True):
    param_file = 'SALib/test_functions/params/Ishigami.txt'
    problem = read_param_file(param_file)
    param_values = saltelli.sample(problem, N=N, calc_second_order=calc_second_order)
    return problem,param_values
Example #38
0
def sa(model, response, policy={}, method="sobol", nsamples=1000, **kwargs):
    if len(model.uncertainties) == 0:
        raise ValueError("no uncertainties defined in model")
    
    problem = { 'num_vars' : len(model.uncertainties),
                'names' : model.uncertainties.keys(),
                'bounds' : [[0.0, 1.0] for u in model.uncertainties],
                'groups' : kwargs.get("groups", None) }

    # estimate the argument N passed to the sampler that produces the requested
    # number of samples
    N = _predict_N(method, nsamples, problem["num_vars"], kwargs)
    
    # generate the samples
    if method == "sobol":
        samples = saltelli.sample(problem, N, **_cleanup_kwargs(saltelli.sample, kwargs))
    elif method == "morris":
        samples = morris_sampler.sample(problem, N, **_cleanup_kwargs(morris_sampler.sample, kwargs))
    elif method == "fast":
        samples = fast_sampler.sample(problem, N, **_cleanup_kwargs(fast_sampler.sample, kwargs))
    elif method == "ff":
        samples = ff_sampler.sample(problem, **_cleanup_kwargs(ff_sampler.sample, kwargs))
    elif method == "dgsm":
        samples = finite_diff.sample(problem, N, **_cleanup_kwargs(finite_diff.sample, kwargs))
    elif method == "delta":
        if "samples" in kwargs:
            samples = kwargs["samples"]
        else:
            samples = latin.sample(problem, N, **_cleanup_kwargs(latin.sample, kwargs))
            
    # convert from samples in [0, 1] to uncertainty domain
    for i, u in enumerate(model.uncertainties):
        samples[:,i] = u.ppf(samples[:,i])
        
    # run the model and collect the responses
    responses = np.empty(samples.shape[0])
    
    for i in range(samples.shape[0]):
        sample = {k : v for k, v in zip(model.uncertainties.keys(), samples[i])}
        responses[i] = evaluate(model, overwrite(sample, policy))[response]
    
    # run the sensitivity analysis method
    if method == "sobol":
        result = sobol.analyze(problem, responses, **_cleanup_kwargs(sobol.analyze, kwargs))
    elif method == "morris":
        result = morris_analyzer.analyze(problem, samples, responses, **_cleanup_kwargs(morris_analyzer.analyze, kwargs))
    elif method == "fast":
        result = fast.analyze(problem, responses, **_cleanup_kwargs(fast.analyze, kwargs))
    elif method == "ff":
        result = ff_analyzer.analyze(problem, samples, responses, **_cleanup_kwargs(ff_analyzer.analyze, kwargs))
    elif method == "dgsm":
        result = dgsm.analyze(problem, samples, responses, **_cleanup_kwargs(dgsm.analyze, kwargs))
    elif method == "delta":
        result = delta.analyze(problem, samples, responses, **_cleanup_kwargs(delta.analyze, kwargs))
         
    # convert the SALib results into a form allowing pretty printing and
    # lookups using the parameter name
    pretty_result = SAResult(result["names"] if "names" in result else problem["names"])
    
    if "S1" in result:
        pretty_result["S1"] = {k : float(v) for k, v in zip(problem["names"], result["S1"])}
    if "S1_conf" in result:
        pretty_result["S1_conf"] = {k : float(v) for k, v in zip(problem["names"], result["S1_conf"])}
    if "ST" in result:
        pretty_result["ST"] = {k : float(v) for k, v in zip(problem["names"], result["ST"])}
    if "ST_conf" in result:
        pretty_result["ST_conf"] = {k : float(v) for k, v in zip(problem["names"], result["ST_conf"])}
    if "S2" in result:
        pretty_result["S2"] = _S2_to_dict(result["S2"], problem)
    if "S2_conf" in result:
        pretty_result["S2_conf"] = _S2_to_dict(result["S2_conf"], problem)
    if "delta" in result:
        pretty_result["delta"] = {k : float(v) for k, v in zip(problem["names"], result["delta"])}
    if "delta_conf" in result:
        pretty_result["delta_conf"] = {k : float(v) for k, v in zip(problem["names"], result["delta_conf"])}
    if "vi" in result:
        pretty_result["vi"] = {k : float(v) for k, v in zip(problem["names"], result["vi"])}
    if "vi_std" in result:
        pretty_result["vi_std"] = {k : float(v) for k, v in zip(problem["names"], result["vi_std"])}
    if "dgsm" in result:
        pretty_result["dgsm"] = {k : float(v) for k, v in zip(problem["names"], result["dgsm"])}
    if "dgsm_conf" in result:
        pretty_result["dgsm_conf"] = {k : float(v) for k, v in zip(problem["names"], result["dgsm_conf"])}
    if "mu" in result:
        pretty_result["mu"] = {k : float(v) for k, v in zip(result["names"], result["mu"])}
    if "mu_star" in result:
        pretty_result["mu_star"] = {k : float(v) for k, v in zip(result["names"], result["mu_star"])}
    if "mu_star_conf" in result:
        pretty_result["mu_star_conf"] = {k : float(v) for k, v in zip(result["names"], result["mu_star_conf"])}
    if "sigma" in result:
        pretty_result["sigma"] = {k : float(v) for k, v in zip(result["names"], result["sigma"])}

    return pretty_result
Example #39
0
def gen_params(num_vars, names, bounds, n, save_loc, second_ord=True):
    """
    Generate the parameter sets for the Sobol sensitivity analysis.
    Saves a file with the information required for the analysis
    that will be performed later.

    Parameters
    -----------
    num_vars   : int
                 the number of parameters you will vary.
    names      : list
                 list of strings with the names of the parameters
    bounds     : list
                 list of lists, where each inner list contains the
                 upper and lower bounds for a given parameter.
    n          : int
                 number of initial samples to generate from
                 the pseudo-random Sobol sequence. n parameter sets
                 will be generated using the Sobol sequence, then the
                 Saltelli cross-sampling method will be applied to give a
                 total of 2n(p+1) parameter sets to be run if second_ord =
                 True.
    save_loc   : str
                 path to the directory where you would like to save the
                 parameters.
    second_ord : bool, optional
                 a boolean to indicate whether or not to calculate second
                 order sensitivity indices.  If False, only 1st and total
                 order indices will be calculated and n(p+2) parameter sets
                 will be generated.

    Returns
    --------
    param_sets : numpy ndarray
         an ndarray where each row is one set of parameter
         values.  You must run your model (in whatever environment
         is appropriate) with each of the sets of parameters from
         this array.  The output must be stored in the same order
         as given in this parameter set array (one row of results
         for each row of parameters).
    """
    # Check that num_vars is an integer
    if not isinstance(num_vars, int):
        raise TypeError('num_vars must be an integer')
    # Check that bounds are specified for every variable
    if num_vars != len(bounds):
        raise ValueError('bounds must be same length as num_vars')
    # Check that a name is given for every parameter
    if num_vars != len(names):
        raise ValueError('length of `names` must equal num_vars')

    problem = {'num_vars': num_vars, 'names': names, 'bounds': bounds}
    param_sets = saltelli.sample(problem, n, calc_second_order=second_ord)

    if second_ord:
        print '%s simulations will be run' % (2*n * (problem['num_vars'] + 1))
    elif second_ord is False:
        print '%s simulations will be run' % (n * (problem['num_vars'] + 2))

    # Write the problem description to a file (required to run the analysis
    # after your model has been run with all the generated parameter sets)
    body = ''
    for i, name in enumerate(problem['names']):
        body += '%s %s %s\n' % (name, problem['bounds'][i][0],
                                problem['bounds'][i][1])
    with open(save_loc+'/saparams_%s-parameters_%s-n.txt'
              % (num_vars, n), 'wb') as params:
        params.write(body)

    return param_sets
Example #40
0
import sys
sys.path.append('../..')

from SALib.analyze import sobol
from SALib.sample import saltelli
from SALib.test_functions import Ishigami
from SALib.util import read_param_file


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

# Generate samples
param_values = saltelli.sample(problem, 1000, calc_second_order=True)

# Run the "model" and save the output in a text file
# This will happen offline for external models
Y = Ishigami.evaluate(param_values)

# Perform the sensitivity analysis using the model output
# Specify which column of the output file to analyze (zero-indexed)
Si = sobol.analyze(problem, Y, calc_second_order=True, conf_level=0.95, print_to_console=True)
# Returns a dictionary with keys 'S1', 'S1_conf', 'ST', and 'ST_conf'
# e.g. Si['S1'] contains the first-order index for each parameter, in the same order as the parameter file
# The optional second-order indices are now returned in keys 'S2', 'S2_conf'
# These are both upper triangular DxD matrices with nan's in the duplicate
# entries.
Example #41
0
 def sample(self, problem, size):
     return saltelli.sample(problem, size,
                            calc_second_order=self.second_order)
Example #42
0
import random as rd

# Example: Run Sobol, Morris, or FAST on a test function (Sobol G Function)
# The parameters shown for each method are also the default values if omitted

# 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=' ')
sys.dont_write_bytecode = True

from SALib.sample import saltelli, morris_oat, fast_sampler
from SALib.analyze import sobol, morris, extended_fast
from SALib.test_functions import Sobol_G, Ishigami
from SALib.util import scale_samples, read_param_file
import numpy as np
import random as rd
from ucav_design_1 import DesignFormulation

np.random.seed(10)

param_file = 'ucav_sensitivity_input.txt'
pf = read_param_file(param_file)

param_values = saltelli.sample(25, pf['num_vars'], calc_second_order = False)


scale_samples(param_values, pf['bounds'])


ac = DesignFormulation()
ac.load_xls('Baseline1')
ac.setup()

Y = np.zeros([len(param_values),9])
fid = open('SGOutput2.txt','wt')
fid.close()
for i,param in enumerate(param_values):
    out = ac.run_full_analysis(param)
    Y[i] = out