# Model parameters
kappa = 0.08  # Maximal contrast difference value
sigma = 0.04  # Perceptual sensitivity

# Initialize task and agent objects
# ---------------------------------

# Task parameters in TaskVars object
task_vars = TaskVars()
task_vars.T = T
task_vars.B = 1
task = Task(task_vars)

# Agent parameters in AgentVars object
agent_vars = AgentVars()
agent_vars.agent = 1
agent_vars.sigma = sigma
agent_vars.task_agent_analysis = False
agent = Agent(agent_vars)
agent.d_t = 0  # Fix perceptual decision to d_t = 0
agent.a_t = 0  # Fix action to a_t = 0

# Sampling-based approximation object
p_hat = PHat(n_bins)

# Number of variables x number of samples x number of time points sample matrix
S = np.full([5, n_samples, T], np.nan)

# Simulation scenarios / observed random variable values
# ------------------------------------------------------
Ejemplo n.º 2
0
    def edm_l_model(self, exp_data, est_vars, sub_params, est_params=1, save_plot=0):
        """ This function computes the likelihood of the models that include economic decision making

            Used for both, evaluation with fixed parameters and estimation with
            free parameters.

        :param exp_data: Data of current experiment
        :param est_vars: Variables that are used for estimation and evaluation
        :param sub_params: Participants' parameter estimates
        :param est_params: Indicates if we evaluate model or additionally estimate a free parameter
        :param save_plot: Indicates if we save plot of model evaluation
        :return: results: Results of evaluation and estimation procedure
        """

        # Control random number generator for reproducible results
        random.seed(123)

        # Agent parameters in GbAgentVars.py object
        agent_vars = AgentVars()

        # Select current agent
        agent_vars.agent = est_vars.agent
        self.agent = est_vars.agent

        # eventuell reset_index() anstatt andere Lösung.
        # --> https://cmdlinetips.com/2018/04/how-to-reset-index-in-pandas-dataframe/
        # Reset index for perceptual parameter estimation
        exp_data.loc[:, 'trial'] = np.linspace(0, len(exp_data)-1, len(exp_data))
        exp_data = exp_data.set_index('trial')

        # Evaluate likelihood of perceptual decisions
        f_llh_d = self.d_llh(sub_params['sigma'], exp_data, agent_vars)

        # Reset index for additional parameter estimation
        exp_data.loc[:, 'trial'] = np.tile(np.linspace(0, self.T-1, self.T), self.B)
        exp_data = exp_data.set_index('trial')

        # Add ID to results to check if participant order is maintained during parallelization
        self.id = np.array(list(set(exp_data['id'])))

        # Estimate free parameters
        if est_params:

            # Initialize values
            min_llh = 1e10  # unrealistically high likelihood
            min_x = np.nan  # no parameter estimate

            # Cycle over starting points
            for r in range(0, self.n_sp):

                # Estimate parameters
                if self.agent == 1 or self.agent == 2:
                    if self.rand_sp:
                        x0 = [random.uniform(self.b_bnds[0], self.b_bnds[1])]
                    else:
                        x0 = np.array([self.b_fixedsp])

                    # Parameter boundary
                    bounds = [self.b_bnds, ]

                elif self.agent == 3:

                    # Starting point
                    if self.rand_sp:
                        x0 = [random.uniform(self.l_bnds[0], self.l_bnds[1]),
                              random.uniform(self.b_bnds[0], self.b_bnds[1])]
                    else:
                        x0 = [self.l_fixedsp, self.b_fixedsp]

                    # Parameter boundary
                    bounds = [self.l_bnds, self.b_bnds]

                elif self.agent == 4 or self.agent == 5:
                    if self.rand_sp:
                        x0 = [random.uniform(self.b_bnds[0], self.b_bnds[1]),
                              random.uniform(self.a_bnds[0], self.a_bnds[1])]
                    else:
                        x0 = [self.b_fixedsp, self.a_fixedsp]

                    # Parameter boundary
                    bounds = [self.b_bnds, self.a_bnds]
                else:
                    if self.rand_sp:
                        x0 = [random.uniform(self.l_bnds[0], self.l_bnds[1]),
                              random.uniform(self.a_bnds[0], self.a_bnds[1]),
                              random.uniform(self.b_bnds[0], self.b_bnds[1])]
                    else:
                        x0 = [self.l_fixedsp, self.a_fixedsp, self.b_fixedsp]

                    # Parameter boundary
                    bounds = [self.l_bnds, self.a_bnds, self.b_bnds]

                # Run the estimation
                res = minimize(self.a_llh, x0, args=(exp_data, sub_params, agent_vars, est_params), method='L-BFGS-B',
                               bounds=bounds)

                # Extract maximum likelihood parameter estimate
                x = res.x

                # Extract minimized negative log likelihood
                llh = res.fun

                # Check if cumulated negative log likelihood is lower than the previous
                # one and select the lowest
                if llh < min_llh:
                    min_llh = llh
                    min_x = x

            # Compute BIC for economic decision
            if self.agent == 1 or self.agent == 2:
                bic_a = self.compute_bic(min_llh, 1)
            elif self.agent == 3 or self.agent == 4 or self.agent == 5:
                bic_a = self.compute_bic(min_llh, 2)
            else:
                bic_a = self.compute_bic(min_llh, 3)

        else:

            # Evaluate the model
            if self.agent == 1:
                min_llh = self.a_llh(sub_params['beta_A1'], exp_data, sub_params, agent_vars, est_params,
                                     save_plot=save_plot)
            elif self.agent == 2:
                min_llh = self.a_llh(sub_params['beta_A2'], exp_data, sub_params, agent_vars, est_params,
                                     save_plot=save_plot)
            elif self.agent == 3:
                min_llh = self.a_llh([sub_params['lambda_A3'], sub_params['beta_A3']], exp_data, sub_params,
                                     agent_vars, est_params, save_plot=save_plot)
            elif self.agent == 4:
                min_llh = self.a_llh([sub_params['beta_A4'], sub_params['alpha_A4']], exp_data, sub_params,
                                     agent_vars, est_params, save_plot=save_plot)
            elif self.agent == 5:
                min_llh = self.a_llh([sub_params['beta_A5'], sub_params['alpha_A5']], exp_data, sub_params,
                                     agent_vars, est_params, save_plot=save_plot)
            elif self.agent == 6:
                min_llh = self.a_llh([sub_params['lambda_A6'], sub_params['alpha_A6'], sub_params['beta_A6']],
                                     exp_data, sub_params, agent_vars, est_params, save_plot=save_plot)
            else:
                # A0
                min_llh = self.a_llh(np.nan, exp_data, sub_params, agent_vars, est_params, save_plot=save_plot)

            # Compute BIC
            bic_a = self.compute_bic(min_llh, 0)

        # Compute BIC for perceptual decision without free parameters
        bic_d = self.compute_bic(f_llh_d, 0)

        # Initialize and fill list with results
        results_list = list()
        results_list.append(np.float(min_llh))
        results_list.append(np.float(bic_d))
        results_list.append(np.float(bic_a))
        results_list.append(np.float(self.id))
        results_list.append(np.float(self.agent))

        if est_params:
            min_x = min_x.tolist()
            results_list = results_list + min_x

        return results_list
