user8937713
user8937713

Reputation:

Senstivity analysis error in Python using SALib

following Performing a sensitivity analysis with python I receive an error.

My code is as follows:

from SALib.sample import saltelli
from SALib.analyze import sobol

def ls(X):
    # column 0 = demand, column 1 =  bookings, column 2 = inventory
    return max(X[:,0] - X[:,1] - X[:,2])

problem = {'num_vars': 3,
           'names': ['demand', 'bookings', 'inventory'],
           'bounds': [[0, 1250],
                     [0, 11000],
                     [0, 120000]]
           } 

# Generate samples
param_values = saltelli.sample(problem, 10000000, calc_second_order=False)

# Run model
Y = ls(param_values)

# Perform analysis
Si = sobol.analyze(problem, Y)

I receive the following error. RuntimeError: Incorrect number of samples in model output file. Confirm that calc_second_order matches option used during sampling.

When I look at https://github.com/SALib/SALib/blob/master/SALib/analyze/sobol.py I see:

if calc_second_order and Y.size % (2 * D + 2) == 0:
        N = int(Y.size / (2 * D + 2))
    elif not calc_second_order and Y.size % (D + 2) == 0:
        N = int(Y.size / (D + 2))
    else:
        raise RuntimeError("""
        Incorrect number of samples in model output file.
        Confirm that calc_second_order matches option used during 
sampling.""")

However, this does not really help me in solving the error. Does it have to do with the second argument in saltelli.sample()?

Upvotes: 1

Views: 2221

Answers (1)

Calvin
Calvin

Reputation: 1359

There are two problems. First, the function ls() returns a single value when it should be a vector of length equal to the number of rows in param_values. Second, the default assumption in saltelli.sample() and sobol.analyze() is to have calc_second_order=True, so you need to set it to False in both cases. Here is some example code that runs, but you may have to adjust the ls() function to meet your requirements.

from SALib.sample import saltelli
from SALib.analyze import sobol

def ls(X):
    # column 0 = demand, column 1 =  bookings, column 2 = inventory
    # modified to return a vector (max was returning max value of vector)
    return (X[:,0] - X[:,1] - X[:,2])

problem = {'num_vars': 3,
           'names': ['demand', 'bookings', 'inventory'],
           'bounds': [[0, 1250],
                     [0, 11000],
                     [0, 120000]]
           } 

# Generate samples
param_values = saltelli.sample(problem, 10000000, calc_second_order=False)

# Run model
Y = ls(param_values)

# Perform analysis
Si = sobol.analyze(problem, Y,calc_second_order=False)

Upvotes: 2

Related Questions