def __init__(self,x,y,Ntrain,maxN=None,ytf=None,ydf=None,ytp=None,ydp=None, yt=None,yd=None,dtran=None ): if type(x)==str: self.x = unserialiseArray(x) self.y = unserialiseArray(y) else: self.x = array(x) self.y = array(y) self.Ntrain = Ntrain self.maxN = maxN self.yt0 = self.y[:Ntrain] self.yd0 = self.y[Ntrain:self.maxN] self.xt = self.x[:Ntrain] self.xd = self.x[Ntrain:self.maxN] # Filtered self.ytf = ytf self.ydf = ydf # Z-scored (normalized) self.yt = yt self.yd = yd # PCAed self.ytp = ytp self.ydp = ydp if dtran is None: self.dtran = DataTransformStack() else: self.dtran = dtran
class Trials(object): def __init__(self,x,y,Ntrain,maxN=None,ytf=None,ydf=None,ytp=None,ydp=None, yt=None,yd=None,dtran=None ): if type(x)==str: self.x = unserialiseArray(x) self.y = unserialiseArray(y) else: self.x = array(x) self.y = array(y) self.Ntrain = Ntrain self.maxN = maxN self.yt0 = self.y[:Ntrain] self.yd0 = self.y[Ntrain:self.maxN] self.xt = self.x[:Ntrain] self.xd = self.x[Ntrain:self.maxN] # Filtered self.ytf = ytf self.ydf = ydf # Z-scored (normalized) self.yt = yt self.yd = yd # PCAed self.ytp = ytp self.ydp = ydp if dtran is None: self.dtran = DataTransformStack() else: self.dtran = dtran @staticmethod def _fd(y0): ''' Calculate the derivative of y0 using finite differences and a univariate spline. ''' y = list() for iy in y0: diy = diff(iy,axis=0) xint = arange(iy.shape[0]) x0 = xint[:-1]+0.5 diy = array([UnivariateSpline(x0,idiy,s=0)(xint) for idiy in diy.T]).T y.append(hstack([iy,diy])) return(array(y)) def _finitediff(self): ''' Calculate derivatives using finite differences. Use this if the kalman filter is under performing due to non-linearities. ''' self.ytf = self._fd(self.yt0) self.ytf = TangentVectors( self.ytf[:,:,:self.ytf.shape[-1]/2].transpose(0,2,1), self.ytf[:,:,self.ytf.shape[-1]/2:].transpose(0,2,1) ) self.ydf = self._fd(self.yd0) self.ydf = TangentVectors( self.ydf[:,:,:self.ydf.shape[-1]/2].transpose(0,2,1), self.ydf[:,:,self.ydf.shape[-1]/2:].transpose(0,2,1) ) @staticmethod def _kf(y0,kal): ''' Apply a kalman kal filter to a specific set of trajectories in y0 ''' y = list() for iy in y0: K = kal.filter(flipud(iy).T,zeros(2*iy.shape[1]),eye(2*iy.shape[1])) ix = K[0][:,-1] iV = K[1][:,:,-1] y.append(kal.smooth(iy.T,ix,iV)[0].T) return(array(y)) def _kalfilt(self,kal): ''' Apply a Kalman filter ''' self.ytf = self._kf(self.yt0,kal) self.ytf = TangentVectors( self.ytf[:,:,:self.ytf.shape[-1]/2].transpose(0,2,1), self.ytf[:,:,self.ytf.shape[-1]/2:].transpose(0,2,1) ) self.ydf = self._kf(self.yd0,kal) self.ydf = TangentVectors( self.ydf[:,:,:self.ydf.shape[-1]/2].transpose(0,2,1), self.ydf[:,:,self.ydf.shape[-1]/2:].transpose(0,2,1) ) def _zscore(self): self.muy = median(self.ytp.getFlatX(),1) self.sigmay = std(self.ytp.getFlatX(),1) self.yt = TangentVectors( ((self.ytp.getX().transpose(0,2,1)-self.muy)/self.sigmay).transpose(0,2,1), (self.ytp.getdX().transpose(0,2,1)/self.sigmay).transpose(0,2,1) ) self.yd = TangentVectors( ((self.ydp.getX().transpose(0,2,1)-self.muy)/self.sigmay).transpose(0,2,1), (self.ydp.getdX().transpose(0,2,1)/self.sigmay).transpose(0,2,1) ) def _pca(self): y,self.Lda,self.U=PCA(self.ytf.getFlatX().T,True) self.ytp = TangentVectors( einsum('...ij,...jl->...il',self.U,self.ytf.getX()), einsum('...ij,...jl->...il',self.U,self.ytf.getdX()) ) self.ydp = TangentVectors( einsum('...ij,...jl->...il',self.U,self.ydf.getX()), einsum('...ij,...jl->...il',self.U,self.ydf.getdX()) ) def initialise(self,kal,pca=True,fd=False): ''' Perform initialisation, applying the kalman filter kal, z-scoring and doing a PCA ''' if fd: self._finitediff() else: self._kalfilt(kal) if pca: #self._pca() self.dtran.addTransform(PCASpec.pcaspec,self.ytf.getFlatX()) self.ytp = TangentVectors( self.dtran(self.ytf.getX()), self.dtran.dapply(self.ytf.getdX()) ) self.ydp = TangentVectors( self.dtran(self.ydf.getX()), self.dtran.dapply(self.ydf.getdX()) ) else: #self.Lda = ones((self.y.shape[-1])) #self.U = eye(self.y.shape[-1]) self.ytp = self.ytf self.ydp = self.ydf self.dtran.addTransform(ZScoreSpec.zscorespec,self.ytp.getFlatX()) self.yt = TangentVectors( self.dtran(self.ytp.getX()), self.dtran.dapply(self.ytp.getdX()) ) self.yd = TangentVectors( self.dtran(self.ydp.getX()), self.dtran.dapply(self.ydp.getdX()) ) self._zscore() def __repr__(self): return("Trials("+ "x="+repr(serialiseArray(self.x))+ ",y="+repr(serialiseArray(self.y))+ ",Ntrain="+repr(self.Ntrain)+ ",maxN="+repr(self.maxN)+ ",ytf="+repr(self.ytf)+ ",ydf="+repr(self.ydf)+ ",ytp="+repr(self.ytp)+ ",ydp="+repr(self.ydp)+ ",yt="+repr(self.yt)+ ",yd="+repr(self.yd)+ ",dtran="+repr(self.dtran)+ ")")