Example #1
0
    def __call__(self, fitted_model):
        # We want to use the fitted model
        self.hf0 = fitted_model.hf0
        self.w = fitted_model.w
        self.nu = fitted_model.nu
        self.pi = fitted_model.pi

        X_ = fitted_model.X.copy()
        for j in fitted_model.applythreshold:
            X_[:, j] = threshold.u_v(X_[:, j], self.nu)
        self.history_evaluation(X_, fitted_model.r, (0.75, .55))

        out = [Likelihood_and_Slope_Collector(fitted_model)]  #0,1,2
        out.append([self.vdifficult])  # 3
        out.append([self.veasy])  # 4
        out.append([self.phist])  # 5
        out.append([self.pstim])  # 6
        out.append([self.pSH])  # 7
        out.append([self.peasy])  # 8
        out.append(fitted_model.pi)  # 9,10,11
        # out.append ( fitted_model.w[1:self.hf0] ) # 12,...,12+hf0
        out.append(
            self.get_thres(fitted_model.w[:self.hf0], fitted_model.nu,
                           fitted_model.pi, .75))  # 12,...,12+hf0
        out.append(
            self.get_thres(fitted_model.w[:self.hf0], fitted_model.nu,
                           fitted_model.pi, .85))  # 12+hf0,...,12+2*hf0
        out.append(fitted_model.nu)  #
        out.append(fitted_model.w)  #
        out.append(np.ravel(self.stimuli))
        out.append(np.ravel(self.conditions))
        out.append(np.ravel(self.variance_explained))
        return np.concatenate(out)
Example #2
0
def pmfplot(d, results, infodict, ax, errors=True):
    """Generate the pmf plot"""
    for i, c in enumerate(infodict['conditions']):
        c = int(c)
        d_ = d.getsummary(c)
        x = pl.mgrid[infodict['xmin']:infodict['xmax']:100j]
        if len(d.th_features) > 0:
            # d_[:,0] = u_v ( d_[:,0], results['model_w_hist'].nu )
            # x = u_v ( x, results['model_w_hist'].nu )
            d_[:, 0] = u_v(d_[:, 0], results['model_nohist'].nu)
            x = u_v(x, results['model_nohist'].nu)

        if errors:
            graphics.plot_data_summary(d_, ax, infodict['colors'][i],
                                       infodict['labels'][i])
        else:
            # AEU: change the marker to make datapoints small. What goes wrong in the plot here?
            ax.plot(d_[:, 0],
                    d_[:, 1] / d_[:, 2],
                    '.',
                    color=infodict['colors'][i],
                    label=infodict['labels'][i])

        # wfit  = results['model_w_hist'].w[infodict['indices'][c]]
        wfit = results['model_nohist'].w[infodict['indices'][i]]
        w0fit = results['model_w_hist'].w0[infodict['indices'][i]]
        pfit = results['model_w_hist'].pi
        p0fit = results['model_nohist'].pi

        if not d.ground_truth is None:
            wgfit = d.ground_truth['w'][infodict['indices'][i]]
            pgfit = d.ground_truth['pi']
            gt = graphics.plot_pmf(pgfit, wgfit, x, ax,
                                   (np.array([255, 240, 240], 'd') / 255 +
                                    infodict['colors'][i]) / 2.)
            pl.setp(gt, linestyle='--')

        # graphics.plot_pmf ( pfit, w0fit, x, ax, [.9,.9,.9], alpha=0.1 )
        graphics.plot_pmf(p0fit, wfit, x, ax, infodict['colors'][i])
    graphics.label_axes(title="(A) psychometric function",
                        xlabel=r"transduced stimulus $u_\nu(s\tilde{z})$",
                        ylabel=r"probability for $r=1$",
                        nxticks=5,
                        ax=ax)
Example #3
0
def plot_nonlinearity(nu, x=None, ax=None, color='k'):
    """Plot a threshold nonlinearity"""
    from threshold import u_v
    if ax is None:
        ax = pl.gca()
    ax = prepare_axes(ax)

    if x is None:
        xmin, xmax = ax.get_xlim()
        x = pl.mgrid[xmin:xmax:100j]

    return ax.plot(x, u_v(x, nu), color=color)
