def restart(self, EpsilonNet=None, DiffeonEpsForNet=None, DiffeonSegmentationRatio=None, DecimationTarget=None):
        if EpsilonNet==None:
            if DecimationTarget==None:
                if DiffeonEpsForNet==None:
                    if DiffeonSegmentationRatio==None:
                        c0 = np.copy(self.x0) ;
                        S0 = np.zeros([self.x0.shape[0], self.x0.shape[1], self.x0.shape[1]])
                        #net = range(c0.shape[0])
                        idx = range(c0.shape[0])
                    else:
                        (c0, S0, idx) = gd.generateDiffeonsFromSegmentation(self.fv0, DiffeonSegmentationRatio)
                        #self.S0 *= self.param.sigmaKernel**2;
                else:
                    (c0, S0, idx) = gd.generateDiffeonsFromNet(self.fv0, DiffeonEpsForNet)
            else:
                (c0, S0, idx) = gd.generateDiffeonsFromDecimation(self.fv0, DecimationTarget)
        else:
            net = EspilonNet[2] 
            (c0, S0, idx) = gd.generateDiffeons(self.fv0, EpsilonNet[0], EpsilonNet[1])

        (ctPrev, StPrev, ct, St) = evol.gaussianDiffeonsEvolutionEuler(self.c0, self.S0, self.at, self.param.sigmaKernel, withDiffeonSet=(c0, S0))
        at = np.zeros([self.Tsize, c0.shape[0], self.x0.shape[1]])
        #fvDef = surfaces.Surface(surf=self.fvDef)
        for t in range(self.Tsize):
            g1 = gd.computeProducts(np.squeeze(ct[t,:,:]),np.squeeze(St[t,:,:]), self.param.sigmaKernel) 
            g2 = gd.computeProductsAsym(np.squeeze(ct[t,:,:]),np.squeeze(St[t,:,:]), np.squeeze(ctPrev[t,:,:]),np.squeeze(StPrev[t,:,:]), self.param.sigmaKernel)
            g2a = np.dot(g2, np.squeeze(self.at[t, :, :]))
            at[t, :, :] = LA.solve(g1, g2a)
            g0 = gd.computeProducts(np.squeeze(ctPrev[t,:,:]),np.squeeze(StPrev[t,:,:]), self.param.sigmaKernel)
            n0 = np.multiply(self.at[t, :, :], np.dot(g0, self.at[t, :, :])).sum()
            n1 = np.multiply(at[t, :, :], np.dot(g1, at[t, :, :])).sum()
            print 'norms: ', n0, n1
            # fvDef.updateVertices(np.squeeze(self.xt[t, :, :]))
            # (AV, AF) = fvDef.computeVertexArea()
            # weights = np.zeros([c0.shape[0], self.c0.shape[0]])
            # diffArea = np.zeros(self.c0.shape[0])
            # diffArea2 = np.zeros(c0.shape[0])
            # for k in range(self.npt):
            #     diffArea[self.idx[k]] += AV[k] 
            #     diffArea2[idx[k]] += AV[k]
            #     weights[idx[k], self.idx[k]] += AV[k]
            # weights /= diffArea.reshape([1, self.c0.shape[0]])
            # at[t] = np.dot(weights, self.at[t, :, :])
        self.c0 = c0
        self.idx = idx
        self.S0 = S0
        self.at = at
        self.ndf = self.c0.shape[0]
        self.ct = np.tile(self.c0, [self.Tsize+1, 1, 1])
        self.St = np.tile(self.S0, [self.Tsize+1, 1, 1, 1])
        if self.dcurr:
	    self.b0 = gd.approximateSurfaceCurrent(self.c0, self.S0, self.fv0, self.param.KparDist.sigma)
            #print self.b0.shape
            self.bt = np.tile(self.b0, [self.Tsize+1, 1, 1])
        self.obj = None
        self.objTry = None
        self.gradCoeff = self.ndf
        self.optimizeMatching()
    def  objectiveFunDef(self, at, Afft, withTrajectory = False, withJacobian=False, initial = None):
        if initial == None:
            x0 = self.x0
            c0 = self.c0
            S0 = self.S0
	    if self.dcurr:
		b0 = self.b0
                xS0 = self.xS0
        else:
            x0 = self.x0
	    if self.dcurr:
		(c0, S0, b0, xS0) = initial
	    else:
		(c0, S0) = initial
        param = self.param
        timeStep = 1.0/self.Tsize
        dim2 = self.dim**2
        A = [np.zeros([self.Tsize, self.dim, self.dim]), np.zeros([self.Tsize, self.dim])]
        if self.affineDim > 0:
            for t in range(self.Tsize):
                AB = np.dot(self.affineBasis, Afft[t])
                A[0][t] = AB[0:dim2].reshape([self.dim, self.dim])
                A[1][t] = AB[dim2:dim2+self.dim]
	if withJacobian:
	    if self.dcurr:
		(ct, St, bt, xt, xSt, Jt)  = evol.gaussianDiffeonsEvolutionEuler(c0, S0, at, param.sigmaKernel, affine=A, withJacobian=True, withNormals=b0, withDiffeonSet=(x0, xS0))
            else:
		(ct, St, xt, Jt)  = evol.gaussianDiffeonsEvolutionEuler(c0, S0, at, param.sigmaKernel, affine=A, withPointSet = x0, withJacobian=True)
        else:
	    if self.dcurr:
		(ct, St, bt, xt, xSt)  = evol.gaussianDiffeonsEvolutionEuler(c0, S0, at, param.sigmaKernel, affine=A, withNormals=b0, withDiffeonSet=(x0, xS0))
            else:
		(ct, St, xt)  = evol.gaussianDiffeonsEvolutionEuler(c0, S0, at, param.sigmaKernel, affine=A, withPointSet = x0)

        #print xt[-1, :, :]
        #print obj
        obj=0
        #print St.shape
        for t in range(self.Tsize):
            c = np.squeeze(ct[t, :, :])
            S = np.squeeze(St[t, :, :, :])
            a = np.squeeze(at[t, :, :])
            #rzz = kfun.kernelMatrix(param.KparDiff, z)
            rcc = gd.computeProducts(c, S, param.sigmaKernel)
            obj = obj + self.regweight*timeStep*np.multiply(a, np.dot(rcc,a)).sum()
            if self.affineDim > 0:
                obj +=  timeStep * np.multiply(self.affineWeight.reshape(Afft[t].shape), Afft[t]**2).sum()
            #print xt.sum(), at.sum(), obj
        if withJacobian:
            if self.dcurr:
                return obj, ct, St, bt, xt, xSt, Jt
            else:
                return obj, ct, St, xt, Jt
        elif withTrajectory:
            if self.dcurr:
                return obj, ct, St, bt, xt, xSt
            else:
                return obj, ct, St, xt
        else:
            return obj
    def dotProduct(self, g1, g2):
        res = np.zeros(len(g2))
        dim2 = self.dim**2
        for t in range(self.Tsize):
            c = np.squeeze(self.ct[t, :, :])
            S = np.squeeze(self.St[t, :, :, :])
            gg = np.squeeze(g1.diff[t, :, :])
            rcc = gd.computeProducts(c, S, self.param.sigmaKernel)
            (L, W) = LA.eigh(rcc)
            rcc += (L.max()/1000)*np.eye(rcc.shape[0])
            u = np.dot(rcc, gg)
            uu = np.multiply(g1.aff[t], self.affineWeight.reshape(g1.aff[t].shape))
            ll = 0
            for gr in g2:
                ggOld = np.squeeze(gr.diff[t, :, :])
                res[ll]  = res[ll] + np.multiply(ggOld,u).sum()
                if self.affineDim > 0:
                    res[ll] += np.multiply(uu, gr.aff[t]).sum()
                ll = ll + 1

        return res