cosmo convert neighborhood skl

function conv_nbrhood = cosmo_convert_neighborhood(nbrhood, output_type)
    % Converts between cell, matrix and struct representations of neighborhoods
    %
    % conv_nbrhood=cosmo_convert_neighborhood(nbrhood[, output_type])
    %
    % Inputs:
    %     nbrhood               Either a cell, struct, or matrix with
    %                           neighborhood information:
    %                           - cell:    Nx1 with nbrhood{k} the indices of
    %                                      the k-th neighborhood
    %                           - struct:  with field .neighbors, which must
    %                                      be a cell
    %                           - matrix:  MxN with nbrhood(:,k) the indices of
    %                                      the k-th neighborhood (non-positive
    %                                      values indicating no index), with M
    %                                      the maximum number of features in a
    %                                      single neighborhood
    %     output_type           Optional, one of 'cell', 'matrix', or
    %                           'struct'.
    %                           If empty or omitted, then output_type is set to
    %                           'matrix', unless nbrhood is a matrix, in
    %                           which case it is set to 'cell'.
    % Output:
    %     conv_nbrhood          Neighborhood information converted to cell,
    %                           struct, or matrix (see above)
    %
    % Example:
    %     ds=cosmo_synthetic_dataset();
    %     nbrhood=cosmo_spherical_neighborhood(ds,'radius',1,'progress',false);
    %     % show the neighbor indices
    %     cosmo_disp(nbrhood.neighbors)
    %     %|| { [ 1         4         2 ]
    %     %||   [ 2         1         5         3 ]
    %     %||   [ 3         2         6 ]
    %     %||   [ 4         1         5 ]
    %     %||   [ 5         4         2         6 ]
    %     %||   [ 6         5         3 ]           }
    %     %
    %     % convert to matrix representation
    %     mx=cosmo_convert_neighborhood(nbrhood,'matrix');
    %     cosmo_disp(mx)
    %     %|| [ 1         2         3         4         5         6
    %     %||   4         1         2         1         4         5
    %     %||   2         5         6         5         2         3
    %     %||   0         3         0         0         6         0 ]
    %     %
    %     % convert to cell representation
    %     neighbors=cosmo_convert_neighborhood(nbrhood,'cell');
    %     cosmo_disp(neighbors)
    %     %|| { [ 1         4         2 ]
    %     %||   [ 2         1         5         3 ]
    %     %||   [ 3         2         6 ]
    %     %||   [ 4         1         5 ]
    %     %||   [ 5         4         2         6 ]
    %     %||   [ 6         5         3 ]           }
    %
    % Notes:
    %    - the rationale of this function is that cell or struct
    %      representations are more intuitive and possible more space
    %      efficient, but also slower to access than matrix representations.
    %      This function provides conversion between different representations.
    %
    % #   For CoSMoMVPA's copyright information and license terms,   #
    % #   see the COPYING file distributed with CoSMoMVPA.           #

    if nargin < 2
        output_type = '';
    end

    if isnumeric(nbrhood)
        converter = @convert_matrix;
    elseif iscell(nbrhood)
        converter = @convert_cell;
    elseif isstruct(nbrhood)
        converter = @convert_struct;
    else
        error('Expected matrix, cell, or struct input');
    end

    conv_nbrhood = converter(nbrhood, output_type);

function y = convert_cell(x, output_type)
    check_cell(x);
    switch output_type
        case {'', 'matrix'}
            y = convert_cell2matrix(x);
        case 'struct'
            y = convert_cell2struct(x);
        case {'cell'}
            y = x;
        otherwise
            throw_illegal_output_type_error();
    end

function y = convert_matrix(x, output_type)
    check_matrix(x);
    switch output_type
        case {'', 'cell'}
            y = convert_matrix2cell(x);
        case 'struct'
            y = convert_matrix2struct(x);
        case 'matrix'
            y = x;
        otherwise
            throw_illegal_output_type_error();
    end

function y = convert_struct(x, output_type)
    check_struct(x);
    switch output_type
        case 'cell'
            y = convert_struct2cell(x);
        case {'', 'matrix'}
            y = convert_struct2matrix(x);
        case 'struct'
            y = x;
        otherwise
            throw_illegal_output_type_error();
    end

function check_matrix(neighbors)
    if numel(size(neighbors)) ~= 2
        error('input is not a matrix');
    end

    assert(isnumeric(neighbors));

    if ~isequal(round(neighbors), neighbors)
        error('input has non-integer values');
    end

function check_struct(nbrhood)
    cosmo_check_neighborhood(nbrhood, 'show_warning', false);

function check_cell(neighbors)
    check_struct(convert_cell2struct(neighbors));

function nbrhood = convert_cell2struct(neighbors)
    nbrhood = struct();
    nbrhood.neighbors = neighbors;
    nbrhood.fa = struct();
    nbrhood.a = struct();

function neighbors = convert_struct2cell(nbrhood)
    neighbors = nbrhood.neighbors;

function neighbor_matrix = convert_cell2matrix(neighbors)
    nfeatures = numel(neighbors);
    nnbrs = cellfun(@numel, neighbors);
    maxn = max(nnbrs);

    neighbor_matrix = zeros(maxn, nfeatures);
    for k = 1:nfeatures
        nbrs = neighbors{k};
        neighbor_matrix(1:numel(nbrs), k) = nbrs;
    end

function neighbors = convert_matrix2cell(neighbor_matrix)
    nfeatures = size(neighbor_matrix, 2);
    neighbors = cell(nfeatures, 1);

    for k = 1:nfeatures
        nbrs = neighbor_matrix(:, k);
        neighbors{k} = nbrs(nbrs > 0)';
    end

function nbrhood = convert_matrix2struct(neighbor_matrix)
    nbrhood = convert_cell2struct(convert_matrix2cell(neighbor_matrix));

function neighbor_matrix = convert_struct2matrix(nbrhood)
    neighbor_matrix = convert_cell2matrix(convert_struct2cell(nbrhood));

function throw_illegal_output_type_error()
    valid_output_types = {'', 'matrix', 'struct', 'cell'};
    error('illegal output type, valid is one of: ''%s''.', ...
          cosmo_strjoin(valid_output_types, ''', '''));