Beispiel #1
0
def estimate_mean(Y, sd):
    """ Estimate the mean of a sample given information about
    the standard deviations of each entry. 
   
    Parameters
    ----------
    Y : ndarray
       Data for which mean is to be estimated.  Should have shape[0] ==
       number of subjects.
    sd : ndarray
       Standard deviation (subject specific) of the data for which the
       mean is to be estimated.  Should have shape[0] == number of
       subjects.

    Returns
    -------
    value : dict
       This dictionary has keys ['effect', 'scale', 't', 'resid', 'sd']
    """
    nsubject = Y.shape[0]
    squeeze = False
    if Y.ndim == 1:
        Y = Y.reshape(Y.shape[0], 1)
        squeeze = True

    _stretch = lambda x: np.multiply.outer(np.ones(nsubject), x)

    W = pos_recipr(sd**2)
    if W.shape in [(), (1,)]:
        W = np.ones(Y.shape) * W
    W.shape = Y.shape

    # Compute the mean using the optimal weights
    effect = (Y * W).sum(0) / W.sum(0)
    resid = (Y - _stretch(effect)) * np.sqrt(W)

    scale = np.add.reduce(np.power(resid, 2), 0) / (nsubject - 1)
    var_total = scale * pos_recipr(W.sum(0))

    value = {}
    value['resid'] = resid        
    value['effect'] = effect
    value['sd'] = np.sqrt(var_total)
    value['t'] = value['effect'] * pos_recipr(value['sd'])
    value['scale'] = np.sqrt(scale)

    if squeeze:
        for key in value.keys():
            value[key] = np.squeeze(value[key])
    return value
Beispiel #2
0
    def _extract_sd(self, results):

        delay = self.IRF.delay

        self.T1 = np.zeros(self.gamma0.shape)

        nrow = self.gamma0.shape[0]
        for i in range(nrow):
            self.T1[i] = self.gamma1[i] * pos_recipr(np.sqrt(results.cov_beta(matrix=self.deltamatrix[i])))

        a1 = 1 + 1. * pos_recipr(self.T0sq)

        gdot = np.array(([(self.r * (a1 - 2.) *
                          recipr0(self.gamma0 * a1**2)),
                         recipr0(self.gamma0 * a1)] *
                        recipr0(delay.dforward(self.deltahat))))

        Cov = results.cov_beta
        E = self.effectmatrix
        D = self.deltamatrix

        nrow = self.effectmatrix.shape[0]
            
        cov = np.zeros((nrow,)*2 + self.T0sq.shape[1:])

        for i in range(nrow):
            for j in range(i + 1):
                cov[i,j] = (gdot[0,i] * gdot[0,j] * Cov(matrix=E[i],
                                                      other=E[j]) +  
                            gdot[0,i] * gdot[1,j] * Cov(matrix=E[i],
                                                      other=D[j]) +
                            gdot[1,i] * gdot[0,j] * Cov(matrix=D[i],
                                                      other=E[j]) +
                            gdot[1,i] * gdot[1,j] * Cov(matrix=D[i],
                                                      other=D[j]))
                cov[j,i] = cov[i,j]

        nout = self.weights.shape[0]
        self._sd = np.zeros(self._effect.shape)

        for r in range(nout):
            var = 0
            for i in range(nrow):
                var += cov[i,i] * np.power(self.weights[r,i], 2)
                for j in range(i):
                    var += 2 * cov[i,j] * self.weights[r,i] * self.weights[r,j]

            self._sd[r] = np.sqrt(var)                
Beispiel #3
0
    def Fcontrast(self, matrix, dispersion=None, invcov=None):
        """
        Compute an Fcontrast for a contrast matrix.

        Here, matrix M is assumed to be non-singular. More precisely,

        M pX pX' M'

        is assumed invertible. Here, pX is the generalized inverse of the
        design matrix of the model. There can be problems in non-OLS models
        where the rank of the covariance of the noise is not full.

        See the contrast module to see how to specify contrasts.
        In particular, the matrices from these contrasts will always be
        non-singular in the sense above.

        """

        ctheta = np.dot(matrix, self.theta)

        if matrix.ndim == 1:
            matrix = matrix.reshape((1, matrix.shape[0]))

        if dispersion is None:
            dispersion = self.dispersion

        q = matrix.shape[0]
        if invcov is None:
            invcov = inv(self.vcov(matrix=matrix, dispersion=1.0))
        F = np.add.reduce(np.dot(invcov, ctheta) * ctheta, 0) * pos_recipr((q * dispersion))
        return FContrastResults(F=F, df_den=self.df_resid, df_num=invcov.shape[0])
