function test_suite = test_neighborhood_split()
% tests for cosmo_neighborhood_split
%
% # For CoSMoMVPA's copyright information and license terms, #
% # see the COPYING file distributed with CoSMoMVPA. #
try % assignment of 'localfunctions' is necessary in Matlab >= 2016
test_functions=localfunctions();
catch % no problem; early Matlab versions can use initTestSuite fine
end
initTestSuite;
function test_neighborhood_split_basics()
ds=cosmo_synthetic_dataset('size','big');
nfeatures=size(ds.samples,2);
rp=randperm(nfeatures);
ds=cosmo_slice(ds,[rp rp],2);
nfeatures=size(ds.samples,2);
radius=1+rand()*3;
nh=cosmo_spherical_neighborhood(ds,'radius',radius,'progress',false);
for divisions=[2 4]
[nh_sp,masks]=cosmo_neighborhood_split(nh,'divisions',divisions);
% basic checks
assert(iscell(nh_sp));
assert(iscell(masks));
n_sp=numel(nh_sp);
assertEqual(n_sp,numel(masks));
assert(n_sp<=(divisions+1)^3);
assert(n_sp>=(divisions-1)^3);
% space for neighborhood matrix consisting of the different splits
max_nh_count=max(cellfun(@numel,nh.neighbors));
n_centers=numel(nh.neighbors);
all_nh_mx=zeros(max_nh_count,n_centers);
% space to store neighborhoods .fa
all_fa_cell=cell(1,n_sp);
feature_id=0;
for k=1:n_sp
sp_nh=nh_sp{k};
assertEqual(sp_nh.a, nh.a);
sp_msk=masks{k};
% mask must have similar 'space' as dataset
assert(islogical(sp_msk.samples));
assertEqual(size(sp_msk.samples),[1,nfeatures]);
assertEqual(sp_msk.fa,ds.fa);
assertEqual(sp_msk.a,ds.a);
% store feature attributes
all_fa_cell{k}=[sp_nh.fa.i; sp_nh.fa.j; sp_nh.fa.k];
m_k_idxs=find(sp_msk.samples);
for j=1:numel(sp_nh.neighbors)
nb=sp_nh.neighbors{j};
% indirect indexing through neighbors must
% only give features that are in the mask
idx_msk=false(1,nfeatures);
assert(max(nb)<=numel(m_k_idxs));
assert(max(m_k_idxs(nb))<=nfeatures);
idx_msk(m_k_idxs(nb))=true;
assert(all(sp_msk.samples(idx_msk)));
assert(~any(idx_msk & ~sp_msk.samples));
% store neighbors in matrix
n_nb=numel(nb);
feature_id=feature_id+1;
all_nh_mx(1:n_nb,feature_id)=m_k_idxs(nb);
end
end
% all centers must be visited
assert(feature_id==n_centers);
% stack the .fa
all_fa=cat(2,all_fa_cell{:});
all_fa_ijk_cell={all_fa(1,:),all_fa(2,:),all_fa(3,:)};
% get the original fa
fa_ijk_cell={nh.fa.i, nh.fa.j, nh.fa.k};
fa=cat(1,fa_ijk_cell{:});
% order may be different as in the original, so find the mapping
mp=cosmo_align(all_fa_ijk_cell,fa_ijk_cell);
assertEqual(all_fa(:,mp),fa);
% verify that neighbors are matching
nh_mx=cosmo_convert_neighborhood(nh,'matrix');
assertEqual(all_nh_mx(:,mp),nh_mx);
end
function test_neighborhood_split_exceptions()
return
aet=@(varargin)assertExceptionThrown(@()...
cosmo_neighborhood_split(varargin{:}),'');
aet(struct);
ds=cosmo_synthetic_dataset();
aet(ds);
nh=cosmo_interval_neighborhood(ds,'i','radius',1);
aet(nh,'foo',2);
aet(nh,'count',0);
aet(nh,'count',1.0001);
aet(nh,'count',[2 2]);
aet(nh,'count',Inf);
aet(nh,'count',[]);
nh2=nh;
nh2=rmfield(nh2,'origin');
aet(nh2,'count',2);
nh2=nh;
nh2=rmfield(nh2,'neighbors');
aet(nh2,'count',2);