Cobin
Cobin

Reputation: 930

Could SALib support other probability distribution when inputing parameters in sensitivity analysis?

from SALib.sample import saltelli
import numpy as np

problem = {
  'num_vars': 3, 
  'names': ['x1', 'x2', 'x3'], 
  'bounds': [-10,10]
}

Must bounds be for a uniform distribution? Could it be an other probability distribution? Such as normal, binormial, poisson, Beta...

Upvotes: 2

Views: 1339

Answers (2)

astoeriko
astoeriko

Reputation: 890

I want to make an addition to Calvin Whealton's answer which is based on this blog post of (I suppose the same) Calvin Whealton:

SALib supports defining different input parameter distributions in the problem dictionary, although this functionality does not seem to be documented on their official website. You just need to add a new key 'dists' to the problem dictionary and give a list of strings which encode the distribution type.

The problem definition in that case looks like this:

# problem definition
prob_dists_code = {
'num_vars':6,
'names': ['P1','P2','P3','P4','P5','P6'],
'bounds':[[0.0,1.0], [1.0, 0.75], [0.0, 0.2], [0.0, 0.2], [-1.0,1.0], [1.0,0.25]],
'dists':['unif','triang','norm','lognorm','unif','triang']
}

The values given in 'bounds' then correspond to the parameters of each distribution, e.g. to the mean and standard deviation in the case of a normal distribution. More details can be found in the blog post.

Upvotes: 6

Calvin
Calvin

Reputation: 1359

If you want other distributions besides uniform from SALib you can do the following:

  1. Generate uniform samples on the interval (0,1).
  2. Use the inverse cumulative distribution function to convert the input for each parameter into the desired distribution. You can use scipy for the transformation, which should give plenty of flexibility for distributions.
  3. Evaluate the model with these transformed inputs.

The following example to convert to normal distributions is based on code modified from the SALib site (https://github.com/SALib/SALib).

from SALib.sample import saltelli
from SALib.analyze import sobol
from SALib.test_functions import Ishigami
import numpy as np
import scipy as sp # for inverse CDF (ppf) function for distributions

problem2 = {
  'num_vars': 3,
  'names': ['x1', 'x2', 'x3'],
  'bounds': [[0,1]]*3
}

# Generate samples
param_values2 = saltelli.sample(problem2, 1000, calc_second_order=False)

# using normal inverse CDF, can change to other distributions as desired
# look at scipy documentation for other distributions and parameters
param_values2[:,0] = sp.stats.norm.ppf(param_values2[:,0],0,np.pi/2.)
param_values2[:,1] = sp.stats.norm.ppf(param_values2[:,1],0,np.pi/2.)
param_values2[:,2] = sp.stats.norm.ppf(param_values2[:,2],0,np.pi/2.)

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

# Perform analysis
Si = sobol.analyze(problem2, Y, print_to_console=True)

Upvotes: 2

Related Questions