Example #4
0
 def pcorrect(self, x, pleft=0.5, pright=0.5, ind=[0, 1]):
     """Get probability of a correct response rather than probability of left/right response
     
     :Parameters:
         *x*         stimulus intensities
         *pleft*     probability that the stimulus is on the left (or number of stimuli on the left)
         *pright*    probability that the stimulus is on the right
     """
     Z = pleft + pright
     if Z > 1:
         pleft /= Z
         pright /= Z
     s = threshold.u_v(x, self.nu)
     psi_p = self.pi[1] + self.pi[2] * logistic(self.w[ind[0]] +
                                                self.w[ind[1]] * s)
     psi_m = self.pi[0] + self.pi[2] * (
         1 - logistic(self.w[ind[0]] - self.w[ind[1]] * s))
     return pleft * psi_m + pright * psi_p, s
Example #5
0
 def e(x):
     p1 = pi[1] + pi[2] * model.logistic(w[0] + w[i] *
                                         threshold.u_v(x, nu))
     p2 = 1 - (pi[1] + pi[2] *
               model.logistic(w[0] + w[i] * threshold.u_v(-x, nu)))
     return abs(.5 * p1 + .5 * p2 - p)
Example #6
0
    def history_evaluation(self, X, r, p):
        """Determine variance explained by history

        :Parameters:
            *X*
                design matrix
            *r*
                responses
            *p*
                probability correct that is considered the border between
                easy and difficult
        """
        difficult, easy = performance_filter(r, X, p, hf0=self.hf0)
        assert np.shape(
            np.shape(difficult))[0] == 1, 'difficult is not a vectors'
        assert np.shape(np.shape(easy))[0] == 1, 'easy is not a vectors'

        # AEU: get both output args from performance_filter
        #easy = np.logical_not ( difficult )

        X_ = X.copy()
        for j in self.applythreshold:
            X_[:, j] = threshold.u_v(X[:, j], self.nu)

        current_stimulus = np.dot(X_[:, 1:self.hf0], self.w[1:self.hf0])
        history_features = np.dot(X_[:, self.hf0:], self.w[self.hf0:])

        self.vdifficult = np.var ( history_features[difficult] ) / \
                (np.var (history_features[difficult]) + np.var(current_stimulus[difficult]))

        self.veasy      = np.var ( history_features[easy] ) / \
                (np.var (history_features[easy]) + np.var(current_stimulus[easy]))

        S = []
        V = []
        C = []

        for condition in xrange(1, self.hf0):
            stimuli = np.unique(abs(X_[:, condition]))
            S_ = []
            V_ = []
            for s in stimuli:
                if abs(s) < 1e-10:
                    continue
                i = abs(X_[:, condition]) == s
                S_.append(s)
                V_.append(
                    np.var(history_features[i]) /
                    (np.var(history_features[i]) +
                     np.var(current_stimulus[i])))
            S.append(S_)
            V.append(V_)
            C.append([condition] * len(S_))
        self.stimuli = np.concatenate(S)
        self.conditions = np.concatenate(C)
        self.variance_explained = np.concatenate(V)

        # c = -self.w[0]
        c = 0.
        self.phist = np.mean((history_features[difficult] > c) == r[difficult])
        self.pstim = np.mean((current_stimulus[difficult] > c) == r[difficult])
        self.pSH = np.mean(((history_features[difficult] +
                             current_stimulus[difficult]) > c) == r)
        self.peasy = np.mean((history_features[easy] > c) == r[easy])

        return np.var(current_stimulus), np.var(history_features), (S, V)
