Esempio n. 1
0
def make_data(param_bounds = [],
              param_bounds_epsilon = [],
              param_is_boundary_param = [0, 0, 1],
              param_names = ['v', 'a', 'w']):
    
    # Generate set of parameters
    tmp_params = make_params(param_bounds = param_bounds, param_bounds_epsilon = param_bounds_epsilon)

    # Define boundary parameters 
    boundary_params = {}
    cnt = 0
    
    for param in parameter_names:
        if param_is_boundary_param[cnt]:
            boundary_params[param] = tmp_params[cnt]
        cnt += 1

    # Run model simulations: MANUAL INTERVENTION TD: AUTOMATE
    ddm_dat_tmp = cds.ddm_flexbound(v = tmp_params[param_names.index('v')],
                                    a = tmp_params[param_names.index('a')],
                                    w = tmp_params[param_names.index('w')],
                                    s = 1,
                                    delta_t = 0.001,
                                    max_t = 20,
                                    n_samples = n_samples,
                                    boundary_fun = boundary, # function of t (and potentially other parameters) that takes in (t, *args)
                                    boundary_multiplicative = boundary_multiplicative, # CAREFUL: CHECK IF BOUND
                                    boundary_params = boundary_params)

    data_np = np.concatenate([ddm_dat_tmp[0], ddm_dat_tmp[1]], axis = 1)
    return data_np, tmp_params
Esempio n. 2
0
def data_generator_ddm_flexbound(batch_size, n):
    v = np.random.uniform(-3, 3, batch_size)
    a = np.random.uniform(0.3, 2.5, batch_size)
    w = np.random.uniform(0.1, 0.9, batch_size)

    # Number of paths to be sampled for each batch
    n_samples = 10000

    # Bool to determine how to put 'rt' and 'choice_made' together
    multiply = True

    boundary_function = bf.constant

    X_train = []

    for i in range(batch_size):
        out = cds.ddm_flexbound(v[i],
                                a[i],
                                w[i],
                                ndt=0.5,
                                delta_t=0.001,
                                s=np.sqrt(2),
                                max_t=20,
                                n_samples=n_samples,
                                boundary_fun=boundary_function,
                                boundary_multiplicative=True,
                                boundary_params={})
        #boundary_params = {"theta": 0.01})
        if multiply:
            # Multiply 'rt' and 'choice_made'
            data = (out[0] * out[1]).reshape(n_samples, )
        else:
            # concatenate 'rt' and 'choice_made'
            data = np.concatenate((out[0].T, out[1].T),
                                  axis=1).reshape(2 * n_samples, )

        X_train.append(data)

    X_train = np.array(X_train)
    # Concatenating a, v and w
    param = np.concatenate(
        (a.reshape(-1, 1), v.reshape(-1, 1), w.reshape(-1, 1)), axis=1)

    return tf.convert_to_tensor(
        X_train, dtype=tf.float32), tf.convert_to_tensor(param,
                                                         dtype=tf.float32)
def data_generator_ddm_flexbound(batch_size, n_samples):
    v = np.random.uniform(-3, 3, batch_size)
    a = np.random.uniform(0.3, 2.5, batch_size)
    w = np.random.uniform(0.1, 0.9, batch_size)
    alpha = np.random.uniform(0.3, 5.0, batch_size)
    beta = np.random.uniform(0.3, 7.0, batch_size)
    # Number of paths to be sampled for each batch
    #     print("n_samples", n_samples)

    # Bool to determine how to put 'rt' and 'choice_made' together
    multiply = True

    boundary_function = bf.weibull_cdf

    X_train = []

    for i in range(batch_size):
        out = cds.ddm_flexbound(v[i],
                                a[i],
                                w[i],
                                ndt=0.5,
                                delta_t=0.001,
                                s=np.sqrt(2),
                                max_t=20,
                                n_samples=n_samples,
                                boundary_fun=boundary_function,
                                boundary_multiplicative=True,
                                boundary_params={
                                    "alpha": alpha[i],
                                    "beta": beta[i]
                                })
        #boundary_params = {"theta": 0.01})

        data = np.concatenate((out[0], out[1]), axis=1)

        X_train.append(data)

    X_train = np.array(X_train)
    # Concatenating a, v and w
    param = np.concatenate((a.reshape(-1, 1), v.reshape(-1, 1), w.reshape(
        -1, 1), alpha.reshape(-1, 1), beta.reshape(-1, 1)),
                           axis=1)

    return tf.convert_to_tensor(
        X_train, dtype=tf.float32), tf.convert_to_tensor(param,
                                                         dtype=tf.float32)
