function test_suite=test_phase_itc
% tests for test_phase_itc
%
% # 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 r=randint()
r=ceil(2+rand()*10);
function test_phase_itc_basics
nclasses=randint();
classes=1:2:(2*nclasses);
nrepeats=randint();
nfeatures=randint();
ds=generate_random_dataset(classes,nrepeats,nfeatures);
% compute expected ITC
itc_ds=cosmo_phase_itc(ds);
expected_samples=zeros(nclasses+1,nfeatures);
for k=1:nclasses
msk=ds.sa.targets==classes(k);
expected_samples(k,:)=quick_itc(ds.samples(msk,:));
end
expected_samples(nclasses+1,:)=quick_itc(ds.samples);
% construct expected dataset
expected_itc_ds=struct();
expected_itc_ds.samples=expected_samples;
expected_itc_ds.sa.targets=[classes,NaN]';
expected_itc_ds.a=ds.a;
expected_itc_ds.fa=ds.fa;
assert_datasets_almost_equal(itc_ds,expected_itc_ds);
function test_phase_itc_unit_length()
% test with 'samples_are_unit_length' option
ds=generate_random_dataset(1:10,randint(),randint());
ds_unit=ds;
ds_unit.samples=ds_unit.samples./abs(ds_unit.samples);
itc_ds=cosmo_phase_itc(ds);
itc_unit_ds=cosmo_phase_itc(ds_unit,'samples_are_unit_length',true);
assert_datasets_almost_equal(itc_ds,itc_unit_ds);
function test_phase_itc_sdim_field
ds=cosmo_synthetic_dataset('ntargets',3,'nchunks',3);
ds.samples=ds.samples+1i*randn(size(ds.samples));
ds.sa.chunks(:)=1:9;
% add sample dimension
ds=cosmo_dim_insert(ds,1,1,{'foo'},{[1:9]},{[1:9]'});
itc_ds=cosmo_phase_itc(ds);
assert(~isfield(itc_ds.a,'sdim'));
assert(~isfield(itc_ds.sa,'foo'));
function assert_datasets_almost_equal(p,q)
assertElementsAlmostEqual(p.samples,q.samples);
p=rmfield(p,'samples');
q=rmfield(q,'samples');
assertEqual(p,q);
function ds=generate_random_dataset(classes,nrepeats,nfeatures)
nclasses=numel(classes);
nsamples=nclasses*nrepeats;
sz=[nsamples,nfeatures];
ds=struct();
ds.samples=randn(sz)+1i*randn(sz);
ds.sa.targets=repmat(classes,1,nrepeats)';
ds.sa.chunks=(1:nsamples)';
ds.a='foo';
ds.fa.bar=1:nfeatures;
% permute randomly
ds=cosmo_slice(ds,cosmo_randperm(nsamples));
function itc=quick_itc(samples)
s=samples./abs(samples);
itc=abs(mean(s,1));
function test_phase_itc_exceptions()
aet=@(varargin)assertExceptionThrown(...
@()cosmo_phase_itc(varargin{:}),'');
ds=cosmo_synthetic_dataset('ntargets',2,'nchunks',6);
nsamples=size(ds.samples,1);
sz=size(ds.samples);
ds.samples=randn(sz)+1i*randn(sz);
ds.sa.chunks(:)=1:nsamples;
cosmo_phase_itc(ds); % ok
% input not imaginary
bad_ds=ds;
bad_ds.samples=randn(sz);
aet(bad_ds);
% chunks not all unique
bad_ds=ds;
bad_ds.sa.chunks(1)=bad_ds.sa.chunks(2);
aet(bad_ds);
% imbalance
bad_ds=ds;
bad_ds.sa.targets(:)=[repmat([1 2],1,5),[1 1]];
aet(bad_ds);
% bad values for samples_are_unit_length
bad_samples_are_unit_length_cell={[],'',1,[true false]};
for k=1:numel(bad_samples_are_unit_length_cell)
arg={'samples_are_unit_length',...
bad_samples_are_unit_length_cell{k}};
aet(ds,arg{:});
end
% with samples_are_unit_length=true, raise exception if some values
% are not unit length
aet(ds,'samples_are_unit_length',true);