Example #7
0
    def __em(self, X, r):
        """Optimize parameters using expectation maximation

        :Parameters:
            *X*
                design matrix
            *r*
                response vector
        """
        w = self.w
        p = self.pi
        nu = self.nu
        # w = np.array ( [.01,.8,-.8,.5] )

        if self.verbose:
            print "Starting values:"
            print "nu:", nu
            print "w: ", w
            print "p: ", p

        X_ = X.copy()
        for j in self.applythreshold:
            X_[:, j] = threshold.u_v(X[:, j], nu)

        # Expectation
        gwx = history_model.__combine_features(X_, w)
        q = history_model.__determine_single_trial_lapses(r, gwx, p)
        p = history_model.__optimize_p(q, self.pprior)

        l = history_model.__likelihood(gwx, r, p)

        for i in xrange(self.emiter):
            # Maximization
            nu_ = nu
            nu = threshold.optimize_nu(X,
                                       r,
                                       q[:, -1],
                                       w,
                                       nu,
                                       self.applythreshold,
                                       niter=self.nuiter,
                                       stop=self.nustop)
            if np.isnan(nu):
                sys.exit(2)
            for j in self.applythreshold:
                X_[:, j] = threshold.u_v(X[:, j], nu)
            # if len ( self.applythreshold ) == 1:
            #     nu = threshold.optimize_nu ( X, r, q[:,-1], w, nu, niter=self.nuiter, stop=self.nustop )
            #     if np.isnan(nu):
            #         sys.exit ( 2 )
            #     for j in self.applythreshold:
            #         X_[:,j] = threshold.u_v ( X[:,j], nu )
            # elif len ( self.applythreshold ) > 1:
            #     raise NotImplementedError, "optimization of the threshold nu is not implemented for this case"

            w_ = w
            p_ = p
            w = glm.optimize_w(X_,
                               r,
                               q[:, -1],
                               w,
                               niter=self.glmiter,
                               stop=self.glmstop,
                               lm=self.lmprior)
            p = history_model.__optimize_p(q, self.pprior)
            if np.isnan(p).any():
                print i, p
                sys.exit(1)

            # Expectation
            gwx = history_model.__combine_features(X_, w)
            q = history_model.__determine_single_trial_lapses(r, gwx, p)

            l_ = history_model.__likelihood(gwx, r, p)

            # Stop?
            rel_e = np.abs((l_ - l) / l)
            abs_e = max(max(np.abs(w - w_).max(),
                            np.abs(p - p_).max()), abs(nu - nu_))
            if i > self.miniter:
                if rel_e < self.emstop and abs_e < self.emabs:
                    if self.verbose:
                        sys.stderr.write(
                            "Converged after %d iterations\n  relative error: %g\n  absolute error: %g\n"
                            % (i, rel_e, abs_e))
                    break
            if self.storeopt:
                self.opt.append([l_, rel_e, abs_e] + [pp for pp in p] +
                                [ww for ww in w] + [float(nu)])

            if self.verbose:
                print l_, rel_e, abs_e
            l = l_
        else:
            if self.verbose:
                sys.stderr.write(
                    "No convergence after %d iterations\nrelative error: %g\n"
                    % (i, rel_e))

        return w, p, q, l, nu