Esempio n. 4
0
def make_data_group(param_bounds = [],
                    param_bounds_epsilon = [],
                    param_is_boundary_param = [0, 0, 1], 
                    params_ordered = ['v', 'a', 'w', 'node', 'theta'],
                    param_varies = [0, 0, 1],
                    params_names = ['v', 'a', 'w_0', 'w_1', 'w_2'],
                    n_subjects = 3):
    
    # Generate set of parameters
    tmp_params_full = make_params(param_bounds = param_bounds, param_bounds_epsilon = param_bounds_epsilon)
    data = {}
    for i in range(n_subjects):
        tmp_params = ktnp.get_tmp_params(params = tmp_params_full,
                                         params_ordered = params_ordered,
                                         param_varies = param_varies,
                                         params_names = params_names,
                                         idx = i)
        
        # Define boundary parameters 
        boundary_params = {}
        cnt = 0

        for param in parameter_names:
            if param_is_boundary_param[cnt]:
                boundary_params[param] = tmp_params[cnt]
            cnt += 1

        # Run model simulations: MANUAL INTERVENTION TD: AUTOMATE
        ddm_dat_tmp = cds.ddm_flexbound(v = tmp_params[params_ordered.index('v')],
                                        a = tmp_params[params_ordered.index('a')],
                                        w = tmp_params[params_ordered.index('w')],
                                        s = 1,
                                        delta_t = 0.01,
                                        max_t = 20,
                                        n_samples = n_samples,
                                        boundary_fun = boundary, # function of t (and potentially other parameters) that takes in (t, *args)
                                        boundary_multiplicative = boundary_multiplicative, # CAREFUL: CHECK IF BOUND IS MULTIPLICATIVE
                                        boundary_params = boundary_params)

        data[str(i)] = np.concatenate([ddm_dat_tmp[0], ddm_dat_tmp[1]], axis = 1)
    return data, tmp_params_full
Esempio n. 5
0
    info['numpy_timings'] = []
    info['keras_var_batch_timings'] = []
    info['keras_fix_batch_timings'] = []
    info['keras_no_batch_timings'] = []
    info['navarro_timings'] = []
    info['keras_var_batch_no_pred_timings'] = []
    info['keras_fix_batch_no_pred_timings'] = []
    info['nsamples'] = []

    # Run timingss
    for n in [1024, 2048, 4096, 8192, 16384, 32768, 65536, 131072]:
        
        print('nsamples: ', n)
        # Generate toy dataset
        out = cds.ddm_flexbound(n_samples = n,
                                boundary_fun = bf.constant,
                                boundary_multiplicative = True)
        out = np.concatenate([out[0], out[1]], axis = 1)
        
        # Arbitraty parameters vector
        params_rep = [0, 1, 0.5, 0.]

        # Prepare batch matrix for keras model
        keras_input_batch = np.zeros((out.shape[0], 6))
        keras_input_batch[:, 4:] = out

        
        # Navarro Fuss timings
        print('Running Navarro')
        for i in range(nreps):
            start = datetime.now()