def gb_simulation(n_trials,
                  n_blocks,
                  sigma,
                  agent,
                  beta,
                  task_agent_analysis=False,
                  eval_ana=True):
    """ This function runs the simulations for model demonstration

    :param n_trials: Number of trials
    :param n_blocks: Number of blocks
    :param sigma: Perceptual sensitivity
    :param agent: Agent-based computational model
    :param beta: Inverse temperature parameter
    :param task_agent_analysis: Indicates if use for data analysis or not
    :param eval_ana: Evaluate agent analytically
    :return: df_subj: Data frame containing simulated data
    """

    # Parameter definition
    # --------------------

    # Task parameters in GbTaskVars.py object
    task_vars = TaskVars()
    task_vars.T = n_trials
    task_vars.B = n_blocks
    task_vars.experiment = 3

    # Agent parameters in GbAgentVars.py object
    agent_vars = AgentVars()
    agent_vars.sigma = sigma
    agent_vars.beta = beta
    agent_vars.c0 = np.array([1])
    agent_vars.kappa = task_vars.kappa
    agent_vars.agent = agent
    agent_vars.lambda_param = np.nan
    agent_vars.task_agent_analysis = task_agent_analysis
    agent_vars.eval_ana = eval_ana

    # Simulation parameters in GbSimVars.py object
    sim_vars = SimVars()

    # Initialize data frame for simulation
    df_subj = pd.DataFrame()

    sleep(0.1)
    print('\nSimulating data for agent demonstration:')
    sleep(0.1)
    pbar = tqdm(total=task_vars.B)

    # Cycle over task blocks
    for b in range(0, task_vars.B):

        # Update progress bar
        pbar.update(1)

        # Block number definition
        sim_vars.block = b
        sim_vars.take_pd = 0

        # Single block task-agent-interaction simulation
        df_block = gb_task_agent_int(task_vars, agent_vars, sim_vars)

        # Add data to data frame
        df_subj = df_subj.append(df_block, ignore_index=True)

    # Close progress bar
    pbar.close()

    return df_subj