Example #8
0
def figure3 ( ):
    w,h = 25,8.5
    fig = pl.figure ( figsize=(fullwidth,h*fullwidth/w) )

    # a,b,c,d = place_axes ( fig, 1.5,2, [9,9,5,5],[6]*4,
    #         [True]*2+[False]*2, [1.8,1.8,.5,.5], (w,h) )
    a,b,c = place_axes ( fig, 1.5,2, [9,9,5],[6]*3,
            [True]*2+[False], [1.8,1.8,.5], (w,h) )
    d = fig.add_axes ( [10,10,1,1] )
    a.text ( .05, laby, r"\textbf{a}", transform=a.transAxes )
    b.text ( .05, laby, r"\textbf{b}", transform=b.transAxes )
    c.text ( .05, laby, r"\textbf{c}", transform=c.transAxes )
    d.text ( .05, laby, r"\textbf{d}", transform=d.transAxes )
    M = results['model_w_hist']

    # Figures 3 A,B
    for condition in plotinfo['conditions']:
        condition = int ( condition )
        print "c",condition
        d_ = data.getsummary ( condition )
        # x = pl.mgrid[0:plotinfo['xmax']:100j]
        x = pl.mgrid[0:30:100j]
        # if len(data.th_features)>0:
        #     x = threshold.u_v ( x, results['model_w_hist'].nu )

        wfit  = results['model_w_hist'].w[plotinfo['indices'][condition]]
        w0fit = results['model_nohist'].w[plotinfo['indices'][condition]]
        pfit  = results['model_w_hist'].pi
        p0fit  = results['model_nohist'].pi
        x_ = threshold.u_v ( x, results['model_w_hist'].nu )
        x0 = threshold.u_v ( x, results['model_nohist'].nu )

        col = plotinfo['colors'][condition]
        pmf = 0.5*(pfit[1]+pfit[2]*model.logistic ( wfit[0]+wfit[1]*x_ )) + \
                0.5*(1-(pfit[1]+pfit[2]*model.logistic ( wfit[0]-wfit[1]*x_ )))
        p0f = 0.5*(p0fit[1]+p0fit[2]*model.logistic ( w0fit[0]+w0fit[1]*x0 )) + \
                0.5*(1-(p0fit[1]+p0fit[2]*model.logistic ( w0fit[0]-w0fit[1]*x0 )))
        print p0fit
        perror = (1-p0f-(1-pmf))/(1-p0f)

        a.plot ( x, pmf, color = col )
        a.plot ( x, p0f, color = col, linestyle='--' )
        b.plot ( x, pl.clip(perror,0,1e5), color = col )

    a.yaxis.set_major_formatter ( prcformatter )
    a.xaxis.set_major_formatter ( myformatter )
    a.set_xticks ( (0,10,20,30) )

    pl.setp ( (a,b), xlabel='Stimulus intensity' )
    a.set_ylabel ( 'Probability correct [\%]' )
    b.set_ylabel ( 'Error rate exp. [\%]' )
    b.set_xticks ( (0,10,20,30) )
    b.yaxis.set_major_locator ( tckr ( density=2, figure=fig, which=1 ) )
    b.yaxis.set_major_formatter ( prcformatter )
    b.xaxis.set_major_formatter ( myformatter )
    if observer in ['KP','sim_KP','sim_KP_nh']:
        b.set_ylim ( 0, .35 )
    if observer in ['pk']:
        pl.setp ( (a,b), xlim=(-.1,30.1) )

    # figure 3 C
    textfile.write ( "Figure 3C:\n" )
    z0 = 0
    C = statistics.EvaluationCollector ( M )
    ewh = C(results['model_w_hist'])
    enh = C(results['model_nohist'])
    hf0 = M.hf0
    # perm = results['permutation_wh']
    # # TODO: These indices have to be adapted to the revised collector
    # thresholds_wh = pl.array([C.get_thres ( perm[i,13+hf0:13+2*hf0], perm[i,12+hf0], perm[i,9:12], p=0.75 ) \
    #         for i in xrange ( 2000 )])
    # perm = results['permutation_nh']
    # thresholds_nh = pl.array([C.get_thres ( perm[i,13+hf0:13+2*hf0], perm[i,12+hf0], perm[i,9:12], p=0.75 ) \
    #         for i in xrange ( 2000 )])
    if thlev == .75:
        thind = 11
    elif thlev == .85:
        thind = 10+hf0
    else:
        raise ValueError

    for condition in xrange ( 1, M.hf0 ):
        s_wh = results['permutation_wh'][:,thind+condition]
        s_nh = results['permutation_nh'][:,thind+condition]
        # s_wh = thresholds_wh[:,condition]
        # s_nh = thresholds_nh[:,condition]
        s_ratio = s_wh/s_nh
        s_ratio_obs = ewh[thind+condition]/enh[thind+condition]
        # s_ratio_obs = results['model_w_hist'].w[condition]/results['model_nohist'].w[condition]
        z = (s_ratio_obs-pl.mean(s_ratio))/pl.std(s_ratio)
        cpe = pl.mean ( s_ratio < s_ratio_obs )
        ci = pl.prctile ( s_ratio, (2.5,97.5) )
        if z < z0 and ci[1]-ci[0] > 0:
            c0 = condition
            s_ratio_ = s_ratio
            s_ratio_obs_ = s_ratio_obs
            ci_ = ci
        textfile.write (
                "Condition %d\n  th75_ratio = %g\n  cpe = %g\n  percentiles of Null-Distribution: %g, %g\n" % \
                        (condition,s_ratio_obs,cpe,ci[0],ci[1]) )
    try:
        print "Using condition %d for figure 3C" % (c0,)
    except:
        c0 = 1
        s_ratio_ = s_ratio
        s_ratio_obs_ = s_ratio_obs
        ci_ = ci

    hist,bins = pl.histogram ( s_ratio_ )
    c.bar ( bins[:-1], hist, pl.diff ( bins ),
        edgecolor=graphics.histogram_color, facecolor=graphics.histogram_color )
    yrange = c.get_ylim ()
    # c.plot ( [1]*2, yrange, 'k:' )
    if s_ratio_obs<ci_[0]:
        c.plot ( [s_ratio_obs_]*2, (yrange[0],yrange[0]+0.85*(yrange[1]-yrange[0])), linewidth=2,
                color=graphics.observed_color )
        c.plot ( [s_ratio_obs_], [yrange[0]+0.95*(yrange[1]-yrange[0])], '*', color=graphics.observed_color )
    else:
        c.plot ( [s_ratio_obs_]*2, yrange, linewidth=2, color=graphics.observed_color )
    c.plot ( [ci_[0]]*2, yrange, color=graphics.C95_color )
    c.plot ( [ci_[1]]*2, yrange, color=graphics.C95_color )
    c.set_ylim ( *yrange )
    c.set_xlabel ( r'Threshold ratio' )
    c.xaxis.set_major_formatter ( myformatter )
    c.xaxis.set_major_formatter ( myformatter )
    # c.text ( .7, 0.7, r"$\frac{\theta_\mathrm{h}}{\theta_0}$",
    #         transform=c.transAxes )
    # c.set_xlim ( trimmed_hlim ( s_ratio_, s_ratio_obs_ ) )
    # c.xaxis.set_major_locator ( tckr ( density=0.4, figure=fig, which=0 ) )
    c.set_xlim ( .99, 1.01 )
    # c.xaxis.set_ticks ( (.95,1) )
    # c.set_xlim ( .85, 1.05 )
    c.xaxis.set_ticks ( (.99,1.,1.01) )


    # figure 3 D
    l_wh  = 0.5*results['permutation_wh'][:,[9,10]].sum(1)
    l_nh  = 0.5*results['permutation_nh'][:,[9,10]].sum(1)
    l_ratio = l_wh-l_nh
    l_ratio_obs = results['model_w_hist'].pi[[0,1]].sum()-results['model_nohist'].pi[[0,1]].sum()
    cpe = pl.mean ( l_ratio < l_ratio_obs )
    ci = pl.prctile ( l_ratio, (2.5,97.5) )
    textfile.write (
        "Figure 3D:\n  lapse_ratio = %g\n  cpe = %g\n  percentiles of Null-distribution: %g, %g\n  lapse_rate (w hist) = %g\n  lapse_rate (no hist) = %g\n" % \
                (l_ratio_obs,cpe,ci[0],ci[1],results['model_w_hist'].pi[[0,1]].sum(),results['model_nohist'].pi[[0,1]].sum()) )

    d = graphics.prepare_axes ( d, haveon=('bottom',) )
    # hist,bins = pl.histogram ( l_ratio )
    hist,bins = pl.histogram ( l_ratio, bins=good_lapse_bins ( l_ratio ) )
    # hist,bins = pl.histogram ( l_ratio, bins=pl.mgrid[-.0001:.0001:20j] )
    d.bar ( bins[:-1], hist, pl.diff(bins),
        edgecolor=graphics.histogram_color, facecolor=graphics.histogram_color, zorder=0 )
    yrange = d.get_ylim ()
    # d.plot ( [1]*2, yrange, 'k:' )
    if l_ratio_obs < ci[0] or l_ratio_obs > ci[1]:
        d.plot ( [l_ratio_obs]*2, [yrange[0], yrange[0]+0.85*(yrange[1]-yrange[0])],
                linewidth=2, color=graphics.observed_color)
        d.plot ( [l_ratio_obs], [yrange[0]+0.95*(yrange[1]-yrange[0])], '*', color=graphics.observed_color)
    else:
        print "lrobs",l_ratio_obs
        d.plot ( [l_ratio_obs]*2, yrange, color=graphics.observed_color, zorder=2)
    d.plot ([ci[0]]*2, yrange, color=graphics.C95_color, zorder=1 )
    d.plot ([ci[1]]*2, yrange, color=graphics.C95_color, zorder=1 )
    d.set_ylim ( yrange )

    d.set_xlabel ( r'Asymptote difference' )
    # d.text ( .7, 0.7, r"$\frac{\lambda_\mathrm{h}}{\lambda_0}$",
    #         transform=d.transAxes )
    # d.set_xlim ( trimmed_hlim ( l_ratio, l_ratio_obs, (0,5) ) )
    d.set_xlim ( -.003, .001 )
    d.xaxis.set_major_locator ( tckr ( density=0.4, figure=fig, which=0 ) )
    d.xaxis.set_ticks ( (-.002,0) )
    # d.set_xlim ( (.75, 1.25) )
    d.xaxis.set_major_formatter ( myformatter )

    a.set_ylim ( .49, 1.01 )

    pl.savefig ( "figures/%s3.pdf" % ( figname, ) )
    pl.savefig ( "figures/%s3.eps" % ( figname, ) )