def test_Rbd_fast_with_NAN(): ''' Test if rbd_fast.analyze raise a ValueError when nan are passed in the Y values ''' problem, model_results, param_values = setup_samples() # Should raise a ValueError type of error with pytest.raises(ValueError): rbd_fast.analyze(problem, model_results, param_values)
def analyze_rbd_fast(self): # RBD-FAST - Random Balance Designs Fourier Amplitude Sensitivity Test return rbd_fast.analyze( self.sa_problem, self.samples_x, self.samples_y, print_to_console=self.options["print_to_console"])
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 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 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 _parallel_analyze(index, method, problem, samples, data, seed): if method == 'sobol': result = sobol.analyze(problem, data, calc_second_order=True, print_to_console=False, seed=seed) elif method == 'fast': result = fast.analyze(problem, data, print_to_console=False, seed=seed) elif method == 'rbd-fast': result = rbd_fast.analyze(problem, samples, data, print_to_console=False, seed=seed) elif method == 'morris': result = morris_analyze(problem, samples, data, print_to_console=False, seed=seed) elif method == 'delta': result = delta.analyze(problem, samples, data, print_to_console=False, seed=seed) elif method == 'dgsm': result = dgsm.analyze(problem, samples, data, print_to_console=False, seed=seed) elif method == 'frac': result = ff_analyze(problem, samples, data, second_order=True, print_to_console=False, seed=seed) else: return 0 for key in result.keys(): result[key] = result[key].tolist() with open('{:s}.json'.format(index), 'w') as outfile: json.dump(result, outfile) return 0
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 analyze(self): """Initiate the analysis, and stores the result at data directory. Generates: Analysis result at 'acbm/data/output/rbd_fast.txt'. """ X = latin.sample(self.problem, self.n_samples, seed=self.seed_sample) Y = ACBM.evaluate(X) si = rbd_fast.analyze(self.problem, X, Y, M=self.M, seed=self.seed_analyze) pickle.dump(si, open(self.path_output + 'rbd_fast.txt', 'wb'))
def _parallel_analyze(data): seed = int(opts['seed']) samples = population['problem', 'samples'] problem = population['problem', 'definition'] if opts['method'] == 'sobol': return sobol.analyze(problem, data, calc_second_order=True, print_to_console=False) elif opts['method'] == 'fast': return fast.analyze(problem, data, print_to_console=False, seed=seed) elif opts['method'] == 'rbd-fast': return rbd_fast.analyze(problem, samples, data, print_to_console=False, seed=seed) elif opts['method'] == 'morris': return morris_analyze(problem, samples, data, print_to_console=False, seed=seed) elif opts['method'] == 'delta': return delta.analyze(problem, samples, data, print_to_console=False, seed=seed) elif opts['method'] == 'dgsm': return dgsm.analyze(problem, samples, data, print_to_console=False, seed=seed) elif opts['method'] == 'frac': return ff_analyze(problem, samples, data, second_order=True, print_to_console=False, seed=seed) else: return 0
def salib_wrapper(problem, y_val, x, analysis_type='sobol', **kwargs): ''' Backend wrapper for sobol, fast and delta analysis. :meta private: ''' if analysis_type == 'sobol': return sobol.analyze(problem, y_val, **kwargs) elif analysis_type == 'fast': return fast.analyze(problem, y_val, **kwargs) elif analysis_type == 'delta': return delta.analyze(problem, x, y_val, **kwargs) elif analysis_type == 'rbd-fast': return rbd_fast.analyze(problem, x, y_val, **kwargs) else: raise Exception( 'Could not find analyzer. analysis_type must be sobol, fast, rbd-fast or delta.' )
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 sensitivity_analysis(self, force=False): """Run a RBD-fast sensitivity analysis and return the first order indices. Theses indices are not trustworthy if the number of samples are not large enough (which depend of the number of dimension and the non-linearity of the model), but can be used for parameters sorting. Arguments: inputs {np.array, (size, nvar)} output {np.array or list, (size,)} Returns: dict -- first order sensitivity indices """ if self.y.size < 60 and not force: raise ValueError("Too few samples for sensitivity analysis." " You will need extra samples for proper" " sensitivity analysis. Use force=True to" " override that behaviour.") S1 = rbd_fast.analyze(self._problem, self.y, self.X)["S1"] return dict( sorted([(var, idx) for var, idx in zip(self._vars, S1)], key=sort_by_values, reverse=True))
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)
def plot_convergence(x, y): """ Visualize the convergence of the sensitivity indices takes two arguments : x,y input and model output samples return plot of sensitivity indices wrt number of samples """ try: ninput = x.shape[1] except (ValueError, IndexError): ninput = x.size try: noutput = y.shape[1] except (ValueError, IndexError): noutput = y.size nsamples = x.shape[0] trials = (nsamples - 30) // 10 all_si_c = np.zeros((trials, ninput)) # ninput for i in range(30, nsamples, 10): modProblem = { 'num_vars': ninput, 'names': inputLabels, 'bounds': bounds } # all_si_c[(i-30)//10,:] = rbdfast(y[:i],x=x[:i,:])[1] res = rbd_fast.analyze(modProblem, x[:i], y[:i], M=10) all_si_c[((i - 30) // 10) - 1, ] = res['S1'] plt.plot([all_si_c[i].mean() for i in range(trials)]) # for i in range(trials): # plt.plot(all_si_c[i].mean(),'k-') plt.show() return
# get option txtinout = sys.argv[3].replace("__space__", " ") report_file = f"{txtinout}/perf_report.stb" par_performance = numpy.loadtxt(report_file) # load problem definition with open(f"{txtinout}/sens_def.stb", "rb") as f: sens_def = pickle.load(f) # Perform analysis if sensitivity_method == "RBD_FAST": with open(f"{txtinout}/sample_def.stb", "rb") as f: sample = pickle.load(f) Si = rbd_fast.analyze(sens_def, sample, par_performance, print_to_console=True) if sensitivity_method == "DMIM": with open(f"{txtinout}/sample_def.stb", "rb") as f: sample = pickle.load(f) Si = delta.analyze(sens_def, sample, par_performance, print_to_console=True) if sensitivity_method == "FAST": Si = fast.analyze(sens_def, par_performance, print_to_console=True) if sensitivity_method == "sobol": Si = sobol.analyze(sens_def, par_performance, print_to_console=False) # Save the first-order sensitivity indices numpy.savetxt(f"{txtinout}/s1_sensitivity.stb",
print("Sobol") #Inputs are prob,N_Yrs,Tropp,PT_d,PT_f,C_Vant,PTopp,inf,v,R,A_m,L_m,Mpv,g,MW_NaCl,csv_name #Tropp = 1 = transmission, 0 = no transmission #PTopp: 0 - no pretreatment, 1 - Draw Pretreatment, 2 = Feed pretreatment, 3 = feed and draw pretreatment Test = pse.comboUSA(param_values, N_Yrs, 0, Pt['MF'], Pt['MF'], C_Vant, 2, inf, v, R, M_geometry, g, MW_NaCl, csv_title_output) #%%#Run Analysis############################################################### Y = Test[ 'PV_net($)'].values #Currently, Y is set for Net Present Value. Can be changed as needed if method.lower() in ['fast']: Si = fast.analyze(problem, Y) #For Fourier Amplitude Sensitivity Test elif method.lower() in ['rbd']: Si = rbd_fast.analyze(problem, Y, param_values) #For RBD-FAST Method elif method.lower() in ['sobol']: Si = sobol.analyze(problem, Y) #For Sobol Method #Type: input the analysis type, e.g. "sobol" #Si = pse.SA_indices(problem,Si,Y,method,csv_title_SI) csv_title_SI_UC = "".join( (csv_title_SI, '_PV_net')) #Configured For net present value - change as needed Si_Var = pse.SA_indices(problem, Si, 'PV_net($)', method, csv_title_SI_UC, Notes, N_samples) #Placed at end so that files not unnecessarily generated for failed tests sys_in = pse.SAin(problem, param_values, csv_title_input) end = timer()
all_si_c[((i - 30) // 10) - 1, ] = res['S1'] plt.plot([all_si_c[i].mean() for i in range(trials)]) # for i in range(trials): # plt.plot(all_si_c[i].mean(),'k-') plt.show() return # inputsNum = inputs._get_numeric_data() inputLabels = noConsts.columns.tolist() inputLabels = list(map(delUnder, inputLabels)) X = noConsts.values plot_convergence(X, Y0) n, k = X.shape if len(Y0) == n: print("Inputs & Outputs agree in array length " + str(n)) else: print("Inputs & Outputs do not agree in array length") #Setup problem dictionary for SALib problem = {'num_vars': k, 'names': inputLabels, 'bounds': bounds} Si = rbd_fast.analyze(problem, X, Y0, M=10, print_to_console=True) Si.plot()
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('../../src/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, param_values, Y, print_to_console=True) # 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
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