def cp_apr(X, R, Minit, outputfile, tol=1e-4, maxiters=150, 
           maxinner=10, epsilon=1e-10, kappatol=1e-10, kappa=1e-2):
    N = X.ndims()
    nInnerIters = np.zeros(maxiters);
    
    ## Initialize M and Phi for iterations
    M = Minit
    prevM = ktensor.copyTensor(M)
    M.normalize(1)
    Phi = [[] for i in range(N)]
    kktModeViolations = np.zeros(N)
    kktViolations = -np.ones(maxiters)
    nViolations = np.zeros(maxiters)
    
    ## statistics
    cpStats = np.zeros(7)
    fmsStats = np.zeros(3)
    
    for iter in range(maxiters):
        startIter = time.time()
        isConverged = True;
        for n in range(N):
            startMode = time.time()
            ## Make adjustments to M[n] entries that violate complementary slackness
            if iter > 0:
                V = np.logical_and(Phi[n] > 1, M.U[n] < kappatol)
                if np.count_nonzero(V) > 0:
                    nViolations[iter] = nViolations[iter] + 1
                    M.U[n][V > 0] = M.U[n][V > 0] + kappa
            # solve the inner problem
            M, Phi[n], inner, kktModeViolations[n], isConverged = __solveSubproblem(X, M, R, n, N, maxinner, epsilon, tol)
            nInnerIters[iter] = nInnerIters[iter]+(inner+1)
            elapsed = time.time()-startMode
            # only write the outer iterations for now
            cpStats = np.vstack((cpStats, np.array([iter, n, inner, __lsqr_fit(X,M), __loglikelihood(X,M), kktModeViolations[n], elapsed])))
        kktViolations[iter] = np.max(kktModeViolations);
        elapsed = time.time()-startIter
        #cpStats = np.vstack((cpStats, np.array([iter, -1, -1, kktViolations[iter], __loglikelihood(X,M), elapsed])))
        print("Iteration {0}: Inner Its={1} with KKT violation={2}, nViolations={3}, and elapsed time={4}".format(iter, nInnerIters[iter], kktViolations[iter], nViolations[iter], elapsed));
        __writeDBFile(M, outputfile.format(iter), iter)
        fmsStats = np.vstack((fmsStats, np.array([iter, M.top_fms(prevM), M.greedy_fms(prevM)])))
        prevM = ktensor.copyTensor(M)
        
        if isConverged:
            break;
        
    cpStats = np.delete(cpStats, (0), axis=0) # delete the first row
    fmsStats = np.delete(fmsStats, (0), axis=0) # delete the first row
    
    ## print out the statistics
    fit = __lsqr_fit(X,M)
    ll = __loglikelihood(X,M)
    print("Number of iterations = {0}".format(iter))
    print("Final least squares fit = {0}".format(fit));
    print("Final log-likelihood = {0}".format(ll));
    print("Final KKT Violation = {0}".format(kktViolations[iter]))
    print("Total inner iterations = {0}".format(np.sum(nInnerIters)));
    modelStats = {"Iters" : iter, "LS" : fit, "LL" : ll, "KKT" : kktViolations[iter]}
    return M, cpStats, fmsStats, modelStats;
Beispiel #2
0
 def projectData(self, XHat, n, maxiters=10, maxinner=10):
     ## store off the old ones
     origM = {REG_LOCATION: ktensor.copyTensor(self.M[REG_LOCATION]), AUG_LOCATION: ktensor.copyTensor(self.M[AUG_LOCATION])} 
     origX = self.X
     self.X = XHat
     ## randomize the nth 
     self.M[REG_LOCATION].U[n] = np.random.rand(self.X.shape[n], self.R)
     self.M[REG_LOCATION].lmbda = np.ones(self.R)
     self.M[AUG_LOCATION].U[n] = np.random.rand(self.X.shape[n], 1)
     self.M[AUG_LOCATION].lmbda = np.ones(1)
     ## renormalize
     self.M[REG_LOCATION].normalize(1)
     self.normalizeAugTensor()
     lastLL = tensorTools.loglikelihood(self.X,self.M)
     for iteration in range(maxiters):
         xsubs = self.X.subs[:,n]
         B, Pi, inI1, kktModeViolation1 = self.__solveSignalTensor(xsubs, self.M[AUG_LOCATION].U[n], n)
         inI2, kktModeViolation2 = self.__solveAugmentedTensor(xsubs, B, Pi, n)
         ll = tensorTools.loglikelihood(self.X,self.M)
         if np.abs(lastLL - ll) < self.dlTol:
             break
         lastLL = ll
     ## scale by summing across the rows
     totWeight = np.sum(self.M[REG_LOCATION].U[n], axis=1)
     zeroIdx = np.where(totWeight < 1e-100)[0]
     if len(zeroIdx) > 0:
         evenDist = 1.0 / self.M[REG_LOCATION].R
         self.M[REG_LOCATION].U[n][zeroIdx, :] = np.tile(evenDist, (len(zeroIdx), self.M[REG_LOCATION].R))
         totWeight = np.sum(self.M[REG_LOCATION].U[n], axis=1)
     twMat = np.repeat(totWeight, self.M[REG_LOCATION].R).reshape(self.X.shape[n], self.M[REG_LOCATION].R)
     projMat = self.M[REG_LOCATION].U[n] / twMat
     biasMat = self.M[AUG_LOCATION].U[n]
     self.M = origM
     self.X = origX
     return projMat, biasMat
def __loglikelihood(X,MF):
    """ 
    Computes the log-likelihood of model M given data X.
    Specifically, ll = -(sum_i m_i - x_i * log_i) where i is a
    multiindex across all tensor dimensions
    
    Parameters
    ----------
    X - input tensor of the class tensor or sptensor
    MF - ktensor

    Returns
    -------
    out : log likelihood value
    """
    N = X.ndims();
    # make a copy of the tensor so absorbing won't affect it
    M = ktensor.copyTensor(MF)    
    M.normalize_absorb(0, 1);
    ll = 0;
    
    if X.__class__ == sptensor.sptensor:
        xsubs = X.subs;
        A = M.U[0][xsubs[:,0], :];
        for n in range(1, N):
            A = np.multiply(A, M.U[n][xsubs[:,n],:]);
        ll = np.sum(np.multiply(X.vals.flatten(), np.log(np.sum(A, axis=1)))) - np.sum(M.U[0]);
    else:
        ## fill in what to do when it's not sparse tensor
        ll = -np.sum(M.U[0]);
    return ll;
Beispiel #4
0
 def __init__(self, M, R):
     ## make a copy of the original basis
     self.basis = [ktensor.copyTensor(m) for m in M]
     self.R = R
 def __init__(self, M, R):
     ## make a copy of the original basis
     self.basis = [ktensor.copyTensor(m) for m in M]
     self.R = R