Exemple #1
0
def update_L_C_single(x, L_C, n, omega, u):
    D = omega.shape[0]
    assert x.ndim == 1
    assert len(x) == D
    m = 1 if np.isscalar(u) else len(u)
    N = 1

    L_C *= np.sqrt(n)

    # since cholupdate works on transposed version
    L_C = L_C.T

    projection = np.dot(x[np.newaxis, :], omega) + u
    np.sin(projection, projection)
    projection *= -np.sqrt(2. / m)
    temp = np.zeros((N, m))
    for d in range(D):
        temp = -projection * omega[d, :]

        # here temp is 1xm, this costs O(m^2)
        cholupdate(L_C, temp[0])

    # since cholupdate works on transposed version
    L_C = L_C.T

    # since the new C has a 1/(n+1) term in it
    L_C /= np.sqrt(n + 1)

    return L_C
Exemple #2
0
def update_L_C_single(x, L_C, n, omega, u):
    D = omega.shape[0]
    assert x.ndim == 1
    assert len(x) == D
    m = 1 if np.isscalar(u) else len(u)
    N = 1
    
    L_C *= np.sqrt(n)
    
    # since cholupdate works on transposed version
    L_C = L_C.T
    
    projection = np.dot(x[np.newaxis, :], omega) + u
    np.sin(projection, projection)
    projection *= -np.sqrt(2. / m)
    temp = np.zeros((N, m))
    for d in range(D):
        temp = -projection * omega[d, :]
        
        # here temp is 1xm, this costs O(m^2)
        cholupdate(L_C, temp[0])
        
    # since cholupdate works on transposed version
    L_C = L_C.T
    
    # since the new C has a 1/(n+1) term in it
    L_C /= np.sqrt(n + 1)
    
    return L_C
def update_mean_cov_L_lmbda(X, old_mean, old_cov_L, lmbdas):
    assert len(X) == len(lmbdas)
    # work on upper triangular cholesky internally
    old_cov_R = old_cov_L.T

    mean = old_mean
    for x, lmbda in zip(X, lmbdas):
        old_cov_R *= np.sqrt(1 - lmbda)
        update_vec = np.sqrt(lmbda) * (x - mean)
        cholupdate(old_cov_R, update_vec)
        mean = (1 - lmbda) * mean + lmbda * x

    # transform back to lower triangular version
    cov_L = old_cov_R.T

    return mean, cov_L
def update_mean_cov_L_lmbda(X, old_mean, old_cov_L, lmbdas):
    assert len(X) == len(lmbdas)
    # work on upper triangular cholesky internally
    old_cov_R = old_cov_L.T
    
    mean = old_mean
    for x, lmbda in zip(X, lmbdas):
        old_cov_R *= np.sqrt(1 - lmbda)
        update_vec = np.sqrt(lmbda) * (x - mean)
        cholupdate(old_cov_R, update_vec)
        mean = (1 - lmbda) * mean + lmbda * x
    
    # transform back to lower triangular version
    cov_L = old_cov_R.T
    
    return mean, cov_L
def update_b_L_C_weighted(X, b, L_C, log_sum_weights, log_weights, omega, u):
    m = 1 if np.isscalar(u) else len(u)
    N = X.shape[0]
    D = X.shape[1]

    # transform weights into (1-\lmbda)*old_mean+ \lmbda*new_term style updates
    lmbdas = log_weights_to_lmbdas(log_sum_weights, log_weights)

    # first and (negative) second derivatives of rff feature map
    projection = np.dot(X, omega) + u
    Phi = np.cos(projection) * np.sqrt(2. / m)
    Phi2 = np.sin(projection) * np.sqrt(2. / m)

    # not needed any longer
    del projection

    # work on upper triangular cholesky internally
    L_R = L_C.T

    b_new_term = np.zeros(m)
    for i in range(N):
        # downscale L_C once for every datum
        L_R *= np.sqrt(1 - lmbdas[i])

        b_new_term[:] = 0
        for d in range(D):
            b_new_term += Phi[i] * (omega[d, :]**2)

            # L_C is updated D times for every datum, each with fixed lmbda
            C_new_term = Phi2[i] * omega[d, :] * np.sqrt(lmbdas[i])
            cholupdate(L_R, C_new_term)

        # b is updated once per datum
        b = (1 - lmbdas[i]) * b + lmbdas[i] * b_new_term

    # transform back to lower triangular version
    L_C = L_R.T

    return b, L_C