def simulator(theta, 
              model = 'angle', 
              n_samples = 1000, 
              delta_t = 0.001,
              max_t = 20,
              bin_dim = None):
    
    # Useful for sbi
    if type(theta) == list or type(theta) == np.ndarray:
        pass
    else:
        theta = theta.numpy()
    
    if model == 'ddm':
        x = ddm_flexbound(v = theta[0],
                          a = theta[1], 
                          w = theta[2],
                          ndt = theta[3],
                          n_samples = n_samples,
                          delta_t = delta_t,
                          boundary_params = {},
                          boundary_fun = bf.constant,
                          boundary_multiplicative = True,
                          max_t = max_t)
    
    if model == 'angle' or model == 'angle2':
        x = ddm_flexbound(v = theta[0], 
                          a = theta[1],
                          w = theta[2], 
                          ndt = theta[3], 
                          boundary_fun = bf.angle, 
                          boundary_multiplicative = False,
                          boundary_params = {'theta': theta[4]}, 
                          delta_t = delta_t,
                          n_samples = n_samples,
                          max_t = max_t)
    
    if model == 'weibull_cdf' or model == 'weibull_cdf2' or model == 'weibull_cdf_ext' or model == 'weibull_cdf_concave':
        x = ddm_flexbound(v = theta[0], 
                          a = theta[1], 
                          w = theta[2], 
                          ndt = theta[3], 
                          boundary_fun = bf.weibull_cdf, 
                          boundary_multiplicative = True, 
                          boundary_params = {'alpha': theta[4], 'beta': theta[5]}, 
                          delta_t = delta_t,
                          n_samples = n_samples,
                          max_t = max_t)
    
    if model == 'levy':
        x = levy_flexbound(v = theta[0], 
                           a = theta[1], 
                           w = theta[2], 
                           alpha_diff = theta[3], 
                           ndt = theta[4], 
                           boundary_fun = bf.constant, 
                           boundary_multiplicative = True, 
                           boundary_params = {},
                           delta_t = delta_t,
                           n_samples = n_samples,
                           max_t = max_t)
    
    if model == 'full_ddm' or model == 'full_ddm2':
        x = full_ddm(v = theta[0],
                     a = theta[1],
                     w = theta[2], 
                     ndt = theta[3], 
                     dw = theta[4], 
                     sdv = theta[5], 
                     dndt = theta[6], 
                     boundary_fun = bf.constant, 
                     boundary_multiplicative = True, 
                     boundary_params = {}, 
                     delta_t = delta_t,
                     n_samples = n_samples,
                     max_t = max_t)

    if model == 'ddm_sdv':
        x = ddm_sdv(v = theta[0], 
                    a = theta[1], 
                    w = theta[2], 
                    ndt = theta[3],
                    sdv = theta[4],
                    boundary_fun = bf.constant,
                    boundary_multiplicative = True, 
                    boundary_params = {},
                    delta_t = delta_t,
                    n_samples = n_samples,
                    max_t = max_t)
        
    if model == 'ornstein':
        x = ornstein_uhlenbeck(v = theta[0], 
                               a = theta[1], 
                               w = theta[2], 
                               g = theta[3], 
                               ndt = theta[4],
                               boundary_fun = bf.constant,
                               boundary_multiplicative = True,
                               boundary_params = {},
                               delta_t = delta_t,
                               n_samples = n_samples,
                               max_t = max_t)

    if model == 'pre':
        x = ddm_flexbound_pre(v = theta[0],
                              a = theta[1], 
                              w = theta[2], 
                              ndt = theta[3],
                              boundary_fun = bf.angle,
                              boundary_multiplicative = False,
                              boundary_params = {'theta': theta[4]},
                              delta_t = delta_t,
                              n_samples = n_samples,
                              max_t = max_t)
        
    if model == 'race_model_3':
        x = race_model(v = theta[:3],
                       a = theta[3],
                       w = theta[4:7],
                       ndt = theta[7],
                       s = np.array([1, 1, 1], dtype = np.float32),
                       boundary_fun = bf.constant,
                       boundary_multiplicative = True,
                       boundary_params = {},
                       delta_t = delta_t,
                       n_samples = n_samples,
                       max_t = max_t)
        
    if model == 'race_model_4':
        x = race_model(v = theta[:4],
                       a = theta[4],
                       w = theta[5:9],
                       ndt = theta[9],
                       s = np.array([1, 1, 1, 1], dtype = np.float32),
                       boundary_fun = bf.constant,
                       boundary_multiplicative = True,
                       boundary_params = {},
                       delta_t = delta_t,
                       n_samples = n_samples,
                       max_t = max_t)
        
    if model == 'lca_3':
        x = lca(v = theta[:3],
                a = theta[4],
                w = theta[4:7],
                g = theta[7],
                b = theta[8],
                ndt = theta[9],
                s = 1.0,
                boundary_fun = bf.constant,
                boundary_multiplicative = True,
                boundary_params = {},
                delta_t = delta_t,
                n_samples = n_samples,
                max_t = max_t)
        
    if model == 'lca_4':
        x = lca(v = theta[:4],
                a = theta[4],
                w = theta[5:9],
                g = theta[9],
                b = theta[10],
                ndt = theta[11],
                s = 1.0,
                boundary_fun = bf.constant,
                boundary_multiplicative = True,
                boundary_params = {},
                delta_t = delta_t,
                n_samples = n_samples,
                max_t = max_t)
        
