function samples = sample_layer(layer_params, file_info, config)

n_samples = get_samples_per_image(config, layer_params, file_info);

samples = cell(1, file_info.num_files);
parfor i = 1:file_info.num_files
    % Read the data and get patches
    [parent_dirs, name_root] = get_file_info_entry(file_info, i);
    [data, ~] = load_feature_map(parent_dirs, name_root, ...
                                 layer_params, config.load_params);
    patches = get_patches(data, layer_params);

    % Randomly select n_samples of the patches
    sample_ind = randsample(size(patches, 2), min(size(patches, 2), n_samples));
    samples{i} = patches(:, sample_ind);
end
samples = cell2mat(samples);

% Cut off incomplete blocks if desired (for parallel ksvd).
if isfield(config, 'blk_size')
    mod_size = size(samples, 2) - mod(size(samples, 2), config.blk_size);
    samples = samples(:, 1:mod_size);
end

fprintf('      Finished sampling %d samples from %d files\n', ...
        size(samples, 2), file_info.num_files);
end

function n_samples = get_samples_per_image(config, layer_params, file_info)
% Read the data and get patches for the first file.
[parent_dirs, name_root] = get_file_info_entry(file_info, 1);
[data, ~] = load_feature_map(parent_dirs, name_root, ...
                             layer_params, config.load_params);
patches = get_patches(data, layer_params);

% Figure out the total number of samples and the number of samples per file.
total_samples = floor(config.max_sample_mem/...
                      ((layer_params.dict_sz + size(patches, 1))*8));
n_samples = floor(total_samples/file_info.num_files);

if n_samples > config.max_samples_per_image
    n_samples = config.max_samples_per_image;
end

if total_samples > config.max_total_samples
    n_samples = ceil(config.max_total_samples/file_info.num_files);
end

total_samples = n_samples*file_info.num_files;

% Print information about sampling and estimated memory usage
fprintf('      Sampling Information:\n');
fprintf('        %d samples total: %d from each of %d files\n', ...
        total_samples, n_samples, file_info.num_files);
fprintf('      Memory Estimates:\n')
fprintf('        Data matrix X: %d x %d, %.3f Gb\n', size(patches, 1), ...
        total_samples, (size(patches, 1)*total_samples*8)/1e9);
fprintf('        D''X matrix when memusage = high: %d x %d, %.3f Gb\n', ...
        layer_params.dict_sz, total_samples, ...
        (layer_params.dict_sz*total_samples*8)/1e9);
end
