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, ''', '''));