def test_latin_sample_seed(): N, problem = problem_setup() sample1 = latin.sample(problem, N, seed=None) sample2 = latin.sample(problem, N, seed=123) np.testing.assert_equal(np.any(np.not_equal(sample1, sample2)), True)
def make_samples_for_row(row, model, fixed_parameters, parameter_bounds={}, analysis_type='sobol', N=1000, **kwargs): ''' Supporting function for sample_and_integrate. Do not run. row must be a pandas Series :meta private: ''' param_names = model['params'] base_value = row[param_names] to_permute = [p for p in param_names if p not in fixed_parameters] to_keep = [p for p in param_names if p in fixed_parameters] if parameter_bounds: bounds = np.array([parameter_bounds[p] for p in to_permute]) else: bounds = [[base_value[p] / 10, base_value[p] * 10] for p in to_permute] problem = { 'num_vars': len(to_permute), 'names': to_permute, 'bounds': bounds, } if analysis_type == 'sobol': new_values = saltelli.sample(problem, N, **kwargs) elif analysis_type == 'fast': new_values = fast_sampler.sample(problem, N, **kwargs) elif analysis_type == 'delta': new_values = latin.sample(problem, N) elif analysis_type == 'rbd-fast': new_values = latin.sample(problem, N) else: raise Exception( 'Could not find analyzer. analysis_type must be sobol, fast, rbd-fast or delta.' ) new_values = pd.DataFrame(new_values, columns=to_permute) fixed_parametersped_values = np.repeat( base_value[to_keep].values[np.newaxis, :], len(new_values), 0) samples = np.concatenate((new_values, fixed_parametersped_values), axis=1) samples = pd.DataFrame(samples, columns=to_permute + to_keep) samples = samples[param_names] return samples, problem
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
def test_regression_hdmr_case1(): problem = { 'num_vars': 5, 'names': ['x1', 'x2', 'x3', 'x4', 'x5'], 'bounds': [[0, 1] * 5] } X = latin.sample(problem, 10000) Y = linear_model_1.evaluate(X) options = { 'maxorder': 2, 'maxiter': 100, 'm': 2, 'K': 1, 'R': 10000, 'alpha': 0.95, 'lambdax': 0.01, 'print_to_console': False } Si = hdmr.analyze(problem, X, Y, **options) assert_allclose(Si['Sa'][0:problem['num_vars']], [0.20] * 5, atol=5e-2, rtol=1e-1) assert_allclose(Si['ST'][0:problem['num_vars']], [0.20] * 5, atol=5e-2, rtol=1e-1)
def fix_group_ranking(input_path, variable, output_path, samples, values, partial_order, index_product, problem, x_fix, x_fix_adjust, num_pce, seed, sample_range, product_uniform, filename): # Calculate the corresponding number of bootstrap with use of group_fix x_sample = latin.sample(problem, sample_range, seed=88).T np.savetxt(f'{output_path}metric_samples.txt', x_sample) # if reduce parameters, change samples if (variable.num_vars()) == 11: x_sample = adjust_sampling(x_sample, index_product, x_fix) conf_uncond, error_dict, pool_res, y_uncond = {}, {}, {}, {} rand = np.random.randint( 0, x_sample.shape[1], size=(500, x_sample.shape[1])) ci_bounds = [0.025, 0.975] import pickle approx_list_all = pickle.load( open(f'{output_path}{filename}-approx-list.pkl', "rb")) for key, value in partial_order.items(): print(key, value) #pce_list = [] pce_list = approx_list_all[key] num_pce = len(pce_list) cv_temp = np.zeros(num_pce) y_temp = np.zeros(shape=(num_pce, x_sample.shape[1])) _, sample_size = key.split('_')[0], int(key.split('_')[1]) #from pyapprox.utilities import get_random_k_fold_sample_indices print(f'------------Training samples: {sample_size}--------------') for i in range(num_pce): poly = pce_list[i] y_temp[i, :] = poly(x_sample).flatten() cv_temp[i] = np.sqrt(poly.variance())[0] / poly.mean()[0] y_uncond[key] = y_temp # Note Now this does not use the same cross validation folds # as used to build the PCE but this should be ok conf_uncond[key] = uncond_cal(y_uncond[key], ci_bounds, rand) conf_uncond[key]['cv'] = cv_temp[i].mean() conf_uncond[key]['cv_low'], conf_uncond[key]['cv_up'] = \ np.quantile(cv_temp, ci_bounds) error_dict[key], pool_res = group_fix( value, pce_list, x_sample, y_uncond[key], x_fix_adjust, rand, {}, file_exist=True) # End for # # separate confidence intervals into separate dicts and write results save_path = f'{output_path}{product_uniform}/' if not os.path.exists(save_path): os.mkdir(save_path) # convert the result into dataframe key_outer = list(error_dict.keys()) f_names = list(error_dict[key_outer[0]].keys()) for ele in f_names: dict_measure = {key: error_dict[key][ele] for key in key_outer} df = to_df(partial_order, dict_measure) df.to_csv(f'{save_path}/{ele}.csv') with open(f'{save_path}y_uncond_stats.json', 'w') as fp: json.dump(conf_uncond, fp, indent=2)
def prepare_sens_analysis(storm_name_list=[]): """ Function to prepare the sensitivity analysis for a country. Arguments: *storm_name_list* (list) -- list of storms to include in sensitivity analysis. If kept empty, default storms will be used. Returns: *param_values* (list) -- list of 5000 combinations of parameter values to be used in sensitivity analysis. *storm_name_list* (list) -- list of storms to include in sensitivity analysis. """ # set parameters for sensitivity analysis problem = { 'num_vars': 5, 'names': ['c2', 'c3', 'c4', 'lu1', 'lu2'], 'bounds': [[0, 100], [0, 100], [0, 100], [0, 50], [0, 50]] } param_values = latin.sample(problem, 5000) # rescale parameters for vulnerability curves (should add up to 100) rescale = param_values[:, :3] for i in range(len(rescale)): inb = (rescale[i] * 100) / sum(rescale[i]) param_values[i, :3] = inb # select storms to assess if len(storm_name_list) == 0: storm_name_list = [ '19991203', '19900125', '20090124', '20070118', '19991226' ] return param_values, storm_name_list
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 test_rbd_to_df(): params = ['x1', 'x2', 'x3'] problem = { 'num_vars': 3, 'names': params, 'groups': None, 'bounds': [[-3.14159265359, 3.14159265359], [-3.14159265359, 3.14159265359], [-3.14159265359, 3.14159265359]] } param_values = latin.sample(problem, 1000) Y = Ishigami.evaluate(param_values) Si = rbd_fast.analyze(problem, Y, param_values, print_to_console=False) Si_df = Si.to_df() assert isinstance(Si_df, pd.DataFrame), \ "RBD Si: Expected DataFrame, got {}".format(type(Si_df)) assert set(Si_df.index) == set(params), "Incorrect index in DataFrame" col_names = set(['S1']) assert set(Si_df.columns) == col_names, \ "Unexpected column names in DataFrame. Expected {}, got {}".format( col_names, Si_df.columns)
def test_regression_rbd_fast(): param_file = 'src/SALib/test_functions/params/Ishigami.txt' problem = read_param_file(param_file) param_values = latin.sample(problem, 10000) Y = Ishigami.evaluate(param_values) Si = rbd_fast.analyze(problem, param_values, Y, print_to_console=False) assert_allclose(Si['S1'], [0.31, 0.44, 0.00], atol=5e-2, rtol=1e-1)
def fit(self, X, y): """ Fits the regressor to the data `(X, y)` and performs a sensitivity analysis on the result of the regression. :param X: Training data :param y: Target values :return: `self` """ from numpy import argpartition N = len(X[0]) if (self.domain is None) or (self.probs is None): self._avg_fucn(X, y) if self.regressor is None: from sklearn.svm import SVR self.regressor = SVR() self.regressor.fit(self.domain, self.probs) bounds = [[ min(self.domain[:, idx]) - self.margin, max(self.domain[:, idx]) + self.margin ] for idx in range(N)] problem = dict(num_vars=N, names=['x%d' % idx for idx in range(N)], bounds=bounds) res = [] if self.method == 'sobol': from SALib.sample import saltelli from SALib.analyze import sobol param_values = saltelli.sample(problem, self.num_smpl) y_ = self.regressor.predict(param_values) res = sobol.analyze(problem, y_)['ST'] self.weights_ = res elif self.method == 'morris': from SALib.sample import morris as mrs from SALib.analyze import morris param_values = mrs.sample(problem, self.num_smpl, num_levels=self.num_levels) y_ = self.regressor.predict(param_values) res = morris.analyze(problem, param_values, y_, num_levels=self.num_levels)['mu_star'] self.weights_ = res elif self.method == 'delta-mmnt': from SALib.sample import latin from SALib.analyze import delta param_values = latin.sample(problem, self.num_smpl) y_ = self.regressor.predict(param_values) res = delta.analyze(problem, param_values, y_, num_resamples=self.num_resmpl)['delta'] self.weights_ = res self.top_features_ = argpartition( res, -self.n_features_to_select)[-self.n_features_to_select:] return self
def test_latin_sample_trivial(self): problem = {'num_vars': 1, 'bounds': [[0, 1]], 'names': ['var1']} actual = sample(problem, 10, seed=42) expected = np.array([[0.8601115], [0.27319939], [0.03745401], [0.60580836], [0.78661761], [0.97080726], [0.35986585], [0.19507143], [0.41560186], [0.51559945]]) np.testing.assert_allclose(actual, expected)
def RBD_FAST_analysis(network, num_samples, prob_def): print("Sampling via RBD-FAST...") samples = latin.sample(prob_def, num_samples) X = samples samples = np.split(samples, samples.shape[1], axis=1) samples = [s.squeeze() for s in samples] values = {n: torch.tensor(s) for n, s in zip(prob_def["names"], samples)} print("Running GrFN..") Y = network.run(values).numpy() print("Analyzing via RBD ...") return rbd_fast.analyze(prob_def, Y, X, print_to_console=True)
def populate(): # 'parameters' dictionary stores each line in the model par_keys = list(parameters.keys()) # init problem definiton seed = int(opts['seed']) levels = int(opts['p_levels']) problem = { 'names': opts['par_name'], 'num_vars': len(opts['par_name']), 'bounds': [], } # define bounds following the model configuration for line in range(len(par_keys)): if parameters[line][0] == 'par': if parameters[line][3] == 'range': lower = float(parameters[par_keys[line]][4]) upper = float(parameters[par_keys[line]][5]) if parameters[line][3] == 'factor': lower = float(parameters[line][2]) * ( 1 - float(parameters[par_keys[line]][4])) upper = float(parameters[line][2]) * ( 1 + float(parameters[par_keys[line]][5])) problem['bounds'].append([lower, upper]) # create samples to simulate if opts['method'] == 'sobol': models = saltelli.sample(problem=problem, N=levels, calc_second_order=True, seed=seed) elif opts['method'] == 'fast': models = fast_sampler.sample(problem=problem, N=levels, seed=seed) elif opts['method'] == 'rbd-fast' or opts['method'] == 'delta' or opts[ 'method'] == 'dgsm': models = latin.sample(problem=problem, N=levels, seed=seed) elif opts['method'] == 'morris': models = morris_sample(problem=problem, N=levels) elif opts['method'] == 'frac': models = ff_sample(problem, seed=seed) else: error_msg = 'Wrong method name.' print(error_msg) raise ValueError(error_msg) population = {} # add samples to population dict population['problem', 'samples'] = models # add problem definition to population dict population['problem', 'definition'] = problem return population
def analyze(self): """Initiate the analysis, and stores the result at data directory. Generates: Analysis result at 'acbm/data/output/delta.txt'. """ X = latin.sample(self.problem, self.n_samples, seed=self.seed_sample) Y = ACBM.evaluate(X) si = delta.analyze(self.problem, X, Y, seed=self.seed_analyze) pickle.dump(si, open(self.path_output + 'delta.txt', 'wb'))
def test_regression_delta(): param_file = 'src/SALib/test_functions/params/Ishigami.txt' problem = read_param_file(param_file) param_values = latin.sample(problem, 10000) Y = Ishigami.evaluate(param_values) Si = delta.analyze(problem, param_values, Y, num_resamples=10, conf_level=0.95, print_to_console=True) assert_allclose(Si['delta'], [0.210, 0.358, 0.155], atol=5e-2, rtol=1e-1) assert_allclose(Si['S1'], [0.31, 0.44, 0.00], atol=5e-2, rtol=1e-1)
def main(name, c): name = name.lower() model, par, parameters, bounds, samples_to_take = setups(name) problem = { 'num_vars': len(parameters), 'names': parameters, 'bounds': bounds } params = sample(problem, samples_to_take) # Create queues done = Queue() paramsdiv = [] p = [] remaining = 0 for i in range(0, PROC_NUM): x = params.shape[0] / PROC_NUM remaining += x - int(x) x = int(x) y = params[x * i:x * (i + 1), :] #filling the y with the x parameter sets if i == PROC_NUM - 1 and remaining != 0: y = np.append(y, params[-int(remaining):, :], axis=0) paramsdiv.append(y) p.append( Process(target=evaluate, args=(paramsdiv[i], model, par, c, done, i))) p[i].start() print(np.asarray(paramsdiv).shape) Ydiv = np.zeros(PROC_NUM).tolist() #no of processes count = 0 while True: temp, no = done.get() Ydiv[no] = temp.tolist() count += 1 if count == PROC_NUM: break Y = [] for i in range(0, PROC_NUM): Y += Ydiv[i] Y = np.asarray(Y) print(Y.shape) #Y = evaluate(params, model, par, c) write_file(Y, parameters, name, c, params)
def rbd_fast(self): """RBD-FAST sensitivity analysis of the objective function. This function estimates the sensitivity with the RBD-FAST method of the objective function with changes in the parameters using SALib: https://salib.readthedocs.io/en/latest/api.html#rbd-fast-random-balance-designs-fourier-amplitude-sensitivity-test Returns: dict: sensitivity values of parameters; dict has keys 'S1' """ X, y, problem = self._sensitivity_prep() n_sample = 2000 param_values = latin.sample(problem, n_sample) X_s, y_s = self._closest_points(problem, X, y, param_values) Si = rbd_fast.analyze(problem, X_s, y_s) return Si
def test_nonuniform_scale_samples_truncnorm(): """ Test the rescaling of samples for truncated normal distribution """ problem = { 'num_vars': 1, 'dists': ['truncnorm'], 'bounds': [[0, 3.14, 2, 1]], 'names': ['x1'] } actual = latin.sample(problem, 10, seed=42) expected = np.array([[2.68693037], [1.34115848], [0.39811064], [2.09477163], [2.49999031], [3.028063], [1.5564238], [1.11686499], [1.68414443], [1.9022482]]) np.testing.assert_allclose(actual, expected)
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))
def delta(self): """Morris Method sensitivity of the objective function. This function estimates the sensitivity with the Morris Method of the objective function with changes in the parameters using SALib: https://salib.readthedocs.io/en/latest/api.html#delta-moment-independent-measure Returns: dict: sensitivity values of parameters; dict has keys 'delta', 'delta_conf', 'S1', and 'S1_conf' """ X, y, problem = self._sensitivity_prep() n_sample = 2000 param_values = latin.sample(problem, n_sample) X_s, y_s = self._closest_points(problem, X, y, param_values) Si = delta.analyze(problem, X_s, y_s) return Si
def coupled_montecarlo_setup(smps=2, firstTimeStep=166): # Get and Save Latin Hypercube Matrix problem = get_problem() smps_matrix = latin.sample(problem, smps) # Normalized matrix (will be re-scaled by phd-model-process) saveLHSmatrix(smps_matrix) mc_upper = problem['upper'] for sample_nr in range(1, smps + 1): sample_vector = getInputVector(sample_nr - 1, smps_matrix) run_coupled_sample(sample_nr, firstTimeStep, sample_vector=sample_vector, mc_upper=mc_upper, couple=True, montecarlo_couple=True)
def redraw(self, random_method): problem = {'num_vars': 2, 'names': ['x', 'y'], 'bounds': [[0, 1]] * 2} if random_method == 'pseudo_random': seq = np.random.random((NUM_DATA_POINTS, 2)) elif random_method == 'sobol_sequence': seq = sobol_sequence.sample(NUM_DATA_POINTS, 2) elif random_method == 'saltelli': seq = saltelli.sample(problem, NUM_DATA_POINTS, calc_second_order=False) elif random_method == 'latin_hypercube': seq = latin.sample(problem, NUM_DATA_POINTS) elif random_method == 'finite_differences': seq = finite_diff.sample(problem, NUM_DATA_POINTS) elif random_method == 'fast': seq = fast_sampler.sample(problem, NUM_DATA_POINTS, M=45) self.random_draws[random_method] = seq
def fix_increase_sample(input_path, variable, output_path, samples, values, partial_order, index_product, problem, x_fix, x_fix_adjust, num_pce, seed, sample_range, product_uniform, filename): # if reduce parameters, change samples key = list(partial_order.keys())[0] _, sample_size = key.split('_') value = partial_order[key] import pickle approx_list_all = pickle.load( open(f'{output_path}{filename}-approx-list.pkl', "rb")) poly_list = [approx_list_all[key][0]] conf_uncond, error_dict, pool_res, y_uncond = {}, {}, {}, {} ci_bounds = [0.025, 0.975] nstart, nstop, nstep = sample_range for n in range(nstart, nstop + 1, nstep): print(n) x_sample = latin.sample(problem, n, seed=88) x_sample = x_sample.T # if reduce parameters, change samples if (variable.num_vars()) == 11: x_sample = adjust_sampling(x_sample, index_product, x_fix) # Calculate the corresponding number of bootstrap with use pf group_fix rand = np.random.randint(0, x_sample.shape[1], size=(500, x_sample.shape[1])) # add the calculation of y_uncond y_uncond_temp = poly_list[0](x_sample).T conf_uncond[str(n)] = uncond_cal(y_uncond_temp, ci_bounds, rand) conf_uncond[str(n)]['median'] = np.quantile(y_uncond_temp[0][rand], ci_bounds, axis=1).mean(axis=0).mean() conf_uncond[str(n)]['mean'] = poly_list[0].mean()[0] error_dict[str(n)], pool_res = group_fix(value, poly_list, x_sample, y_uncond_temp, x_fix_adjust, rand, {}, file_exist=True) # End for # separate confidence intervals into separate dicts and write results save_path = f'{output_path}{product_uniform}/' if not os.path.exists(save_path): os.mkdir(save_path) # convert the result into dataframe key_outer = list(error_dict.keys()) f_names = list(error_dict[key_outer[0]].keys()) for ele in f_names: dict_measure = {key: error_dict[key][ele] for key in key_outer} df = pd.DataFrame.from_dict(dict_measure) df.to_csv(f'{save_path}/{ele}_adaptive.csv') df_stats = pd.DataFrame(data=conf_uncond, index=np.arange(nstart, nstop + 1, nstep)) df_stats.to_csv(f'{save_path}/stats_uncond_adaptive.csv')
def test_latin_sample_two_groups(self): problem = { 'num_vars': 2, 'bounds': [[0, 1], [0, 1]], 'names': ['var1', 'var2'], 'groups': ['group1', 'group2'] } actual = sample(problem, 10, seed=42) expected = np.array([[0.17319939, 0.85247564], [0.50205845, 0.21559945], [0.4601115, 0.59699099], [0.83042422, 0.71834045], [0.03745401, 0.38661761], [0.7181825, 0.15986585], [0.68324426, 0.92912291], [0.30580836, 0.09507143], [0.21560186, 0.47080726], [0.9431945, 0.62123391]]) np.testing.assert_allclose(actual, expected)
def lhs_uniform_sample(num_vars, num_samples): """ Create uncorrelated uniform samples on the unit interval Parameters ---------- num_vars num_samples Returns ------- """ samples = lhs.sample( { 'num_vars': num_vars, 'bounds': [[0, 1] for i in range(num_vars)] }, num_samples) return samples
def test_latin_sample_no_groups(self): problem = { 'num_vars': 2, 'bounds': [[0, 1], [0, 1]], 'names': ['var1', 'var2'], 'groups': None } actual = sample(problem, 10, seed=42) expected = np.array([[0.86011150, 0.15247564], [0.27319939, 0.84560700], [0.03745401, 0.73663618], [0.60580836, 0.51394939], [0.78661761, 0.46118529], [0.97080726, 0.97851760], [0.35986585, 0.03042422], [0.19507143, 0.32912291], [0.41560186, 0.62921446], [0.51559945, 0.24319450]]) approx(actual, expected)
def test_regression_hdmr_ishigami(): param_file = 'src/SALib/test_functions/params/Ishigami.txt' problem = read_param_file(param_file) X = latin.sample(problem, 10000) Y = Ishigami.evaluate(X) options = { 'maxorder': 2, 'maxiter': 100, 'm': 4, 'K': 1, 'R': 10000, 'alpha': 0.95, 'lambdax': 0.01, 'print_to_console': False } Si = hdmr.analyze(problem, X, Y, **options) assert_allclose(Si['Sa'][0:problem['num_vars']], [0.31, 0.44, 0.00], atol=5e-2, rtol=1e-1) assert_allclose(Si['ST'][0:problem['num_vars']], [0.55, 0.44, 0.24], atol=5e-2, rtol=1e-1)
def sensitivity_analysis(self, N=1000, force=False): """Run a RBD-fast sensitivity analysis and return the first order indices. Keyword Arguments: N {int} -- number of sampled used to run the analysis (default: {1000}) Returns: dict -- first order sensitivity indices """ # noqa if self._expensive and not force: raise ValueError("sensitivity analysis should not be done on " "expensive function, but only on metamodel or " "test functions. Use force=True to override that " "behavior") X = latin.sample(self._problem, N) y = self(X) S1 = rbd_fast.analyze(self._problem, y, X)["S1"] return dict(sorted([(var, idx) for var, idx in zip(self.inputs, S1)], key=sort_by_values, reverse=True))
def sample(**kwargs): """ :param kwargs: dictionary containing the following parameters problem_file_path or -prob: path to a json that contains the problem with parameters and bounds, String n_samples or -n: the number of parameter samples that should be returned, :return: None """ n_samples = kwargs.get('n_samples') problem_file_path = kwargs.get('problem_file_path') if kwargs.get('output_file_name'): output_file_name = kwargs.get('output_file_name') else: output_file_name = 'hypercube.json' with open(problem_file_path) as json_file: problem = json.load(json_file) latin_hyper_cube = latin.sample(problem=problem, N=n_samples) latin_hyper_cube = latin_hyper_cube.tolist() # create list of problems with initial values problems = [] for pars in latin_hyper_cube: # transform the necessary parameters into integers for idx, p in enumerate(pars): if problem['integer'][idx]: pars[idx] = round(int(pars[idx])) new_problem = copy.deepcopy(problem) new_problem['initial'] = pars problems.append(new_problem) with open(output_file_name, 'w') as f: json.dump(problems, f) click.echo( 'Sampling {} samples done, check out the samples here: {}'.format( n_samples, output_file_name))
def random_sample(args): items = args.dimensions n = args.n f = NamedTemporaryFile(delete=False) for i in range(len(items)): f.write(str(i) + " 0.501 " + str(items[i] + 0.499) + "\n") f.close() # Read the parameter range file and generate samples problem = read_param_file(f.name) # Generate samples param_values = latin.sample(problem, n) param_rounded = [] for l in param_values: param_rounded.append([int(round(n, 0)) for n in l]) for i in param_rounded: print i
def sample_uniforms(model, num_samples=1000, log=[]): bounds = [] names = [] for name, tuple in model.parameter_distributions.items(): names.append(name) bounds.append(tuple) for name, tuple in model.species_distributions.items(): names.append(name) bounds.append(tuple) problem = {'num_vars': len(names), 'names': names, 'bounds': bounds} problem = salib_problem_to_log_space(problem, log) lhc_samples = latin.sample(problem, num_samples) lhc_samples = samples_to_normal_space(lhc_samples, problem, log) samples = parse_samples(lhc_samples, list(model.parameter_distributions.keys()), list(model.species_distributions.keys())) return samples
def test_rbd_to_df(): params = ['x1', 'x2', 'x3'] problem = { 'num_vars': 3, 'names': params, 'groups': None, 'bounds': [[-3.14159265359, 3.14159265359], [-3.14159265359, 3.14159265359], [-3.14159265359, 3.14159265359]] } param_values = latin.sample(problem, 1000) Y = Ishigami.evaluate(param_values) Si = rbd_fast.analyze(problem, param_values, Y, print_to_console=False) Si_df = Si.to_df() assert isinstance(Si_df, pd.DataFrame), \ "RBD Si: Expected DataFrame, got {}".format(type(Si_df)) assert set(Si_df.index) == set(params), "Incorrect index in DataFrame" col_names = set(['S1']) assert set(Si_df.columns) == col_names, \ "Unexpected column names in DataFrame. Expected {}, got {}".format( col_names, Si_df.columns)
import sys sys.path.append('../..') from SALib.analyze import rbd_fast from SALib.sample import latin 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 = latin.sample(problem, 1000) # 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 = rbd_fast.analyze(problem, Y, param_values, print_to_console=False) # Returns a dictionary with keys 'S1' and 'ST' # e.g. Si['S1'] contains the first-order index for each parameter, in the # same order as the parameter file
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