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]]))
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]]))
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]]))
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]]))
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
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