Skip to content

Commit

Permalink
Adds preliminary documentation to functions
Browse files Browse the repository at this point in the history
  • Loading branch information
David Hadka committed Sep 17, 2015
1 parent de80989 commit 0a47e05
Show file tree
Hide file tree
Showing 12 changed files with 325 additions and 80 deletions.
43 changes: 39 additions & 4 deletions SALib/analyze/delta.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,47 @@
from ..util import read_param_file


# Perform Delta moment-independent Analysis on file of model results
# Returns a dictionary with keys 'delta', 'delta_conf', 'S1', and 'S1_conf'
# Where each entry is a list of size D (the number of parameters)
# Containing the indices in the same order as the parameter file
def analyze(problem, X, Y, calc_second_order=True, num_resamples=10,
conf_level=0.95, print_to_console=False):
"""Perform Delta Moment-Independent Analysis on model outputs.
Returns a dictionary with keys 'delta', 'delta_conf', 'S1', and 'S1_conf',
where each entry is a list of size D (the number of parameters) containing
the indices in the same order as the parameter file.
Parameters
----------
problem : dict
The problem definition
X: numpy.matrix
A NumPy matrix containing the model inputs
Y : numpy.array
A NumPy array containing the model outputs
calc_second_order : bool
Not used
num_resamples : int
The number of resamples when computing confidence intervals (default 10)
conf_level : float
The confidence interval level (default 0.95)
print_to_console : bool
Print results directly to console (default False)
References
----------
.. [1] Borgonovo, E. (2007). "A new uncertainty importance measure."
Reliability Engineering & System Safety, 92(6):771-784,
doi:10.1016/j.ress.2006.04.015.
.. [2] Plischke, E., E. Borgonovo, and C. L. Smith (2013). "Global
sensitivity measures from given data." European Journal of
Operational Research, 226(3):536-550, doi:10.1016/j.ejor.2012.11.047.
Examples
--------
>>> X = latin.sample(problem, 1000)
>>> Y = Ishigami.evaluate(X)
>>> Si = delta.analyze(problem, X, Y, print_to_console=True)
"""

D = problem['num_vars']
N = Y.size
Expand Down
33 changes: 29 additions & 4 deletions SALib/analyze/dgsm.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,37 @@
from ..util import read_param_file


# Calculate DGSM from file of model results
# Returns a dictionary with keys 'vi', 'vi_std', 'dgsm', and 'dgsm_conf'
# Where each entry is a list of size D (the number of parameters)
# Containing the indices in the same order as the parameter file
def analyze(problem, X, Y, num_resamples=1000,
conf_level=0.95, print_to_console=False):
"""Calculates Derivative-based Global Sensitivity Measure on model outputs.
Returns a dictionary with keys 'vi', 'vi_std', 'dgsm', and 'dgsm_conf',
where each entry is a list of size D (the number of parameters) containing
the indices in the same order as the parameter file.
Parameters
----------
problem : dict
The problem definition
X : numpy.matrix
The NumPy matrix containing the model inputs
Y : numpy.array
The NumPy array containing the model outputs
num_resamples : int
The number of resamples used to compute the confidence
intervals (default 1000)
conf_level : float
The confidence interval level (default 0.95)
print_to_console : bool
Print results directly to console (default False)
References
----------
.. [1] Sobol, I. M. and S. Kucherenko (2009). "Derivative based global
sensitivity measures and their link with global sensitivity
indices." Mathematics and Computers in Simulation, 79(10):3009-3017,
doi:10.1016/j.matcom.2009.01.023.
"""

D = problem['num_vars']

Expand Down
40 changes: 36 additions & 4 deletions SALib/analyze/fast.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,43 @@
from ..util import read_param_file


# Perform FAST Analysis on file of model results
# Returns a dictionary with keys 'S1' and 'ST'
# Where each entry is a list of size D (the number of parameters)
# Containing the indices in the same order as the parameter file
def analyze(problem, Y, M=4, print_to_console=False):
"""Performs the Fourier Amplitude Sensitivity Test (FAST) on model outputs.
Returns a dictionary with keys 'S1' and 'ST', where each entry is a list of
size D (the number of parameters) containing the indices in the same order
as the parameter file.
Parameters
----------
problem : dict
The problem definition
Y : numpy.array
A NumPy array containing the model outputs
M : int
The interference parameter, i.e., the number of harmonics to sum in
the Fourier series decomposition (default 4)
print_to_console : bool
Print results directly to console (default False)
References
----------
.. [1] Cukier, R. I., C. M. Fortuin, K. E. Shuler, A. G. Petschek, and J. H.
Schaibly (1973). "Study of the sensitivity of coupled reaction
systems to uncertainties in rate coefficients." J. Chem. Phys.,
59(8):3873-3878, doi:10.1063/1.1680571.
.. [2] Saltelli, A., S. Tarantola, and K. P.-S. Chan (1999). "A
Quantitative Model-Independent Method for Global Sensitivity
Analysis of Model Output." Technometrics, 41(1):39-56,
doi:10.1080/00401706.1999.10485594.
Examples
--------
>>> X = fast_sampler.sample(problem, 1000)
>>> Y = Ishigami.evaluate(X)
>>> Si = fast.analyze(problem, Y, print_to_console=False)
"""

