Пример #1
0
 def test1(self):
     p = np.matrix([[1,2],
                    [1,2]])
     q = np.matrix([[1,2],
                    [1,2]])
     d = sqdist(p, q)
     assert np.all(d==np.array([[0,2],[2,0]]))
Пример #2
0
 def test2(self):
     p = np.matrix([[1,2],
                    [1,2]])
     q = np.matrix([[1,2],
                    [1,2]])
     A = np.matrix([[1,0],
                    [.5,0]])
     d = sqdist(p, q, A)
     assert np.all(d==np.array([[0,1.5],[1.5,0]]))
Пример #3
0
 def test2(self):
     p = np.matrix([[1, 2], [1, 2]])
     q = np.matrix([[1, 2], [1, 2]])
     A = np.matrix([[1, 0], [.5, 0]])
     d = sqdist(p, q, A)
     assert np.all(d == np.array([[0, 1.5], [1.5, 0]]))
Пример #4
0
 def test1(self):
     p = np.matrix([[1, 2], [1, 2]])
     q = np.matrix([[1, 2], [1, 2]])
     d = sqdist(p, q)
     assert np.all(d == np.array([[0, 2], [2, 0]]))
Пример #5
0
def mixgauss_prob(data, mu, Sigma, mixmat=None, unit_norm=False):
    '''
    % EVAL_PDF_COND_MOG Evaluate the pdf of a conditional mixture of Gaussians
    % function [B, B2] = eval_pdf_cond_mog(data, mu, Sigma, mixmat, unit_norm)
    %
    % Notation: Y is observation, M is mixture component, and both may be conditioned on Q.
    % If Q does not exist, ignore references to Q=j below.
    % Alternatively, you may ignore M if this is a conditional Gaussian.
    %
    % INPUTS:
    % data(:,t) = t'th observation vector 
    %
    % mu(:,k) = E[Y(t) | M(t)=k] 
    % or mu(:,j,k) = E[Y(t) | Q(t)=j, M(t)=k]
    %
    % Sigma(:,:,j,k) = Cov[Y(t) | Q(t)=j, M(t)=k]
    % or there are various faster, special cases:
    %   Sigma() - scalar, spherical covariance independent of M,Q.
    %   Sigma(:,:) diag or full, tied params independent of M,Q. 
    %   Sigma(:,:,j) tied params independent of M. 
    %
    % mixmat(k) = Pr(M(t)=k) = prior
    % or mixmat(j,k) = Pr(M(t)=k | Q(t)=j) 
    % Not needed if M is not defined.
    %
    % unit_norm - optional; if 1, means data(:,i) AND mu(:,i) each have unit norm (slightly faster)
    %
    % OUTPUT:
    % B(t) = Pr(y(t)) 
    % or
    % B(i,t) = Pr(y(t) | Q(t)=i) 
    % B2(i,k,t) = Pr(y(t) | Q(t)=i, M(t)=k) 
    %
    % If the number of mixture components differs depending on Q, just set the trailing
    % entries of mixmat to 0, e.g., 2 components if Q=1, 3 components if Q=2,
    % then set mixmat(1,3)=0. In this case, B2(1,3,:)=1.0.
    '''

    if mu.ndim == 1:
        d = len(mu)
        Q = 1
        M = 1
    elif mu.ndim == 2:
        d, Q = mu.shape
        M = 1
    else:
        d, Q, M = mu.shape

    d, T = data.shape

    if mixmat == None:
        mixmat = np.asmatrix(np.ones((Q, 1)))

    # B2 = zeros(Q,M,T); % ATB: not needed allways
    # B = zeros(Q,T);

    if np.isscalar(Sigma):
        mu = np.reshape(mu, (d, Q * M))
        if unit_norm:  # (p-q)'(p-q) = p'p + q'q - 2p'q = n+m -2p'q since p(:,i)'p(:,i)=1
            # avoid an expensive repmat
            print('unit norm')
            # tic; D = 2 -2*(data'*mu)'; toc
            D = 2 - 2 * np.dot(mu.T * data)
            # tic; D2 = sqdist(data, mu)'; toc
            D2 = sqdist(data, mu).T
            assert (approxeq(D, D2))
        else:
            D = sqdist(data, mu).T
        del mu
        del data  # ATB: clear big old data
        # D(qm,t) = sq dist between data(:,t) and mu(:,qm)
        logB2 = -(d / 2.) * np.log(
            2 * pi * Sigma) - (1 / (2. * Sigma)) * D  # det(sigma*I) = sigma^d
        B2 = np.reshape(np.asarray(np.exp(logB2)), (Q, M, T))
        del logB2  # ATB: clear big old data

    elif Sigma.ndim == 2:  # tied full
        mu = np.reshape(mu, (d, Q * M))
        D = sqdist(data, mu, inv(Sigma)).T
        # D(qm,t) = sq dist between data(:,t) and mu(:,qm)
        logB2 = -(d / 2) * np.log(2 * pi) - 0.5 * logdet(Sigma) - 0.5 * D
        #denom = sqrt(det(2*pi*Sigma));
        #numer = exp(-0.5 * D);
        #B2 = numer/denom;
        B2 = np.reshape(np.asarray(np.exp(logB2)), (Q, M, T))

    elif Sigma.ndim == 3:  # tied across M
        B2 = np.zeros((Q, M, T))
        for j in range(0, Q):
            # D(m,t) = sq dist between data(:,t) and mu(:,j,m)
            if isposdef(Sigma[:, :, j]):
                D = sqdist(data, np.transpose(mu[:, j, :], (0, 2, 1)),
                           inv(Sigma[:, :, j])).T
                logB2 = -(d / 2) * np.log(2 * pi) - 0.5 * logdet(
                    Sigma[:, :, j]) - 0.5 * D
                B2[j, :, :] = np.exp(logB2)
            else:
                logging.error('mixgauss_prob: Sigma(:,:,q=%d) not psd\n' % j)

    else:  # general case
        B2 = np.zeros((Q, M, T))
        for j in range(0, Q):
            for k in range(0, M):
                # if mixmat(j,k) > 0
                B2[j, k, :] = gaussian_prob(data, mu[:, j, k], Sigma[:, :, j,
                                                                     k])

    # B(j,t) = sum_k B2(j,k,t) * Pr(M(t)=k | Q(t)=j)

    # The repmat is actually slower than the for-loop, because it uses too much memory
    # (this is true even for small T).

    # B = squeeze(sum(B2 .* repmat(mixmat, [1 1 T]), 2));
    # B = reshape(B, [Q T]); % undo effect of squeeze in case Q = 1

    B = np.zeros((Q, T))
    if Q < T:
        for q in range(0, Q):
            # B(q,:) = mixmat(q,:) * squeeze(B2(q,:,:)); % squeeze chnages order if M=1
            B[q, :] = np.dot(
                mixmat[q, :], B2[q, :, :]
            )  # vector * matrix sums over m #TODO: had to change this. Is this correct?
    else:
        for t in range(0, T):
            B[:, t] = np.sum(np.asarray(np.multiply(mixmat, B2[:, :, t])),
                             1)  # sum over m
    # t=toc;fprintf('%5.3f\n', t)

    # tic
    # A = squeeze(sum(B2 .* repmat(mixmat, [1 1 T]), 2));
    # t=toc;fprintf('%5.3f\n', t)
    # assert(approxeq(A,B)) % may be false because of round off error

    return B, B2
