function [feature_map map_info] = omp_pooling(patch_codes, layer_params, prev_map_info)

pooling = layer_params.pooling;
patch_sz = layer_params.patch_sz;
map_info = get_map_info(pooling, patch_sz, prev_map_info);

% Max pooling
if pooling == 1
    % No changes needed
    feature_map = patch_codes;
else    
    % Height of the coded feature map (minus patch borders)
    codes_h = prev_map_info.height - patch_sz + 1;
    codes_w = prev_map_info.width - patch_sz + 1;

    [patch_codes, map_info] = ...
        pad_codes(patch_codes, codes_h, codes_w, pooling, map_info);

    % Width and height of the new pooled feature map
    map_h = map_info.height;
    map_w = map_info.width;

    % Base indices that should be pooled together
    % We can add a scalar ind_s to get the indices
    % needed for a particular patch (as done below).
    ind_b = [];
    for i = 1:pooling
       ind_b = [ind_b; (1:pooling)'+(i-1)*codes_h];
    end
    feature_map = sparse(zeros(size(patch_codes,1),map_w*map_h));

    % Pool the features
    for i = 1:map_w
       for j = 1:map_h
           ind_s = pooling*(j-1)+(i-1)*pooling*codes_h;
           ind_p = ind_b + ind_s;
           feature_map(:,(i-1)*map_h+j) = max(patch_codes(:,ind_p(:)),[],2);
       end
    end
end

end

function [codes, map_info] = pad_codes(codes, codes_h, codes_w, ...
                                             pooling, map_info);
% Pad the coded map if necessary.
if (codes_h < pooling) || (codes_w < pooling)
    codes = full(codes)';
    codes = reshape(codes, codes_h, codes_w, size(codes, 2));
    
    if codes_h < pooling
        codes = padarray(codes, [(pooling - size(codes, 1)) 0 0], 0, 'post');
        map_info.height = 1;
        codes_h = pooling;
    end

    if codes_w < pooling
        codes = padarray(codes, [0 (pooling - size(codes, 2)) 0], 0, 'post');
        map_info.width = 1;
        codes_w = pooling;
    end
    
    codes = reshape(codes, codes_h*codes_w, size(codes, 3));
    codes = sparse(codes');
end

end