Beispiel #4
0
 def resel2fwhm(self, resels):
     """
     :Parameters:
         resels : ``float``
             Convert a resel value to an equivalent isotropic FWHM based on
             step sizes in self.coordmap.
     
     :Returns: FWHM
     """
     return np.sqrt(4*np.log(2.)) * self.wedge * pos_recipr(np.power(resels, 1./self.D))
Beispiel #5
0
    def fwhm2resel(self, fwhm):
        """
        :Parameters:
            fwhm : ``float``
                Convert an FWHM value to an equivalent resels per voxel based on
                step sizes in self.coordmap.


        :Returns: resels
        """
        return pos_recipr(np.power(fwhm / np.sqrt(4*np.log(2)) * self.wedge, self.D))
Beispiel #6
0
    def Tcontrast(self, matrix, t=True, sd=True, dispersion=None):
        """
        Compute a Tcontrast for a row vector matrix. To get the t-statistic
        for a single column, use the 't' method.
        """

        _t = _sd = None

        _effect = np.dot(matrix, self.theta)

        if sd:
            _sd = np.sqrt(self.vcov(matrix=matrix, dispersion=dispersion))
        if t:
            _t = _effect * pos_recipr(_sd)
        return TContrastResults(effect=_effect, t=_t, sd=_sd, df_den=self.df_resid)
Beispiel #7
0
    def t(self, column=None):
        """
        Return the (Wald) t-statistic for a given parameter estimate.

        Use Tcontrast for more complicated (Wald) t-statistics.

        """

        if column is None:
            column = range(self.theta.shape[0])

        column = np.asarray(column)
        _theta = self.theta[column]
        _cov = self.vcov(column=column)
        if _cov.ndim == 2:
            _cov = np.diag(_cov)
        _t = _theta * pos_recipr(np.sqrt(_cov))
        return _t
Beispiel #8
0
    def __call__(self, results):
        """
        :Parameters:
            `results` : a scipy.stats.models.model.LikelihoodModelResults instance
        :Returns: ``numpy.ndarray``
        """
        resid = results.resid.reshape((results.resid.shape[0],
                                       np.product(results.resid.shape[1:])))

        sum_sq = results.scale.reshape(resid.shape[1:]) * results.df_resid

        cov = np.zeros((self.p + 1,) + sum_sq.shape)
        cov[0] = sum_sq
        for i in range(1, self.p+1):
            cov[i] = np.add.reduce(resid[i:] * resid[0:-i], 0)
        cov = np.dot(self.invM, cov)
        output = cov[1:] * pos_recipr(cov[0])
        return np.squeeze(output)
Beispiel #9
0
    def norm_resid(self):
        """
        Residuals, normalized to have unit length.

        Notes
        -----
        Is this supposed to return "stanardized residuals," residuals standardized
        to have mean zero and approximately unit variance?

        d_i = e_i/sqrt(MS_E)

        Where MS_E = SSE/(n - k)

        See: Montgomery and Peck 3.2.1 p. 68
             Davidson and MacKinnon 15.2 p 662

        """

        return self.resid * utils.pos_recipr(np.sqrt(self.dispersion))
Beispiel #10
0
    def _extract_effect(self, results):

        delay = self.IRF.delay

        self.gamma0 = np.dot(self.effectmatrix, results.beta)
        self.gamma1 = np.dot(self.deltamatrix, results.beta)

        nrow = self.gamma0.shape[0]
        self.T0sq = np.zeros(self.gamma0.shape)
        
        for i in range(nrow):
            self.T0sq[i] = (self.gamma0[i]**2 *
                            pos_recipr(results.cov_beta(matrix=self.effectmatrix[i])))

        self.r = self.gamma1 * recipr0(self.gamma0)
        self.rC = self.r * self.T0sq / (1. + self.T0sq)
        self.deltahat = delay.inverse(self.rC)

        self._effect = np.dot(self.weights, self.deltahat)
Beispiel #11
0
def test_pos_recipr():
    X = np.array([2,1,-1,0], dtype=np.int8)
    eX = np.array([0.5,1,0,0])
    Y = pos_recipr(X)
    yield assert_array_almost_equal, Y, eX
    yield assert_equal, Y.dtype.type, np.float64
    X2 = X.reshape((2,2))
    Y2 = pos_recipr(X2)
    yield assert_array_almost_equal, Y2, eX.reshape((2,2))
    # check that lists have arrived
    XL = [0, 1, -1]
    yield assert_array_almost_equal, pos_recipr(XL), [0, 1, 0]
    # scalars
    yield assert_equal, pos_recipr(-1), 0
    yield assert_equal, pos_recipr(0), 0
    yield assert_equal, pos_recipr(2), 0.5