#         race_model(v = np.array([0, 0, 0], dtype = DTYPE), # np.array expected, one column of floats
#                float a = 1, # initial boundary separation
#                w = np.array([0, 0, 0], dtype = DTYPE), # np.array expected, one column of floats
#                float ndt = 1, # for now we we don't allow ndt by choice
#                #ndt = np.array([0.0, 0.0, 0.0], dtype = DTYPE),
#                s = np.array([1, 1, 1], dtype = DTYPE), # np.array expected, one column of floats
#                float delta_t = 0.001, # time increment step
#                float max_t = 20, # maximum rt allowed
#                int n_samples = 2000, 
#                print_info = True,
#                boundary_fun = None,
#                boundary_multiplicative = True,
#                boundary_params = {})       
#     if model == 'race_model_4':
    
    if bin_dim == 0:
        return x
    else:
        return bin_simulator_output(x, nbins = bin_dim)
def kde_vs_mlp_likelihoods(ax_titles=[],
                           title='Likelihoods KDE - MLP',
                           network_dir='',
                           x_labels=[],
                           parameter_matrix=[],
                           cols=3,
                           model='angle',
                           data_signature='',
                           n_samples=10,
                           nreps=10,
                           save=True,
                           show=False,
                           machine='home',
                           method='mlp',
                           traindatanalytic=0,
                           plot_format='svg'):

    mpl.rcParams['text.usetex'] = True
    #matplotlib.rcParams['pdf.fonttype'] = 42
    mpl.rcParams['svg.fonttype'] = 'none'

    # Initialize rows and graph parameters
    rows = int(np.ceil(len(ax_titles) / cols))
    sns.set(style="white", palette="muted", color_codes=True, font_scale=2)

    fig, ax = plt.subplots(rows,
                           cols,
                           figsize=(10, 10),
                           sharex=True,
                           sharey=False)

    fig.suptitle(title + ': ' + model.upper().replace('_', '-'), fontsize=40)
    sns.despine(right=True)

    # Data template
    plot_data = np.zeros((4000, 2))
    plot_data[:, 0] = np.concatenate(([i * 0.0025 for i in range(2000, 0, -1)],
                                      [i * 0.0025 for i in range(1, 2001, 1)]))
    plot_data[:, 1] = np.concatenate((np.repeat(-1, 2000), np.repeat(1, 2000)))

    # Load Keras model and initialize batch container
    keras_model = keras.models.load_model(network_dir + 'model_final.h5')
    keras_input_batch = np.zeros((4000, parameter_matrix.shape[1] + 2))
    keras_input_batch[:, parameter_matrix.shape[1]:] = plot_data

    for i in range(len(ax_titles)):

        print('Making Plot: ', i)

        row_tmp = int(np.floor(i / cols))
        col_tmp = i - (cols * row_tmp)

        # Get predictions from keras model
        keras_input_batch[:, :parameter_matrix.shape[1]] = parameter_matrix[
            i, :]
        ll_out_keras = keras_model.predict(keras_input_batch, batch_size=100)

        # Get prediction from navarro if traindatanalytic = 1
        if traindatanalytic:
            ll_out_gt = cdw.batch_fptd(plot_data[:, 0] * plot_data[:, 1],
                                       v=parameter_matrix[i, 0],
                                       a=parameter_matrix[i, 1],
                                       w=parameter_matrix[i, 2],
                                       ndt=parameter_matrix[i, 3])

            sns.lineplot(plot_data[:, 0] * plot_data[:, 1],
                         ll_out_gt,
                         color='black',
                         alpha=0.5,
                         label='TRUE',
                         ax=ax[row_tmp, col_tmp])

        # Get predictions from simulations /kde

        if not traindatanalytic:
            for j in range(nreps):
                if model == 'ddm' or model == 'ddm_analytic':
                    out = cds.ddm_flexbound(v=parameter_matrix[i, 0],
                                            a=parameter_matrix[i, 1],
                                            w=parameter_matrix[i, 2],
                                            ndt=parameter_matrix[i, 3],
                                            s=1,
                                            delta_t=0.001,
                                            max_t=20,
                                            n_samples=n_samples,
                                            print_info=False,
                                            boundary_fun=bf.constant,
                                            boundary_multiplicative=True,
                                            boundary_params={})

                if model == 'ddm_sdv':
                    out = cds.ddm_sdv(v=parameter_matrix[i, 0],
                                      a=parameter_matrix[i, 1],
                                      w=parameter_matrix[i, 2],
                                      ndt=parameter_matrix[i, 3],
                                      sdv=parameter_matrix[i, 4],
                                      s=1,
                                      delta_t=0.001,
                                      max_t=20,
                                      n_samples=n_samples,
                                      print_info=False,
                                      boundary_fun=bf.constant,
                                      boundary_multiplicative=True,
                                      boundary_params={})

                if model == 'full_ddm' or model == 'full_ddm2':
                    out = cds.full_ddm(v=parameter_matrix[i, 0],
                                       a=parameter_matrix[i, 1],
                                       w=parameter_matrix[i, 2],
                                       ndt=parameter_matrix[i, 3],
                                       dw=parameter_matrix[i, 4],
                                       sdv=parameter_matrix[i, 5],
                                       dndt=parameter_matrix[i, 6],
                                       s=1,
                                       delta_t=0.001,
                                       max_t=20,
                                       n_samples=n_samples,
                                       print_info=False,
                                       boundary_fun=bf.constant,
                                       boundary_multiplicative=True,
                                       boundary_params={})

                if model == 'angle' or model == 'angle2':
                    out = cds.ddm_flexbound(
                        v=parameter_matrix[i, 0],
                        a=parameter_matrix[i, 1],
                        w=parameter_matrix[i, 2],
                        ndt=parameter_matrix[i, 3],
                        s=1,
                        delta_t=0.001,
                        max_t=20,
                        n_samples=n_samples,
                        print_info=False,
                        boundary_fun=bf.angle,
                        boundary_multiplicative=False,
                        boundary_params={'theta': parameter_matrix[i, 4]})

                if model == 'weibull_cdf' or model == 'weibull_cdf2':
                    out = cds.ddm_flexbound(v=parameter_matrix[i, 0],
                                            a=parameter_matrix[i, 1],
                                            w=parameter_matrix[i, 2],
                                            ndt=parameter_matrix[i, 3],
                                            s=1,
                                            delta_t=0.001,
                                            max_t=20,
                                            n_samples=n_samples,
                                            print_info=False,
                                            boundary_fun=bf.weibull_cdf,
                                            boundary_multiplicative=True,
                                            boundary_params={
                                                'alpha': parameter_matrix[i,
                                                                          4],
                                                'beta': parameter_matrix[i, 5]
                                            })

                if model == 'levy':
                    out = cds.levy_flexbound(v=parameter_matrix[i, 0],
                                             a=parameter_matrix[i, 1],
                                             w=parameter_matrix[i, 2],
                                             alpha_diff=parameter_matrix[i, 3],
                                             ndt=parameter_matrix[i, 4],
                                             s=1,
                                             delta_t=0.001,
                                             max_t=20,
                                             n_samples=n_samples,
                                             print_info=False,
                                             boundary_fun=bf.constant,
                                             boundary_multiplicative=True,
                                             boundary_params={})

                if model == 'ornstein':
                    out = cds.ornstein_uhlenbeck(v=parameter_matrix[i, 0],
                                                 a=parameter_matrix[i, 1],
                                                 w=parameter_matrix[i, 2],
                                                 g=parameter_matrix[i, 3],
                                                 ndt=parameter_matrix[i, 4],
                                                 s=1,
                                                 delta_t=0.001,
                                                 max_t=20,
                                                 n_samples=n_samples,
                                                 print_info=False,
                                                 boundary_fun=bf.constant,
                                                 boundary_multiplicative=True,
                                                 boundary_params={})

                mykde = kdec.logkde((out[0], out[1], out[2]))
                ll_out_gt = mykde.kde_eval((plot_data[:, 0], plot_data[:, 1]))

                # Plot kde predictions
                if j == 0:
                    sns.lineplot(plot_data[:, 0] * plot_data[:, 1],
                                 np.exp(ll_out_gt),
                                 color='black',
                                 alpha=0.5,
                                 label='KDE',
                                 ax=ax[row_tmp, col_tmp])
                elif j > 0:
                    sns.lineplot(plot_data[:, 0] * plot_data[:, 1],
                                 np.exp(ll_out_gt),
                                 color='black',
                                 alpha=0.5,
                                 ax=ax[row_tmp, col_tmp])

            # Plot keras predictions
            sns.lineplot(plot_data[:, 0] * plot_data[:, 1],
                         np.exp(ll_out_keras[:, 0]),
                         color='green',
                         label='MLP',
                         alpha=1,
                         ax=ax[row_tmp, col_tmp])

        # Legend adjustments
        if row_tmp == 0 and col_tmp == 0:
            ax[row_tmp, col_tmp].legend(loc='upper left',
                                        fancybox=True,
                                        shadow=True,
                                        fontsize=12)
        else:
            ax[row_tmp, col_tmp].legend().set_visible(False)

        if row_tmp == rows - 1:
            ax[row_tmp, col_tmp].set_xlabel('rt', fontsize=24)
        else:
            ax[row_tmp, col_tmp].tick_params(color='white')

        if col_tmp == 0:
            ax[row_tmp, col_tmp].set_ylabel('likelihood', fontsize=24)

        ax[row_tmp, col_tmp].set_title(ax_titles[i], fontsize=20)
        ax[row_tmp, col_tmp].tick_params(axis='y', size=16)
        ax[row_tmp, col_tmp].tick_params(axis='x', size=16)

    for i in range(len(ax_titles), rows * cols, 1):
        row_tmp = int(np.floor(i / cols))
        col_tmp = i - (cols * row_tmp)
        ax[row_tmp, col_tmp].axis('off')

    if save == True:
        if machine == 'home':
            fig_dir = "/users/afengler/OneDrive/git_repos/nn_likelihoods/figures/" + method + "/likelihoods/"
            if not os.path.isdir(fig_dir):
                os.mkdir(fig_dir)

        figure_name = 'mlp_vs_kde_likelihood_'
        plt.subplots_adjust(top=0.9)
        plt.subplots_adjust(hspace=0.3, wspace=0.3)

        if traindatanalytic == 1:
            if plot_format == 'svg':
                plt.savefig(fig_dir + '/' + figure_name + model +
                            data_signature + '_' + train_data_type + '.svg',
                            format='svg',
                            transparent=True,
                            frameon=False)
            if plot_format == 'png':
                plt.savefig(fig_dir + '/' + figure_name + model + '_analytic' +
                            '.png',
                            dpi=300)  #, bbox_inches = 'tight')

        else:
            if plot_format == 'svg':
                plt.savefig(fig_dir + '/' + figure_name + model + '_kde' +
                            '.svg',
                            format='svg',
                            transparent=True,
                            frameon=False)

            if plot_format == 'png':
                plt.savefig(fig_dir + '/' + figure_name + model + '_kde' +
                            '.png',
                            dpi=300)  #, bbox_inches = 'tight')

    if show:
        return plt.show()
    else:
        plt.close()
        return 'finished'
