function test_suite=test_stack
% tests for cosmo_stack
%
% # 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_stack_samples
ds=cosmo_synthetic_dataset();
ds1=cosmo_slice(ds,[2 1 4 3 6 5]);
ds2=cosmo_slice(ds,6:-1:1,2);
% test first dimension
s=cosmo_stack({ds,ds1});
assertEqual(s.samples,[ds.samples;ds1.samples])
assertEqual(s.sa.targets,[ds.sa.targets;ds1.sa.targets]);
assertEqual(s.fa,ds1.fa);
s2=cosmo_stack({ds,ds2},1,'drop_nonunique');
assertEqual(fieldnames(s2.fa),{'k'});
assertEqual(s2.samples,[ds.samples;ds2.samples]);
assertExceptionThrown(@()cosmo_stack({ds,ds2},1,'unique'),'');
assertExceptionThrown(@()cosmo_stack({ds,ds2}),'');
s3=cosmo_stack({ds,ds2},1,'drop');
assertTrue(isempty(fieldnames(s3.fa)));
assertEqual(s3.sa,s2.sa);
s4=cosmo_stack({ds,ds2},1,'drop_nonunique');
assertEqual(s2,s4);
s5=cosmo_stack({ds,ds2},1,2);
assertEqual(s5.fa,ds2.fa);
% should properly deal with NaNs
ds.fa.i(2:4)=NaN;
ds1.fa.i(2:4)=NaN;
s=cosmo_stack({ds,ds1});
assertEqual(s.fa,ds1.fa);
function test_stack_features
ds=cosmo_synthetic_dataset();
ds1=cosmo_slice(ds,6:-1:1,2);
ds2=cosmo_slice(ds,[2 1 4 3 6 5]);
% test second dimension
s=cosmo_stack({ds,ds1},2,'drop_nonunique');
assertEqual(s.samples,[ds.samples ds1.samples])
assertEqual(s.fa.i,[ds.fa.i ds1.fa.i]);
assertEqual(s.sa,ds1.sa);
s2=cosmo_stack({ds,ds2},2,'drop_nonunique');
assertEqual(fieldnames(s2.sa),{'chunks'});
assertEqual(s2.samples,[ds.samples ds2.samples]);
assertExceptionThrown(@()cosmo_stack({ds,ds2},2,'unique'),'');
assertExceptionThrown(@()cosmo_stack({ds,ds2},2),'');
s3=cosmo_stack({ds,ds2},2,'drop');
assertTrue(isempty(fieldnames(s3.sa)));
assertEqual(s3.fa,s2.fa);
s4=cosmo_stack({ds,ds2},2,'drop_nonunique');
assertEqual(s2,s4);
s5=cosmo_stack({ds,ds2},2,2);
assertEqual(s5.sa,ds2.sa);
s6=cosmo_stack({ds},1);
assertEqual(s6,ds);
% should properly deal with NaNs
ds.sa.targets(2:4)=NaN;
ds1.sa.targets(2:4)=NaN;
s=cosmo_stack({ds,ds},2);
assertEqual(s.sa,ds1.sa);
function test_stack_exceptions
% test exceptions
ds=cosmo_synthetic_dataset();
aet=@(varargin)assertExceptionThrown(@()cosmo_stack(varargin{:}),'');
aet('foo');
aet({ds},3);
aet({ds},1,'foo');
% sample size mismatch
ds1=ds;
ds1.samples=ones(1,5);
aet({ds,ds1});
% .sa size mismatch
ds1=ds;
ds1.sa.targets=1;
aet({ds,ds1});
% non-matching elements
ds1=ds;
ds2=ds;
ds2.sa.targets=ds2.sa.targets(end:-1:1);
aet({ds1,ds2},2);
ds2=ds;
ds2.fa.i=ds2.fa.i(end:-1:1);
aet({ds1,ds2},1);