Beispiel #12
0
def estimateAR(resid, design, order=1):
    """
    Estimate AR parameters using bias correction from fMRIstat.

    Parameters
    ----------
    resid:  residual image
    model:  an OLS model used to estimate residuals

    Returns
    -------
    output : 
    """
    p = order

    R = np.identity(design.shape[0]) - np.dot(design, np.linalg.pinv(design))
    M = np.zeros((p+1,)*2)
    I = np.identity(R.shape[0])

    for i in range(p+1):
        Di = np.dot(R, toeplitz(I[i]))
        for j in range(p+1):
            Dj = np.dot(R, toeplitz(I[j]))
            M[i,j] = np.diagonal((np.dot(Di, Dj))/(1.+(i>0))).sum()
                    
    invM = np.linalg.inv(M)

    rresid = np.asarray(resid).reshape(resid.shape[0], 
                                       np.product(resid.shape[1:]))
    sum_sq = np.sum(rresid**2, axis=0)

    cov = np.zeros((p + 1,) + sum_sq.shape)
    cov[0] = sum_sq
    for i in range(1, p+1):
        cov[i] = np.add.reduce(rresid[i:] * rresid[0:-i], 0)
    cov = np.dot(invM, cov)
    output = cov[1:] * pos_recipr(cov[0])
    output = np.squeeze(output)
    output.shape = resid.shape[1:]
    return output
Beispiel #13
0
def estimate_varatio(Y, sd, df=None, niter=10):
    """
    
    In a one-sample random effects problem, estimate
    the ratio between the fixed effects variance and
    the random effects variance. 

    Parameters
    ----------

    Y : np.ndarray
        Data for which mean is to be estimated.
        Should have shape[0] == number of subjects.
    sd : array
        Standard deviation (subject specific) 
        of the data for which the mean is to be estimated.
        Should have shape[0] == number of subjects.
    df : int or None, optional
        If supplied, these are used as weights when
        deriving the fixed effects variance. Should have
        length == number of subjects.
    niter : int, optional
        Number of EM iterations to perform (default 10)
    
    Returns
    -------
    value : dict
       This dictionary has keys ['fixed', 'ratio', 'random'], where
       'fixed' is the fixed effects variance implied by the input
       parameter 'sd'; 'random' is the random effects variance and
       'ratio' is the estimated ratio of variances: 'random'/'fixed'.
    """
    nsubject = Y.shape[0]
    squeeze = False
    if Y.ndim == 1:
        Y = Y.reshape(Y.shape[0], 1)
        squeeze = True
    _stretch = lambda x: np.multiply.outer(np.ones(nsubject), x)

    W = pos_recipr(sd**2)
    if W.shape in [(), (1,)]:
        W = np.ones(Y.shape) * W
    W.shape = Y.shape

    S = 1. / W
    R = Y - np.multiply.outer(np.ones(Y.shape[0]), Y.mean(0))
    sigma2 = np.squeeze((R**2).sum(0)) / (nsubject - 1)

    Sreduction = 0.99
    minS = S.min(0) * Sreduction
    Sm = S - _stretch(minS)

    for _ in range(niter):
        Sms = Sm + _stretch(sigma2)
        W = pos_recipr(Sms)
        Winv = pos_recipr(W.sum(0))
        mu = Winv * (W*Y).sum(0)
        R = W * (Y - _stretch(mu))
        ptrS = 1 + (Sm * W).sum(0) - (Sm * W**2).sum(0) * Winv
        sigma2 = np.squeeze((sigma2 * ptrS + (sigma2**2) * (R**2).sum(0)) / nsubject)
    sigma2 = sigma2 - minS

    if df is None:
        df = np.ones(nsubject)
            
    df.shape = (1, nsubject)
        
    _Sshape = S.shape
    S.shape = (S.shape[0], np.product(S.shape[1:]))

    value = {}
    value['fixed'] = (np.dot(df, S) / df.sum()).reshape(_Sshape[1:])
    value['ratio'] = np.nan_to_num(sigma2 / value['fixed'])
    value['random'] = sigma2

    if squeeze:
        for key in value.keys():
            value[key] = np.squeeze(value[key])
    return value
Beispiel #14
0
 def _extract_t(self):
     t = self._effect * pos_recipr(self._sd)        
     t = np.clip(t, self.Tmin, self.Tmax)
     return t