def recovsim(task_vars, sim_vars, exp_data, **kwargs):
    """ This function runs the simulations for parameter and model recovery

    :param task_vars: Variables to initialize the task object
    :param sim_vars: Variables to initialize the simulation object
    :param exp_data: Experimental data
    :param kwargs: Optionally; participant parameters
    :return: df_recov: Data-frame with simulated data
    """

    # Extract the optionally provided parameters
    opt_params = kwargs.get('opt_params', None)

    # Agent parameters
    agent_vars = AgentVars()
    agent_vars.agent = sim_vars.agent

    # Initialize data frame for data that will be recovered
    df_recov = pd.DataFrame()

    # Initialize counter for simulation order
    sleep(0.1)
    print('\nSimulating data for recovery | Agent A%s:' % sim_vars.agent)
    sleep(0.1)
    pbar = tqdm(total=len(opt_params))

    # Initialize array that indicates the ID of data set used for simulations
    which_id = np.full(len(opt_params), np.nan)

    # Cycle over parameters
    for m in range(0, len(opt_params)):

        # Randomly determine current data set
        which_id[m] = randint(0, sim_vars.N - 1)

        # For experiment 2 and 3 we additionally use participant parameters
        if task_vars.experiment == 2:
            agent_vars.sigma = opt_params['sigma'][m]
        elif task_vars.experiment == 3:
            agent_vars.sigma = opt_params['sigma'][m]
            if sim_vars.agent == 1:
                agent_vars.beta = opt_params['beta_A1'][m]
            elif sim_vars.agent == 2:
                agent_vars.beta = opt_params['beta_A2'][m]
            elif sim_vars.agent == 3:
                agent_vars.beta = opt_params['beta_A3'][m]
                agent_vars.lambda_param = opt_params['lambda_A3'][m]
            elif sim_vars.agent == 4:
                agent_vars.beta = opt_params['beta_A4'][m]
                agent_vars.alpha = opt_params['alpha_A4'][m]
            elif sim_vars.agent == 5:
                agent_vars.beta = opt_params['beta_A5'][m]
                agent_vars.alpha = opt_params['alpha_A5'][m]
            elif sim_vars.agent == 6:
                agent_vars.beta = opt_params['beta_A6'][m]
                agent_vars.alpha = opt_params['alpha_A6'][m]
                agent_vars.lambda_param = opt_params['lambda_A6'][m]

        # Cycle over task blocks
        for b in range(0, task_vars.B):

            # Extract data of current block
            exp_data_block = exp_data[(exp_data['id'] == which_id[m])
                                      & (exp_data['b_t'] == b)].copy()

            # Add trial as index
            exp_data_block.loc[:,
                               'trial'] = np.linspace(0,
                                                      len(exp_data_block) - 1,
                                                      len(exp_data_block))
            exp_data_block = exp_data_block.set_index('trial')

            # Block number definition
            sim_vars.block = b

            # Single block task-agent-interaction simulation
            df_block = gb_task_agent_int(task_vars,
                                         agent_vars,
                                         sim_vars,
                                         real_outc=exp_data_block)
            df_block['id'] = m
            df_block['blockNumber'] = b
            df_block['agent'] = sim_vars.agent

            # Add data to data frame
            df_recov = df_recov.append(df_block, ignore_index=True)

        # Update progress bar
        pbar.update(1)

    if task_vars.experiment == 2 or task_vars.experiment == 3:

        # Check if this is consistent across scripts
        # This could be adjusted at the global level
        df_recov = df_recov.rename(index=str,
                                   columns={"corr": "decision2.corr"})
        df_recov['a_t'] = df_recov['a_t'] + 1

    # Close progress par
    pbar.close()

    return df_recov