Пример #6
0
def mixgauss_prob(data, mu, Sigma, mixmat = None, unit_norm = False):
    '''
    % EVAL_PDF_COND_MOG Evaluate the pdf of a conditional mixture of Gaussians
    % function [B, B2] = eval_pdf_cond_mog(data, mu, Sigma, mixmat, unit_norm)
    %
    % Notation: Y is observation, M is mixture component, and both may be conditioned on Q.
    % If Q does not exist, ignore references to Q=j below.
    % Alternatively, you may ignore M if this is a conditional Gaussian.
    %
    % INPUTS:
    % data(:,t) = t'th observation vector 
    %
    % mu(:,k) = E[Y(t) | M(t)=k] 
    % or mu(:,j,k) = E[Y(t) | Q(t)=j, M(t)=k]
    %
    % Sigma(:,:,j,k) = Cov[Y(t) | Q(t)=j, M(t)=k]
    % or there are various faster, special cases:
    %   Sigma() - scalar, spherical covariance independent of M,Q.
    %   Sigma(:,:) diag or full, tied params independent of M,Q. 
    %   Sigma(:,:,j) tied params independent of M. 
    %
    % mixmat(k) = Pr(M(t)=k) = prior
    % or mixmat(j,k) = Pr(M(t)=k | Q(t)=j) 
    % Not needed if M is not defined.
    %
    % unit_norm - optional; if 1, means data(:,i) AND mu(:,i) each have unit norm (slightly faster)
    %
    % OUTPUT:
    % B(t) = Pr(y(t)) 
    % or
    % B(i,t) = Pr(y(t) | Q(t)=i) 
    % B2(i,k,t) = Pr(y(t) | Q(t)=i, M(t)=k) 
    %
    % If the number of mixture components differs depending on Q, just set the trailing
    % entries of mixmat to 0, e.g., 2 components if Q=1, 3 components if Q=2,
    % then set mixmat(1,3)=0. In this case, B2(1,3,:)=1.0.
    '''

    if mu.ndim == 1:
        d = len(mu)
        Q = 1
        M = 1
    elif mu.ndim == 2:
        d, Q = mu.shape
        M = 1
    else:
        d, Q, M = mu.shape;
    
    d, T = data.shape
    
    if mixmat == None:
        mixmat = np.asmatrix(np.ones((Q,1)))
    
    # B2 = zeros(Q,M,T); % ATB: not needed allways
    # B = zeros(Q,T);
    
    if np.isscalar(Sigma):
        mu = np.reshape(mu, (d, Q * M))
        if unit_norm:  # (p-q)'(p-q) = p'p + q'q - 2p'q = n+m -2p'q since p(:,i)'p(:,i)=1
            # avoid an expensive repmat
            print('unit norm')
            # tic; D = 2 -2*(data'*mu)'; toc 
            D = 2 - 2 * np.dot(mu.T * data)
            # tic; D2 = sqdist(data, mu)'; toc
            D2 = sqdist(data, mu).T
            assert(approxeq(D,D2)) 
        else:
            D = sqdist(data, mu).T
        del mu 
        del data  # ATB: clear big old data
        # D(qm,t) = sq dist between data(:,t) and mu(:,qm)
        logB2 = -(d / 2.) * np.log(2 * pi * Sigma) - (1 / (2. * Sigma)) * D  # det(sigma*I) = sigma^d
        B2 = np.reshape(np.asarray(np.exp(logB2)), (Q, M, T))
        del logB2  # ATB: clear big old data
      
    elif Sigma.ndim == 2:  # tied full
        mu = np.reshape(mu, (d, Q * M))
        D = sqdist(data, mu, inv(Sigma)).T
        # D(qm,t) = sq dist between data(:,t) and mu(:,qm)
        logB2 = -(d/2)*np.log(2*pi) - 0.5*logdet(Sigma) - 0.5*D;
        #denom = sqrt(det(2*pi*Sigma));
        #numer = exp(-0.5 * D);
        #B2 = numer/denom;
        B2 = np.reshape(np.asarray(np.exp(logB2)), (Q, M, T))
      
    elif Sigma.ndim==3: # tied across M
        B2 = np.zeros((Q,M,T))
        for j in range(0,Q):
            # D(m,t) = sq dist between data(:,t) and mu(:,j,m)
            if isposdef(Sigma[:,:,j]):
                D = sqdist(data, np.transpose(mu[:,j,:], (0, 2, 1)), inv(Sigma[:,:,j])).T
                logB2 = -(d / 2) * np.log(2 * pi) - 0.5 * logdet(Sigma[:, :, j]) - 0.5 * D;
                B2[j, :, :] = np.exp(logB2);
            else:
                logging.error('mixgauss_prob: Sigma(:,:,q=%d) not psd\n' % j)
      
    else:  # general case
        B2 = np.zeros((Q, M, T))
        for j in range(0, Q):
            for k in range(0, M):
                # if mixmat(j,k) > 0
                B2[j, k, :] = gaussian_prob(data, mu[:, j, k], Sigma[:, :, j, k]);
    
    # B(j,t) = sum_k B2(j,k,t) * Pr(M(t)=k | Q(t)=j) 
    
    # The repmat is actually slower than the for-loop, because it uses too much memory
    # (this is true even for small T).
    
    # B = squeeze(sum(B2 .* repmat(mixmat, [1 1 T]), 2));
    # B = reshape(B, [Q T]); % undo effect of squeeze in case Q = 1
      
    B = np.zeros((Q, T))
    if Q < T:
        for q in range(0, Q):
            # B(q,:) = mixmat(q,:) * squeeze(B2(q,:,:)); % squeeze chnages order if M=1
            B[q, :] = np.dot(mixmat[q, :], B2[q, :, :])  # vector * matrix sums over m #TODO: had to change this. Is this correct?
    else:
        for t in range(0, T):
            B[:, t] = np.sum(np.asarray(np.multiply(mixmat, B2[:, :, t])), 1)  # sum over m
    # t=toc;fprintf('%5.3f\n', t)
    
    # tic
    # A = squeeze(sum(B2 .* repmat(mixmat, [1 1 T]), 2));
    # t=toc;fprintf('%5.3f\n', t)
    # assert(approxeq(A,B)) % may be false because of round off error

    return B, B2