Daniel@0: function [data, label] = gmmsamp(mix, n) Daniel@0: %GMMSAMP Sample from a Gaussian mixture distribution. Daniel@0: % Daniel@0: % Description Daniel@0: % Daniel@0: % DATA = GSAMP(MIX, N) generates a sample of size N from a Gaussian Daniel@0: % mixture distribution defined by the MIX data structure. The matrix X Daniel@0: % has N rows in which each row represents a MIX.NIN-dimensional sample Daniel@0: % vector. Daniel@0: % Daniel@0: % [DATA, LABEL] = GMMSAMP(MIX, N) also returns a column vector of Daniel@0: % classes (as an index 1..N) LABEL. Daniel@0: % Daniel@0: % See also Daniel@0: % GSAMP, GMM Daniel@0: % Daniel@0: Daniel@0: % Copyright (c) Ian T Nabney (1996-2001) Daniel@0: Daniel@0: % Check input arguments Daniel@0: errstring = consist(mix, 'gmm'); Daniel@0: if ~isempty(errstring) Daniel@0: error(errstring); Daniel@0: end Daniel@0: if n < 1 Daniel@0: error('Number of data points must be positive') Daniel@0: end Daniel@0: Daniel@0: % Determine number to sample from each component Daniel@0: priors = rand(1, n); Daniel@0: Daniel@0: % Pre-allocate data array Daniel@0: data = zeros(n, mix.nin); Daniel@0: if nargout > 1 Daniel@0: label = zeros(n, 1); Daniel@0: end Daniel@0: cum_prior = 0; % Cumulative sum of priors Daniel@0: total_samples = 0; % Cumulative sum of number of sampled points Daniel@0: for j = 1:mix.ncentres Daniel@0: num_samples = sum(priors >= cum_prior & ... Daniel@0: priors < cum_prior + mix.priors(j)); Daniel@0: % Form a full covariance matrix Daniel@0: switch mix.covar_type Daniel@0: case 'spherical' Daniel@0: covar = mix.covars(j) * eye(mix.nin); Daniel@0: case 'diag' Daniel@0: covar = diag(mix.covars(j, :)); Daniel@0: case 'full' Daniel@0: covar = mix.covars(:, :, j); Daniel@0: case 'ppca' Daniel@0: covar = mix.covars(j) * eye(mix.nin) + ... Daniel@0: mix.U(:, :, j)* ... Daniel@0: (diag(mix.lambda(j, :))-(mix.covars(j)*eye(mix.ppca_dim)))* ... Daniel@0: (mix.U(:, :, j)'); Daniel@0: otherwise Daniel@0: error(['Unknown covariance type ', mix.covar_type]); Daniel@0: end Daniel@0: data(total_samples+1:total_samples+num_samples, :) = ... Daniel@0: gsamp(mix.centres(j, :), covar, num_samples); Daniel@0: if nargout > 1 Daniel@0: label(total_samples+1:total_samples+num_samples) = j; Daniel@0: end Daniel@0: cum_prior = cum_prior + mix.priors(j); Daniel@0: total_samples = total_samples + num_samples; Daniel@0: end Daniel@0: