Latin Hyopercube SamplingΒΆ

%matplotlib inline
import pysd
import numpy as np
import pandas as pd
import pyDOE
import scipy.stats.distributions as dist
import multiprocessing
model = pysd.read_vensim('../../models/Capability_Trap/Capability Trap.mdl')
# define the sample space
ranges = {'Fraction of Effort for Sales':(0,1),
          'Startup Subsidy':(0,2),
          'Startup Subsidy Length':(0,12)}

# generate LHS samples within the unit square
lhs = pyDOE.lhs(n=len(ranges), samples=2000)

# transform samples into our sample space
samples = pd.DataFrame(
    data=dist.uniform(loc=[x[0] for x in ranges.values()],
                      scale=[x[1] for x in ranges.values()]).ppf(lhs),
    columns=ranges.keys())

samples.head()
Fraction of Effort for Sales Startup Subsidy Startup Subsidy Length
0 0.611800 1.367751 2.058684
1 0.851258 0.305343 2.631837
2 0.114397 1.789170 2.471216
3 0.126074 1.541200 2.653847
4 0.546046 0.012404 6.980225
def runner(params):
    market = market_model.run(dict(params),return_columns=['Tenure'])
    motiv = motivation_model.run(dict(params),return_columns=['Tenure'])
    return pd.Series({'market':market['Tenure'].iloc[-1],
                      'motivation':motiv['Tenure'].iloc[-1]})
def _apply_df(args):
    df, func, kwargs = args
    return df.apply(func, **kwargs)

def apply_by_multiprocessing(df, func, workers=multiprocessing.cpu_count(), **kwargs):
    pool = multiprocessing.Pool(processes=workers)
    result = pool.map(_apply_df, [(d, func, kwargs) for d in np.array_split(df, workers)])
    pool.close()
    return pd.concat(list(result))

res = apply_by_multiprocessing(samples, runner, axis=1)
# define the sample space
ranges = {'Fraction of Effort for Sales':(0,1),
          'Startup Subsidy':(0,2),
          'Startup Subsidy Length':(0,12)}

# generate LHS samples within the unit square
lhs = pyDOE.lhs(n=len(ranges), samples=2000)

# transform samples into our sample space
samples = pd.DataFrame(
    data=dist.uniform(loc=[x[0] for x in ranges.values()],
                      scale=[x[1] for x in ranges.values()]).ppf(lhs),
    columns=ranges.keys())

samples.head()