From 8a1981b20c6fc1280e8deebebb801b1bdb3ed542 Mon Sep 17 00:00:00 2001 From: Will Usher Date: Tue, 30 Jun 2015 18:43:23 +0100 Subject: [PATCH 1/7] Test and code for fractional factorial sampling --- SALib/sample/ff.py | 41 +++++++++++++++++++++++++++++++++++++++++ SALib/tests/test_ff.py | 38 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 79 insertions(+) create mode 100644 SALib/sample/ff.py create mode 100644 SALib/tests/test_ff.py diff --git a/SALib/sample/ff.py b/SALib/sample/ff.py new file mode 100644 index 00000000..c8aaaf8e --- /dev/null +++ b/SALib/sample/ff.py @@ -0,0 +1,41 @@ +''' +Created on 30 Jun 2015 + +@author: will2 +''' + +from scipy.linalg import hadamard +import numpy as np +from . import common_args +from ..util import scale_samples, read_param_file + +def sample(problem): + + num_vars = problem['num_vars'] + + # Find the smallest n, such that num_vars < k + k = [2 ** n for n in range(16)] + k_chosen = 2**(np.argmax(num_vars < np.array(k)) - 1) + dummy_vars = k_chosen - num_vars + + # Generate the sample + sample = np.vstack([hadamard(k_chosen), -hadamard(k_chosen)]) + + sample = np.array((sample + 1.) / 2, dtype=np.float) + + scale_samples(sample, problem['bounds']) + + return sample + + +if __name__ == "__main__": + + parser = common_args.create() + args = parser.parse_args() + + problem = read_param_file(args.paramfile) + param_values = sample(problem, args.samples, args.levels, \ + args.grid_jump, args.k_optimal) + + np.savetxt(args.output, param_values, delimiter=args.delimiter, + fmt='%.' + str(args.precision) + 'e') diff --git a/SALib/tests/test_ff.py b/SALib/tests/test_ff.py new file mode 100644 index 00000000..9685be51 --- /dev/null +++ b/SALib/tests/test_ff.py @@ -0,0 +1,38 @@ +''' +Created on 30 Jun 2015 + +@author: will2 +''' +from numpy.testing import assert_equal +from SALib.sample import ff +import numpy as np +from scipy.linalg import hadamard + +def test_ff_sample(): + problem = {'bounds': [[0., 1.], [0., 1.], [0., 1.], [0., 1.]], + 'num_vars': 4} + actual = ff.sample(problem) + expected = np.array([[ 1, 1, 1, 1], + [ 1, 0, 1, 0], + [ 1, 1, 0, 0], + [ 1, 0, 0, 1], + [0, 0, 0, 0], + [0, 1, 0, 1], + [0, 0, 1, 1], + [0, 1, 1, 0]]) + assert_equal(actual, expected) + + +def test_ff_sample_scaled(): + problem = {'bounds': [[0., 2.5], [0., 1.], [0., 1.], [0., 1.]], + 'num_vars': 4} + actual = ff.sample(problem) + expected = np.array([[ 2.5, 1, 1, 1], + [ 2.5, 0, 1, 0], + [ 2.5, 1, 0, 0], + [ 2.5, 0, 0, 1], + [0, 0, 0, 0], + [0, 1, 0, 1], + [0, 0, 1, 1], + [0, 1, 1, 0]], dtype=np.float) + assert_equal(actual, expected) From 00efb29c676d736890f85a19c72f0b80b016db13 Mon Sep 17 00:00:00 2001 From: Will Usher Date: Tue, 30 Jun 2015 19:01:52 +0100 Subject: [PATCH 2/7] Added factorial analyze function and test --- SALib/analyze/ff.py | 45 ++++++++++++++++++++++++++++++++++++++++++ SALib/sample/ff.py | 4 +--- SALib/tests/test_ff.py | 35 +++++++++++++++++++++++++------- 3 files changed, 74 insertions(+), 10 deletions(-) create mode 100644 SALib/analyze/ff.py diff --git a/SALib/analyze/ff.py b/SALib/analyze/ff.py new file mode 100644 index 00000000..b1bd7cf6 --- /dev/null +++ b/SALib/analyze/ff.py @@ -0,0 +1,45 @@ +''' +Created on 30 Jun 2015 + +@author: will2 +''' + +import numpy as np +from . import common_args +from ..util import read_param_file + +def analyze(problem, X, Y): + + num_vars = problem['num_vars'] + number_of_vars_in_input_sample = X.shape[1] + + number_of_dummy_vars = number_of_vars_in_input_sample - num_vars + + names = problem['names'] + names.extend(["dummy_" + var for var in range(number_of_dummy_vars)]) + + main_effect = (1. / (2 * number_of_vars_in_input_sample)) * np.dot(Y, X) + + Si = dict((k, [None] * num_vars) + for k in ['names', 'ME']) + Si['ME'] = main_effect + Si['names'] = names + + return Si + +if __name__ == "__main__": + + parser = common_args.create() + parser.add_argument('-X', '--model-input-file', type=str, + required=True, default=None, help='Model input file') + args = parser.parse_args() + + problem = read_param_file(args.paramfile) + + Y = np.loadtxt(args.model_output_file, delimiter=args.delimiter, usecols=(args.column,)) + X = np.loadtxt(args.model_input_file, delimiter=args.delimiter, ndmin=2) + if len(X.shape) == 1: + X = X.reshape((len(X), 1)) + + analyze(problem, X, Y, num_resamples=args.resamples, print_to_console=True, + num_levels=args.levels, grid_jump=args.grid_jump) diff --git a/SALib/sample/ff.py b/SALib/sample/ff.py index c8aaaf8e..bf28b1ae 100644 --- a/SALib/sample/ff.py +++ b/SALib/sample/ff.py @@ -16,7 +16,6 @@ def sample(problem): # Find the smallest n, such that num_vars < k k = [2 ** n for n in range(16)] k_chosen = 2**(np.argmax(num_vars < np.array(k)) - 1) - dummy_vars = k_chosen - num_vars # Generate the sample sample = np.vstack([hadamard(k_chosen), -hadamard(k_chosen)]) @@ -34,8 +33,7 @@ def sample(problem): args = parser.parse_args() problem = read_param_file(args.paramfile) - param_values = sample(problem, args.samples, args.levels, \ - args.grid_jump, args.k_optimal) + param_values = sample(problem) np.savetxt(args.output, param_values, delimiter=args.delimiter, fmt='%.' + str(args.precision) + 'e') diff --git a/SALib/tests/test_ff.py b/SALib/tests/test_ff.py index 9685be51..14ab8118 100644 --- a/SALib/tests/test_ff.py +++ b/SALib/tests/test_ff.py @@ -4,14 +4,16 @@ @author: will2 ''' from numpy.testing import assert_equal -from SALib.sample import ff +from SALib.sample.ff import sample import numpy as np -from scipy.linalg import hadamard + +from SALib.analyze.ff import analyze def test_ff_sample(): problem = {'bounds': [[0., 1.], [0., 1.], [0., 1.], [0., 1.]], - 'num_vars': 4} - actual = ff.sample(problem) + 'num_vars': 4, + 'names': ['x1', 'x2', 'x3', 'x4']} + actual = sample(problem) expected = np.array([[ 1, 1, 1, 1], [ 1, 0, 1, 0], [ 1, 1, 0, 0], @@ -19,14 +21,15 @@ def test_ff_sample(): [0, 0, 0, 0], [0, 1, 0, 1], [0, 0, 1, 1], - [0, 1, 1, 0]]) + [0, 1, 1, 0]], dtype=np.float) assert_equal(actual, expected) def test_ff_sample_scaled(): problem = {'bounds': [[0., 2.5], [0., 1.], [0., 1.], [0., 1.]], - 'num_vars': 4} - actual = ff.sample(problem) + 'num_vars': 4, + 'names': ['x1', 'x2', 'x3', 'x4']} + actual = sample(problem) expected = np.array([[ 2.5, 1, 1, 1], [ 2.5, 0, 1, 0], [ 2.5, 1, 0, 0], @@ -36,3 +39,21 @@ def test_ff_sample_scaled(): [0, 0, 1, 1], [0, 1, 1, 0]], dtype=np.float) assert_equal(actual, expected) + + +def test_ff_analyze(): + problem = {'bounds': [[0., 2.5], [0., 1.], [0., 1.], [0., 1.]], + 'num_vars': 4, + 'names': ['x1', 'x2', 'x3', 'x4']} + X = np.array([[ 1, 1, 1, 1], + [ 1, 0, 1, 0], + [ 1, 1, 0, 0], + [ 1, 0, 0, 1], + [0, 0, 0, 0], + [0, 1, 0, 1], + [0, 0, 1, 1], + [0, 1, 1, 0]], dtype=np.float) + Y = np.array([1.5, 1, 1.5, 1, 2, 2.5, 2, 2.5], dtype=np.float) + actual = analyze(problem, X, Y) + expected = None + assert_equal(actual, expected) From 7728367c66f365c7cc6cf8bf03806fc8b7fd134c Mon Sep 17 00:00:00 2001 From: Will Usher Date: Tue, 30 Jun 2015 20:14:53 +0100 Subject: [PATCH 3/7] Fixed some bugs in the factorial analyze and sample --- SALib/analyze/ff.py | 14 ++++++++++-- SALib/sample/ff.py | 17 ++++++++++++-- SALib/tests/test_ff.py | 51 +++++++++++++++++++++++++++++++++++++++++- 3 files changed, 77 insertions(+), 5 deletions(-) diff --git a/SALib/analyze/ff.py b/SALib/analyze/ff.py index b1bd7cf6..f4907ddc 100644 --- a/SALib/analyze/ff.py +++ b/SALib/analyze/ff.py @@ -8,7 +8,7 @@ from . import common_args from ..util import read_param_file -def analyze(problem, X, Y): +def analyze(problem, X, Y, second_order=False): num_vars = problem['num_vars'] number_of_vars_in_input_sample = X.shape[1] @@ -16,7 +16,7 @@ def analyze(problem, X, Y): number_of_dummy_vars = number_of_vars_in_input_sample - num_vars names = problem['names'] - names.extend(["dummy_" + var for var in range(number_of_dummy_vars)]) + names.extend(["dummy_" + str(var) for var in range(number_of_dummy_vars)]) main_effect = (1. / (2 * number_of_vars_in_input_sample)) * np.dot(Y, X) @@ -25,8 +25,18 @@ def analyze(problem, X, Y): Si['ME'] = main_effect Si['names'] = names + if second_order == True: + interactions(problem, X, Y) + return Si +def interactions(problem, X, Y): + + for col in range(X.shape[1]): + for col_2 in range(col): + x = X[:,col] * X[:,col_2] + print (1. / (2 * problem['num_vars'])) * np.dot(Y, x) + if __name__ == "__main__": parser = common_args.create() diff --git a/SALib/sample/ff.py b/SALib/sample/ff.py index bf28b1ae..bd910207 100644 --- a/SALib/sample/ff.py +++ b/SALib/sample/ff.py @@ -9,20 +9,33 @@ from . import common_args from ..util import scale_samples, read_param_file + +def find_smallest(num_vars): + for x in range(10): + if num_vars <= 2 ** x: + return x + + def sample(problem): num_vars = problem['num_vars'] # Find the smallest n, such that num_vars < k k = [2 ** n for n in range(16)] - k_chosen = 2**(np.argmax(num_vars < np.array(k)) - 1) + k_chosen = 2 ** find_smallest(num_vars) + + num_dummy_variables = k_chosen - num_vars # Generate the sample sample = np.vstack([hadamard(k_chosen), -hadamard(k_chosen)]) sample = np.array((sample + 1.) / 2, dtype=np.float) - scale_samples(sample, problem['bounds']) + bounds = list(problem['bounds']) + if num_dummy_variables > 0: + bounds.extend([[0, 1] for x in range(num_dummy_variables)]) + + scale_samples(sample, bounds) return sample diff --git a/SALib/tests/test_ff.py b/SALib/tests/test_ff.py index 14ab8118..e3ac83a5 100644 --- a/SALib/tests/test_ff.py +++ b/SALib/tests/test_ff.py @@ -26,6 +26,8 @@ def test_ff_sample(): def test_ff_sample_scaled(): + ''' + ''' problem = {'bounds': [[0., 2.5], [0., 1.], [0., 1.], [0., 1.]], 'num_vars': 4, 'names': ['x1', 'x2', 'x3', 'x4']} @@ -42,6 +44,9 @@ def test_ff_sample_scaled(): def test_ff_analyze(): + ''' + ''' + problem = {'bounds': [[0., 2.5], [0., 1.], [0., 1.], [0., 1.]], 'num_vars': 4, 'names': ['x1', 'x2', 'x3', 'x4']} @@ -55,5 +60,49 @@ def test_ff_analyze(): [0, 1, 1, 0]], dtype=np.float) Y = np.array([1.5, 1, 1.5, 1, 2, 2.5, 2, 2.5], dtype=np.float) actual = analyze(problem, X, Y) - expected = None + expected = {'ME': np.array([ 0.625, 1. , 0.875, 0.875]), 'names': ['x1', 'x2', 'x3', 'x4']} assert_equal(actual, expected) + + +def test_ff_example(): + ''' + ''' + + problem = {'bounds': np.repeat([-1, 1], 12).reshape(2, 12).T, + 'num_vars': 12, + 'names': ["x" + str(x + 1) for x in range(12)] + } + + X = sample(problem) + print X + Y = X[:, 0] + 2 * X[:, 1] + 3 * X[:, 2] + 4 * X[:, 6] * X[:, 11] + + expected = np.array([10, -2, 4, -8, 2, 6, -4, + 0, 2, 6, -4, 0, 10, -2, 4, -8, + - 2, -6, 4, 0, -10, 2, -4, 8, + - 10, 2, -4, 8, -2, -6, 4, 0]) + + assert_equal(Y, expected) + + Si = analyze(problem, X, Y) + + expected = np.array([1, 2, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], dtype=np.float) + assert_equal(expected, Si['ME']) + +def test_interactions(): + ''' + ''' + problem = {'bounds': [[0., 2.5], [0., 1.], [0., 1.], [0., 1.]], + 'num_vars': 4, + 'names': ['x1', 'x2', 'x3', 'x4']} + X = np.array([[ 1, 1, 1, 1], + [ 1, 0, 1, 0], + [ 1, 1, 0, 0], + [ 1, 0, 0, 1], + [0, 0, 0, 0], + [0, 1, 0, 1], + [0, 0, 1, 1], + [0, 1, 1, 0]], dtype=np.float) + Y = np.array([1.5, 1, 1.5, 1, 2, 2.5, 2, 2.5], dtype=np.float) + actual = analyze(problem, X, Y, second_order=True) + assert_equal(1,0) \ No newline at end of file From 233b9d7db1d97d7a76f10fb9bab7331d425de2d6 Mon Sep 17 00:00:00 2001 From: Will Usher Date: Tue, 30 Jun 2015 20:19:04 +0100 Subject: [PATCH 4/7] Added print to console --- SALib/analyze/ff.py | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/SALib/analyze/ff.py b/SALib/analyze/ff.py index f4907ddc..ad2ffb0f 100644 --- a/SALib/analyze/ff.py +++ b/SALib/analyze/ff.py @@ -8,7 +8,7 @@ from . import common_args from ..util import read_param_file -def analyze(problem, X, Y, second_order=False): +def analyze(problem, X, Y, second_order=False, print_to_console=False): num_vars = problem['num_vars'] number_of_vars_in_input_sample = X.shape[1] @@ -28,13 +28,18 @@ def analyze(problem, X, Y, second_order=False): if second_order == True: interactions(problem, X, Y) + if print_to_console: + print("Parameter ME") + for j in range(num_vars): + print("%s %f" % (problem['names'][j], Si['ME'][j])) + return Si def interactions(problem, X, Y): for col in range(X.shape[1]): for col_2 in range(col): - x = X[:,col] * X[:,col_2] + x = X[:, col] * X[:, col_2] print (1. / (2 * problem['num_vars'])) * np.dot(Y, x) if __name__ == "__main__": From a7912d72f946f4b3e17f51822589f7335193254e Mon Sep 17 00:00:00 2001 From: Will Usher Date: Tue, 30 Jun 2015 20:26:12 +0100 Subject: [PATCH 5/7] Added interactions and printing to console --- SALib/analyze/ff.py | 16 ++++++++++------ SALib/tests/test_ff.py | 2 +- 2 files changed, 11 insertions(+), 7 deletions(-) diff --git a/SALib/analyze/ff.py b/SALib/analyze/ff.py index ad2ffb0f..2b1d77b0 100644 --- a/SALib/analyze/ff.py +++ b/SALib/analyze/ff.py @@ -24,23 +24,27 @@ def analyze(problem, X, Y, second_order=False, print_to_console=False): for k in ['names', 'ME']) Si['ME'] = main_effect Si['names'] = names - - if second_order == True: - interactions(problem, X, Y) - + if print_to_console: print("Parameter ME") for j in range(num_vars): print("%s %f" % (problem['names'][j], Si['ME'][j])) + if second_order == True: + interactions(problem, X, Y, print_to_console) + return Si -def interactions(problem, X, Y): +def interactions(problem, X, Y, print_to_console=False): + + names = problem['names'] for col in range(X.shape[1]): for col_2 in range(col): x = X[:, col] * X[:, col_2] - print (1. / (2 * problem['num_vars'])) * np.dot(Y, x) + if print_to_console: + var_names = names[col_2] + names[col] + print ('%s %f' % (var_names, (1. / (2 * problem['num_vars'])) * np.dot(Y, x))) if __name__ == "__main__": diff --git a/SALib/tests/test_ff.py b/SALib/tests/test_ff.py index e3ac83a5..34a5e193 100644 --- a/SALib/tests/test_ff.py +++ b/SALib/tests/test_ff.py @@ -104,5 +104,5 @@ def test_interactions(): [0, 0, 1, 1], [0, 1, 1, 0]], dtype=np.float) Y = np.array([1.5, 1, 1.5, 1, 2, 2.5, 2, 2.5], dtype=np.float) - actual = analyze(problem, X, Y, second_order=True) + actual = analyze(problem, X, Y, second_order=True, print_to_console=True) assert_equal(1,0) \ No newline at end of file From 4d31bb585f9ab8e97b878a6b04d861e3dd3ca119 Mon Sep 17 00:00:00 2001 From: Will Usher Date: Thu, 2 Jul 2015 17:38:38 +0100 Subject: [PATCH 6/7] Refactored ff and added more tests for new procedures. Also amended calculation of main effect. --- SALib/analyze/ff.py | 44 ++++++++++++++------ SALib/sample/ff.py | 42 +++++++++++++------ SALib/tests/test_ff.py | 93 +++++++++++++++++++++++++++++++++++------- 3 files changed, 140 insertions(+), 39 deletions(-) diff --git a/SALib/analyze/ff.py b/SALib/analyze/ff.py index 2b1d77b0..a7cfd64d 100644 --- a/SALib/analyze/ff.py +++ b/SALib/analyze/ff.py @@ -6,24 +6,22 @@ import numpy as np from . import common_args -from ..util import read_param_file +from ..util import read_param_file, unscale_samples +from ..sample.ff import generate_contrast, sample, extend_bounds def analyze(problem, X, Y, second_order=False, print_to_console=False): + problem = extend_bounds(problem) num_vars = problem['num_vars'] - number_of_vars_in_input_sample = X.shape[1] - number_of_dummy_vars = number_of_vars_in_input_sample - num_vars + X = generate_contrast(problem) - names = problem['names'] - names.extend(["dummy_" + str(var) for var in range(number_of_dummy_vars)]) - - main_effect = (1. / (2 * number_of_vars_in_input_sample)) * np.dot(Y, X) + main_effect = (1. / (2 * num_vars)) * np.dot(Y, X) Si = dict((k, [None] * num_vars) for k in ['names', 'ME']) Si['ME'] = main_effect - Si['names'] = names + Si['names'] = problem['names'] if print_to_console: print("Parameter ME") @@ -31,20 +29,40 @@ def analyze(problem, X, Y, second_order=False, print_to_console=False): print("%s %f" % (problem['names'][j], Si['ME'][j])) if second_order == True: - interactions(problem, X, Y, print_to_console) + interaction_names, interaction_effects = interactions(problem, + Y, + print_to_console) + + Si['names'].append(interaction_names) + Si['IE'] = interaction_effects return Si -def interactions(problem, X, Y, print_to_console=False): + +def interactions(problem, Y, print_to_console=False): + ''' + Computes the second order effects (interactions) between + all combinations of pairs of input factors + ''' names = problem['names'] + num_vars = problem['num_vars'] + X = generate_contrast(problem) + + ie_names = [] + IE = [] + for col in range(X.shape[1]): for col_2 in range(col): x = X[:, col] * X[:, col_2] - if print_to_console: - var_names = names[col_2] + names[col] - print ('%s %f' % (var_names, (1. / (2 * problem['num_vars'])) * np.dot(Y, x))) + var_names = names[col_2] + names[col] + ie_names.append(var_names) + IE.append((1. / (2 * num_vars)) * np.dot(Y, x)) + if print_to_console: + print[('%s %f \n' % (n, i) ) for (n, i) in zip(ie_names, IE) ] + + return ie_names, IE if __name__ == "__main__": diff --git a/SALib/sample/ff.py b/SALib/sample/ff.py index bd910207..12b0923c 100644 --- a/SALib/sample/ff.py +++ b/SALib/sample/ff.py @@ -11,12 +11,33 @@ def find_smallest(num_vars): + ''' + Find the smallest exponent of two that is greater than the number + of variables + ''' for x in range(10): if num_vars <= 2 ** x: return x -def sample(problem): +def extend_bounds(problem): + + num_vars = problem['num_vars'] + num_ff_vars = 2 ** find_smallest(num_vars) + num_dummy_variables = num_ff_vars - num_vars + + bounds = list(problem['bounds']) + names = problem['names'] + if num_dummy_variables > 0: + bounds.extend([[0, 1] for x in range(num_dummy_variables)]) + names.extend(["dummy_" + str(var) for var in range(num_dummy_variables)]) + problem['bounds'] = bounds + problem['names'] = names + problem['num_vars'] = num_ff_vars + + return problem + +def generate_contrast(problem): num_vars = problem['num_vars'] @@ -24,21 +45,18 @@ def sample(problem): k = [2 ** n for n in range(16)] k_chosen = 2 ** find_smallest(num_vars) - num_dummy_variables = k_chosen - num_vars - - # Generate the sample - sample = np.vstack([hadamard(k_chosen), -hadamard(k_chosen)]) - - sample = np.array((sample + 1.) / 2, dtype=np.float) + # Generate the fractional factorial contrast + contrast = np.vstack([hadamard(k_chosen), -hadamard(k_chosen)]) - bounds = list(problem['bounds']) - if num_dummy_variables > 0: - bounds.extend([[0, 1] for x in range(num_dummy_variables)]) + return contrast - scale_samples(sample, bounds) +def sample(problem): + contrast = generate_contrast(problem) + sample = np.array((contrast + 1.) / 2, dtype=np.float) + problem = extend_bounds(problem) + scale_samples(sample, problem['bounds']) return sample - if __name__ == "__main__": diff --git a/SALib/tests/test_ff.py b/SALib/tests/test_ff.py index 34a5e193..82022850 100644 --- a/SALib/tests/test_ff.py +++ b/SALib/tests/test_ff.py @@ -3,11 +3,41 @@ @author: will2 ''' -from numpy.testing import assert_equal -from SALib.sample.ff import sample import numpy as np +from numpy.testing import assert_equal, assert_allclose +from ..sample.ff import sample, find_smallest, extend_bounds +from ..analyze.ff import analyze, interactions -from SALib.analyze.ff import analyze + +def test_find_smallest(): + ''' + ''' + num_vars = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 15, 16, 17, 31, 32, 33] + expected = [0, 1, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 6] + for x, y in zip(num_vars, expected): + actual = find_smallest(x) + assert_equal(actual, y) + + +def test_extend_bounds(): + problem = {'bounds': np.repeat([-1, 1], 12).reshape(2, 12).T, + 'num_vars': 12, + 'names': ["x" + str(x + 1) for x in range(12)] + } + actual = extend_bounds(problem) + expected = {'names': ['x1', 'x2', 'x3', 'x4', 'x5', 'x6', 'x7', 'x8', 'x9', 'x10', 'x11', 'x12', 'dummy_0', 'dummy_1', 'dummy_2', 'dummy_3'], + 'bounds': [np.array([-1, 1]), np.array([-1, 1]), + np.array([-1, 1]), np.array([-1, 1]), + np.array([-1, 1]), np.array([-1, 1]), + np.array([-1, 1]), np.array([-1, 1]), + np.array([-1, 1]), np.array([-1, 1]), + np.array([-1, 1]), np.array([-1, 1]), + np.array([0, 1]), np.array([0, 1]), + np.array([0, 1]), np.array([0, 1])], + 'num_vars': 16} + + print actual + assert_equal(actual, expected) def test_ff_sample(): problem = {'bounds': [[0., 1.], [0., 1.], [0., 1.], [0., 1.]], @@ -60,7 +90,7 @@ def test_ff_analyze(): [0, 1, 1, 0]], dtype=np.float) Y = np.array([1.5, 1, 1.5, 1, 2, 2.5, 2, 2.5], dtype=np.float) actual = analyze(problem, X, Y) - expected = {'ME': np.array([ 0.625, 1. , 0.875, 0.875]), 'names': ['x1', 'x2', 'x3', 'x4']} + expected = {'ME': np.array([ -0.5 , 0.25, 0. , 0. ]), 'names': ['x1', 'x2', 'x3', 'x4']} assert_equal(actual, expected) @@ -89,20 +119,55 @@ def test_ff_example(): expected = np.array([1, 2, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], dtype=np.float) assert_equal(expected, Si['ME']) + +def test_interactions_from_saltelli(): + ''' + ''' + problem = {'bounds': np.repeat([-1, 1], 12).reshape(2, 12).T, + 'num_vars': 12, + 'names': ["x" + str(x + 1) for x in range(12)] + } + + X = sample(problem) + + Y = np.array([10, -2, 4, -8, 2, 6, -4, 0, + 2, 6, -4, 0, 10, -2, 4, -8, + - 2, -6, 4, 0, -10, 2, -4, 8, + - 10, 2, -4, 8, -2, -6, 4, 0]) + + Si = analyze(problem, X, Y, second_order=True) + print Si + actual = Si['IE'] + expected = [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 4.0, 0.0, 0.0, + 0.0, 0.0, 0.0, 0.0, 4.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.0, 0.0, 0.0, 0.0, 4.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.0, 4.0, 0.0, 0.0, 0.0, 0.0, 0.0, 4.0, 0.0, 0.0, 0.0, 0.0, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 4.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 4.0, 0.0, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 4.0, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0] + + assert_equal(actual, expected) + + def test_interactions(): ''' ''' problem = {'bounds': [[0., 2.5], [0., 1.], [0., 1.], [0., 1.]], 'num_vars': 4, 'names': ['x1', 'x2', 'x3', 'x4']} - X = np.array([[ 1, 1, 1, 1], - [ 1, 0, 1, 0], - [ 1, 1, 0, 0], - [ 1, 0, 0, 1], + X = np.array([[ 2.5, 1.0, 1.0, 1.0], + [ 2.5, 0, 1.0, 0], + [ 2.5, 1.0, 0, 0], + [ 2.5, 0, 0, 1.0], [0, 0, 0, 0], - [0, 1, 0, 1], - [0, 0, 1, 1], - [0, 1, 1, 0]], dtype=np.float) - Y = np.array([1.5, 1, 1.5, 1, 2, 2.5, 2, 2.5], dtype=np.float) - actual = analyze(problem, X, Y, second_order=True, print_to_console=True) - assert_equal(1,0) \ No newline at end of file + [0, 1.0, 0, 1.0], + [0, 0, 1.0, 1.0], + [0, 1.0, 1.0, 0]], dtype=np.float) + Y = X[:, 0] + (0.1 * X[:, 1]) + ((1.2 * X[:, 2]) * (1.3 + X[:, 3])) +# Y = np.array([1.5, 1, 1.5, 1, 2, 2.5, 2, 2.5], dtype=np.float) + ie_names, ie = interactions(problem, Y, print_to_console=True) + actual = ie + assert_allclose(actual, [0.3, 0, 0, 0, 0, 0.3], rtol=1e-4, atol=1e-4) From adf53e3b347a681b400dd36f113c72a0cf0c8bf8 Mon Sep 17 00:00:00 2001 From: Will Usher Date: Thu, 2 Jul 2015 18:12:05 +0100 Subject: [PATCH 7/7] Python3 compatibility (removed print commands) --- SALib/tests/test_ff.py | 3 --- 1 file changed, 3 deletions(-) diff --git a/SALib/tests/test_ff.py b/SALib/tests/test_ff.py index 82022850..40595304 100644 --- a/SALib/tests/test_ff.py +++ b/SALib/tests/test_ff.py @@ -36,7 +36,6 @@ def test_extend_bounds(): np.array([0, 1]), np.array([0, 1])], 'num_vars': 16} - print actual assert_equal(actual, expected) def test_ff_sample(): @@ -104,7 +103,6 @@ def test_ff_example(): } X = sample(problem) - print X Y = X[:, 0] + 2 * X[:, 1] + 3 * X[:, 2] + 4 * X[:, 6] * X[:, 11] expected = np.array([10, -2, 4, -8, 2, 6, -4, @@ -136,7 +134,6 @@ def test_interactions_from_saltelli(): - 10, 2, -4, 8, -2, -6, 4, 0]) Si = analyze(problem, X, Y, second_order=True) - print Si actual = Si['IE'] expected = [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,