def urgency_gating(trial): """ Decide using Cisek's (2009) urgency gating algorithm. """ l = float(len(trial)) for ii, t in enumerate(trial): urgency = ii ## urgency is elapsed "time", ## i.e. a index of trial length pA_ii = _p_response(trial, ii, 'A') pB_ii = _p_response(trial, ii, 'B') print("pA_ii: {0}".format(pA_ii)) print("pB_ii: {0}".format(pB_ii)) score_A = fabs(gain * urgency * (pA_ii - 0.5)) score_B = fabs(gain * urgency * (pB_ii - 0.5)) print("score_A: {0}".format(score_A)) print("score_B: {0}".format(score_B)) decision = decider(score_A, score_B, threshold, ii+1) if decision != None: return decision else: # If threshold is never met, # we end up here... return _create_d_result('N', None, None, None)
def relcount(trial): """ Return a category (A, B, or N (neutral)) for <trial> based on proportion of As to Bs. """ cA = 0.0 cB = 0.0 for ii, t in enumerate(trial): # Update scores based on t if t == 'A': cA += 1 else: cB += 1 if (cA > 0) and (cB > 0): score_A = cA / (cA + cB) score_B = 1 - score_A # And see if a decision can be made decision = decider(score_A, score_B, threshold, ii+1) if decision != None: return decision else: continue else: # If threshold is never met, # we end up here... return _create_d_result('N', None, None, None)
def incremental_lba(trial): """ Use Brown and Heathcote's (2008) LBA model, modified so A/B updates are exclusive rather than simultanous, to make the decision. """ # Init score_A = k score_B = k for ii, t in enumerate(trial): if t == 'A': # An incremental version of LBA. # that recognizes the balistic updates # are exclusive. A and B updates happen # at each time step. In this form # updates are exclusive to A or B # but still ballistic. score_A += d else: score_B += d decision = decider(score_A, score_B, threshold, ii+1) if decision != None: return decision else: # If threshold is never met, # we end up here... return _create_d_result('N', None, None, None)
def abscount(trial): """ Return a category (A, B, or N (neutral)) for <trial> based on number of As versus Bs. """ import random score_A = 0 score_B = 0 l = float(len(trial)) for ii, t in enumerate(trial): # Update scores based on t if t == 'A': score_A += 1 else: score_B += 1 # Norm them score_A_norm = score_A / l score_B_norm = score_B / l # print("({0}). {1}, {2}".format(ii, score_A_norm, score_B_norm)) # And see if a decision can be made decision = decider(score_A_norm, score_B_norm, threshold, ii+1) if decision != None: return decision else: # If threshold is never met, # we end up here... return _create_d_result('N', None, None, None)
def snr(trial): """ Gardelle et al's mean / SNR model. """ # Init l = len(trial) meanA = 0 meanB = 0 M2A = 0 # Second mean (needed for online) M2B = 0 score_A = 0.0 score_B = 0.0 for ii, t in enumerate(trial): n = ii + 1 ## reindex needed ## so n is the A/B count # Calculate the mean and sd # using online algortimns outlined # in Donald E. Knuth (1998). The Art of Computer # Programming, volume 2: Seminumerical Algorithms, # 3rd edn. x = 1.0 / l if t == 'A': delta = x - meanA meanA += delta/n # Can't update if any # of the denom are 0 try: M2A += delta * (x - meanA) sdA = sqrt(M2A / (n - 1)) score_A += meanA/sdA except ZeroDivisionError: if mean_default: score_A += meanA else: pass else: delta = x - meanB meanB += delta/n try: M2B += delta * (x - meanB) sdB = sqrt(M2B / (n - 1)) score_B += meanB/sdB except ZeroDivisionError: if mean_default: score_B += meanB else: pass # print("{2} - {3}. score_A: {0}, score_B: {1}".format( # score_A, score_B, ii, t)) # And see if a decision can be made decision = decider(score_A, score_B, threshold, n) if decision != None: return decision else: # If threshold is never met, # we end up here... return _create_d_result('N', None, None, None)
def information(trial): H_a = 0 H_b = 0 l = float(len(trial)) norm_const = np.log2(l) / l for ii,t in enumerate(trial): if t == 'A': H_a += -0.5 * np.log2(0.5) ## For a binary alphabet, b-ary entropy is ## H(A) = sum_i(b*log_2(b)) ## where b is the probability a letter ## in the alphabet ## appears at slot i (i.e. = t above). ## In this case b = p(A) = p(b) = 0.5 for all i. else: H_b += -0.5 * np.log2(0.5) # And see if a decision can be made decision = decider(H_a * norm_const, H_b * norm_const, threshold, ii+1) if decision != None: return decision else: # If threshold is never met, # we end up here... return _create_d_result('N', None, None, None)
def likelihood_ratio(trial): """ Use a version of the sequential ratio test to decide (log_10). """ # Transform threshold to suitable deciban # equivilant. dthreshold = threshold * 2.0 ## 2 decibans is 99% confidence, ## so use that to map threshold (0-1) ## to the deciban threshold (dthreshold). cA = 0.0 cB = 0.0 logLR = 0.0 l = float(len(trial)) for ii,t in enumerate(trial): if t == 'A': cA += 1 else: cB += 1 if (cA > 0) and (cB > 0): logLR += log(cA/cB, 10) else: continue ## This implementaion can't decide on all ## A or B trials. Live with this edge case for now? # A custom decision function # was necessary: if fabs(logLR) >= dthreshold: if logLR > 0: return _create_d_result('A', logLR, 0, ii+1) elif logLR < 0: return _create_d_result('B', logLR, 0, ii+1) elif logLR == 0: return _create_d_result('N', logLR, 0, ii+1) else: # It should be impossible to get here, however # just in case something very odd happens.... raise ValueError( "Something is very wrong with the scores.") else: # If threshold is never met, # we end up here... return _create_d_result('N', None, None, None)
def blcba(trial): """ Decide using Usher and McClelland's (2001) ballistic leaky competing accumulator model. """ score_A = k score_B = k # impulse = wi * (1.0 / length) for ii, t in enumerate(trial): # As score_A + score_B = 1, if one is 1, the # other must be zero. if t == 'A': score_A += wi * 1 - (k * score_A) - beta * score_B score_B += wi * 0 - (k * score_B) - beta * score_A else: score_A += wi * 0 - (k * score_A) - beta * score_B score_B += wi * 1 - (k * score_B) - beta * score_A # print("{2} - {3}. score_A: {0}, score_B: {1}".format( # score_A, score_B, ii, t)) # Scores must be postive, # reset if otherwise if score_A < 0: # print("Reset A") score_A = 0 elif score_B < 0: score_B = 0 # print("Reset B") decision = decider(score_A, score_B, threshold, ii+1) if decision != None: # print("hit") return decision else: # If threshold is never met, # we end up here... return _create_d_result('N', None, None, None)
def naive_probability(trial): """ Calculate the likelihood of the continuous sequence of either A or B in <trial>, decide when p_sequence(A) or (B) exceeds <threshold>. """ ## Init score_A = 0 score_B = 0 lastcat = trial[0] p = 0.5 # Loop over trial calculating scores. for ii, t in enumerate(trial[1:]): if t == lastcat: # If t is the same, # decrease the likelihood (p). p = p * 0.5 # Assign p to a score, # also reflect it if t == 'A': score_A = 1 - deepcopy(p) else: score_B = 1 - deepcopy(p) # And see if a decision can be made decision = decider(score_A, score_B, threshold, ii+1) if decision != None: return decision else: # Otherwise reset lastcat = deepcopy(t) p = 0.5 else: # If threshold is never met, # we end up here... return _create_d_result('N', None, None, None)