D = problem['num_vars']

Expand Down
49 changes: 45 additions & 4 deletions SALib/analyze/morris.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,16 +9,57 @@
from ..util import read_param_file


# Perform Morris Analysis on file of model results
# Returns a dictionary with keys 'mu', 'mu_star', 'sigma', and 'mu_star_conf'
# Where each entry is a list of size num_vars (the number of parameters)
# Containing the indices in the same order as the parameter file
def analyze(problem, X, Y,
num_resamples=1000,
conf_level=0.95,
print_to_console=False,
grid_jump=2,
num_levels=4):
"""Perform Morris Analysis on model outputs.
Returns a dictionary with keys 'mu', 'mu_star', 'sigma', and 'mu_star_conf',
where each entry is a list of size D (the number of parameters) containing
the indices in the same order as the parameter file.
Parameters
----------
problem : dict
The problem definition
X : numpy.matrix
The NumPy matrix containing the model inputs
Y : numpy.array
The NumPy array containing the model outputs
num_resamples : int
The number of resamples used to compute the confidence
intervals (default 1000)
conf_level : float
The confidence interval level (default 0.95)
print_to_console : bool
Print results directly to console (default False)
grid_jump : int
The grid jump size, must be identical to the value passed
to :func:`SALib.sample.morris.sample` (default 2)
num_levels : int
The number of grid levels, must be identical to the value
passed to SALib.sample.morris (default 4)
References
----------
.. [1] Morris, M. (1991). "Factorial Sampling Plans for Preliminary
Computational Experiments." Technometrics, 33(2):161-174,
doi:10.1080/00401706.1991.10484804.
.. [2] Campolongo, F., J. Cariboni, and A. Saltelli (2007). "An effective
screening design for sensitivity analysis of large models."
Environmental Modelling & Software, 22(10):1509-1518,
doi:10.1016/j.envsoft.2006.10.004.
Examples
--------
>>> X = morris.sample(problem, 1000, num_levels=4, grid_jump=2)
>>> Y = Ishigami.evaluate(X)
>>> Si = morris.analyze(problem, X, Y, conf_level=0.95,
>>> print_to_console=True, num_levels=4, grid_jump=2)
"""

# Assume that there are no groups
groups = None
Expand Down
47 changes: 43 additions & 4 deletions SALib/analyze/sobol.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,52 @@
from itertools import izip_longest as zip_longest


# Perform Sobol Analysis on a vector of model results
# Returns a dictionary with keys 'S1', 'S1_conf', 'ST', and 'ST_conf'
# Where each entry is a list of size D (the number of parameters)
# Containing the indices in the same order as the parameter file
def analyze(problem, Y, calc_second_order=True, num_resamples=100,
conf_level=0.95, print_to_console=False, parallel=False,
n_processors=None):
"""Perform Sobol Analysis on model outputs.
Returns a dictionary with keys 'S1', 'S1_conf', 'ST', and 'ST_conf', where
each entry is a list of size D (the number of parameters) containing the
indices in the same order as the parameter file. If calc_second_order is
True, the dictionary also contains keys 'S2' and 'S2_conf'.
Parameters
----------
problem : dict
The problem definition
Y : numpy.array
A NumPy array containing the model outputs
calc_second_order : bool
Calculate second-order sensitivities (default True)
num_resamples : int
The number of resamples (default 100)
conf_level : float
The confidence interval level (default 0.95)
print_to_console : bool
Print results directly to console (default False)
References
----------
.. [1] Sobol, I. M. (2001). "Global sensitivity indices for nonlinear
mathematical models and their Monte Carlo estimates." Mathematics
and Computers in Simulation, 55(1-3):271-280,
doi:10.1016/S0378-4754(00)00270-6.
.. [2] Saltelli, A. (2002). "Making best use of model evaluations to
compute sensitivity indices." Computer Physics Communications,
145(2):280-297, doi:10.1016/S0010-4655(02)00280-1.
.. [3] Saltelli, A., P. Annoni, I. Azzini, F. Campolongo, M. Ratto, and
S. Tarantola (2010). "Variance based sensitivity analysis of model
output. Design and estimator for the total sensitivity index."
Computer Physics Communications, 181(2):259-270,
doi:10.1016/j.cpc.2009.09.018.
Examples
--------
>>> X = saltelli.sample(problem, 1000)
>>> Y = Ishigami.evaluate(X)
>>> Si = sobol.analyze(problem, Y, print_to_console=True)
"""