def simulator(theta,
              model='angle',
              n_samples=1000,
              n_trials=1,
              delta_t=0.001,
              max_t=20,
              cartoon=False,
              bin_dim=None,
              bin_pointwise=False):

    # Useful for sbi
    if type(theta) == list:
        print('theta is supplied as list --> simulator assumes n_trials = 1')
        theta = np.asarray(theta).astype(np.float32)
    elif type(theta) == np.ndarray:
        theta = theta.astype(np.float32)
    else:
        theta = theta.numpy()

    if len(theta.shape) < 2:
        theta = np.expand_dims(theta, axis=0)
    if theta.shape[0] != n_trials:
        print(
            'ERROR number of trials does not match first dimension of theta array'
        )
        return

    # 2 choice models
    if cartoon:
        s = 0.0
    else:
        s = 1.0

    if model == 'test':
        x = ddm_flexbound(v=theta[:, 0],
                          a=theta[:, 1],
                          w=theta[:, 2],
                          ndt=theta[:, 3],
                          s=s,
                          n_samples=n_samples,
                          n_trials=n_trials,
                          delta_t=delta_t,
                          boundary_params={},
                          boundary_fun=bf.constant,
                          boundary_multiplicative=True,
                          max_t=max_t)

    if model == 'ddm' or model == 'ddm_elife' or model == 'ddm_analytic':
        x = ddm_flexbound(v=theta[:, 0],
                          a=theta[:, 1],
                          w=theta[:, 2],
                          ndt=theta[:, 3],
                          s=s,
                          n_samples=n_samples,
                          n_trials=1,
                          delta_t=delta_t,
                          boundary_params={},
                          boundary_fun=bf.constant,
                          boundary_multiplicative=True,
                          max_t=max_t)

    if model == 'angle' or model == 'angle2':
        x = ddm_flexbound(v=theta[:, 0],
                          a=theta[:, 1],
                          w=theta[:, 2],
                          ndt=theta[:, 3],
                          s=s,
                          boundary_fun=bf.angle,
                          boundary_multiplicative=False,
                          boundary_params={'theta': theta[:, 4]},
                          delta_t=delta_t,
                          n_samples=n_samples,
                          n_trials=n_trials,
                          max_t=max_t)

    if model == 'weibull_cdf' or model == 'weibull_cdf2' or model == 'weibull_cdf_ext' or model == 'weibull_cdf_concave' or model == 'weibull':
        x = ddm_flexbound(v=theta[:, 0],
                          a=theta[:, 1],
                          w=theta[:, 2],
                          ndt=theta[:, 3],
                          s=s,
                          boundary_fun=bf.weibull_cdf,
                          boundary_multiplicative=True,
                          boundary_params={
                              'alpha': theta[:, 4],
                              'beta': theta[:, 5]
                          },
                          delta_t=delta_t,
                          n_samples=n_samples,
                          n_trials=n_trials,
                          max_t=max_t)

    if model == 'levy':
        x = levy_flexbound(v=theta[:, 0],
                           a=theta[:, 1],
                           w=theta[:, 2],
                           alpha_diff=theta[:, 3],
                           ndt=theta[:, 4],
                           s=s,
                           boundary_fun=bf.constant,
                           boundary_multiplicative=True,
                           boundary_params={},
                           delta_t=delta_t,
                           n_samples=n_samples,
                           n_trials=n_trials,
                           max_t=max_t)

    if model == 'full_ddm' or model == 'full_ddm2':
        x = full_ddm(v=theta[:, 0],
                     a=theta[:, 1],
                     w=theta[:, 2],
                     ndt=theta[:, 3],
                     dw=theta[:, 4],
                     sdv=theta[:, 5],
                     dndt=theta[:, 6],
                     s=s,
                     boundary_fun=bf.constant,
                     boundary_multiplicative=True,
                     boundary_params={},
                     delta_t=delta_t,
                     n_samples=n_samples,
                     n_trials=n_trials,
                     max_t=max_t)

    if model == 'ddm_sdv':
        x = ddm_sdv(v=theta[:, 0],
                    a=theta[:, 1],
                    w=theta[:, 2],
                    ndt=theta[:, 3],
                    sdv=theta[:, 4],
                    s=s,
                    boundary_fun=bf.constant,
                    boundary_multiplicative=True,
                    boundary_params={},
                    delta_t=delta_t,
                    n_samples=n_samples,
                    n_trials=n_trials,
                    max_t=max_t)

    if model == 'ornstein' or model == 'ornstein_uhlenbeck':
        x = ornstein_uhlenbeck(v=theta[:, 0],
                               a=theta[:, 1],
                               w=theta[:, 2],
                               g=theta[:, 3],
                               ndt=theta[:, 4],
                               s=s,
                               boundary_fun=bf.constant,
                               boundary_multiplicative=True,
                               boundary_params={},
                               delta_t=delta_t,
                               n_samples=n_samples,
                               n_trials=n_trials,
                               max_t=max_t)

    # 3 Choice models
    if cartoon:
        s = np.tile(np.array([0.0, 0.0, 0.0], dtype=np.float32), (n_trials, 1))
    else:
        s = np.tile(np.array([1.0, 1.0, 1.0], dtype=np.float32), (n_trials, 1))

    if model == 'race_model_3' or model == 'race_3':
        x = race_model(v=theta[:, :3],
                       a=theta[:, [3]],
                       w=theta[:, 4:7],
                       ndt=theta[:, [7]],
                       s=s,
                       boundary_fun=bf.constant,
                       boundary_multiplicative=True,
                       boundary_params={},
                       delta_t=delta_t,
                       n_samples=n_samples,
                       n_trials=n_trials,
                       max_t=max_t)

    if model == 'lca_3':
        x = lca(v=theta[:, :3],
                a=theta[:, [4]],
                w=theta[:, 4:7],
                g=theta[:, [7]],
                b=theta[:, [8]],
                ndt=theta[:, [9]],
                s=s,
                boundary_fun=bf.constant,
                boundary_multiplicative=True,
                boundary_params={},
                delta_t=delta_t,
                n_samples=n_samples,
                n_trials=n_trials,
                max_t=max_t)

    # 4 Choice models
    if cartoon:
        s = np.tile(np.array([0.0, 0.0, 0.0, 0.0], dtype=np.float32),
                    (n_trials, 1))
    else:
        s = np.tile(np.array([1.0, 1.0, 1.0, 1.0], dtype=np.float32),
                    (n_trials, 1))

    if model == 'race_model_4' or model == 'race_4':
        x = race_model(v=theta[:, :4],
                       a=theta[:, [4]],
                       w=theta[:, 5:9],
                       ndt=theta[:, [9]],
                       s=s,
                       boundary_fun=bf.constant,
                       boundary_multiplicative=True,
                       boundary_params={},
                       delta_t=delta_t,
                       n_samples=n_samples,
                       n_trials=n_trials,
                       max_t=max_t)

    if model == 'lca_4':
        x = lca(v=theta[:, :4],
                a=theta[:, [4]],
                w=theta[:, 5:9],
                g=theta[:, [9]],
                b=theta[:, [10]],
                ndt=theta[:, [11]],
                s=s,
                boundary_fun=bf.constant,
                boundary_multiplicative=True,
                boundary_params={},
                delta_t=delta_t,
                n_samples=n_samples,
                n_trials=n_trials,
                max_t=max_t)

    # Seq / Parallel models (4 choice)
    if cartoon:
        s = 0.0
    else:
        s = 1.0

    if model == 'ddm_seq2':
        x = ddm_flexbound_seq2(v_h=theta[:, 0],
                               v_l_1=theta[:, 1],
                               v_l_2=theta[:, 2],
                               a=theta[:, 3],
                               w_h=theta[:, 4],
                               w_l_1=theta[:, 5],
                               w_l_2=theta[:, 6],
                               ndt=theta[:, 7],
                               s=s,
                               n_samples=n_samples,
                               n_trials=n_trials,
                               delta_t=delta_t,
                               max_t=max_t,
                               boundary_fun=bf.constant,
                               boundary_multiplicative=True,
                               boundary_params={})

    if model == 'ddm_par2':
        x = ddm_flexbound_par2(v_h=theta[:, 0],
                               v_l_1=theta[:, 1],
                               v_l_2=theta[:, 2],
                               a=theta[:, 3],
                               w_h=theta[:, 4],
                               w_l_1=theta[:, 5],
                               w_l_2=theta[:, 6],
                               ndt=theta[:, 7],
                               s=s,
                               n_samples=n_samples,
                               n_trials=n_trials,
                               delta_t=delta_t,
                               max_t=max_t,
                               boundary_fun=bf.constant,
                               boundary_multiplicative=True,
                               boundary_params={})

    if model == 'ddm_mic2':
        x = ddm_flexbound_mic2(v_h=theta[:, 0],
                               v_l_1=theta[:, 1],
                               v_l_2=theta[:, 2],
                               a=theta[:, 3],
                               w_h=theta[:, 4],
                               w_l_1=theta[:, 5],
                               w_l_2=theta[:, 6],
                               d=theta[:, 7],
                               ndt=theta[:, 8],
                               s=s,
                               n_samples=n_samples,
                               n_trials=n_trials,
                               delta_t=delta_t,
                               max_t=max_t,
                               boundary_fun=bf.constant,
                               boundary_multiplicative=True,
                               boundary_params={})

    if n_trials == 1:
        #print('passing through')
        #print(x)
        x = (np.squeeze(x[0], axis=1), np.squeeze(x[1], axis=1), x[2])

    if bin_dim == 0 or bin_dim == None:
        return x
    elif bin_dim > 0 and not bin_pointwise and n_trials == 1:
        binned_out = bin_simulator_output(x, nbins=bin_dim)
        return (binned_out, x[2])
    elif bin_dim > 0 and bin_pointwise and n_trials == 1:
        binned_out = bin_simulator_output_pointwise(x, nbins=bin_dim)
        return (np.expand_dims(binned_out[:, 0],
                               axis=1), np.expand_dims(binned_out[:, 1],
                                                       axis=1), x[2])
    elif bin_dim > 0 and n_trials > 1:
        return 'currently binned outputs not implemented for multi-trial simulators'
    elif bin_dim == -1:
        return 'invalid bin_dim'