function test_suite = test_distatis
% tests for cosmo_distatis
%
% # 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_statis_
% using: 1. Abdi, H. & Valentin, D. in Encyclopedia of Measurement
% and Statistics (Salkind, N.) 42?42 (SAGE Publications, 2007).
d=cell(0);
% note: element [1,3] is reported as .148, for symmetry use .146
d{1}=[ 0 0.1120 0.1460 0.0830 0.1860 0.1100
0.1120 0 0.1520 0.0980 0.1580 0.1340
0.1460 0.1520 0 0.2020 0.2850 0.2490
0.0830 0.0980 0.2020 0 0.1310 0.1100
0.1860 0.1580 0.2850 0.1310 0 0.1550
0.1100 0.1340 0.2490 0.1100 0.1550 0];
d{2}=[ 0 0.6000 1.9800 0.4200 0.1400 0.5800
0.6000 0 2.1000 0.7800 0.4200 1.3400
1.9800 2.1000 0 2.0200 1.7200 2.0600
0.4200 0.7800 2.0200 0 0.5000 0.8800
0.1400 0.4200 1.7200 0.5000 0 0.3000
0.5800 1.3400 2.0600 0.8800 0.3000 0];
d{3}=[ 0 0.5400 1.3900 5.7800 10.2800 6.7700
0.5400 0 1.0600 3.8000 6.8300 4.7100
1.3900 1.0600 0 8.0100 11.0300 5.7200
5.7800 3.8000 8.0100 0 2.5800 6.0900
10.2800 6.8300 11.0300 2.5800 0 3.5300
6.7700 4.7100 5.7200 6.0900 3.5300 0];
d{4}=[ 0 0.0140 0.1590 0.0040 0.0010 0.0020
0.0140 0 0.0180 0.0530 0.0240 0.0040
0.1590 0.0180 0 0.2710 0.0670 0.0530
0.0040 0.0530 0.2710 0 0.0010 0.0080
0.0010 0.0240 0.0670 0.0010 0 0.0070
0.0020 0.0040 0.0530 0.0080 0.0070 0];
ds=get_distance_dataset(d);
ds=cosmo_stack({ds,ds,ds},2); % features
cosmo_check_dataset(ds);
opt=struct();
opt.split_by='subject';
opt.return='crossproduct';
opt.progress=false;
res=cosmo_distatis(ds,opt);
% note: S_{[+]}[6,2] is reported as -0.01, should be -.100
s= [.176 .004 -.058 .014 -.100 -.036
.004 .178 .022 -.038 -.068 -.100
-.058 .022 .579 -.243 -.186 -.115
.014 -.038 -.243 .240 .054 -.027
-.100 -.068 -.186 .054 .266 .034
-.036 -.100 -.115 -.027 .034 .243];
u=cosmo_unflatten(res,1);
assertElementsAlmostEqual(repmat(s,[1,1,3]),u,'absolute',.001);
assertElementsAlmostEqual(res.fa.quality(2),.6551,'absolute',.001)
opt.return='distance';
opt.shape='square';
res=cosmo_distatis(ds,opt);
u=cosmo_unflatten(res,1);
sq=cosmo_squareform(u(:,:,1));
assertElementsAlmostEqual(sq,[0.3452 0.8710 0.3888 0.6419 ...
0.4911 0.7112 0.4919 0.5789 ...
0.6203 1.3049 1.2163 1.0512 ...
0.3996 0.5354 0.4400],'absolute',.001);
opt.shape='triangle';
resvec=cosmo_distatis(ds,opt);
assertElementsAlmostEqual(resvec.samples(:,1),sq');
% test numeric input
vec_samples=mat2cell(ds.samples(:,1),ones(4,1)*15,1);
resvec2=cosmo_distatis(vec_samples,opt);
assertElementsAlmostEqual(resvec2.samples,resvec.samples(:,1));
assertEqual(cellfun(@numel,resvec2.a.sdim.values),...
cellfun(@numel,resvec.a.sdim.values));
resvec2.a.sdim.values=resvec.a.sdim.values;
resvec_single_feature=cosmo_slice(resvec,1,2);
assertElementsAlmostEqual(resvec_single_feature.samples,...
resvec2.samples);
assertElementsAlmostEqual(resvec_single_feature.fa.quality,...
resvec2.fa.quality);
resvec2.samples=resvec_single_feature.samples;
resvec2.fa.quality=resvec_single_feature.fa.quality;
assertEqual(resvec2,resvec_single_feature);
opt.weights='uniform';
resvec=cosmo_distatis(ds,opt);
assertElementsAlmostEqual(resvec.samples(:,1)',...
[0.3156 0.8625 0.3704 0.6043 0.4646 ...
0.6572 0.4788 0.5489 0.5783 1.3221 ...
1.1576 0.9885 0.3644 0.5068 0.4037],...
'absolute',.001);
% test exceptions
aet=@(varargin)assertExceptionThrown(@()...
cosmo_distatis(varargin{:},'progress',false),'');
% no compromise possible
d2=d;
d2{4}(1,5)=3;
d2{4}(5,1)=3;
opt.weights='eig';
ds2=get_distance_dataset(d2);
aet(ds2,opt);
% illegal arguments
ds.sa.chunks=ds.sa.subject;
opt=struct();
opt.shape='foo';
aet(ds,opt);
opt=struct();
opt.weights='foo';
aet(ds,opt);
opt=struct();
opt.return='foo';
aet(ds,opt);
opt=struct();
% cannot deal with empty input
aet({},opt);
% needs dataset or numeric input
aet({false,true},opt);
% cannot take non-matrix input
aet({zeros([2 2 2])},opt);
% illegal field in dataset
ds_bad=ds;
ds_bad.foo=2;
opt=struct();
aet(ds_bad,opt);
function ds=get_distance_dataset(d)
nsubj=numel(d);
ds_all=cell(nsubj,1);
for k=1:nsubj
ds=struct();
sq=cosmo_squareform(d{k});
ds.samples=sq(:);
nd=size(d{k},1);
ns=size(ds.samples,1);
ds.sa.subject=k*ones(ns,1);
[i,j]=find(triu(repmat(1:nd,nd,1)',1)');
ds.sa.targets1=i;
ds.sa.targets2=j;
faces={'f1','f2','f3','f4','f5','f6'}';
ds.a.sdim.values={faces,faces};
ds.a.sdim.labels={'targets1','targets2'};
ds_all{k}=ds;
end
ds=cosmo_stack(ds_all);