D = problem['num_vars']

Expand Down
18 changes: 17 additions & 1 deletion SALib/sample/fast_sampler.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,24 @@
from .. util import scale_samples, read_param_file


# Generate N x D matrix of extended FAST samples (Saltelli 1999)
def sample(problem, N, M=4):
"""Generate model inputs for the Fourier Amplitude Sensitivity Test (FAST).
Returns a NumPy matrix containing the model inputs required by the Fourier
Amplitude sensitivity test. The resulting matrix contains N rows and D
columns, where D is the number of parameters. The samples generated are
intended to be used by :func:`SALib.analyze.fast.analyze`.
Parameters
----------
problem : dict
The problem definition
N : int
The number of samples to generate
M : int
The interference parameter, i.e., the number of harmonics to sum in the
Fourier series decomposition (default 4)
"""

D = problem['num_vars']

Expand Down
17 changes: 15 additions & 2 deletions SALib/sample/latin.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,22 @@
from ..util import scale_samples, read_param_file


# Generate N x D matrix of latin hypercube samples
def sample(problem, N):

"""Generate model inputs using Latin hypercube sampling (LHS).
Returns a NumPy matrix containing the model inputs generated by Latin
hypercube sampling. The resulting matrix contains N rows and D columns,
where D is the number of parameters.
Parameters
----------
problem : dict
The problem definition
N : int
The number of samples to generate
calc_second_order : bool
Calculate second-order sensitivities (default True)
"""
D = problem['num_vars']

result = np.empty([N, D])
Expand Down
64 changes: 40 additions & 24 deletions SALib/sample/morris.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,31 +17,47 @@
else:
_has_gurobi = True

'''
Three variants of Morris' sampling for
elementary effects:
- vanilla Morris
- optimised trajectories (Campolongo's enhancements from 2007)
- groups with optimised trajectories (again Campolongo 2007)
At present, optimised trajectories is implemented using a brute-force
approach, which can be very slow, especially if you require more than four
trajectories. Note that the number of factors makes little difference,
but the ratio between number of optimal trajectories and the sample size
results in an exponentially increasing number of scores that must be
computed to find the optimal combination of trajectories.
I suggest going no higher than 4 from a pool of 100 samples.
Suggested enhancements:
- a parallel brute force method (incomplete)
- a combinatorial optimisation approach (completed, but dependencies are
not open-source)
'''


#Suggested enhancements:
# - a parallel brute force method (incomplete)
# - a combinatorial optimisation approach (completed, but dependencies are
# not open-source)
def sample(problem, N, num_levels, grid_jump, optimal_trajectories=None):

"""Generates model inputs using for Method of Morris.
Returns a NumPy matrix containing the model inputs required for Method of
Morris. The resulting matrix has N rows and D columns, where D is the
number of parameters. These model inputs are intended to be used with
:func:`SALib.analyze.morris.analyze`.
Three variants of Morris' sampling for elementary effects is supported:
- Vanilla Morris
- Optimised trajectories when optimal_trajectories is set (using
Campolongo's enhancements from 2007)
- Groups with optimised trajectories when optimal_trajectores is set and
the problem definition specifies groups
At present, optimised trajectories is implemented using a brute-force
approach, which can be very slow, especially if you require more than four
trajectories. Note that the number of factors makes little difference,
but the ratio between number of optimal trajectories and the sample size
results in an exponentially increasing number of scores that must be
computed to find the optimal combination of trajectories. We suggest going
no higher than 4 from a pool of 100 samples.
Parameters
----------
problem : dict
The problem definition
N : int
The number of samples to generate
num_levels : int
The number of grid levels
grid_jump : int
The grid jump size
optimal_trajectories : int
The number of optimal trajectories to sample (between 2 and N)
"""
if grid_jump >= num_levels:
raise ValueError("grid_jump must be less than num_levels")

Expand Down

0 comments on commit 0a47e05

Please sign in to comment.