Exemple #6
0
def update_b_L_C_weighted(X, b, L_C, log_sum_weights, log_weights, omega, u):
    m = 1 if np.isscalar(u) else len(u)
    N = X.shape[0]
    D = X.shape[1]
    
    # transform weights into (1-\lmbda)*old_mean+ \lmbda*new_term style updates
    lmbdas = log_weights_to_lmbdas(log_sum_weights, log_weights)
    
    # first and (negative) second derivatives of rff feature map
    projection = np.dot(X, omega) + u
    Phi = np.cos(projection) * np.sqrt(2. / m)
    Phi2 = np.sin(projection) * np.sqrt(2. / m)
    
    # not needed any longer
    del projection
    
    # work on upper triangular cholesky internally
    L_R = L_C.T
    
    b_new_term = np.zeros(m)
    for i in range(N):
        # downscale L_C once for every datum
        L_R *= np.sqrt(1 - lmbdas[i])
        
        b_new_term[:] = 0
        for d in range(D):
            b_new_term += Phi[i] * (omega[d, :] ** 2)
            
            # L_C is updated D times for every datum, each with fixed lmbda
            C_new_term = Phi2[i] * omega[d, :] * np.sqrt(lmbdas[i])
            cholupdate(L_R, C_new_term)
        
        # b is updated once per datum
        b = (1 - lmbdas[i]) * b + lmbdas[i] * b_new_term
    
    # transform back to lower triangular version
    L_C = L_R.T
    
    return b, L_C
Exemple #7
0
 def rank_one_update_mean_covariance_cholesky_lmbda(u, lmbda=.1, mean=None, cov_L=None, nu2=1., gamma2=None):
     """
     Returns updated mean and Cholesky of sum of outer products following a
     (1-lmbda)*old + lmbda* step_size*uu^T+lmbda*gamm2*I
     rule
     
     Optional: If gamma2 is given, an isotropic term gamma2 * I is added to the uu^T part
     
     where old mean and cov_L=Cholesky(old) (lower Cholesky) are given.
     
     Performs efficient rank-one updates of the Cholesky directly.
     """
     assert lmbda >= 0 and lmbda <= 1
     assert u.ndim == 1
     D = len(u)
     
     # check if first term
     if mean is None or cov_L is None :
         # in that case, zero mean and scaled identity matrix
         mean = np.zeros(D)
         cov_L = np.eye(D) * nu2
     else:
         assert len(mean) == D
         assert mean.ndim == 1
         assert cov_L.ndim == 2
         assert cov_L.shape[0] == D
         assert cov_L.shape[1] == D
     
     # update mean
     updated_mean = (1 - lmbda) * mean + lmbda * u
     
     # update Cholesky: first downscale existing Cholesky
     update_cov_L = np.sqrt(1 - lmbda) * cov_L.T
     
     # rank-one update of the centered new vector
     update_vec = np.sqrt(lmbda) * np.sqrt(nu2) * (u - mean)
     cholupdate(update_cov_L, update_vec)
     
     # optional: add isotropic term if specified, requires looping rank-one updates over
     # all basis vectors e_1, ..., e_D
     if gamma2 is not None:
         e_d = np.zeros(D)
         for d in range(D):
             e_d[:] = 0
             e_d[d] = np.sqrt(gamma2)
             
             # could do a Cholesky update, but this routine does a loop over dimensions
             # where the vector only has one non-zero component
             # That is O(D^2) and therefore not efficient when used in a loop
             cholupdate(update_cov_L, np.sqrt(lmbda) * e_d)
             
             # TODO:
             # in contrast, can do a simplified update when knowing that e_d is sparse
             # manual Cholesky update (only doing the d-th component of algorithm on
             # https://en.wikipedia.org/wiki/Cholesky_decomposition#Rank-one_update
 #             # wiki (MB) code:
 #             r = sqrt(L(k,k)^2 + x(k)^2);
 #             c = r / L(k, k);
 #             s = x(k) / L(k, k);
 #             L(k, k) = r;
 #             L(k+1:n,k) = (L(k+1:n,k) + s*x(k+1:n)) / c;
 #             x(k+1:n) = c*x(k+1:n) - s*L(k+1:n,k);
 
     # since cholupdate works on transposed version
     update_cov_L = update_cov_L.T
     
     # done updating Cholesky
     
     return updated_mean, update_cov_L