├── .directory ├── config ├── kELM-A.mat ├── kELM-V.mat ├── nELM-A.mat ├── nELM-V.mat ├── sSOM-A.mat ├── sSOM-V.mat └── sSOM-2D.mat ├── features ├── dev_1.mat ├── dev_2.mat ├── dev_3.mat ├── dev_4.mat ├── dev_5.mat ├── dev_6.mat ├── dev_7.mat ├── dev_8.mat ├── dev_9.mat ├── test_1.mat ├── test_2.mat ├── test_3.mat ├── test_4.mat ├── test_5.mat ├── test_6.mat ├── test_7.mat ├── test_8.mat ├── test_9.mat ├── train_1.mat ├── train_2.mat ├── train_3.mat ├── train_4.mat ├── train_5.mat ├── train_6.mat ├── train_7.mat ├── train_8.mat └── train_9.mat ├── somtoolbox ├── som │ ├── iscolvec.m │ ├── som_use_vs1.m │ ├── som_use_vs2.m │ ├── vis_grid_struct.m │ ├── som_table_print.m │ ├── som_ind2sub.m │ ├── som_sub2ind.m │ ├── som_cod2ind.m │ ├── som_neighbors.m │ ├── som_fillnans.m │ ├── som_ind2cod.m │ ├── hits.m │ ├── nanstats.m │ ├── vis_footnoteButtonDownFcn.m │ ├── som_dmatclusters.m │ ├── som_label2num.m │ ├── vis_PlaneAxisProperties.m │ ├── som_dmat.m │ ├── som_gapindex.m │ ├── som_dmatminima.m │ ├── som_projections.m │ ├── som_drsignif.m │ ├── pcaproj.m │ ├── som_estimate_gmm.m │ ├── som_mdist.m │ ├── som_bmucolor.m │ ├── som_eucdist2.m │ ├── som_table_struct.m │ ├── som_projections_plot.m │ ├── som_normcolor.m │ ├── som_divide.m │ ├── som_dreval.m │ ├── som_probability_gmm.m │ ├── vis_footnote.m │ ├── som_coloring.m │ ├── som_table_modify.m │ ├── som_clget.m │ ├── som_neighf.m │ ├── vis_planeGetArgs.m │ ├── som_stats_report.m │ ├── som_stats_table.m │ ├── som_plotmatrix.m │ ├── vis_patch.m │ ├── som_kmeans.m │ ├── som_kmeanscolor.m │ ├── som_distortion.m │ ├── som_prototrain.m │ ├── som_clspread.m │ ├── som_stats_plot.m │ ├── som_show_clear.m │ ├── som_clustercolor.m │ ├── som_neighborhood.m │ ├── som_unit_neighs.m │ └── som_vis_coords.m └── README ├── lib ├── svr │ ├── gaussKernel.m │ ├── svr_predict.m │ ├── README.md │ └── svr_trainer.m ├── SOMTrain.m ├── activationFunction.m ├── kernel_matrix.m ├── cccPerformance.m ├── ELMPredict.m ├── makeDataStruct.m ├── postProcessing.m ├── smoothts.m ├── SOMPredict.m └── featureExtraction.m └── README.md /.directory: -------------------------------------------------------------------------------- 1 | [Dolphin] 2 | Timestamp=2017,8,29,18,8,54 3 | Version=3 4 | -------------------------------------------------------------------------------- /config/kELM-A.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lbugnon/emoHR/HEAD/config/kELM-A.mat -------------------------------------------------------------------------------- /config/kELM-V.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lbugnon/emoHR/HEAD/config/kELM-V.mat -------------------------------------------------------------------------------- /config/nELM-A.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lbugnon/emoHR/HEAD/config/nELM-A.mat -------------------------------------------------------------------------------- /config/nELM-V.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lbugnon/emoHR/HEAD/config/nELM-V.mat -------------------------------------------------------------------------------- /config/sSOM-A.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lbugnon/emoHR/HEAD/config/sSOM-A.mat -------------------------------------------------------------------------------- /config/sSOM-V.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lbugnon/emoHR/HEAD/config/sSOM-V.mat -------------------------------------------------------------------------------- /config/sSOM-2D.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lbugnon/emoHR/HEAD/config/sSOM-2D.mat -------------------------------------------------------------------------------- /features/dev_1.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lbugnon/emoHR/HEAD/features/dev_1.mat -------------------------------------------------------------------------------- /features/dev_2.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lbugnon/emoHR/HEAD/features/dev_2.mat -------------------------------------------------------------------------------- /features/dev_3.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lbugnon/emoHR/HEAD/features/dev_3.mat -------------------------------------------------------------------------------- /features/dev_4.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lbugnon/emoHR/HEAD/features/dev_4.mat -------------------------------------------------------------------------------- /features/dev_5.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lbugnon/emoHR/HEAD/features/dev_5.mat -------------------------------------------------------------------------------- /features/dev_6.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lbugnon/emoHR/HEAD/features/dev_6.mat -------------------------------------------------------------------------------- /features/dev_7.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lbugnon/emoHR/HEAD/features/dev_7.mat -------------------------------------------------------------------------------- /features/dev_8.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lbugnon/emoHR/HEAD/features/dev_8.mat -------------------------------------------------------------------------------- /features/dev_9.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lbugnon/emoHR/HEAD/features/dev_9.mat -------------------------------------------------------------------------------- /features/test_1.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lbugnon/emoHR/HEAD/features/test_1.mat -------------------------------------------------------------------------------- /features/test_2.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lbugnon/emoHR/HEAD/features/test_2.mat -------------------------------------------------------------------------------- /features/test_3.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lbugnon/emoHR/HEAD/features/test_3.mat -------------------------------------------------------------------------------- /features/test_4.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lbugnon/emoHR/HEAD/features/test_4.mat -------------------------------------------------------------------------------- /features/test_5.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lbugnon/emoHR/HEAD/features/test_5.mat -------------------------------------------------------------------------------- /features/test_6.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lbugnon/emoHR/HEAD/features/test_6.mat -------------------------------------------------------------------------------- /features/test_7.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lbugnon/emoHR/HEAD/features/test_7.mat -------------------------------------------------------------------------------- /features/test_8.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lbugnon/emoHR/HEAD/features/test_8.mat -------------------------------------------------------------------------------- /features/test_9.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lbugnon/emoHR/HEAD/features/test_9.mat -------------------------------------------------------------------------------- /features/train_1.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lbugnon/emoHR/HEAD/features/train_1.mat -------------------------------------------------------------------------------- /features/train_2.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lbugnon/emoHR/HEAD/features/train_2.mat -------------------------------------------------------------------------------- /features/train_3.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lbugnon/emoHR/HEAD/features/train_3.mat -------------------------------------------------------------------------------- /features/train_4.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lbugnon/emoHR/HEAD/features/train_4.mat -------------------------------------------------------------------------------- /features/train_5.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lbugnon/emoHR/HEAD/features/train_5.mat -------------------------------------------------------------------------------- /features/train_6.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lbugnon/emoHR/HEAD/features/train_6.mat -------------------------------------------------------------------------------- /features/train_7.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lbugnon/emoHR/HEAD/features/train_7.mat -------------------------------------------------------------------------------- /features/train_8.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lbugnon/emoHR/HEAD/features/train_8.mat -------------------------------------------------------------------------------- /features/train_9.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lbugnon/emoHR/HEAD/features/train_9.mat -------------------------------------------------------------------------------- /somtoolbox/som/iscolvec.m: -------------------------------------------------------------------------------- 1 | function status = iscolvec(x) 2 | 3 | status = ~isempty(x) && isvector(x) && size(x,2) == 1; -------------------------------------------------------------------------------- /lib/svr/gaussKernel.m: -------------------------------------------------------------------------------- 1 | % ================================================ 2 | % sinc(i) - http://sinc.unl.edu.ar 3 | % Leandro Bugnon (lbugnon@sinc.unl.edu.ar) 4 | % ================================================ 5 | function M=gaussKernel(x,y,gamma) 6 | 7 | XXh1 = sum(x.^2,2)*ones(1,size(y,1)); 8 | XXh2 = sum(y.^2,2)*ones(1,size(x,1)); 9 | M = XXh1+XXh2' - 2*x*y'; 10 | M = exp(-M*gamma); 11 | end 12 | 13 | -------------------------------------------------------------------------------- /lib/svr/svr_predict.m: -------------------------------------------------------------------------------- 1 | % Modified version from Support Vector Regression 2 | % by Ronnie Clark 3 | % ================================================ 4 | % sinc(i) - http://sinc.unl.edu.ar 5 | % Leandro Bugnon (lbugnon@sinc.unl.edu.ar) 6 | % ================================================ 7 | function f = svr_predict(y,svrmodel) 8 | 9 | f = 0; 10 | 11 | for n=1:size(svrmodel.trainData,1) 12 | % gauss kernel 13 | f = f + svrmodel.alpha(n)*gaussKernel(y,svrmodel.trainData(n,:),svrmodel.gamma); 14 | end 15 | 16 | f = f + svrmodel.b; 17 | f = f/2; 18 | end -------------------------------------------------------------------------------- /lib/svr/README.md: -------------------------------------------------------------------------------- 1 | # SVR quadprog 2 | 3 | A simple script to train a Support Vector Machine for Regression (SVR) using MATLAB quadratic programming functions. 4 | 5 | Modified from original version of Ronny Clark (https://uk.mathworks.com/matlabcentral/fileexchange/43429-support-vector-regression), optimizing kernel and matrix operations for a better performance. 6 | 7 | --- 8 | Example usage: 9 | ``` 10 | svrobj = svr_trainer(x_train,y_train,400,0.000000025,'gaussian',0.5); 11 | y = svrobj.predict(x_test); 12 | ``` 13 | --- 14 | sinc(i) - http://fich.unl.edu.ar/sinc/. 15 | Leandro Bugnon (lbugnon@sinc.unl.edu.ar) 16 | -------------------------------------------------------------------------------- /somtoolbox/som/som_use_vs1.m: -------------------------------------------------------------------------------- 1 | function som_use_vs1() 2 | 3 | % SOM_USE_VS1 Use SOM Toolbox version 1. 4 | % 5 | % Removes SOM Toolbox version 2 from the path and adds version 1 there 6 | % instead. Before doing this, remember to convert any version 2 structs you 7 | % will need to the corresponding version 1 structs using function SOM_VS2TO1. 8 | % 9 | % See also SOM_USE_VS2, SOM_VS1TO2, SOM_VS2TO1, PATHTOOL. 10 | 11 | rmpath /share/somtoolbox/www/package/codes2 12 | 13 | s=path; 14 | p=findstr(s,'/share/matlab5'); p=p(1); 15 | i=p+12; while ~strcmp(s(i),'/'), i=i+1; end 16 | r=strcat(s(p:i),'toolbox/somtoolbox'); 17 | addpath(r) 18 | 19 | fprintf(1,'Version 1 of SOM Toolbox now in use.\n'); 20 | fprintf(1,'Use som_vs2to1 function to convert any vs2 structs to vs1.\n') 21 | -------------------------------------------------------------------------------- /somtoolbox/som/som_use_vs2.m: -------------------------------------------------------------------------------- 1 | function som_use_vs2() 2 | 3 | % SOM_USE_VS2 Use SOM Toolbox version 2. 4 | % 5 | % Removes SOM Toolbox version 1 from the path and adds version 2 6 | % there instead. You can use function SOM_VS1TO2 to convert 7 | % any version 1 structs to the corresponding version 2 structs. 8 | % 9 | % See also SOM_USE_VS1, SOM_VS1TO2, SOM_VS2TO1, PATHTOOL. 10 | 11 | s=path; p=findstr(s,'somtoolbox'); 12 | while any(p), 13 | p=p(1); 14 | i=p; while i1 && ~strcmp(s(j),':'), j=j-1; end 17 | if strcmp(s(j),':'), j=j+1; end 18 | r=s(j:i); 19 | rmpath(r); 20 | s=path; p=findstr(s,'somtoolbox'); 21 | end 22 | 23 | addpath /share/somtoolbox/www/package/codes2 24 | 25 | fprintf(1,'Version 2 of SOM Toolbox now in use.\n'); 26 | fprintf(1,'Latest changes to SOM Toolbox: August 22nd 2000\n'); 27 | fprintf(1,' see /share/somtoolbox/vs2/changelog.txt\n'); 28 | fprintf(1,'Use som_vs1to2 function to convert any vs1 structs to vs2.\n') 29 | 30 | -------------------------------------------------------------------------------- /somtoolbox/som/vis_grid_struct.m: -------------------------------------------------------------------------------- 1 | function S=vis_grid_struct 2 | 3 | % VIS_GRID_STRUCT Initiates and returns a default grid struct 4 | % 5 | % S = vis_grid_struct 6 | % 7 | % Output arguments: 8 | % S (struct) som_grid struct 9 | % 10 | % Fields and their initial values: 11 | % S.type='som_grid'; 12 | % S.neigh=neigh; 13 | % S.shape='sheet'; 14 | % S.msize=msize; 15 | % S.coord=[]; 16 | % S.line='-'; 17 | % S.linecolor=[.8 .8 .8]; 18 | % S.linewidth=0.5; 19 | % S.marker='o'; 20 | % S.markersize=6; 21 | % S.markercolor='k'; 22 | % S.surf=[]; 23 | % S.label=[]; 24 | % S.labelcolor='g'; 25 | % S.labelsize=12; 26 | % 27 | % This is a subfunction for SOM_GRID. 28 | 29 | % Copyright (c) 1999-2000 by the SOM toolbox programming team. 30 | % http://www.cis.hut.fi/projects/somtoolbox/ 31 | 32 | % Version 2.0beta Johan 090499 33 | 34 | S.type='som_grid'; 35 | S.neigh='hexa'; 36 | S.shape='sheet'; 37 | S.msize=[1 1]; 38 | S.coord=[]; 39 | S.line='-'; 40 | S.linecolor=[.8 .8 .8]; 41 | S.linewidth=0.5; 42 | S.marker='o'; 43 | S.markersize=6; 44 | S.markercolor='k'; 45 | S.surf=[]; 46 | S.label=[]; 47 | S.labelcolor='g'; 48 | S.labelsize=12; 49 | -------------------------------------------------------------------------------- /somtoolbox/som/som_table_print.m: -------------------------------------------------------------------------------- 1 | function T = som_table_print(sTable,fid,fmt) 2 | 3 | %SOM_TABLE_PRINT Print a table to a file / standard output. 4 | % 5 | % som_table_print(sTable,[fid],[fmt]) 6 | % 7 | % som_table_print(sTable) 8 | % som_table_print(sTable,fid,'html') 9 | % 10 | % Input and output arguments ([]'s are optional): 11 | % sTable (struct) a table struct (see SOM_TABLE_STRUCT) 12 | % [fid] (scalar) a file id (from FOPEN, for example) 13 | % (empty) by default standard output (fid=1) is used 14 | % [fmt] (string) 'txt' (default), 'ps', 'pdf' or 'html' 15 | % the output format type 16 | % 17 | % See also SOM_TABLE_STRUCT, SOM_STATS_TABLE, SOM_STATS_REPORT. 18 | 19 | % Contributed to SOM Toolbox 2.0, January 2nd, 2002 by Juha Vesanto 20 | % Copyright (c) by Juha Vesanto 21 | % http://www.cis.hut.fi/projects/somtoolbox/ 22 | 23 | % Version 2.0beta juuso 020102 24 | 25 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 26 | 27 | if nargin<2 || isempty(fid) || isnan(fid), fid = 1; end 28 | if nargin<3 || isempty(fmt) || isnan(fmt), fmt = 'txt'; end 29 | 30 | rowlines = 0; 31 | longtable = 0; 32 | 33 | T = rep_utils({'inserttable',sTable,rowlines,longtable},fmt,fid); 34 | 35 | return; 36 | 37 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 38 | -------------------------------------------------------------------------------- /somtoolbox/som/som_ind2sub.m: -------------------------------------------------------------------------------- 1 | function Subs = som_ind2sub(msize,inds) 2 | 3 | %SOM_IND2SUB Map grid subscripts from linear index. 4 | % 5 | % Subs = som_ind2sub(msize,inds) 6 | % 7 | % sub = som_ind2sub([10 15],44); 8 | % sub = som_ind2sub(sMap,44); 9 | % sub = som_ind2sub(sMap.msize,44); 10 | % Subs = som_ind2sub([10 15],[44 13 91]'); 11 | % 12 | % Input and output arguments: 13 | % msize (struct) map or topology struct 14 | % (vector) size 1 x m, specifies the map grid size 15 | % inds (vector) size n x 1, linear indeces of n map units 16 | % 17 | % Subs (matrix) size n x m, the subscripts 18 | % 19 | % See also SOM_SUB2IND. 20 | 21 | % Contributed to SOM Toolbox vs2, February 2nd, 2000 by Juha Vesanto 22 | % http://www.cis.hut.fi/projects/somtoolbox/ 23 | 24 | % Version 2.0beta juuso 300798 25 | 26 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 27 | 28 | if isstruct(msize), 29 | if strcmp(msize.type,'som_map'), msize = msize.topol.msize; 30 | elseif strcmp(msize.type,'som_topol'), msize = msize.msize; 31 | else error('Invalid first argument.'); end 32 | end 33 | 34 | n = length(msize); 35 | k = [1 cumprod(msize(1:end-1))]; 36 | inds = inds - 1; 37 | for i = n:-1:1, 38 | Subs(:,i) = floor(inds/k(i))+1; 39 | inds = rem(inds,k(i)); 40 | end 41 | 42 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 43 | -------------------------------------------------------------------------------- /somtoolbox/som/som_sub2ind.m: -------------------------------------------------------------------------------- 1 | function inds = som_sub2ind(msize,Subs) 2 | 3 | %SOM_SUB2IND Linear index from map grid subscripts. 4 | % 5 | % ind = som_sub2ind(msize,Subs) 6 | % 7 | % ind = som_sub2ind([10 15],[4 5]); 8 | % ind = som_sub2ind(sMap,[4 5]); 9 | % ind = som_sub2ind(sMap.msize,[4 5]); 10 | % inds = som_sub2ind([10 15],[4 5; 3 2; 1 10]); 11 | % 12 | % Input and output arguments: 13 | % msize (struct) map or topology struct 14 | % (vector) size 1 x m, specifies the map grid size 15 | % Subs (matrix) size n x m, the subscripts of n vectors 16 | % 17 | % inds (vector) size n x 1, corresponding linear indeces 18 | % 19 | % See also SOM_IND2SUB. 20 | 21 | % Contributed to SOM Toolbox vs2, February 2nd, 2000 by Juha Vesanto 22 | % http://www.cis.hut.fi/projects/somtoolbox/ 23 | 24 | % juuso 300798 25 | 26 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 27 | 28 | if isstruct(msize), 29 | if strcmp(msize.type,'som_map'), msize = msize.topol.msize; 30 | elseif strcmp(msize.type,'som_topol'), msize = msize.msize; 31 | else error('Invalid first argument.'); end 32 | end 33 | 34 | % check off-limits 35 | [n d] = size(Subs); 36 | offl = find(Subs < 1 | Subs > msize(ones(n,1),1:d)); 37 | Subs(offl) = NaN; 38 | 39 | % indexes 40 | k = [1 cumprod(msize(1:end-1))]'; 41 | inds = 1 + (Subs-1)*k; 42 | 43 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 44 | -------------------------------------------------------------------------------- /somtoolbox/som/som_cod2ind.m: -------------------------------------------------------------------------------- 1 | function ind = som_cod2ind(msize,cind) 2 | 3 | %SOM_COD2IND Matlab linear index from SOM_PAK style linear indeces. 4 | % 5 | % ind = som_cod2ind(msize,cind) 6 | % 7 | % ind = som_cod2ind([10 15],44); 8 | % ind = som_cod2ind(sMap,44); 9 | % ind = som_cod2ind(sMap.msize,44); 10 | % ind = som_cod2ind([10 15],[44 13 91]'); 11 | % 12 | % Input and output arguments: 13 | % msize (struct) map or topology struct 14 | % (vector) size 1 x m, specifies the map grid size 15 | % cind (vector) size n x 1, SOM_PAK style linear indeces for n map units 16 | % (row first, then column) 17 | % 18 | % ind (vector) size n x 1, Matlab linear indeces 19 | % 20 | % See also SOM_IND2COD. 21 | 22 | % Contributed to SOM Toolbox vs2, January 14th, 2002 by Juha Vesanto 23 | % http://www.cis.hut.fi/projects/somtoolbox/ 24 | 25 | % Version 2.0beta juuso 140102 26 | 27 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 28 | 29 | if isstruct(msize), 30 | if strcmp(msize.type,'som_map'), msize = msize.topol.msize; 31 | elseif strcmp(msize.type,'som_topol'), msize = msize.msize; 32 | else error('Invalid first argument.'); end 33 | end 34 | 35 | if nargin<2, cind = 1:prod(msize); end 36 | 37 | I2C = som_ind2cod(msize,[1:prod(msize)]); 38 | [~,C2I] = sort(I2C); 39 | ind = C2I(cind); 40 | 41 | return; 42 | 43 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 44 | -------------------------------------------------------------------------------- /somtoolbox/som/som_neighbors.m: -------------------------------------------------------------------------------- 1 | function Ne = som_neighbors(sM,neigh) 2 | 3 | % Ne = som_neighbors(sM,neigh) 4 | % 5 | % sM (struct) map or data struct 6 | % (matrix) data matrix, size n x dim 7 | % [neigh] (string) 'kNN' or 'Nk' (which is valid for a SOM only) 8 | % for example '6NN' or 'N1' 9 | % default is '10NN' for a data set and 'N1' for SOM 10 | % 11 | % Ne (matrix) size n x n, a sparse matrix 12 | % indicating the neighbors of each sample by value 1 13 | % (note: the unit itself also has value 0) 14 | 15 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 16 | 17 | if isstruct(sM), 18 | switch sM.type, 19 | case 'som_map', M = sM.codebook; 20 | case 'som_data', M = sM.data; sM = []; 21 | end 22 | else 23 | M = sM; 24 | sM = []; 25 | end 26 | 27 | n = size(M,1); 28 | 29 | if nargin<2, 30 | if isempty(sM), neigh = '10NN'; else neigh = 'N1'; end 31 | end 32 | 33 | if strcmp(neigh(end-1:end),'NN'), 34 | k = str2num(neigh(1:end-2)); 35 | kmus = som_bmus(M,M,1:k+1); 36 | Ne = sparse(n,n); 37 | for i=1:n, Ne(i,kmus(i,:)) = 1; end 38 | else 39 | if ~isstruct(sM), error('Prototypes must be in a map struct.'); end 40 | k = str2num(neigh(2:end)); 41 | N1 = som_unit_neighs(sM); 42 | Ne = sparse(som_neighborhood(N1,k)<=k); 43 | end 44 | Ne([0:n-1]*n+[1:n]) = 0; % remove self from neighbors 45 | 46 | return; -------------------------------------------------------------------------------- /somtoolbox/som/som_fillnans.m: -------------------------------------------------------------------------------- 1 | function sD = som_fillnans(sD,sM,bmus) 2 | 3 | % SOM_FILLNANS Replaces NaNs in the data matrix with values from 4 | % SOM prototypes. 5 | % 6 | % sD = som_fillnans(sD,sM, [bmus]) 7 | % 8 | % sD (struct) data struct 9 | % (matrix) size dlen x dim 10 | % sM (struct) data struct, with .data of size dlen x dim 11 | % (matrix) size dlen x dim, a matrix from which 12 | % the values are taken from directly 13 | % (struct) map struct: replacement values are taken from 14 | % sM.codebook(bmus,:) 15 | % [bmus] (vector) BMU for each data vector (calculated if not specified) 16 | % 17 | % See also SOM_MAKE. 18 | 19 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 20 | 21 | if isstruct(sD), 22 | [dlen dim] = size(sD.data); 23 | nans = find(isnan(sD.data)); 24 | else 25 | [dlen dim] = size(sD); 26 | nans = find(isnan(sD)); 27 | end 28 | 29 | if nargin<3, 30 | bmus = som_bmus(sM,sD); 31 | end 32 | 33 | if isstruct(sM) && strcmp(sM.type,'som_map'), 34 | sM = sM.codebook(bmus,:); 35 | elseif isstruct(sM), 36 | sM = sM.data(bmus,:); 37 | else 38 | sM = sM(bmus,:); 39 | end 40 | me = mean(sM); 41 | 42 | if any(size(sM) ~= [dlen dim]), 43 | error('Invalid input arguments.') 44 | end 45 | 46 | if isstruct(sD), 47 | sD.data(nans) = sM(nans); 48 | else 49 | sD(nans) = sM(nans); 50 | end 51 | 52 | return; 53 | 54 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 55 | 56 | 57 | -------------------------------------------------------------------------------- /somtoolbox/som/som_ind2cod.m: -------------------------------------------------------------------------------- 1 | function cind = som_ind2cod(msize,ind) 2 | 3 | %SOM_IND2COD SOM_PAK style linear indeces from Matlab linear index. 4 | % 5 | % Cind = som_ind2cod(msize,inds) 6 | % 7 | % cind = som_ind2cod([10 15],44); 8 | % cind = som_ind2cod(sMap,44); 9 | % cind = som_ind2cod(sMap.msize,44); 10 | % Cind = som_ind2cod([10 15],[44 13 91]'); 11 | % 12 | % Input and output arguments: 13 | % msize (struct) map or topology struct 14 | % (vector) size 1 x m, specifies the map grid size 15 | % ind (vector) size n x 1, linear indeces of n map units 16 | % 17 | % cind (matrix) size n x 1, SOM_PAK style linear indeces 18 | % (row first, then column) 19 | % 20 | % See also SOM_COD2IND. 21 | 22 | % Contributed to SOM Toolbox vs2, January 14th, 2002 by Juha Vesanto 23 | % http://www.cis.hut.fi/projects/somtoolbox/ 24 | 25 | % Version 2.0beta juuso 140102 26 | 27 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 28 | 29 | if isstruct(msize), 30 | if strcmp(msize.type,'som_map'), msize = msize.topol.msize; 31 | elseif strcmp(msize.type,'som_topol'), msize = msize.msize; 32 | else error('Invalid first argument.'); end 33 | end 34 | 35 | if nargin<2, ind = 1:prod(msize); end 36 | 37 | Co = som_unit_coords(msize,'rect','sheet'); 38 | 39 | switch size(Co,2), 40 | case 1, I2C = [1:prod(msize)]; 41 | case 2, I2C = 1 + Co(:,1) + Co(:,2)*msize(2); 42 | case 3, I2C = 1 + Co(:,1) + Co(:,2)*msize(2) + Co(:,3)*msize(1)*msize(2); % ????? 43 | end 44 | 45 | cind = I2C(ind); 46 | return; 47 | 48 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 49 | -------------------------------------------------------------------------------- /somtoolbox/README: -------------------------------------------------------------------------------- 1 | COPYRIGHT 2 | --------- 3 | 4 | SOM Toolbox 2.0, a software library for Matlab 5 implementing the 5 | Self-Organizing Map algorithm is Copyright (C) 1999 by Esa Alhoniemi, 6 | Johan Himberg, Jukka Parviainen and Juha Vesanto. 7 | 8 | SOM Toolbox 2.1 is a revision to the SOM Toolbox made in 9 | December 2012. 10 | 11 | Note: the files distributed in this package are only a part of the 12 | SOM Toolbox. Please visit https://github.com/ilarinieminen/SOM-Toolbox 13 | for more details. 14 | 15 | This package is free software; you can redistribute it and/or 16 | modify it under the terms of the GNU General Public License 17 | as published by the Free Software Foundation; either version 2 18 | of the License, or any later version. 19 | 20 | 21 | This package is distributed in the hope that it will be useful, 22 | but WITHOUT ANY WARRANTY; without even the implied warranty of 23 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 24 | GNU General Public License for more details. 25 | 26 | You should have received a copy of the GNU General Public License 27 | along with this package (file COPYING); if not, write to the Free 28 | Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 29 | 02111-1307, USA. 30 | 31 | LICENSING THE LIBRARY FOR PROPRIETARY PROGRAMS 32 | ---------------------------------------------- 33 | 34 | As stated in the GNU General Public License (see the license in COPYING) 35 | it is not possible to include this software library in a commercial 36 | proprietary program without written permission from the owners of the 37 | copyright. If you wish to obtain such permission, you can reach us by 38 | paper mail: 39 | 40 | SOM Toolbox team 41 | Aalto University 42 | Department of Information and Computer Science 43 | PO Box 15400 44 | FI-00076 Aalto 45 | Finland 46 | -------------------------------------------------------------------------------- /lib/SOMTrain.m: -------------------------------------------------------------------------------- 1 | % ========================================================================= 2 | % sinc(i) - http://fich.unl.edu.ar/sinc/ 3 | % Copyright 2017 Leandro Bugnon 4 | % lbugnon@sinc.unl.edu.ar 5 | % ========================================================================= 6 | % Methods for training supervised self-organization maps (sSOM). 7 | function model=SOMTrain(trainData,parameters) 8 | 9 | tracking=0; 10 | somTopologyRatio=0.5; 11 | lambda=ones(size(trainData.targets,2),1); 12 | mapInit='lininit'; 13 | training='short'; 14 | for p=1:length(parameters) 15 | switch parameters(p).name 16 | case 'mapsize' 17 | mapsize=parameters(p).val; 18 | case 'somTopologyRatio' 19 | somTopologyRatio=parameters(p).val; 20 | case 'lambda' 21 | lambda=parameters(p).val; 22 | end 23 | end 24 | 25 | % Build train struct ====================================================== 26 | model=struct; 27 | model.dtargets=length(trainData.targetNames); % Dimension of labels 28 | 29 | [trainStruct,ok,msg]=som_set('som_data','data',[trainData.features ... 30 | bsxfun(@times,lambda,double(trainData.targets))],... 31 | 'comp_names',[trainData.featNames,trainData.targetNames],... 32 | 'comp_norm',cell(1,length(trainData.featNames)+model.dtargets)); 33 | 34 | if ~isempty(find(ok==0)) 35 | errorMsg=msg(ok==0); 36 | error(errorMsg{1}) 37 | end 38 | % ========================================================================= 39 | 40 | 41 | % Train SOM =============================================================== 42 | somTopology=[mapsize floor(mapsize*somTopologyRatio)]; 43 | 44 | model.som=som_make(trainStruct,'init',mapInit,'msize',somTopology,... 45 | 'training',training,'tracking',tracking); 46 | % ========================================================================= 47 | 48 | end -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # emoHR: Dimensional Affect Recognition from HRV 2 | 3 | This is a distribution of the source code used in: 4 | 5 | L.A. Bugnon, R.A. Calvo and D.H. Milone, "Dimensional Affect Recognition from HRV: an Approach Based on Supervised SOM and ELM", (to appear in) IEEE Transactions on Affective Computing , 2017. 6 | 7 | This code can be used, modified or distributed for academic purposes under GNU GPL. 8 | 9 | Supervised Self-Organizing Maps (sSOM) and two types of Extreme Learning Machines (kELM and nELM) are provided. For a very quick test, you can try these methods in a web-demo application: http://sinc.unl.edu.ar/web-demo/dimensional-affect-recognition/. The only requirement is a web browser. 10 | 11 | To use this code, please run the ‘main.m’ with Matlab software (R2013 or higher). In this implementation, methods are trained and tested using a reduced feature set extracted from RECOLA dataset. Only Heart Rate Variability (HRV) is used as input to estimate dimensional affect targets: arousal and valence. The outputs of the script are: the correlation concordance coefficient (ccc), the classifiers outputs and the graphical interpretation by sSOM. 12 | 13 | Classifier hyperparameters are in 'config/'. This parameters can be easily modified in the 'parameters' structure. Other features can be used by placing them in the 'features/' folder, just replicate the data structure used in methods. 14 | 15 | The HRV features can be extracted directly from the HR signal provided in the RECOLA dataset. If you want to do so, please download the dataset from https://diuf.unifr.ch/diva/recola/ and set the flag ‘forceFeatureExtraction=true’ in ‘main.m’. From the AVEC_2016, copy the folders 'recordings_physio' and 'ratings_gold_standard' into the 'recola' folder. 16 | 17 | sinc(i) - www.sinc.unl.edu.ar 18 | Leandro Bugnon, Rafael Calvo, Diego Milone 19 | _lbugnon@sinc.unl.edu.ar_ 20 | -------------------------------------------------------------------------------- /somtoolbox/som/hits.m: -------------------------------------------------------------------------------- 1 | function [hits,ninvalid] = hits(bmus, mmax, values) 2 | 3 | %HITS Calculate number of occurances of each value. 4 | % 5 | % hits = hits(bmus,[mmax],[values]) 6 | % 7 | % h = hits(bmus); 8 | % h = hits(bmus,length(sM.codebook)); 9 | % 10 | % Input and output arguments ([]'s are optional): 11 | % bmus (vector) BMU indeces (or other similar) 12 | % [mmax] (scalar) maximum index, default value max(bmus) 13 | % (struct) map or topology struct from where the maximum 14 | % index is acquired 15 | % [values] (vector) values associated with the data (default = 1) 16 | % 17 | % hits (vector) the number of occurances of each index 18 | % (or if values are given, their sum for each index) 19 | % ninvalid (scalar) number of invalid indeces (NaN, Inf or 20 | % <=0 or > mmax) 21 | % 22 | % See also SOM_HITS, SOM_BMUS. 23 | 24 | % Copyright (c) 2002 by the SOM toolbox programming team. 25 | % Contributed to SOM Toolbox by Juha Vesanto, April 24th, 2002 26 | % http://www.cis.hut.fi/projects/somtoolbox/ 27 | 28 | % Version 2.0beta juuso 240402 29 | 30 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 31 | 32 | if nargin<2 || isempty(mmax), 33 | mmax = max(bmus); 34 | elseif isstruct(mmax), 35 | switch mmax.type, 36 | case 'som_map', mmax = prod(mmax.topol.msize); 37 | case 'som_topol', mmax = prod(mmax.msize); 38 | otherwise, 39 | error('Illegal struct for 2nd argument.') 40 | end 41 | end 42 | 43 | if nargin<3, values = 1; end 44 | 45 | valid_bmus = find(isfinite(bmus) & bmus>0 & bmus<=mmax); 46 | ninvalid = length(bmus)-length(valid_bmus); 47 | 48 | bmus = bmus(valid_bmus); 49 | if length(values)>length(bmus), values = values(valid_bmus); end 50 | hits = full(sum(sparse(bmus,1:length(bmus),values,mmax,length(bmus)),2)); 51 | 52 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 53 | 54 | -------------------------------------------------------------------------------- /somtoolbox/som/nanstats.m: -------------------------------------------------------------------------------- 1 | function [me, st, md, no] = nanstats(D) 2 | 3 | %NANSTATS Statistical operations that ignore NaNs and Infs. 4 | % 5 | % [mean, std, median, nans] = nanstats(D) 6 | % 7 | % Input and output arguments: 8 | % D (struct) data or map struct 9 | % (matrix) size dlen x dim 10 | % 11 | % me (double) columnwise mean 12 | % st (double) columnwise standard deviation 13 | % md (double) columnwise median 14 | % no (vector) columnwise number of samples (finite, not-NaN) 15 | 16 | % Contributed to SOM Toolbox vs2, February 2nd, 2000 by Juha Vesanto 17 | % http://www.cis.hut.fi/projects/somtoolbox/ 18 | 19 | % Version 2.0beta juuso 300798 200900 20 | 21 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 22 | %% check arguments 23 | 24 | error(nargchk(1, 1, nargin)); % check no. of input args is correct 25 | 26 | if isstruct(D), 27 | if strcmp(D.type,'som_map'), D = D.codebook; 28 | else D = D.data; 29 | end 30 | end 31 | [~, dim] = size(D); 32 | me = zeros(dim,1)+NaN; 33 | md = me; 34 | st = me; 35 | no = me; 36 | 37 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 38 | %% computation 39 | 40 | for i = 1:dim, 41 | ind = find(isfinite(D(:, i))); % indices of non-NaN/Inf elements 42 | n = length(ind); % no of non-NaN/Inf elements 43 | 44 | me(i) = sum(D(ind, i)); % compute average 45 | if n == 0, me(i) = NaN; else me(i) = me(i) / n; end 46 | 47 | if nargout>1, 48 | md(i) = median(D(ind, i)); % compute median 49 | 50 | if nargout>2, 51 | st(i) = sum((me(i) - D(ind, i)).^2); % compute standard deviation 52 | if n == 0, st(i) = NaN; 53 | elseif n == 1, st(i) = 0; 54 | else st(i) = sqrt(st(i) / (n - 1)); 55 | end 56 | 57 | if nargout>3, 58 | no(i) = n; % number of samples (finite, not-NaN) 59 | end 60 | end 61 | end 62 | end 63 | 64 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 65 | 66 | -------------------------------------------------------------------------------- /somtoolbox/som/vis_footnoteButtonDownFcn.m: -------------------------------------------------------------------------------- 1 | function vis_footnoteButtonDownFcn 2 | 3 | % VIS_FOOTNOTEBUTTONDOWNFCN Callback set by VIS_FOOTNOTE 4 | % 5 | % som_showtitleButtonDownFcn 6 | % 7 | % Moves the axis of current callback object using DRAGRECT 8 | % command. This callback is set to all texts added to figures by 9 | % VIS_FOOTNOTE function. 10 | % 11 | % See also DRAGRECT, SOM_SHOWTITLE. 12 | 13 | % Copyright (c) 1997-2000 by the SOM toolbox programming team. 14 | % http://www.cis.hut.fi/projects/somtoolbox/ 15 | 16 | % Version 2.0beta Johan 080698 17 | 18 | % Action 19 | 20 | [txt,fig]=gcbo; % Get text and figure handles 21 | ax=get(txt,'parent'); % Get axis handle 22 | 23 | memunits_fig=get(fig,'units'); % Get figure size in pixels 24 | set(gcf,'units','pixels'); 25 | pos_fig=get(fig,'position'); 26 | 27 | memunits_txt=get(txt,'units'); % Get text field size in pixels 28 | set(txt,'units','pixels'); 29 | text_size=get(txt,'extent'); 30 | 31 | memunits_ax=get(ax,'units'); % Get axis position in pixels 32 | set(ax,'units','pixels'); 33 | pos_ax=get(ax,'position'); 34 | 35 | %%% Move text 36 | 37 | pos_final=dragrect([pos_ax(1:2) text_size(3:4)]); 38 | 39 | %%% Keep the text inside the figure! 40 | 41 | pos_final(1)=max(pos_final(1),0); 42 | pos_final(2)=max(pos_final(2),0); 43 | pos_final(1)=min(pos_final(1),pos_fig(3)-text_size(3)); 44 | pos_final(2)=min(pos_final(2),pos_fig(4)-text_size(4)); 45 | 46 | %%% Set new position 47 | 48 | new_pos=[pos_final(1:2) pos_ax(3:4)]; 49 | set(ax,'position', new_pos); 50 | 51 | %%% Set the text on the top of the object stack 52 | 53 | children=get(gcf,'children'); 54 | i=find(ismember(children,ax)); 55 | new_i=[i 1:i-1 i+1:length(children)]; 56 | set(gcf,'children',children(new_i)); 57 | 58 | set(txt,'position',[0 0 0]); 59 | set(fig,'units',memunits_fig); 60 | set(ax,'units',memunits_ax); 61 | set(txt,'units',memunits_txt); 62 | 63 | 64 | 65 | -------------------------------------------------------------------------------- /somtoolbox/som/som_dmatclusters.m: -------------------------------------------------------------------------------- 1 | function [base,seed] = som_dmatclusters(sM,linkage,neigh,ignore) 2 | 3 | % SOM_DMATCLUSTERS Cluster map based on neighbor distance matrix. 4 | % 5 | % base = som_dmatclusters(sM,linkage,neigh,ignore) 6 | % 7 | % sM (struct) map or data struct 8 | % (matrix) data matrix, size n x dim 9 | % [linkage] (string) 'closest', 'single', 'average', 'complete', 10 | % 'centroid', 'ward', and 'neighf' (last for SOM only) 11 | % default is 'centroid' 12 | % [neigh] (string) 'kNN' or 'Nk' (which is valid for a SOM only) 13 | % for example '6NN' or 'N1' 14 | % default is '10NN' for a data set and 'N1' for SOM 15 | % (matrix) 0/1 matrix of size size n x n, 1=connection exists 16 | % [ignore] (vector) indeces of vectors to be ignored in the spreading 17 | % phase, empty vector by default 18 | % 19 | % base (vector) size n x 1, cluster indeces (1...c) 20 | % seed (vector) size c x 1, indeces of seed units for the clusters 21 | % 22 | % See also SOM_NEIGHBORS, KMEANS_CLUSTERS, SOM_DMATMINIMA. 23 | 24 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 25 | %% input arguments 26 | 27 | if nargin<2 || isempty(linkage), linkage = 'centroid'; end 28 | 29 | if nargin<3 || isempty(neigh), 30 | if isstruct(sM) && strcmp(sM.type,'som_map'), 31 | neigh = 'N1'; 32 | else 33 | neigh = '10NN'; 34 | end 35 | end 36 | 37 | if nargin<4, ignore = []; end 38 | n = size(sM.codebook,1); 39 | 40 | % neighborhoods 41 | if ischar(neigh), 42 | Ne = som_neighbors(sM,neigh); 43 | else 44 | Ne = neigh; 45 | end 46 | 47 | % find seed points 48 | seed = som_dmatminima(sM,[],Ne); 49 | 50 | % make partition 51 | base = zeros(n,1); 52 | base(seed) = 1:length(seed); 53 | if any(ignore), base(ignore) = NaN; end 54 | base = som_clspread(sM,base,linkage,Ne,0); 55 | 56 | % assign the ignored units, too 57 | base(isnan(base)) = 0; 58 | if any(base==0), base = som_clspread(sM,base,linkage,Ne,0); end 59 | 60 | return; 61 | 62 | -------------------------------------------------------------------------------- /somtoolbox/som/som_label2num.m: -------------------------------------------------------------------------------- 1 | function [nos,names] = som_label2num(L) 2 | 3 | %SOM_LABEL2NUM Recodes textual data labels to interger class labels 4 | % 5 | % [class,names]=class2num(L) 6 | % 7 | % [class,names]=class2num(sData) 8 | % [class,names]=class2num(sMap) 9 | % [class,names]=class2num(sData.labels); 10 | % 11 | % Input and output arguments ([]'s are optional): 12 | % 13 | % L (map struct, data struct, 14 | % Nx1 cell array of strings, 15 | % a Nxn char array) textual labels 16 | % class (vector) Nx1 vector of integers where N is the number of original text labels 17 | % names (cell) kx1 array of strings where names(i) correspons to integer label i 18 | % 19 | % See also KNN 20 | 21 | % Contributed to SOM Toolbox 2.0, October 29th, 2000 by Johan Himberg 22 | % Copyright (c) by Johan Himberg 23 | % http://www.cis.hut.fi/projects/somtoolbox/ 24 | 25 | % Version 2.0beta Johan 291000 26 | 27 | %% Init %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 28 | 29 | if isstruct(L); 30 | if isfield(L,'type') && ischar(L.type), 31 | else 32 | error('Invalid map/data struct?'); 33 | end 34 | switch L.type 35 | case {'som_map', 'som_data'} 36 | class=L.labels(:,1); 37 | otherwise error('Invalid map/data struct?'); 38 | end 39 | elseif vis_valuetype(L,{'cellcolumn_of_char'}), 40 | class=L; 41 | elseif vis_valuetype(L,{'chararray'}), 42 | class=cellstr(L); 43 | else 44 | error('Input must be an Nx1 cell array of strings, a char array, a map struct or a data struct.'); 45 | end 46 | 47 | names = {}; 48 | nos = zeros(length(class),1); 49 | for i=1:length(class), 50 | if ~isempty(class{i}) && ~any(strcmp(class{i},names)), 51 | names=cat(1,names,class(i)); 52 | end 53 | end 54 | 55 | tmp_nos = (1:length(names))'; 56 | for i=1:length(class), 57 | if ~isempty(class{i}), 58 | nos(i,1) = find(strcmp(class{i},names)); 59 | end 60 | end 61 | 62 | if any(nos==0), 63 | nos=nos+1; 64 | names(2:end+1)=names; 65 | names{1}=''; 66 | end 67 | 68 | 69 | 70 | -------------------------------------------------------------------------------- /lib/activationFunction.m: -------------------------------------------------------------------------------- 1 | %%%% Authors: MR HONG-MING ZHOU AND DR GUANG-BIN HUANG 2 | %%%% NANYANG TECHNOLOGICAL UNIVERSITY, SINGAPORE 3 | %%%% EMAIL: EGBHUANG@NTU.EDU.SG; GBHUANG@IEEE.ORG 4 | %%%% WEBSITE: http://www.ntu.edu.sg/eee/icis/cv/egbhuang.htm 5 | %%%% DATE: MARCH 2012 6 | function [H,funcOrderOut]=activationFunction(X,func,funcOrderIn) 7 | 8 | if nargin==2 9 | funcOrderIn=[]; 10 | end 11 | funcOrderOut=[]; 12 | 13 | switch lower(func) 14 | case {'sig','sigmoid'} 15 | %%%%%%%% Sigmoid 16 | H = 1 ./ (1 + exp(-X)); 17 | case {'sin','sine'} 18 | %%%%%%%% Sine 19 | H = sin(X); 20 | case {'hardlim'} 21 | %%%%%%%% Hard Limit 22 | H = hardlim(X); 23 | case {'lin'} 24 | %%%%%%%% Linear 25 | H = X; 26 | case {'tanh'} 27 | H = tanh(X); 28 | case {'radbas'} 29 | %%%%%%%% Radial basis function 30 | H = radbas(tempH); 31 | 32 | case {'rand'} 33 | H=X; 34 | for x=1:length(X) 35 | if isempty(funcOrderIn) % generate functions 36 | func=randi(5,1); 37 | funcOrderOut=[funcOrderOut; func]; 38 | else % use model functions 39 | func=funcOrderIn(x); 40 | end 41 | switch func 42 | case 1 43 | %%%%%%%% Sigmoid 44 | H(x) = 1 ./ (1 + exp(-X(x))); 45 | case 2 46 | %%%%%%%% Sine 47 | H(x) = sin(X(x)); 48 | case 3 49 | %%%%%%%% Hard Limit 50 | H(x) = hardlim(X(x)); 51 | %%%%%%%% More activation functions can be added here 52 | case 4 53 | %%%%%%%% Hard Limit 54 | H(x) = X(x); 55 | case 5 56 | H(x) = tanh(X(x)); 57 | end 58 | end 59 | end 60 | end 61 | 62 | function a=hardlim(n) 63 | a = double(n >= 0); 64 | a(isnan(n)) = nan; 65 | end 66 | -------------------------------------------------------------------------------- /lib/kernel_matrix.m: -------------------------------------------------------------------------------- 1 | %%%% Authors: MR HONG-MING ZHOU AND DR GUANG-BIN HUANG 2 | %%%% NANYANG TECHNOLOGICAL UNIVERSITY, SINGAPORE 3 | %%%% EMAIL: EGBHUANG@NTU.EDU.SG; GBHUANG@IEEE.ORG 4 | %%%% WEBSITE: http://www.ntu.edu.sg/eee/icis/cv/egbhuang.htm 5 | %%%% DATE: MARCH 2012 6 | function omega = kernel_matrix(Xtrain,kernel_type, kernel_pars,Xt) 7 | 8 | nb_data = size(Xtrain,1); 9 | 10 | 11 | if strcmp(kernel_type,'RBF_kernel'), 12 | if nargin<4, 13 | XXh = sum(Xtrain.^2,2)*ones(1,nb_data); 14 | omega = XXh+XXh'-2*(Xtrain*Xtrain'); 15 | omega = exp(-omega./kernel_pars(1)); 16 | else 17 | XXh1 = sum(Xtrain.^2,2)*ones(1,size(Xt,1)); 18 | XXh2 = sum(Xt.^2,2)*ones(1,nb_data); 19 | omega = XXh1+XXh2' - 2*Xtrain*Xt'; 20 | omega = exp(-omega./kernel_pars(1)); 21 | end 22 | 23 | elseif strcmp(kernel_type,'lin_kernel') 24 | if nargin<4, 25 | omega = Xtrain*Xtrain'; 26 | else 27 | omega = Xtrain*Xt'; 28 | end 29 | 30 | elseif strcmp(kernel_type,'poly_kernel') 31 | if nargin<4, 32 | omega = (Xtrain*Xtrain'+kernel_pars(1)).^kernel_pars(2); 33 | else 34 | omega = (Xtrain*Xt'+kernel_pars(1)).^kernel_pars(2); 35 | end 36 | 37 | elseif strcmp(kernel_type,'wav_kernel') 38 | if nargin<4, 39 | XXh = sum(Xtrain.^2,2)*ones(1,nb_data); 40 | omega = XXh+XXh'-2*(Xtrain*Xtrain'); 41 | 42 | XXh1 = sum(Xtrain,2)*ones(1,nb_data); 43 | omega1 = XXh1-XXh1'; 44 | omega = cos(kernel_pars(3)*omega1./kernel_pars(2)).*exp(-omega./kernel_pars(1)); 45 | 46 | else 47 | XXh1 = sum(Xtrain.^2,2)*ones(1,size(Xt,1)); 48 | XXh2 = sum(Xt.^2,2)*ones(1,nb_data); 49 | omega = XXh1+XXh2' - 2*(Xtrain*Xt'); 50 | 51 | XXh11 = sum(Xtrain,2)*ones(1,size(Xt,1)); 52 | XXh22 = sum(Xt,2)*ones(1,nb_data); 53 | omega1 = XXh11-XXh22'; 54 | 55 | omega = cos(kernel_pars(3)*omega1./kernel_pars(2)).*exp(-omega./kernel_pars(1)); 56 | end 57 | end 58 | end 59 | -------------------------------------------------------------------------------- /somtoolbox/som/vis_PlaneAxisProperties.m: -------------------------------------------------------------------------------- 1 | function vis_PlaneAxisProperties(ax,lattice,msize,pos) 2 | 3 | % VIS_PLANEAXISPROPERTIES Set axis properties for SOM_CPLANE, 4 | % SOM_PIEPLANE, SOM_BARPLANE and SOM_PLOTPLANE. 5 | % 6 | % vis_PlaneAxisProperties(ax,lattice,msize,pos) 7 | % 8 | % Input arguments: 9 | % ax (scalar) axis handle 10 | % lattice (string) 'hexa', 'rect', 'hexaU' or 'rectU' 11 | % (matrix) defines the patch, see e.g. help vis_patch 12 | % msize (vector) a 1x2 vector defining the grid size 13 | % pos (vector) a 1x2 vector that determines position of 14 | % origin or NaN which means default operation: 15 | % origin to [1 1] and tighten axis limits 16 | % according to the grid size. 17 | % 18 | % This is a subfunction for SOM_CPLANE, SOM_PIEPLANE, SOM_BARPLANE and 19 | % SOM_PLOTPLANE. This subfunction sets the proper values for axis. 20 | 21 | % Copyright (c) 1999-2000 by the SOM toolbox programming team. 22 | % http://www.cis.hut.fi/projects/somtoolbox/ 23 | 24 | % Version 2.0beta Johan 060799 25 | 26 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 27 | 28 | xdim=msize(1);ydim=msize(2); 29 | set(ax,'Visible','off'); 30 | set(get(ax,'Title'),'Visible','on'); 31 | set(ax,'XaxisLocation','Top'); % axis orientation 32 | set(ax,'xdir','normal'); % = axis ij = matrix mode 33 | set(ax,'ydir','reverse'); 34 | 35 | switch lattice 36 | case {'rect', 'rectU'} 37 | lelim=-.51; rilim=.51; uplim=-.51; lolim=.51; % axis limits 38 | set(ax,'DataAspectRatio', [1 1 1]); % =axis equal 39 | case {'hexa','hexaU'} 40 | lelim=-.51; rilim=1.01; uplim=-.67; lolim=.67; % axis limits 41 | set(ax,'DataAspectRatio',[0.9015 1 1]); % this corrects hexagons 42 | end 43 | 44 | % Nan: default origin [1 1] & tighten the axis 45 | if isnan(pos) 46 | set(ax,'XLim',[1+lelim ydim+rilim],'YLim',[1+uplim xdim+lolim], ... 47 | 'XLimMode','manual','YLimMode','manual'); % tighten the axis 48 | end 49 | 50 | -------------------------------------------------------------------------------- /somtoolbox/som/som_dmat.m: -------------------------------------------------------------------------------- 1 | function dmat = som_dmat(sM,Ne,mode) 2 | 3 | %SOM_DMAT Find distance to neighbors for each map unit. 4 | % 5 | % dmat = som_dmat(sM,[Ne],[mode]) 6 | % 7 | % Input and output arguments ([]'s are optional): 8 | % sM (struct) map or data struct 9 | % (matrix) data matrix, size n x dim 10 | % [Ne] (matrix) neighborhood connections matrix 11 | % (string) 'Nk' (on map) or 'kNN' (any vector set) 12 | % where k = some number, e.g. 'N1' or '10NN' 13 | % (empty) use default 14 | % [mode] (string) 'min', 'median', 'mean', 'max', or 15 | % some arbitrary scalar function of 16 | % a set of vectors 17 | % 18 | % dmat (vector) size n x 1, distance associated with each vector 19 | % 20 | % See also KMEANS_CLUSTERS, SOM_CLLINKAGE, SOM_CLSTRUCT. 21 | 22 | % Copyright (c) 2000 by Juha Vesanto 23 | % Contributed to SOM Toolbox on June 16th, 2000 by Juha Vesanto 24 | % http://www.cis.hut.fi/projects/somtoolbox/ 25 | 26 | % Version 2.0beta juuso 220800 27 | 28 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 29 | 30 | % map 31 | if isstruct(sM), 32 | switch sM.type, 33 | case 'som_map', M = sM.codebook; mask = sM.mask; 34 | case 'som_data', M = sM.data; mask = ones(size(M,2),1); 35 | end 36 | else 37 | M = sM; mask = ones(size(M,2),1); 38 | end 39 | [n dim] = size(M); 40 | 41 | % neighborhoods 42 | if nargin<2 || isempty(Ne), Ne = som_neighbors(sM); 43 | elseif ischar(Ne), Ne = som_neighbors(sM,Ne); 44 | end 45 | l = size(Ne,1); Ne([0:l-1]*l+[1:l]) = 0; % set diagonal elements = 0 46 | 47 | % mode 48 | if nargin<3 || isempty(mode), mode = 'median'; end 49 | calc = sprintf('%s(x)',mode); 50 | 51 | % distances 52 | dmat = zeros(n,1); 53 | for i=1:n, 54 | ne = find(Ne(i,:)); 55 | if any(ne), 56 | [dummy,x] = som_bmus(M(ne,:),M(i,:),[1:length(ne)],mask); 57 | dmat(i) = eval(calc); 58 | else 59 | dmat(i) = NaN; 60 | end 61 | end 62 | 63 | return; 64 | 65 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 66 | 67 | 68 | 69 | -------------------------------------------------------------------------------- /somtoolbox/som/som_gapindex.m: -------------------------------------------------------------------------------- 1 | function [t,r,Cd,S] = som_gapindex(sM, base, between) 2 | 3 | % SOM_GAPINDEX Gap clustering evaluation index. 4 | % 5 | % [t,r] = som_gapindex(sM, base, [between]) 6 | % 7 | % Input and output arguments ([]'s are optional): 8 | % sM (struct) map struct 9 | % base (vector) clusters indeces for each map unit, map units 10 | % with index<=0 or NaN are not taken into account 11 | % [between] (vector) indices of prototypes which are "between" clusters: 12 | % the associated distances are doubled 13 | % 14 | % t (scalar) Gap index index for the clustering (=mean(r)) 15 | % r (vector) maximum Gap index for each cluster (size max(base) x 1) 16 | % 17 | % See also KMEANS, KMEANS_CLUSTERS, SOM_GAPINDEX. 18 | 19 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 20 | 21 | if nargin<3, between = find(isnan(base)); end 22 | 23 | nc = max(base); 24 | cinds = cell(nc,1); 25 | for i=1:nc, cinds{i} = find(base==i); end 26 | 27 | % distances between neighboring prototypes 28 | Ne = som_neighbors(sM,'N1'); 29 | Md = som_mdist(sM.codebook,2,[],Ne); 30 | Md(Ne==0) = NaN; 31 | 32 | Md(between,:) = Md(between,:)*2; 33 | Md(:,between) = Md(:,between)*2; 34 | Md(between,between) = Md(between,between)/2; 35 | 36 | % dispersion in each cluster 37 | S = zeros(nc,1); 38 | for i=1:nc, 39 | inds = setdiff(cinds{i},between); 40 | if any(inds), 41 | indist = Md(inds,inds); 42 | for j=1:size(indist,1), indist(j,j) = NaN; end 43 | indist = indist(isfinite(indist(:))); 44 | if any(indist), S(i) = mean(indist); end 45 | end 46 | end 47 | 48 | % distances between clusters 49 | Cd = zeros(nc,nc) + NaN; 50 | for i=1:nc, 51 | inds1 = cinds{i}; 52 | for j=1:nc, 53 | inds2 = cinds{j}; 54 | od = Md(inds1,inds2); 55 | od = od(isfinite(od(:))); 56 | if any(od), Cd(i,j) = mean(od(:)); end 57 | end 58 | end 59 | 60 | % Gap index 61 | R = NaN * zeros(nc); 62 | for i = 1:nc 63 | for j = i+1:nc 64 | R(i,j) = (S(i) + S(j))/Cd(i,j); 65 | R(j,i) = R(i,j); 66 | end 67 | end 68 | r = max(R,[],2); 69 | 70 | t = mean(r(isfinite(r))); 71 | 72 | return; 73 | -------------------------------------------------------------------------------- /lib/cccPerformance.m: -------------------------------------------------------------------------------- 1 | % ========================================================================= 2 | % sinc(i) - http://fich.unl.edu.ar/sinc/ 3 | % Copyright 2017 Leandro Bugnon 4 | % lbugnon@sinc.unl.edu.ar 5 | % ========================================================================= 6 | % Lin's concordance correlation coeficient. Outputs is a cell of sessions 7 | % targets. testData contains target reference. 8 | function [stats reftargets]=cccPerformance(output,testData,varargin) 9 | original=false; 10 | % aditional parameters 11 | for v=1:2:length(varargin) 12 | switch varargin{v} 13 | case 'original' 14 | original=varargin{v+1}; 15 | end 16 | end 17 | 18 | if isempty(testData.targets) 19 | stats=NaN; 20 | reftargets=[]; 21 | return 22 | end 23 | Ns=size(testData.sessionLabels,1); 24 | stats=zeros(1,size(output{1},2)); 25 | reftargets=cell(Ns,1); 26 | 27 | % For each target dimension, get concordance score 28 | for l=1:length(stats) 29 | 30 | res=[]; 31 | for s=1:Ns 32 | if original 33 | expectedOutput=testData.original.targets(testData.original.sessionLabels{s,2}:... 34 | testData.original.sessionLabels{s,3},l); 35 | else 36 | expectedOutput=testData.targets(testData.sessionLabels{s,2}:... 37 | testData.sessionLabels{s,3},l); 38 | end 39 | res=[res linConcordance(output{s}(:,l),expectedOutput)]; 40 | end 41 | stats(l)=mean(res); 42 | end 43 | 44 | for s=1:Ns 45 | if original 46 | reftargets{s}=testData.original.targets(testData.original.sessionLabels{s,2}:... 47 | testData.original.sessionLabels{s,3},:); 48 | else 49 | reftargets{s}=testData.targets(testData.sessionLabels{s,2}:testData.sessionLabels{s,3},:); 50 | end 51 | end 52 | end 53 | % ========================================================================= 54 | function [concord pearson]=linConcordance(x,y) 55 | 56 | concord=zeros(size(y,2),1); 57 | pearson=concord; 58 | 59 | for k=1:length(concord) 60 | stdx=std(x); 61 | stdy=std(y(:,k)); 62 | mux=mean(x); 63 | muy=mean(y(:,k)); 64 | N=length(x); 65 | 66 | pearson(k)=(x-mux)'*(y-muy)/N/stdx/stdy; 67 | concord(k)=2*(x-mux)'*(y-muy)/N/(stdx^2+stdy^2+(mux-muy)^2); 68 | end 69 | 70 | end 71 | -------------------------------------------------------------------------------- /somtoolbox/som/som_dmatminima.m: -------------------------------------------------------------------------------- 1 | function minima = som_dmatminima(sM,U,Ne) 2 | 3 | %SOM_DMATMINIMA Find clusters based on local minima of U-matrix. 4 | % 5 | % minima = som_dmatminima(sM,[U],[Ne]) 6 | % 7 | % Input and output arguments ([]'s are optional): 8 | % sM (struct) map struct 9 | % U (matrix) the distance matrix from which minima is 10 | % searched from 11 | % size msize(1) x ... x msize(end) or 12 | % 2*msize(1)-1 x 2*msize(2)-1 or 13 | % munits x 1 14 | % Ne (matrix) neighborhood connections matrix 15 | % 16 | % minima (vector) indeces of the map units where locla minima of 17 | % of U-matrix (or other distance matrix occured) 18 | % 19 | % See also KMEANS_CLUSTERS, SOM_CLLINKAGE, SOM_CLSTRUCT. 20 | 21 | % Copyright (c) 2000 by Juha Vesanto 22 | % Contributed to SOM Toolbox on June 16th, 2000 by Juha Vesanto 23 | % http://www.cis.hut.fi/projects/somtoolbox/ 24 | 25 | % Version 2.0beta juuso 220800 26 | 27 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 28 | 29 | % map 30 | if isstruct(sM), 31 | switch sM.type, 32 | case 'som_map', M = sM.codebook; mask = sM.mask; 33 | case 'som_data', M = sM.data; mask = ones(size(M,2),1); 34 | end 35 | else 36 | M = sM; mask = ones(size(M,2),1); 37 | end 38 | [munits dim] = size(M); 39 | 40 | % distances between map units 41 | if nargin<2, U = []; end 42 | 43 | % neighborhoods 44 | if nargin<3, Ne = som_neighbors(sM); end 45 | 46 | % distance matrix 47 | if nargin<2 || isempty(U), U = som_dmat(sM,Ne,'median'); end 48 | if numel(U)>munits, U = U(1:2:size(U,1),1:2:size(U,2)); end 49 | U = U(:); 50 | if length(U) ~= munits, error('Distance matrix has incorrect size.'); end 51 | 52 | % find local minima 53 | minima = []; 54 | for i=1:munits, 55 | ne = find(Ne(i,:)); 56 | if all(U(i)<=U(ne)) && ~anycommon(ne,minima), minima(end+1)=i; end 57 | end 58 | 59 | return; 60 | 61 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 62 | 63 | function t = anycommon(i1,i2) 64 | if isempty(i1) || isempty(i2), t = 0; 65 | else 66 | m = max(max(i1),max(i2)); 67 | t = any(sparse(i1,1,1,m,1) & sparse(i2,1,1,m,1)); 68 | end 69 | return; 70 | 71 | -------------------------------------------------------------------------------- /somtoolbox/som/som_projections.m: -------------------------------------------------------------------------------- 1 | function [cPCAarg, Pdata, Pproto] = som_projections(D,sM,bmus) 2 | 3 | % SOM_PROJECTIONS Makes different kinds of projections for the data and the prototypes. 4 | % 5 | % [cPCAarg, Pdata, Pproto] = som_projections(D,sM,[bmus]) 6 | % 7 | % sD (struct) data struct 8 | % (matrix) size dlen x dim 9 | % sM (struct) map struct 10 | % (matrix) size munits x dim: prototype vectors 11 | % [bmus] (vector) BMU for each data vector (calculated if not specified) 12 | % 13 | % cPCAarg (cell array) PCA arguments: {V, me, l} from pcaproj function 14 | % Pdata (matrix) size dlen x 7, consisting of 3 projection coordinates from PCA, 15 | % 1 residual from the rest of the PCA-projection coordinates, 16 | % and 3 color components 17 | % Pproto (matrix) size dlen x 7, consisting of 3 projection coordinates from PCA, 18 | % 1 residual from the rest of the PCA-projection coordinates, 19 | % 3 color components, and 3 projection coordinates from CCA 20 | % 21 | % See also PCAPROJ, CCA, SAMMON, SOM_PROJECTIONS_PLOT, SOM_COLORING, SOM_COLORCODE, 22 | % SOM_CLUSTERCOLOR, SOM_KMEANCOLOR. 23 | 24 | if isstruct(D), 25 | cn = D.comp_names; 26 | D = D.data; 27 | end 28 | [dlen dim] = size(D); 29 | if nargin<3, bmus = som_bmus(sM,D); end 30 | 31 | % projection of data 32 | 33 | [P0,V,me,l] = pcaproj(D,dim); 34 | D1 = som_fillnans(D,sM); 35 | P1 = pcaproj(D1,V,me); 36 | Res4 = zeros(dlen,1); 37 | if dim<=3, 38 | Res4 = zeros(dlen,1); 39 | else 40 | Res4 = sqrt(sum(P1(:,4:end).*P1(:,4:end),2)); 41 | end 42 | P1 = P1(:,1:min(3,dim)); 43 | if dim<3, P1 = [P1, zeros(dlen,3-dim)]; end 44 | 45 | % projection of codebook vectors 46 | 47 | P1_m = pcaproj(sM,V,me); 48 | Res4_m = zeros(dlen,1); 49 | if dim<=3, 50 | Res4_m = zeros(dlen,1); 51 | else 52 | Res4_m = sum(P1_m(:,4:end).*P1_m(:,4:end),2); 53 | end 54 | P1_m = P1_m(:,1:min(3,dim)); 55 | if dim<3, P1_m = [P1_m, zeros(size(P1_m,1),3-dim)]; end 56 | 57 | P2_m = cca(sM,P1_m,20); 58 | 59 | PCol_m = som_coloring(sM); 60 | 61 | PCol = PCol_m(bmus,:); 62 | 63 | % output 64 | 65 | cPCAarg = {V,me,l}; 66 | Pdata = [P1, Res4, PCol]; 67 | Pproto = [P1_m, Res4_m, PCol_m, P2_m]; 68 | 69 | return; 70 | -------------------------------------------------------------------------------- /somtoolbox/som/som_drsignif.m: -------------------------------------------------------------------------------- 1 | function sig = som_drsignif(sigmea,Cm) 2 | 3 | % SOM_DRSIGNIF Significance measure from confusion matrix between two clusters and a rule. 4 | % 5 | % sig = som_drsignif(sigmea,Cm) 6 | % 7 | % sigmea (string) significance measure: 'accuracy', 8 | % 'mutuconf' (default), or 'accuracyI'. 9 | % (See definitions below). 10 | % Cn Vectorized confusion matrix, or a matrix of such vectors. 11 | % (vector) [a, c, b, d] (see below) 12 | % (matrix) [[a1,c1,b1,d1], ..., [an,cn,bn,dn]] 13 | % 14 | % sig (vector) length=n, significance values 15 | % 16 | % The confusion matrix Cm below between group (G) and contrast group (not G) 17 | % and rule (true - false) is used to determine the significance values: 18 | % 19 | % G not G 20 | % --------------- accuracy = (a+d) / (a+b+c+d) 21 | % true | a | b | 22 | % |-------------- mutuconf = a*a / ((a+b)(a+c)) 23 | % false | c | d | 24 | % --------------- accuracyI = a / (a+b+c) 25 | % 26 | % See also SOM_DREVAL, SOM_DRMAKE. 27 | 28 | % Contributed to SOM Toolbox 2.0, March 4th, 2002 by Juha Vesanto 29 | % Copyright (c) by Juha Vesanto 30 | % http://www.cis.hut.fi/projects/somtoolbox/ 31 | 32 | % Version 2.0beta juuso 040302 33 | 34 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 35 | %% input arguments 36 | 37 | true_x = Cm(:,1); % x = in group 38 | false_x = Cm(:,2); % false = rule is false 39 | true_y = Cm(:,3); % true = rule is true 40 | false_y = Cm(:,4); % y = not in group 41 | 42 | true_items = true_x + true_y; 43 | x_items = true_x + false_x; 44 | all_items = true_x + false_x + true_y + false_y; 45 | true_or_x = x_items + true_items - true_x; 46 | 47 | switch sigmea, 48 | case 'mutuconf', 49 | % mutual confidence, or relevance (as defined in WSOM2001 paper) 50 | sig = zeros(size(true_x)); 51 | i = find(true_items>0 & x_items>0); 52 | sig(i) = (true_x(i).^2) ./ (true_items(i).*x_items(i)); 53 | case 'accuracy', 54 | % accuracy 55 | sig = (true_x + false_y) ./ all_items; 56 | case 'accuracyI', 57 | % accuracy such that false_y is left out of consideration 58 | sig = true_x./true_or_x; 59 | otherwise, 60 | error(['Unrecognized significance measures: ' sigmea]); 61 | end 62 | 63 | return; 64 | -------------------------------------------------------------------------------- /somtoolbox/som/pcaproj.m: -------------------------------------------------------------------------------- 1 | function [P,V,me,l] = pcaproj(D,arg1,arg2) 2 | 3 | %PCAPROJ Projects data vectors using Principal Component Analysis. 4 | % 5 | % [P,V,me,l] = pcaproj(D, odim) 6 | % P = pcaproj(D, V, me) 7 | % 8 | % Input and output arguments ([]'s are optional) 9 | % D (matrix) size dlen x dim, the data matrix 10 | % (struct) data or map struct 11 | % odim (scalar) how many principal vectors are used 12 | % 13 | % P (matrix) size dlen x odim, the projections 14 | % V (matrix) size dim x odim, principal eigenvectors (unit length) 15 | % me (vector) size 1 x dim, center point of D 16 | % l (vector) size 1 x odim, the corresponding eigenvalues, 17 | % relative to total sum of eigenvalues 18 | % 19 | % See also SAMMON, CCA. 20 | 21 | % Contributed to SOM Toolbox 2.0, February 2nd, 2000 by Juha Vesanto 22 | % Copyright (c) by Juha Vesanto 23 | % http://www.cis.hut.fi/projects/somtoolbox/ 24 | 25 | % juuso 191297 070200 26 | 27 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 28 | 29 | error(nargchk(2, 3, nargin)); % check the number of input arguments 30 | 31 | % the data 32 | if isstruct(D), 33 | if strcmp(D.type,'som_map'), D=D.codebook; else D=D.data; end 34 | end 35 | [dlen dim] = size(D); 36 | 37 | if nargin==2, 38 | 39 | odim = arg1; 40 | 41 | % autocorrelation matrix 42 | A = zeros(dim); 43 | me = zeros(1,dim); 44 | for i=1:dim, 45 | me(i) = mean(D(isfinite(D(:,i)),i)); 46 | D(:,i) = D(:,i) - me(i); 47 | end 48 | for i=1:dim, 49 | for j=i:dim, 50 | c = D(:,i).*D(:,j); c = c(isfinite(c)); 51 | A(i,j) = sum(c)/length(c); A(j,i) = A(i,j); 52 | end 53 | end 54 | 55 | % eigenvectors, sort them according to eigenvalues, and normalize 56 | [V,S] = eig(A); 57 | eigval = diag(S); 58 | [~,ind] = sort(abs(eigval)); 59 | eigval = eigval(flipud(ind)); 60 | V = V(:,flipud(ind)); 61 | for i=1:odim, V(:,i) = (V(:,i) / norm(V(:,i))); end 62 | 63 | % take only odim first eigenvectors 64 | V = V(:,1:odim); 65 | l = abs(eigval)/sum(abs(eigval)); 66 | l = l(1:odim); 67 | 68 | else % nargin==3, 69 | 70 | V = arg1; 71 | me = arg2; 72 | odim = size(V,2); 73 | D = D-me(ones(dlen,1),:); 74 | 75 | end 76 | 77 | % project the data using odim first eigenvectors 78 | P = D*V; 79 | 80 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 81 | -------------------------------------------------------------------------------- /somtoolbox/som/som_estimate_gmm.m: -------------------------------------------------------------------------------- 1 | function [K,P] = som_estimate_gmm(sM, sD) 2 | 3 | %SOM_ESTIMATE_GMM Estimate a gaussian mixture model based on map. 4 | % 5 | % [K,P] = som_estimate_gmm(sM, sD) 6 | % 7 | % Input and output arguments: 8 | % sM (struct) map struct 9 | % sD (struct) data struct 10 | % (matrix) size dlen x dim, the data to use when estimating 11 | % the gaussian kernels 12 | % 13 | % K (matrix) size munits x dim, kernel width parametes for 14 | % each map unit 15 | % P (vector) size 1 x munits, a priori probability of each map unit 16 | % 17 | % See also SOM_PROBABILITY_GMM. 18 | 19 | % Reference: Alhoniemi, E., Himberg, J., Vesanto, J., 20 | % "Probabilistic measures for responses of Self-Organizing Maps", 21 | % Proceedings of Computational Intelligence Methods and 22 | % Applications (CIMA), 1999, Rochester, N.Y., USA, pp. 286-289. 23 | 24 | % Contributed to SOM Toolbox vs2, February 2nd, 2000 by Esa Alhoniemi 25 | % Copyright (c) by Esa Alhoniemi 26 | % http://www.cis.hut.fi/projects/somtoolbox/ 27 | 28 | % ecco 180298 juuso 050100 250400 29 | 30 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 31 | 32 | [c, dim] = size(sM.codebook); 33 | M = sM.codebook; 34 | 35 | if isstruct(sD), D = sD.data; else D = sD; end 36 | dlen = length(D(:,1)); 37 | 38 | %%%%%%%%%%%%%%%%%%%%% 39 | % compute hits & bmus 40 | 41 | [bmus, qerrs] = som_bmus(sM, D); 42 | hits = zeros(1,c); 43 | for i = 1:c, hits(i) = sum(bmus == i); end 44 | 45 | %%%%%%%%%%%%%%%%%%%% 46 | % a priori 47 | 48 | % neighborhood kernel 49 | r = sM.trainhist(end).radius_fin; % neighborhood radius 50 | if isempty(r) || isnan(r), r=1; end 51 | Ud = som_unit_dists(sM); 52 | Ud = Ud.^2; 53 | r = r^2; 54 | if r==0, r=eps; end % to get rid of div-by-zero errors 55 | switch sM.neigh, 56 | case 'bubble', H = (Ud<=r); 57 | case 'gaussian', H = exp(-Ud/(2*r)); 58 | case 'cutgauss', H = exp(-Ud/(2*r)) .* (Ud<=r); 59 | case 'ep', H = (1-Ud/r) .* (Ud<=r); 60 | end 61 | 62 | % a priori prob. = hit histogram weighted by the neighborhood kernel 63 | P = hits*H; 64 | P = P/sum(P); 65 | 66 | %%%%%%%%%%%%%%%%%%%% 67 | % kernel widths (& centers) 68 | 69 | K = ones(c, dim) * NaN; % kernel widths 70 | for m = 1:c, 71 | w = H(bmus,m); 72 | w = w/sum(w); 73 | for i = 1:dim, 74 | d = (D(:,i) - M(m,i)).^2; % compute variance of ith 75 | K(m,i) = w'*d; % variable of centroid m 76 | end 77 | end 78 | 79 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 80 | -------------------------------------------------------------------------------- /somtoolbox/som/som_mdist.m: -------------------------------------------------------------------------------- 1 | function Md = som_mdist(D,q,mask,Ne) 2 | 3 | % SOM_MDIST Mutual (or pairwise) distance matrix for the given data. 4 | % 5 | % Md = som_mdist(D,[q],[mask],[Ne]) 6 | % 7 | % Md = som_mdist(D); 8 | % Md = som_mdist(D,Inf); 9 | % Md = som_mdist(D,2,Ne); 10 | % 11 | % Input and output arguments ([]'s are optional): 12 | % D (matrix) size dlen x dim, the data set 13 | % (struct) map or data struct 14 | % [q] (scalar) distance norm, default = 2 15 | % [mask] (vector) size dim x 1, the weighting mask 16 | % [Ne] (matrix) size dlen x dlen, sparse matrix 17 | % indicating which distances should be 18 | % calculated (ie. less than Infinite) 19 | % 20 | % See also PDIST. 21 | 22 | % Copyright (c) 2000 by Juha Vesanto 23 | % Contributed to SOM Toolbox on XXX by Juha Vesanto 24 | % http://www.cis.hut.fi/projects/somtoolbox/ 25 | 26 | % Version 2.0beta juuso 220800 27 | 28 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 29 | 30 | % mask 31 | if nargin<3, mask = []; end 32 | 33 | % the data 34 | if isstruct(D), 35 | switch D.type, 36 | case 'som_map', if isempty(mask), mask = D.mask; end, D = D.codebook; 37 | case 'som_data', D = D.data; 38 | otherwise, error('Bad first argument'); 39 | end 40 | end 41 | nans = sum(isnan(D),2); 42 | if any(nans>0), 43 | D(find(nans>0),:) = 0; 44 | warning('Distances of vectors with NaNs are not calculated.'); 45 | end 46 | [dlen dim] = size(D); 47 | 48 | % distance norm 49 | if nargin<2 || isempty(q) || isnan(q), q = 2; end 50 | 51 | % mask 52 | if isempty(mask), mask = ones(dim,1); end 53 | 54 | % connections 55 | if nargin<4, Ne = []; end 56 | if ~isempty(Ne), 57 | l = size(Ne,1); Ne([0:l-1]*l+[1:l]) = 1; % set diagonal elements = 1 58 | end 59 | 60 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 61 | 62 | m = mask; 63 | o = ones(dlen,1); 64 | l = dlen; 65 | Md = zeros(dlen); 66 | calculate_all = isempty(Ne); 67 | 68 | if ~calculate_all, Md(Ne==0) = Inf; end 69 | 70 | for i=1:l-1, 71 | j=(i+1):l; 72 | if ~calculate_all, j=find(Ne(i,j))+i; end 73 | C=D(j,:)-D(i*o(1:length(j)),:); 74 | switch q, 75 | case 1, Md(j,i)=abs(C)*m; 76 | case 2, Md(j,i)=sqrt((C.^2)*m); 77 | case Inf, Md(j,i)=max(diag(m)*abs(C),[],2); 78 | otherwise, Md(j,i)=((abs(C).^q)*m).^(1/q); 79 | end 80 | Md(i,j) = Md(j,i)'; 81 | end 82 | 83 | Md(find(nans>0),:) = NaN; 84 | Md(:,find(nans>0)) = NaN; 85 | 86 | return; 87 | 88 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 89 | 90 | -------------------------------------------------------------------------------- /somtoolbox/som/som_bmucolor.m: -------------------------------------------------------------------------------- 1 | function bmu_colors=som_bmucolor(bmus, m, colors) 2 | 3 | % SOM_BMUCOLOR Returns the colors of the bmus according to a map colorcode 4 | % 5 | % bmu_colors=som_bmucolor(bmus, msize, colors); 6 | % 7 | % INPUT ARGUMENTS ([]'s are optional) 8 | % 9 | % bmus (matrix) Nx1 vector of BMU indexes 10 | % msize (map struct, topol struct or 1x2 vector) 11 | % gives the map grid size 12 | % colors (matrix) colormap(s): munits x 3 x d matrix of RGB vectors 13 | % 14 | % OUTPUT ARGUMENTS 15 | % 16 | % bmu_colors (Nx3xd matrix) color of the data point according to its BMU's 17 | % color(s). 18 | % 19 | % Idea is to get a color for each data point that links it to its BMU. 20 | % 21 | % EXAMPLE 22 | % 23 | % We want to show how an time series is projected to a map. Instead of 24 | % a trajectory, we use 'color linking' 25 | % 26 | % map=som_make(multi_dim_signal); 27 | % bmus=som_bmu(map,multi_dim_signal); 28 | % Colors=som_bmucolor(bmus, map, som_colorcode(map,'rgb1')); 29 | % colorsignal(Colors, multi_dim_signal); 30 | % 31 | % See also SOM_COLORCODE. 32 | 33 | % Copyright (c) 1999-2000 by the SOM toolbox programming team. 34 | % http://www.cis.hut.fi/projects/somtoolbox/ 35 | 36 | % Version 2.0alpha Johan 170699 37 | 38 | %% Check arguments %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 39 | 40 | error(nargchk(3, 3, nargin)) % check no. of input args is correct 41 | 42 | % Check map grid size 43 | 44 | if vis_valuetype(m,{'1x2'}), 45 | msize=m; 46 | else 47 | [tmp,ok,tmp]=som_set(m); 48 | if isstruct(m) && all(ok) % check m type 49 | switch m.type 50 | case 'som_topol' 51 | msize=m.msize; 52 | lattice=m.lattice; 53 | case 'som_map' 54 | msize=m.topol.msize; 55 | lattice=m.topol.lattice; 56 | otherwise 57 | error('Invalid map or topol struct.'); 58 | end 59 | end 60 | end 61 | 62 | if length(msize)>2 63 | error('Only 2D maps allowed!'); 64 | end 65 | 66 | n=prod(msize) 67 | 68 | % Check colorcode size 69 | 70 | if ~vis_valuetype(colors,{'nx3xdimrgb','nx3rgb'}) 71 | error('Colorcode matrix not valid!'); 72 | end 73 | 74 | % Check bmu vector 75 | 76 | if ~vis_valuetype(bmus,{'nx1'}), 77 | error('Need a column vector of BMU indexes!'); 78 | else 79 | bmus=round(bmus); 80 | if max(bmus) > n || min(bmus) < 1 81 | error('BMU indexes exeed the map size!') 82 | end 83 | end 84 | 85 | %% Action %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 86 | 87 | bmu_c=colors(bmus,:,:); 88 | 89 | %% Build output %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 90 | 91 | 92 | bmu_colors=squeeze(bmu_c); 93 | 94 | -------------------------------------------------------------------------------- /somtoolbox/som/som_eucdist2.m: -------------------------------------------------------------------------------- 1 | function d=som_eucdist2(Data, Proto) 2 | 3 | %SOM_EUCDIST2 Calculates matrix of squared euclidean distances between set of vectors or map, data struct 4 | % 5 | % d=som_eucdist2(D, P) 6 | % 7 | % d=som_eucdist(sMap, sData); 8 | % d=som_eucdist(sData, sMap); 9 | % d=som_eucdist(sMap1, sMap2); 10 | % d=som_eucdist(datamatrix1, datamatrix2); 11 | % 12 | % Input and output arguments ([]'s are optional): 13 | % D (matrix) size Nxd 14 | % (struct) map or data struct 15 | % P (matrix) size Pxd 16 | % (struct) map or data struct 17 | % d (matrix) distance matrix of size NxP 18 | % 19 | % IMPORTANT 20 | % 21 | % * Calculates _squared_ euclidean distances 22 | % * Observe that the mask in the map struct is not taken into account while 23 | % calculating the euclidean distance 24 | % 25 | % See also KNN, PDIST. 26 | 27 | % Contributed to SOM Toolbox 2.0, October 29th, 2000 by Johan Himberg 28 | % Copyright (c) by Johan Himberg 29 | % http://www.cis.hut.fi/projects/somtoolbox/ 30 | 31 | % Version 2.0beta Johan 291000 32 | 33 | %% Init %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 34 | 35 | if isstruct(Data); 36 | if isfield(Data,'type') && ischar(Data.type) 37 | else 38 | error('Invalid map/data struct?'); 39 | end 40 | switch Data.type 41 | case 'som_map' 42 | data=Data.codebook; 43 | case 'som_data' 44 | data=Data.data; 45 | end 46 | else 47 | % is already a matrix 48 | data=Data; 49 | end 50 | 51 | % Take prototype vectors from prototype struct 52 | 53 | if isstruct(Proto), 54 | 55 | if isfield(Proto,'type') && ischar(Proto.type), 56 | else 57 | error('Invalid map/data struct?'); 58 | end 59 | switch Proto.type 60 | case 'som_map' 61 | proto=Proto.codebook; 62 | case 'som_data' 63 | proto=Proto.data; 64 | end 65 | else 66 | % is already a matrix 67 | proto=Proto; 68 | end 69 | 70 | % Check that inputs are matrices 71 | if ~vis_valuetype(proto,{'nxm'}) || ~vis_valuetype(data,{'nxm'}), 72 | error('Prototype or data input not valid.') 73 | end 74 | 75 | % Record data&proto sizes and check their dims 76 | [N_data dim_data]=size(data); 77 | [N_proto dim_proto]=size(proto); 78 | if dim_proto ~= dim_data, 79 | error('Data and prototype vector dimension does not match.'); 80 | end 81 | 82 | % Calculate euclidean distances between classifiees and prototypes 83 | d=distance(data,proto); 84 | 85 | %%%% Classification %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 86 | function d=distance(X,Y); 87 | 88 | % Euclidean distance matrix between row vectors in X and Y 89 | 90 | U=~isnan(Y); Y(~U)=0; 91 | V=~isnan(X); X(~V)=0; 92 | d=abs(X.^2*U'+V*Y'.^2-2*X*Y'); 93 | -------------------------------------------------------------------------------- /somtoolbox/som/som_table_struct.m: -------------------------------------------------------------------------------- 1 | function sTable = som_table_struct(values,headers,span,colfmt) 2 | 3 | %SOM_TABLE_STRUCT Create a table struct. 4 | % 5 | % sTable = som_table_struct(values,[headers],[span],[colfmt]) 6 | % 7 | % Input and output arguments ([]'s are optional): 8 | % values (cell array) size nrow x ncol, the contents of the table 9 | % (char array) size nrow x * 10 | % (matrix) size nrow x ncol 11 | % [headers] (cell array) size 1 x ncol, header row of the table 12 | % (empty) by default, empty headers are used ('') 13 | % [span] (matrix) size nrow x ncol x 2, span of each cell of the 14 | % table: span(:,:,1) gives horizontal span and 15 | % span(:,:,2) gives vertical span. If the value 16 | % for a cell is greater than 1, it should be 17 | % followed by a corresponding number of zeros 18 | % for the following cells (left or down) 19 | % (empty) by default ones(nrow,ncol,1) 20 | % [colfmt] (string) the format of each column as given in LaTeX, 21 | % only used if the table is printed as 'ps' or 'pdf', 22 | % by default colfmt = '' 23 | % 24 | % sTable (struct) the table struct, with the following fields: 25 | % .headers (cell array) header row, size 1 x ncol 26 | % .values (cell array) values, size nrow x ncol 27 | % .span (matrix) span of each cell, size nrow x ncol x 2 28 | % 29 | % See also SOM_TABLE_MODIFY, SOM_TABLE_PRINT. 30 | 31 | % Contributed to SOM Toolbox 2.0, December 31st, 2001 by Juha Vesanto 32 | % Copyright (c) by Juha Vesanto 33 | % http://www.cis.hut.fi/projects/somtoolbox/ 34 | 35 | % Version 2.0beta juuso 311201 36 | 37 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 38 | 39 | if ischar(values), values = cellstr(values); 40 | elseif isnumeric(values), values = num2cell(values); 41 | end 42 | [nrow,ncol] = size(values); 43 | 44 | if nargin<2 || isempty(headers), headers = cell(1,ncol); headers(:) = {''}; end 45 | if ischar(headers), headers = cellstr(headers); end 46 | 47 | if nargin<3 || isempty(span), span = ones(nrow,ncol,2); end 48 | if sum(span(:)) > 2*nrow*ncol, 49 | warning('span matrix has overlapping cells') 50 | elseif sum(span(:)) < 2*nrow*ncol, 51 | warning('span matrix has noncontinuous cells') 52 | end 53 | 54 | if nargin<4 || isempty(colfmt), colfmt = ''; end 55 | 56 | sTable = struct('colfmt','','headers',[],'values',[],'span',[]); 57 | sTable.colfmt = colfmt; 58 | sTable.headers = headers; 59 | sTable.span = span; 60 | sTable.values = values; 61 | 62 | return; 63 | 64 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 65 | -------------------------------------------------------------------------------- /somtoolbox/som/som_projections_plot.m: -------------------------------------------------------------------------------- 1 | function som_projections_plot(pmode,varargin) 2 | 3 | % SOM_PROJECTIONS_PLOT Projection visualizations. 4 | % 5 | % som_projections_plot(pmode,varargin) 6 | % 7 | % [cPCAarg, Pdata, Pproto] = som_projections(D,sM); 8 | % som_projections_plot('scatter',Pdata(:,1:3)) 9 | % som_projections_plot('scatter',Pproto(:,1:3),Pproto(:,5:7),5,sM) 10 | % som_projections_plot('residuals',Pdata(:,1:4)) 11 | % som_projections_plot('scree',cPCAarg{3}) 12 | % 13 | % The other arguments depend on the pmode: 14 | % 15 | % pmode = 'scatter' 16 | % 17 | % arg1: Co (matrix) coordinates 18 | % arg2: color (matrix) color vectors 19 | % (string) colorstring ('k' by default) 20 | % arg3: psize (scalar) point size 21 | % arg4: sT (struct) topology struct, if map grid is drawn 22 | % 23 | % pmode = 'residuals' 24 | % 25 | % arg1: Co (matrix) coordinates (2 first columns) + residuals (the rest) 26 | % arg2: color (string) colorstring ('k' by default) 27 | % 28 | % pmode = 'scree' 29 | % 30 | % arg1: eigval (vector) vector of eigenvalues 31 | % 32 | % See also SOM_PROJECTIONS. 33 | 34 | switch pmode, 35 | case 'scatter', 36 | Co = varargin{1}; 37 | if length(varargin)>1, color = varargin{2}; else color = 'k'; end 38 | if length(varargin)>2, psize = varargin{3}; else psize = 5; end 39 | if length(varargin)>3, sT = varargin{4}; else sT = []; end 40 | if isstruct(sT) && strcmp(sT.type,'som_map'), sT = sT.topol; end 41 | 42 | if isempty(sT), 43 | som_grid({'rect',[size(Co,1) 1]},'Coord',Co,'Markercolor',color,'line','none','markersize',psize); 44 | else 45 | if ischar(color), lcolor = color; else lcolor = 'k'; end 46 | som_grid(sT,'Coord',Co,'Markercolor',color,'markersize',psize,'linecolor',lcolor); 47 | end 48 | 49 | case 'residuals', 50 | CoRes = varargin{1}; 51 | n = size(CoRes,1); 52 | if length(varargin)>1, color = varargin{2}; else color = 'k'; end 53 | Co = CoRes(:,1:2); Co(end+1,:) = NaN; 54 | res = sqrt(sum(CoRes(:,3:end).*CoRes(:,3:end),2)); 55 | h=plot(Co(:,1),Co(:,2),'k.'); set(h,'color',color); 56 | Co(end+1,:) = NaN; 57 | res = [res; 0; NaN]; 58 | i = [1:n; 1:n; (n+1)+zeros(1,n)]; i = i(:); 59 | j = [(n+1)+zeros(1,n); 1:n; (n+2)+zeros(1,n)]; j = j(:); 60 | h = line(Co(i,1),Co(i,2),res(j)); set(h,'color',color); 61 | axis tight, axis equal, view(3) 62 | 63 | case 'scree', 64 | eigval = varargin{1}; 65 | if size(eigval,1)>1, eigval = eigval'; end 66 | eigval = eigval / sum(eigval); 67 | cumeig = cumsum(eigval); 68 | bar(cumeig,0.1) 69 | i = find(cumeig>=0.75); i75 = i(1); 70 | hold on 71 | plot([0 2],cumeig([2 2]),'r-',[0 i75],cumeig([i75 i75]),'r-'); 72 | set(gca,'YTick',unique([0:0.1:1 cumeig(2) cumeig(i75)])); 73 | axis tight, grid on 74 | 75 | end 76 | 77 | -------------------------------------------------------------------------------- /somtoolbox/som/som_normcolor.m: -------------------------------------------------------------------------------- 1 | function color = som_normcolor(data, clrmap) 2 | 3 | %SOM_NORMCOLOR RGB values of indexed colors for a given dataset and colormap 4 | % 5 | % color = som_normcolor(data, [clrmap]) 6 | % 7 | % color = som_normcolor(data); 8 | % color = som_normcolor(data,jet(64)); 9 | % 10 | % Input and output arguments ([]'s are optional): 11 | % data (struct) map or data struct 12 | % (matrix) size N x dim 13 | % [clrmap] (matrix) size N x 3, a valid colormap (an RGB value matrix) 14 | % Default is current colormap. See COLORMAP. 15 | % 16 | % color (matrix) size N x 3 x dim, RGB matrix 17 | % 18 | % Purpose of this function is to calculate fixed RGB colors that are similar 19 | % to indexed colors with the specified colormap. This is because some 20 | % SOM Toolbox visualization functions (as SOM_GRID) do not use indexed colors 21 | % if the underlying Matlab function (e.g. PLOT) do not use indexed colors 22 | % 23 | % EXAMPLE 24 | % 25 | % %%% Visualize three variables in a map using som_grid: 26 | % %%% Give coordinates for the markers according to variables 1 and 2, and 27 | % %%% 'indexed colors' according to variable 3. 28 | % 29 | % som_grid(map.topol.lattice,map.topol.msize,'Coord',map.codebook(:,1:2), ... 30 | % 'markercolor', som_normcolor(map.codebook(:,3))); 31 | 32 | % Contributed to SOM Toolbox 2.0, February 11th, 2000 by Johan Himberg 33 | % Copyright (c) by Johan Himberg 34 | % http://www.cis.hut.fi/projects/somtoolbox/ 35 | 36 | % juha 150799 johan 010999 37 | 38 | %%%% check possible errors %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 39 | 40 | error(nargchk(1,2,nargin)); 41 | 42 | if nargin < 2 || isempty(clrmap), 43 | clrmap=colormap; 44 | elseif ~vis_valuetype(clrmap,{'nx3rgb'}), 45 | error('The specified colormap is invalid!'); 46 | end 47 | 48 | d=size(clrmap,1); 49 | 50 | if isstruct(data), 51 | m_names={'type';'codebook';'topol';'labels';'neigh';'mask';'trainhist';... 52 | 'name';'comp_names';'comp_norm'}; 53 | d_names=fieldnames(vis_struct); 54 | if length(fieldnames(data)) ~= length(d_names) % data is not som_data_struct 55 | if length(fieldnames(data)) ~= length(m_names) % and not som_map_struct 56 | error('Input argument is not a ''som_vis'' or ''som_map'' struct.') 57 | elseif ~all(strcmp(fieldnames(data),m_names)) 58 | error('Input argument is not a ''som_vis'' or ''som_map'' struct.') 59 | else 60 | data=data.codebook; 61 | end 62 | elseif ~all(strcmp(fieldnames(data),dnames)) 63 | error('Input argument is not a ''som_vis'' or ''som_map'' struct.') 64 | else 65 | data=data.data; 66 | end 67 | end 68 | 69 | if ~isnumeric(data) || ndims(data) ~= 2 70 | error('Data is not 2 dimensional numeric matrix.'); 71 | end 72 | 73 | %%% action %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 74 | 75 | data=som_normalize(data,'range'); 76 | 77 | for i=1:size(data,2), 78 | inds=~isnan(data(:,i)); 79 | color(inds,:,i)=clrmap(round(data(inds,i)*(d-1))+1,:); 80 | color(~inds,:,i)=NaN; 81 | end 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | -------------------------------------------------------------------------------- /somtoolbox/som/som_divide.m: -------------------------------------------------------------------------------- 1 | function [V,I]=som_divide(sMap, D, inds, mode) 2 | 3 | %SOM_DIVIDE Divides a dataset according to a given map. 4 | % 5 | % [V,I]=som_divide(sMap, sData, [inds], [mode]) 6 | % 7 | % ARGUMENTS ([]'s are optional) 8 | % 9 | % sMap (struct or matrix) map struct or codebook (size munits x dim) 10 | % sData (struct or matrix) data struct or matrix (size N x dim ) 11 | % [inds] From which map units should the local data sets 12 | % be constructed. Interpretation depends on mode 13 | % argument. By default [1:munits]. 14 | % 'class': (vector) munits x 1 matrix of class numbers 15 | % 'index': (vector) K x 1 vector of map node indexes 16 | % 'index': (matrix) K x k matrix of map node subscripts 17 | % [mode] (string) 'index' or 'class', if inds is a vector of length 18 | % munits, default is 'class', otherwise 'index'. 19 | % RETURNS 20 | % 21 | % If mode == 'index' 22 | % V (matrix) data vectors hitting the specified nodes (size K x dim) 23 | % I (vector) corresponding data row indexes (size K x 1) 24 | % 25 | % If mode == 'class' (this can be used after using som_select) 26 | % V (cell array) V{K} includes vectors whose BMU has class number 27 | % K in the input matrix 'coord'. Note that 28 | % values of K below 1 are ignored. 29 | % I (cell array) corresponding data indexes in the cell array 30 | % 31 | % NOTE: if the same node is specified multiple times, only one 32 | % set of hits is returned. 33 | % 34 | % See also SOM_BMU, SOM_HITS, SOM_SELECT. 35 | 36 | % Version 1.0beta 260997 Johan 37 | % Version 2.0beta 230300 juuso 38 | 39 | % Contributed to SOM Toolbox vs2, Mar 23rd, 2000 by Juha Vesanto 40 | % http://www.cis.hut.fi/projects/somtoolbox/ 41 | 42 | %%%% Init & Check %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 43 | 44 | error(nargchk(0, 4, nargin)) % check if no. of input args is correct 45 | 46 | % map 47 | if isstruct(sMap), 48 | msize = sMap.topol.msize; 49 | dim = size(sMap.codebook,2); 50 | else 51 | msize = [size(sMap,1) 1]; 52 | dim = size(sMap,2); 53 | end 54 | munits = prod(msize); 55 | 56 | % data 57 | if isstruct(D), D=D.data; end 58 | 59 | % inds 60 | if nargin<3, inds = 1:munits; end 61 | isvec = numel(inds)==length(inds); 62 | 63 | % mode 64 | if nargin<4, 65 | if isvec && length(inds)==munits, 66 | mode = 'class'; 67 | else 68 | mode = 'index'; 69 | end 70 | end 71 | 72 | %%% Action & Build output according to the mode string output 73 | 74 | if ~isvec, inds = som_sub2ind(msize,inds); end 75 | 76 | bmus=som_bmus(sMap,D); 77 | 78 | switch mode 79 | case 'index' 80 | I=find(ismember(bmus,inds)); 81 | V=D(I,:); 82 | case 'class' 83 | K=max(inds); % classes 84 | V = cell(K,1); 85 | I = cell(K,1); 86 | for i=1:K, 87 | N_ind=find(inds == i); % indexes of the units of class i 88 | I{i}=find(ismember(bmus,N_ind)); % data indexes 89 | V{i}=D(I{i},:); 90 | end 91 | end 92 | 93 | 94 | 95 | 96 | 97 | -------------------------------------------------------------------------------- /somtoolbox/som/som_dreval.m: -------------------------------------------------------------------------------- 1 | function [sig,cm,truex,truey] = som_dreval(sR,D,sigmea,inds1,inds2,andor) 2 | 3 | % SOM_DREVAL Evaluate the significance of the given descriptive rule. 4 | % 5 | % [sig,Cm,truex,truey] = som_dreval(cR,D,sigmea,[inds1],[inds2],[andor]) 6 | % 7 | % sR (struct) a rule struct, or an array of rule structs 8 | % D (matrix) the data, of size [dlen x nr] 9 | % sigmea (string) significance measure ('accuracy','accuracyI','mutuconf'), 10 | % see definitions below 11 | % [inds1] (vector) indeces belonging to the group 12 | % (by default: the whole data set) 13 | % [inds2] (vector) indeces belonging to the contrast group 14 | % (by default: the rest of the data set) 15 | % [andor] (string) 'and' or 'or': which conjunction operator to use 16 | % to join the rules for each variable 17 | % 18 | % sig (scalar) significance of the rule 19 | % cm (vector) length 4, vectorized confusion matrix ([a,c,b,d]: see below) 20 | % truex (vector) binary vector indicating for each item in the 21 | % group whether it was true or not 22 | % truey (vector) binary vector indicating for each item in the 23 | % contrast group whether it was true or not 24 | % 25 | % Descriptive rule significance is measured as the match between the 26 | % given groups (inds1 = G1, inds2 = G2) and the rule being true or false. 27 | % 28 | % G1 G2 29 | % --------------- accuracy = (a+d) / (a+b+c+d) 30 | % true | a | b | 31 | % |-------------- mutuconf = a*a / ((a+b)(a+c)) 32 | % false | c | d | 33 | % --------------- accuracyI = a / (a+b+c) 34 | % 35 | % See also SOM_DRSIGNIF, SOM_DRMAKE. 36 | 37 | % Contributed to SOM Toolbox 2.0, March 4th, 2002 by Juha Vesanto 38 | % Copyright (c) by Juha Vesanto 39 | % http://www.cis.hut.fi/projects/somtoolbox/ 40 | 41 | % Version 2.0beta juuso 040302 42 | 43 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 44 | 45 | % input arguments 46 | if isstruct(D), 47 | switch D.type, 48 | case 'som_data', D = D.data; 49 | case 'som_map', D = D.codebook; 50 | end 51 | end 52 | [dlen,dim] = size(D); 53 | if nargin<4, inds1 = 1:dlen; end 54 | if nargin<5, i = ones(dlen,1); i(inds1) = 0; inds2 = find(i); end 55 | if nargin<6, andor = 'and'; end 56 | 57 | % initialize 58 | nr = length(sR); 59 | X = D(inds1,:); 60 | Y = D(inds2,:); 61 | nx = size(X,1); 62 | ny = size(Y,1); 63 | truex = ones(nx,1); 64 | truey = ones(ny,1); 65 | 66 | % go through the individual rules 67 | for i=1:nr, 68 | tx = (X(:,i)>=sR(i).low & X(:,i)=sR(i).low & Y(:,i)=2, Pdm = zeros(c,dlen); end 48 | if nargout==3, pmd = zeros(c,dlen); end 49 | 50 | % the parameters of each kernel 51 | cCoeff = cell(c,1); 52 | cCoinv = cell(c,1); 53 | for m=1:c, 54 | co = diag(K(m,:)); 55 | cCoinv{m} = inv(co); 56 | cCoeff{m} = 1 / ((2*pi)^(dim/2)*det(co)^.5); 57 | end 58 | 59 | % go through the vectors one by one 60 | for i=1:dlen, 61 | 62 | x = D(i,:); 63 | 64 | % compute p(x|m) 65 | pxm = zeros(c,1); 66 | for m = 1:c, 67 | dx = M(m,:) - x; 68 | pxm(m) = cCoeff{m} * exp(-.5 * dx * cCoinv{m} * dx'); 69 | %pxm(m) = normal(dx, zeros(1,dim), diag(K(m,:))); 70 | end 71 | pxm(isnan(pxm(:))) = 0; 72 | 73 | % p(x|m) 74 | if nargin>=2, Pdm(:,i) = pxm; end 75 | 76 | % P(x) = P(x|M) = sum( P(m) * p(x|m) ) 77 | pd(i) = P*pxm; 78 | 79 | % p(m|x) = p(x|m) * P(m) / P(x) 80 | if nargout==3, pmd(:,i) = (P' .* pxm) / pd(i); end 81 | 82 | end 83 | 84 | 85 | return; 86 | 87 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 88 | % 89 | % subfunction normal 90 | % 91 | % computes probability of x when mean and covariance matrix 92 | % of a distribution are known 93 | 94 | function result = normal(x, mu, co) 95 | 96 | [l dim] = size(x); 97 | coinv = inv(co); 98 | coeff = 1 / ((2*pi)^(dim/2)*det(co)^.5); 99 | diff = x - mu; 100 | result = coeff * exp(-.5 * diff * coinv * diff'); 101 | -------------------------------------------------------------------------------- /lib/ELMPredict.m: -------------------------------------------------------------------------------- 1 | % ========================================================================= 2 | % sinc(i) - http://fich.unl.edu.ar/sinc/ 3 | % Copyright 2017 Leandro Bugnon 4 | % lbugnon@sinc.unl.edu.ar 5 | % ========================================================================= 6 | % Methods for Extreme Learning Machine prediction (classification and 7 | % regression). 8 | function [outputs]=ELMPredict(testData,elmmodel,parameters) 9 | outputs={}; 10 | % Test per session 11 | for s=1:size(testData.sessionLabels,1) 12 | 13 | sind=testData.sessionLabels{s,2}:testData.sessionLabels{s,3}; 14 | 15 | switch elmmodel.elmMethod 16 | case 'neural' 17 | [soutput]=elmNeuralPredict(testData.features(sind,:),elmmodel); 18 | case 'kernel' 19 | [soutput]=elmKernelPredict(testData.features(sind,:),elmmodel); 20 | end 21 | 22 | outputs=[outputs; soutput]; 23 | 24 | end 25 | end 26 | % ========================================================================= 27 | 28 | % Modified from: 29 | %%%% Authors: MR QIN-YU ZHU AND DR GUANG-BIN HUANG 30 | %%%% NANYANG TECHNOLOGICAL UNIVERSITY, SINGAPORE 31 | %%%% EMAIL: EGBHUANG@NTU.EDU.SG; GBHUANG@IEEE.ORG 32 | %%%% WEBSITE: http://www.ntu.edu.sg/eee/icis/cv/egbhuang.htm 33 | %%%% DATE: APRIL 2004 34 | % Get output of ELM neural model for regression/classification. 35 | function [output] =elmNeuralPredict(testFeat,model) 36 | 37 | N=size(testFeat,1); 38 | 39 | tempH=model.w1*testFeat'; 40 | clear testFeat; 41 | % Extend the bias matrix BiasofHiddenNeurons to match the demention of H 42 | ind=ones(1,N); 43 | BiasMatrix=model.b1(:,ind); 44 | tempH=tempH+BiasMatrix; 45 | 46 | H=activationFunction(tempH,model.neuralFunc,model.funcList); 47 | % Release the temparary array for calculation of hidden neuron output 48 | % matrix H 49 | clear tempH; 50 | 51 | output=(model.w2*H)'; 52 | clear H; 53 | 54 | if isequal(model.task,'classification') 55 | % de-binarize the outputs (select winning neuron in each output frame) 56 | output=debinarizeLabels(output,model.classes); 57 | end 58 | end 59 | % ========================================================================= 60 | 61 | % ========================================================================= 62 | % Modified from: 63 | %%%% Authors: MR QIN-YU ZHU AND DR GUANG-BIN HUANG 64 | %%%% NANYANG TECHNOLOGICAL UNIVERSITY, SINGAPORE 65 | %%%% EMAIL: EGBHUANG@NTU.EDU.SG; GBHUANG@IEEE.ORG 66 | %%%% WEBSITE: http://www.ntu.edu.sg/eee/icis/cv/egbhuang.htm 67 | %%%% DATE: APRIL 2004 68 | % Test ELM kernel model for regression/classification. 69 | function [output] =elmKernelPredict(testFeat,model) 70 | 71 | N=size(testFeat,1); 72 | 73 | Omega_test = kernel_matrix(model.trainFeat,model.kernelType, [model.kernelParam1 model.kernelParam2],testFeat); 74 | output=Omega_test' * model.wo; 75 | 76 | if isequal(model.task,'classification') 77 | % de-binarize the outputs (select winning neuron in each output frame) 78 | output=debinarizeLabels(output,model.classes); 79 | end 80 | 81 | end 82 | % ========================================================================= 83 | function labels=debinarizeLabels(binLabels,classes) 84 | labels=zeros(size(binLabels,1),size(classes,2)); 85 | for n=1:size(binLabels,1) 86 | [~,maxind]=max(binLabels(n,:)); 87 | labels(n,:)=classes(maxind,:); 88 | end 89 | end -------------------------------------------------------------------------------- /lib/makeDataStruct.m: -------------------------------------------------------------------------------- 1 | % ========================================================================= 2 | % sinc(i) - http://fich.unl.edu.ar/sinc/ 3 | % Copyright 2017 Leandro Bugnon 4 | % lbugnon@sinc.unl.edu.ar 5 | % ========================================================================= 6 | % Create a struct from data in sessionFiles. 7 | function dataStruct=makeDataStruct(sessionFiles,parameters,varargin) 8 | 9 | includeOriginal=false; 10 | allFeatures=true; 11 | 12 | 13 | for v=1:2:length(varargin) 14 | switch varargin{v} 15 | case 'featSelected' 16 | featSelected=varargin{v+1}; 17 | allFeatures=false; 18 | case 'includeOriginal' 19 | includeOriginal=varargin{v+1}; 20 | end 21 | 22 | end 23 | 24 | 25 | for p=1:length(parameters) 26 | switch parameters(p).name 27 | case 'selectedLabels' 28 | targetsSelected=parameters(p).val; 29 | case 'classificationTask' 30 | classificationTask=parameters(p).val; 31 | end 32 | end 33 | 34 | 35 | dataStruct=struct; 36 | dataStruct.features=[]; 37 | dataStruct.targets=[]; 38 | dataStruct.timeStamp=[]; 39 | dataStruct.sessionLabels={}; 40 | if includeOriginal 41 | dataStruct.original=struct; 42 | dataStruct.original.targets=[]; 43 | dataStruct.original.sessionLabels={}; 44 | dataStruct.original.timeStamp=[]; 45 | end 46 | 47 | 48 | targetNames={'Arousal','Valence'}; 49 | dataStruct.targetNames=targetNames(targetsSelected); 50 | 51 | for s=sessionFiles' 52 | s=s{:}; 53 | load(s) 54 | 55 | if allFeatures 56 | featSelected=1:size(features,2); 57 | end 58 | 59 | dataStruct.features=[dataStruct.features; features(:,featSelected)]; 60 | 61 | try 62 | dataStruct.targets=[dataStruct.targets; targets(:,targetsSelected)]; 63 | catch 64 | end 65 | session={s(strfind(s,'/')+1:end-4)}; 66 | if isempty(dataStruct.sessionLabels) 67 | dataStruct.sessionLabels=[dataStruct.sessionLabels; [session 1 size(features,1)]]; 68 | else 69 | dataStruct.sessionLabels=[dataStruct.sessionLabels; [session ... 70 | dataStruct.sessionLabels{end,3}+1 dataStruct.sessionLabels{end,3}+size(features,1)]]; 71 | end 72 | 73 | dataStruct.timeStamp=[dataStruct.timeStamp; timeStamp(1) timeStamp(end)]; 74 | 75 | dataStruct.includeOriginal=includeOriginal; 76 | try 77 | if includeOriginal 78 | dataStruct.original.targets=[dataStruct.original.targets; originalTargets(:,targetsSelected)]; 79 | 80 | if isempty(dataStruct.original.sessionLabels) 81 | dataStruct.original.sessionLabels=[dataStruct.original.sessionLabels; {session 1 size(originalTargets,1)}]; 82 | else 83 | dataStruct.original.sessionLabels=[dataStruct.original.sessionLabels; {session ... 84 | dataStruct.original.sessionLabels{end,3}+1 dataStruct.original.sessionLabels{end,3}+size(originalTargets,1)}]; 85 | end 86 | 87 | dataStruct.original.timeStamp=[dataStruct.original.timeStamp; originalTimeStamp(1) originalTimeStamp(end)]; 88 | dataStruct.original.fs_feat=fs_targets; 89 | 90 | end 91 | catch 92 | end 93 | end 94 | 95 | dataStruct.featNames=featNames; 96 | dataStruct.fs_feat=fs_feat; 97 | dataStruct.sessionFiles=sessionFiles; 98 | dataStruct.targetsSelected=targetsSelected; 99 | 100 | end -------------------------------------------------------------------------------- /somtoolbox/som/vis_footnote.m: -------------------------------------------------------------------------------- 1 | function h=vis_footnote(txt) 2 | 3 | % VIS_FOOTNOTE Adds a movable text to the current figure 4 | % 5 | % h = vis_footnote(T) 6 | % 7 | % Input and output arguments ([]'s are optional) 8 | % [T] (string) text to be written 9 | % (scalar) font size to use in all strings 10 | % 11 | % h (vector) handles to axis objects created by this function 12 | % 13 | % This function sets a text to the current figure. If T is a string, 14 | % it's written as it is to the same place. If T is a scalar, the font 15 | % size of all text objects created by this function are changed to the 16 | % pointsize T. If no input argument is given the function only returns 17 | % the handles to all objects created by this function. The texts may 18 | % be dragged to a new location at any time using mouse. Note that the 19 | % current axis will be the parent of the text object after dragging. 20 | % 21 | % String 'Info' is set to the Tag property field of the objects. 22 | % 23 | % EXAMPLES 24 | % 25 | % % add movable texts to the current figure and change their 26 | % % fontsize to 20 points 27 | % vis_footnote('Faa'); vis_footnote('Foo'); vis_footnote(20); 28 | % 29 | % % delete all objects created by this function from the current figure 30 | % delete(vis_footnote); 31 | % 32 | % See also SOM_SHOW. 33 | 34 | % Copyright (c) 1997-2000 by the SOM toolbox programming team. 35 | % http://www.cis.hut.fi/projects/somtoolbox/ 36 | 37 | % Version 2.0beta Johan 080698 38 | 39 | %% Check arguments %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 40 | 41 | narginchk(0, 1) % check no. of input args 42 | 43 | %% Init %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 44 | 45 | % Get the handles to the existing Info-axes objects 46 | 47 | h_infotxt=findobj(gcf,'tag','Info','type','text'); 48 | h_infoax=findobj(gcf,'tag','Info','type','axes'); 49 | 50 | %% Action %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 51 | 52 | % If no arguments are given, return the old axes handles 53 | 54 | if nargin == 0 || isempty(txt), 55 | elseif ischar(txt) % text: set new text 56 | [t,h_]=movetext(txt); 57 | h_infoax=[h_; h_infoax]; 58 | elseif vis_valuetype(txt,{'1x1'}) % scalar: change font size 59 | set(h_infotxt,'fontunits','points'); 60 | set(h_infotxt,'fontsize',txt); 61 | else 62 | error('Input argument should be a string or a scalar.'); 63 | end 64 | 65 | %% Build output %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 66 | 67 | if nargout>0 % output only if necessary 68 | h=h_infoax; 69 | end 70 | 71 | %%% SUBFUNCTIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 72 | 73 | function [t,h]=movetext(txt) 74 | % Moves the text. See also VIS_FOOTNOTEBUTTONDOWNFCN 75 | % 76 | % 77 | initpos=[0.05 0.05 0.01 0.01]; 78 | 79 | memaxes = gca; % Memorize the gca 80 | 81 | %% Create new axis on the lower left corner. 82 | %% This will be the parent for the text object 83 | 84 | h = axes('position',initpos,'units','normalized'); 85 | set(h,'visible','off'); % hide axis 86 | 87 | t = text(0,0,txt); % write text 88 | set(t,'tag','Info'); % set tag 89 | set(h,'tag','Info'); % set tag 90 | 91 | set(t,'verticalalignment','bottom'); % set text alignment 92 | set(t,'horizontalalignment','left'); 93 | 94 | %% Set ButtonDownFcn 95 | 96 | set(t,'buttondownfcn','vis_footnoteButtonDownFcn') 97 | 98 | axes(memaxes); % Reset original gca 99 | 100 | 101 | -------------------------------------------------------------------------------- /somtoolbox/som/som_coloring.m: -------------------------------------------------------------------------------- 1 | function Col = som_coloring(sM,ncol,chaingap,dw) 2 | 3 | % SOM_COLORING Make a SOM-based coloring for given data/map. 4 | % 5 | % Col = som_coloring(sM,[ncol],[chaingap],[dw]) 6 | % 7 | % Col = som_coloring(sM,5); 8 | % som_show(sM,'color',Col); 9 | % 10 | % Input and output arguments ([]'s are optional): 11 | % sM (struct) map or data struct 12 | % (matrix) data matrix 13 | % [ncol] (scalar) number of colors to use 14 | % [chaingap] (scalar) size of gap in the color circle (see below), 15 | % 0.1 by default 16 | % [dw] (scalar) 1 = use input space distances to stretch 17 | % the color circle (default) 18 | % 0 = don't use 19 | % 20 | % Col (matrix) color for each data/codebook vector 21 | % 22 | % This function trains a 1-dimensional SOM using the input data 23 | % (codebook of a SOM, or a set of data vectors). A color from the 24 | % color circle (see HSV function) is associated with each map unit, 25 | % and each data/codebook vector of the input data picks its color 26 | % from its BMU on the 1-dimensional SOM. 27 | % 28 | % If the chaingap argument == 0, the 1-dimensional map has a cylinder 29 | % (in effect, a ring) topology. Otherwise, the topology is rectangular 30 | % (in effect, a chain). 31 | % 32 | % The colors are mapped to the 1-dimensional SOM simply by picking colors 33 | % from the color circle. If chaingap>0, a slice of the color circle is 34 | % removed before map units pick their colors from it. This creates a 35 | % discontiuity in the coloring at the ends of the 1-dimensional SOM. 36 | % 37 | % If the dw argument == 0, the colors are picked from the color circle 38 | % equidistantly. If not, the distances between the prototype vectors 39 | % in the 1-dimensional SOM are taken into account. 40 | % 41 | % See also SOM_KMEANSCOLOR, SOM_KMEANSCOLOR2, SOM_FUZZYCOLOR. 42 | 43 | % Contributed to SOM Toolbox 2.0, December 21st, 2001 by Juha Vesanto 44 | % http://www.cis.hut.fi/projects/somtoolbox/ 45 | 46 | % Version 2.0beta juuso 211201 47 | 48 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 49 | 50 | if isstruct(sM), 51 | if strcmp(sM.type,'som_map'), ismap = 1; D = sM.codebook; 52 | else ismap = 0; D = sM.data; 53 | end 54 | else ismap = 0; D = sM; 55 | end 56 | 57 | if nargin<2 || isempty(ncol) || isnan(ncol), ncol = min(64,size(D,1)); end 58 | if nargin<3 || isempty(chaingap) || isnan(chaingap), chaingap = 0.1; end 59 | if nargin<4 || isempty(dw) || isnan(dw), dw = 1; end 60 | 61 | if chaingap == 0, lattice = 'sheet'; else lattice = 'cyl'; end 62 | sMring = som_make(D,'msize',[1,ncol],lattice,'tracking',0); 63 | b = som_bmus(sMring,D); 64 | 65 | Colmap = hsv(ceil(ncol*(1+chaingap))); 66 | Colmap = Colmap(1:ncol,:); 67 | 68 | if dw, % take distances in input space into account 69 | dist = sqrt(sum((sMring.codebook-sMring.codebook([2:end 1],:)).^2,2)); 70 | ind = round([0; cumsum(dist)/sum(dist)]*(ncol-1)) + 1; 71 | Colmap = Colmap(ind,:); 72 | end 73 | Col = Colmap(b,:); 74 | 75 | return; 76 | 77 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 78 | 79 | % visualization 80 | if ismap, 81 | a = som_bmus(sM.codebook,sMring.codebook); 82 | if chaingap==0, a(end+1) = a(1); end 83 | som_show(sM,'color',Col); 84 | som_show_add('traj',a) 85 | else 86 | i = find(sum(isnan(D),2)==0); 87 | [P,V,me] = pcaproj(D(i,:),2); 88 | Pr = pcaproj(sMring.codebook,V,me); 89 | a = som_bmus(D(i,:),sMring.codebook); % Pr = P(a,:); 90 | som_grid({'rect',[length(i) 1]},'line','none',... 91 | 'coord',P,'markercolor',Col(i,:)); 92 | hold on 93 | if chaingap==0, Pr(end+1,:) = Pr(1,:); end 94 | som_grid({'rect',[size(Pr,1) 1]},'linecolor','k',... 95 | 'linewidth',2,'markercolor','k','coord',Pr); 96 | end 97 | 98 | 99 | -------------------------------------------------------------------------------- /somtoolbox/som/som_table_modify.m: -------------------------------------------------------------------------------- 1 | function sT = som_table_modify(sT,action,arg1,arg2,arg3) 2 | 3 | %SOM_TABLE_MODIFY Modify table: add or remove columns or rows. 4 | % 5 | % sTable = som_table_modify(sTable,action,arg1,[arg2],[arg3]) 6 | % 7 | % Input and output arguments ([]'s are optional): 8 | % sTable (struct) table struct 9 | % action (string) action id (see below). 10 | % arg1 (varies) Depending on action, 1 to 3 arguments 11 | % [arg2] (varies) are needed. See below. 12 | % [arg3] (varies) 13 | % 14 | % sTable (struct) the modified table struct 15 | % 16 | % Actions and their arguments: 17 | % 'addcol' Add one or several new columns. 18 | % arg1 (cell array) new values 19 | % (char) new values (a single column can be given) 20 | % (matrix) new values 21 | % arg2 (cell array) new headers 22 | % arg3 (scalar) at which position the new columns 23 | % should be inserted (at the end by default) 24 | % 'addrow' Add one or several new rows. 25 | % arg1 (cell array) new values 26 | % (char) new values (a single row can be given) 27 | % (matrix) new values 28 | % arg2 (scalar) at which position the new rows 29 | % should be inserted (at the end by default) 30 | % 'removecol' Remove one or several columns. 31 | % arg1 (vector) indeces of columns to be removed 32 | % 'removerow' Remove one or several rows. 33 | % arg1 (vector) indeces of rows to be removed 34 | % 35 | % See also SOM_TABLE_STRUCT, SOM_TABLE_PRINT. 36 | 37 | % Contributed to SOM Toolbox 2.0, January 4th, 2002 by Juha Vesanto 38 | % Copyright (c) by Juha Vesanto 39 | % http://www.cis.hut.fi/projects/somtoolbox/ 40 | 41 | % Version 2.0beta juuso 040102 42 | 43 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 44 | 45 | [nrT,ncT] = size(sT.values); 46 | 47 | switch action, 48 | case 'addcol', 49 | values = arg1; 50 | if ischar(values), values = cellstr(values); end 51 | if isnumeric(values), values = num2cell(values); end 52 | spans = ones([size(values) 2]); 53 | [nr,nc] = size(values); 54 | if nargin<4, header = cell(1,nc); header(:) = {''}; else header = arg2; end 55 | if ischar(header), header = cellstr(header); end 56 | if nargin<5, where = ncT+1; else where = arg3; end 57 | if nrT ~= nr, 58 | error('Mismatch between sizes of given table and additional columns') 59 | else 60 | sT.headers = [sT.headers(:,1:where-1), header, sT.headers(:,where:end)]; 61 | sT.values = [sT.values(:,1:where-1), values, sT.values(:,where:end)]; 62 | sT.span = [sT.span(:,1:where-1,:), spans, sT.span(:,where:end,:)]; 63 | end 64 | case 'addrow', 65 | values = arg1; 66 | if ischar(values), values = cellstr(values); end 67 | if isnumeric(values), values = num2cell(values); end 68 | [nr,nc] = size(values); 69 | spans = ones([size(values) 2]); 70 | if nargin<4, where = nrT+1; else where = arg2; end 71 | if ncT ~= nc, 72 | error('Mismatch between sizes of given table and additional rows') 73 | else 74 | sT.values = [sT.values(1:where-1,:); values; sT.values(where:end,:)]; 75 | sT.span = [sT.span(1:where-1,:,:); spans; sT.span(where:end,:,:)]; 76 | end 77 | case 'removecol', 78 | where = setdiff(1:ncT,arg1); 79 | sT.values = sT.values(:,where); 80 | sT.headers = sT.headers(:,where); 81 | sT.span = sT.span(:,where,:); 82 | case 'removerow', 83 | where = setdiff(1:nrT,arg1); 84 | sT.values = sT.values(where,:); 85 | sT.headers = sT.headers(where,:); 86 | sT.span = sT.span(where,:,:); 87 | end 88 | 89 | return; 90 | 91 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 92 | -------------------------------------------------------------------------------- /lib/postProcessing.m: -------------------------------------------------------------------------------- 1 | % ========================================================================= 2 | % sinc(i) - http://fich.unl.edu.ar/sinc/ 3 | % Copyright 2017 Leandro Bugnon 4 | % lbugnon@sinc.unl.edu.ar 5 | % ========================================================================= 6 | % Generic function for postprocessing classifier output, like filtering and 7 | % interpolation. 8 | function [trainOutputProcessed,testOutputProcessed]=postProcessing... 9 | (trainOutput,trainData,testOutput,parameters) 10 | 11 | outputScaling='no'; 12 | for p=1:length(parameters) 13 | switch parameters(p).name 14 | case 'outputScaling' 15 | outputScaling=parameters(p).val; 16 | end 17 | end 18 | 19 | 20 | % Aditional processing on classifier output (e.g. filtering): 21 | [trainOutputProcessed]=smoothingFunc(trainOutput,parameters); 22 | [testOutputProcessed]=smoothingFunc(testOutput,parameters); 23 | 24 | preScaling=testOutputProcessed;%debug 25 | 26 | switch outputScaling 27 | case 'no' 28 | case 'trainAmpl' 29 | % get mean amplitude diference of outputs and labels (only in training) 30 | scaleFactor=zeros(1,size(trainOutputProcessed{1},2)); 31 | for s=1:length(trainOutputProcessed) % session 32 | sind=trainData.sessionLabels{s,2}:trainData.sessionLabels{s,3}; 33 | outputAmpl=max(trainOutputProcessed{s})-min(trainOutputProcessed{s}); 34 | 35 | labelAmpl=max(trainData.targets(sind,:))-min(trainData.targets(sind,:)); 36 | 37 | scaleFactor=scaleFactor+labelAmpl./outputAmpl; 38 | end 39 | % finish average 40 | scaleFactor=scaleFactor/length(trainOutputProcessed); 41 | 42 | for s=1:length(trainOutputProcessed) % session 43 | for l=1:size(trainOutputProcessed{s},2) 44 | trainOutputProcessed{s}(:,l)=(trainOutputProcessed{s}(:,l)-mean(trainOutputProcessed{s}(:,l)))*scaleFactor(l)+mean(trainOutputProcessed{s}(:,l)); 45 | end 46 | end 47 | for s=1:length(testOutputProcessed) % session 48 | for l=1:size(testOutputProcessed{s},2) 49 | testOutputProcessed{s}(:,l)=(testOutputProcessed{s}(:,l)-mean(testOutputProcessed{s}(:,l)))*scaleFactor(l)+mean(testOutputProcessed{s}(:,l)); 50 | end 51 | end 52 | end 53 | 54 | end 55 | % ========================================================================= 56 | 57 | % ========================================================================= 58 | function [output]=smoothingFunc(input,parameters,varargin) 59 | 60 | delay=0; 61 | filterFunc='no'; 62 | for p=1:length(parameters) 63 | switch parameters(p).name 64 | case 'filterFunc' 65 | % function and parameter combined 66 | filterFunc=parameters(p).val{1}; 67 | filterParam=parameters(p).val{2}; 68 | case 'delay' 69 | delay=parameters(p).val; 70 | end 71 | end 72 | 73 | output=input; 74 | 75 | % Process each session 76 | for s=1:length(output) 77 | 78 | switch filterFunc 79 | case 'median' 80 | output{s}=medfilt1(output{s},filterParam); 81 | case 'average' 82 | outputcopy=output{s}; 83 | for n=filterParam/2:size(output{s},1)-filterParam/2 84 | output{s}(n,:)=mean(outputcopy((n-filterParam/2+1):(n+filterParam/2),:)); 85 | end 86 | case 'exp' 87 | output{s}=smoothts(output{s}','e',filterParam)'; 88 | case 'no' 89 | % do nothing 90 | end 91 | 92 | % Label delay ========================================================= 93 | if delay~=0 94 | output{s}=circshift(output{s},delay); 95 | end 96 | % ============================================================= 97 | 98 | end 99 | end 100 | -------------------------------------------------------------------------------- /somtoolbox/som/som_clget.m: -------------------------------------------------------------------------------- 1 | function a = som_clget(sC, mode, ind) 2 | 3 | %SOM_CLGET Get properties of specified clusters. 4 | % 5 | % a = som_clget(sC, mode, ind) 6 | % 7 | % inds = som_clget(sC,'dinds',20); 8 | % col = som_clget(sC,'depth',[1 2 3 20 54]); 9 | % 10 | % Input and output arguments: 11 | % sC (struct) clustering struct 12 | % mode (string) what kind of property is requested 13 | % 'binds' (a union over) indeces of base clusters 14 | % belonging to the specified cluster(s) 15 | % 'dinds' (a union over) indeces of the data vectors 16 | % belonging to the specified cluster(s) 17 | % 'dlen' number of data vectors belonging 18 | % to each of the specified cluster(s) 19 | % 'depth' depths of the specified clusters 20 | % (depth of the root cluster is 0, 21 | % depth of its children are 1, etc.) 22 | % 'child' (a union over) children clusters 23 | % of specified cluster(s), including 24 | % the clusters themselves 25 | % 'base' base partitioning based on given 26 | % clusters 27 | % ind (vector) indeces of the clusters 28 | % 29 | % a (vector) the answer 30 | % 31 | % See also SOM_CLSTRUCT, SOM_CLPLOT. 32 | 33 | % Copyright (c) 2000 by the SOM toolbox programming team. 34 | % Contributed to SOM Toolbox on XXX by Juha Vesanto 35 | % http://www.cis.hut.fi/projects/somtoolbox/ 36 | 37 | % Version 2.0beta juuso 180800 38 | 39 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 40 | 41 | clen = size(sC.tree,1)+1; 42 | 43 | switch mode, 44 | case 'binds', 45 | a = []; 46 | for i=1:length(ind), a = [a, getbaseinds(sC.tree,ind(i))]; end 47 | a = unique(a); 48 | case 'dinds', 49 | b = []; 50 | for i=1:length(ind), b = [b, getbaseinds(sC.tree,ind(i))]; end 51 | b = unique(b); 52 | a = zeros(length(sC.base),1); 53 | for i=1:length(b), a(find(sC.base==b(i)))=1; end 54 | a = find(a); 55 | case 'dlen', 56 | a = zeros(length(ind),1); 57 | for i=1:length(ind), 58 | b = getbaseinds(sC.tree,ind(i)); 59 | for j=1:length(b), a(i) = a(i) + sum(sC.base==b(j)); end 60 | end 61 | case 'depth', 62 | a = getdepth(sC.tree); 63 | a = a(ind); 64 | case 'child', 65 | a = getchildren(sC.tree,ind); 66 | case 'base', 67 | a = sC.base*0; 68 | ind = -sort(-ind); 69 | for i=1:length(ind), a(som_clget(sC,'dinds',ind(i))) = ind(i); end 70 | end 71 | 72 | return; 73 | 74 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 75 | 76 | function ch = getchildren(Z,ind) 77 | 78 | clen = size(Z,1)+1; 79 | ch = ind; cho = ind; 80 | while any(cho), 81 | i = cho(1); cho = cho(2:end); 82 | j = Z(i-clen,1); k = Z(i-clen,2); 83 | if j>clen, cho(end+1) = j; end 84 | if k>clen, cho(end+1) = k; end 85 | ch(end+1) = j; ch(end+1) = k; 86 | end 87 | return; 88 | 89 | function binds = getbaseinds(Z,ind) 90 | 91 | clen = size(Z,1)+1; 92 | binds = ind; 93 | while binds(1)>clen, 94 | i = binds(1); 95 | binds = binds(2:end); 96 | j = Z(i-clen,1); k = Z(i-clen,2); 97 | if j>clen, binds = [j binds]; else binds(end+1) = j; end 98 | if k>clen, binds = [k binds]; else binds(end+1) = k; end 99 | end 100 | return; 101 | 102 | function depth = getdepth(Z) 103 | 104 | clen = size(Z,1)+1; 105 | depth = zeros(2*clen-1,1); 106 | ch = 2*clen-1; % active nodes 107 | while any(ch), 108 | c = ch(1); ch = ch(2:end); 109 | if c>clen && isfinite(Z(c-clen,3)), 110 | chc = Z(c-clen,1:2); % children of c 111 | depth(chc) = depth(c) + 1; % or +(ind==chc(1)) 112 | ch = [ch, chc]; 113 | end 114 | end 115 | return; 116 | -------------------------------------------------------------------------------- /somtoolbox/som/som_neighf.m: -------------------------------------------------------------------------------- 1 | function H = som_neighf(sMap,radius,neigh,ntype) 2 | 3 | %SOM_NEIGHF Return neighborhood function values. 4 | % 5 | % H = som_neighf(sMap,[radius],[neigh],[ntype]); 6 | % 7 | % Input and output arguments ([]'s are optional): 8 | % sMap (struct) map or topology struct 9 | % [radius] (scalar) neighborhood radius (by default, the last used value 10 | % in sMap.trainhist is used, or 1 if that is unavailable) 11 | % [neigh] (string) neighborhood function type (by default, ..., or 12 | % 'gaussian' if that is unavailable) 13 | % [ntype] (string) 'normal' (default), 'probability' or 'mirror' 14 | % 15 | % H (matrix) [munits x munits] neighborhood function values from 16 | % each map unit to each other map unit 17 | % 18 | % For more help, try 'type som_batchtrain' or check out online documentation. 19 | % See also SOM_MAKE, SOM_SEQTRAIN, SOM_TRAIN_STRUCT. 20 | 21 | % Copyright (c) 1997-2000 by the SOM toolbox programming team. 22 | % http://www.cis.hut.fi/projects/somtoolbox/ 23 | 24 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 25 | %% Check arguments 26 | 27 | % defaults 28 | rdefault = 1; 29 | ndefault = 'gaussian'; 30 | tdefault = 'normal'; 31 | 32 | % map 33 | switch sMap.type, 34 | case 'som_map', 35 | sTopol = sMap.topol; 36 | sTrain = sMap.trainhist(end); 37 | if isempty(sTrain.radius_fin) || isnan(sTrain.radius_fin), 38 | rdefault = 1; 39 | else 40 | rdefault = sTrain.radius_fin; 41 | end 42 | if ~isempty(sTrain.neigh) && ~isnan(sTrain.neigh), 43 | ndefault = sTrain.neigh; 44 | end 45 | case 'som_topol', sTopol = sMap; 46 | end 47 | munits = prod(sTopol.msize); 48 | 49 | % other parameters 50 | if nargin<2 || isempty(radius), radius = rdefault; end 51 | if nargin<3 || isempty(neigh), neigh = ndefault; end 52 | if nargin<4 || isempty(ntype), ntype = tdefault; end 53 | 54 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 55 | %% initialize 56 | 57 | % basic neighborhood 58 | Ud = som_unit_dists(sTopol); 59 | Ud = Ud.^2; 60 | radius = radius.^2; 61 | if radius==0, radius = eps; end % zero neighborhood radius may cause div-by-zero error 62 | 63 | switch ntype, 64 | case 'normal', 65 | H = neighf(neigh,Ud,radius); 66 | case 'probability', 67 | H = neighf(neigh,Ud,radius); 68 | for i=1:munits, H(i,:) = H(i,:)/sum(H(i,:)); end 69 | case 'mirror', % only works for 2-dim grid!!! 70 | H = zeros(munits,munits); 71 | Co = som_unit_coords(sTopol); 72 | for i=-1:1, 73 | for j=-1:1, 74 | Ud = gridmirrordist(Co,i,j); 75 | H = H + neighf(neigh,Ud,radius); 76 | end 77 | end 78 | end 79 | 80 | return; 81 | 82 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 83 | %% subfunctions 84 | 85 | function H = neighf(neigh,Ud,radius) 86 | 87 | switch neigh, 88 | case 'bubble', H = (Ud<=radius); 89 | case 'gaussian', H = exp(-Ud/(2*radius)); 90 | case 'cutgauss', H = exp(-Ud/(2*radius)) .* (Ud<=radius); 91 | case 'ep', H = (1-Ud/radius) .* (Ud<=radius); 92 | end 93 | return; 94 | 95 | function Ud = gridmirrordist(Co,mirrorx,mirrory) 96 | 97 | [munits,mdim] = size(Co); 98 | if mdim>2, error('Mirrored neighborhood only works for 2-dim map grids.'); end 99 | 100 | % width and height of the grid 101 | dx = max(Co(:,1))-min(Co(:,1)); 102 | dy = max(Co(:,2))-min(Co(:,2)); 103 | 104 | % calculate distance from each location to each other location 105 | Ud = zeros(munits,munits); 106 | for i=1:munits, 107 | inds = [i:munits]; 108 | coi = Co(i,:); % take hexagonal shift into account 109 | coi(1) = coi(1)*(1-2*(mirrorx~=0)) + 2*dx*(mirrorx==1); % +mirrorx * step 110 | coi(2) = coi(2)*(1-2*(mirrory~=0)) + 2*dy*(mirrory==1); % +mirrory * step 111 | Dco = (Co(inds,:) - coi(ones(munits-i+1,1),:))'; 112 | Ud(i,inds) = sqrt(sum(Dco.^2)); 113 | Ud(inds,i) = Ud(i,inds)'; 114 | end 115 | return; 116 | 117 | 118 | -------------------------------------------------------------------------------- /somtoolbox/som/vis_planeGetArgs.m: -------------------------------------------------------------------------------- 1 | function [nargin_,varargout]=vis_planeGetArgs(varargin) 2 | 3 | % VIS_PLANEGETARGS Subfunction for som_*plane: extracts topolopy 4 | % information from the first arguments. 5 | % 6 | % [nargin,varargout]=vis_planeGetArgs(varargin) 7 | % 8 | % Input and output arguments: 9 | % varargin (varies) arguments given to som_*plane function 10 | % nargin_ (scalar) number of arguments that nargchk of som_*plane "should see" 11 | % +number_of_varargins if varargin{1} is not map/topol struct 12 | % +number_of_varargins+1 if varargin{2} is a map/topol struct 13 | % varargout (varies) the arguments that som_*plane "should see" 14 | % 15 | % Basically, this function allows topology information to be given 16 | % in various ways: either as a map/topology struct, or as a argument pair: 17 | % lattice, msize. The topology is always converted into the (lattice, msize) 18 | % argument pair. 19 | % - if first input argument (varargin{1}) is a map or topol struct 20 | % the function extracts lattice and msize fields to two first 21 | % output variables after 'nargin_'. 22 | % - otherwise it copies the input arguments to the output arguments 23 | % after 'nargin_'. 24 | % If there are too many inputs (as compared to number of outputs), the 25 | % last ones are ignored. If too few, they are replaced by empty values 26 | % in outputs. 27 | % 28 | % Example of usage: 29 | % function definition: h = som_cplane(varargin) 30 | % first code line: [nargin,lattice,msize,color,size,pos]=vis_planeGetArgs(varargin); 31 | % 32 | % See also SOM_CPLANE, SOM_BARPLANE, SOM_PLOTPLANE, SOM_PIEPLANE. 33 | 34 | % Copyright (c) 2000 by the SOM toolbox programming team. 35 | % http://www.cis.hut.fi/projects/somtoolbox/ 36 | 37 | % Version 2.0beta Johan 240300 38 | 39 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 40 | 41 | nout=nargout-1; 42 | 43 | % Set first all varargins to contain empty (==default values in som_*plane) 44 | 45 | for i=1:nout, varargout{i}=[]; end 46 | 47 | nargin_ = nargin; %#ok 48 | % Struct: might be map or topol 49 | 50 | if isstruct(varargin{1}), 51 | 52 | % Get topol from topol field 53 | if isfield(varargin{1},'topol'), topol=varargin{1}.topol; 54 | else topol=varargin{1}; % assume that this is topol struct 55 | end 56 | 57 | if ~isstruct(topol), 58 | % topol not a struct !? 59 | warning('SOMTOOLBOX:warning', 'Field ''topol'' is not a struct.'); 60 | varargout{1}=varargin{1}; 61 | varargoutC=2; 62 | nargin_ = nargin; 63 | elseif ~isfield(topol,'msize') || ~isfield(topol,'lattice'), 64 | % Field missing?! 65 | warning('SOMTOOLBOX:warning', 'Invalid topology struct.'); 66 | varargout{1}=topol; 67 | varargoutC=2; 68 | nargin_ = nargin; 69 | else 70 | varargout{1}=topol.lattice; 71 | varargout{2}=topol.msize; 72 | % increment input arg. counter 73 | varargoutC=3; 74 | nargin_ = nargin+1; 75 | end 76 | 77 | elseif iscell(varargin{1}), 78 | 79 | % ITN TODO: why is there a shape parameter here anyway? 80 | c = varargin{1}; 81 | lattice = 'hexa'; shape = 'sheet'; msize = [1 1]; 82 | for i=1:length(c), 83 | if ischar(c{i}), 84 | switch c{i}, 85 | case {'hexa','hexaU','rect','rectU'}, lattice = c{i}; 86 | case {'sheet','cyl','toroid'}, shape = c{i}; 87 | end 88 | else 89 | msize = c{i}; 90 | end 91 | end 92 | varargout{1} = lattice; 93 | varargout{2} = msize; 94 | varargoutC=3; 95 | nargin_ = nargin+1; 96 | 97 | else 98 | 99 | % should be a lattice (string) 100 | varargout{1}=varargin{1}; 101 | varargoutC=2; 102 | nargin_=nargin; 103 | 104 | end 105 | 106 | for i=2:nargin, varargout{varargoutC+i-2}=varargin{i}; end 107 | 108 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 109 | -------------------------------------------------------------------------------- /somtoolbox/som/som_stats_report.m: -------------------------------------------------------------------------------- 1 | function som_stats_report(csS,fname,fmt,texonly) 2 | 3 | % SOM_STATS_REPORT Make report of the statistics. 4 | % 5 | % som_stats_report(csS, fname, fmt, [standalone]) 6 | % 7 | % som_stats_report(csS, 'data_stats', 'ps') 8 | % 9 | % Input and output arguments ([]'s are optional): 10 | % csS (cell array) of statistics structs 11 | % (struct) a statistics struct 12 | % fname (string) output file name (without extension) 13 | % (cellstr) {direc, fname} 14 | % fmt (string) report format: 'ps', 'pdf', 'html' or 'txt' 15 | % [texonly] (any) for 'ps' and 'pdf' formats: if 4th argument 16 | % is given, only the tex file is written 17 | % (w/o document start/end), and it is not compiled 18 | % 19 | % See also SOM_STATS, SOM_STATS_PLOT, SOM_STATS_TABLE, SOM_TABLE_PRINT, REP_UTILS. 20 | 21 | % Contributed to SOM Toolbox 2.0, December 31st, 2001 by Juha Vesanto 22 | % Copyright (c) by Juha Vesanto 23 | % http://www.cis.hut.fi/projects/somtoolbox/ 24 | 25 | % Version 2.0beta juuso 311201 26 | 27 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 28 | %% input arguments 29 | 30 | if isstruct(csS), csS = {csS}; end 31 | dim = length(csS); 32 | if iscell(fname), direc = fname{1}; fname = fname{2}; else direc = '.'; end 33 | if nargin<4, texonly = 0; else texonly = 1; end 34 | 35 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 36 | %% action 37 | 38 | % additional analysis 39 | continuity = zeros(dim,1); 40 | for i=1:dim, continuity(i) = csS{i}.nunique / csS{i}.nvalid; end 41 | 42 | entropy_rel = zeros(dim,1); 43 | for i=1:dim, 44 | c = csS{i}.hist.counts; 45 | if length(c) < 2 || all(c==0), entropy(i) = 0; 46 | else 47 | maxent = log(length(c)); 48 | c = c(c>0)/sum(c); 49 | entropy_rel(i) = -sum(c.*log(c)) / maxent; 50 | end 51 | end 52 | 53 | % meta-statistics 54 | values = {'Number of variables',dim; ... 55 | 'Number of samples',csS{1}.ntotal; ... 56 | 'Valid values',c_and_p_str(count_total(csS,'nvalid'),dim*csS{1}.ntotal); ... 57 | 'Mean(#unique / #valid)',mean(continuity); ... 58 | 'Mean relative entropy',mean(entropy_rel)}; 59 | %'Dataset name',sD.name; 'Report generated',datestr(now); 60 | sTdset = som_table_struct(values); 61 | 62 | % statistics tables 63 | [sTstats,csThist] = som_stats_table(csS); 64 | sTstats = som_table_modify(sTstats,'addcol',entropy_rel,{'entropy'}); 65 | 66 | % write report 67 | if isempty(fname), fid = 1; 68 | else 69 | switch fmt, 70 | case {'ps','pdf'}, ending = '.tex'; 71 | case 'html', ending = '.html'; 72 | case 'txt', ending = '.txt'; 73 | end 74 | fid = fopen([direc '/' fname ending],'w'); 75 | end 76 | if ~texonly, rep_utils('header',fmt,fid); end 77 | 78 | rep_utils({'inserttable',sTdset,1,0},fmt,fid); 79 | rep_utils({'insertbreak'},fmt,fid); 80 | rep_utils({'inserttable',sTstats,1,0},fmt,fid); 81 | rep_utils({'insertbreak'},fmt,fid); 82 | som_stats_plot(csS,'stats'); 83 | rep_utils({'printfigure',[direc '/histograms']},fmt); 84 | rep_utils({'insertfigure','histograms'},fmt,fid); 85 | for i=1:dim, 86 | rep_utils({'insertbreak'},fmt,fid); 87 | rep_utils({'inserttable',csThist{i},1,0},fmt,fid); 88 | end 89 | 90 | if ~texonly, rep_utils('footer',fmt,fid); end 91 | if fid~=1, fclose(fid); end 92 | 93 | if ~texonly && any(strcmp(fmt,{'ps','pdf'})), rep_utils('compile',fmt); end 94 | return; 95 | 96 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 97 | %% subfunctions 98 | 99 | function a = count_total(csS,field) 100 | % count total of the field values 101 | a = 0; for i=1:length(csS), a = a + getfield(csS{i},field); end 102 | return; 103 | 104 | function str = c_and_p_str(n,m) 105 | % return a string of form # (%), e.g. '23 (12%)' 106 | if n==m, p = '100'; 107 | elseif n==0, p = '0'; 108 | else p = sprintf('%.2g',100*n/m); 109 | end 110 | str = sprintf('%d (%s%%)',round(n),p); 111 | return; 112 | 113 | 114 | -------------------------------------------------------------------------------- /somtoolbox/som/som_stats_table.m: -------------------------------------------------------------------------------- 1 | function [sTstats,csThist] = som_stats_table(csS,histlabel) 2 | 3 | %SOM_STATS_TABLE Statistics table. 4 | % 5 | % [sTstats,csThist] = som_stats_table(csS) 6 | % 7 | % sTstats = som_stats_table(csS); 8 | % som_table_print(sTstats); 9 | % 10 | % Input and output arguments ([]'s are optional): 11 | % csS (cell array) of statistics structs 12 | % (struct) a statistics struct 13 | % 14 | % sTstats (struct) a table struct with basic descriptive 15 | % statistics for each variable 16 | % csThist (cell array) of table structs, with histograms for 17 | % each variable 18 | % 19 | % See also SOM_STATS, SOM_STATS_PLOT, SOM_TABLE_PRINT, SOM_STATS_REPORT. 20 | 21 | % Contributed to SOM Toolbox 2.0, December 31st, 2001 by Juha Vesanto 22 | % Copyright (c) by Juha Vesanto 23 | % http://www.cis.hut.fi/projects/somtoolbox/ 24 | 25 | % Version 2.0beta juuso 311201 26 | 27 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 28 | %% arguments 29 | 30 | if isstruct(csS), csS = {csS}; end 31 | dim = length(csS); 32 | 33 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%5 34 | %% action 35 | 36 | sTable = struct('colfmt','','headers',[],'values',[],'span',[]); 37 | 38 | % summary table of all variables 39 | sT = sTable; 40 | sT.headers = {'name','min','mean','max','std','missing'}; 41 | if ~isnan(csS{1}.nunique), sT.headers{end+1} = 'unique'; end 42 | %if length(col_values), sT.headers = [sT.headers, col_headers]; end 43 | sT.values = cell(dim,length(sT.headers)); 44 | sT.span = ones([size(sT.values) 2]); 45 | 46 | %if length(col_values), sT.values(:,end-size(col_values,2)+1:end) = col_values; end 47 | %if length(col_spans), sT.span(:,end-size(col_spans,2)+1:end,:) = col_spans; end 48 | 49 | for i=1:dim, 50 | sT.values{i,1} = csS{i}.name; 51 | v = [csS{i}.min,csS{i}.mean,csS{i}.max,csS{i}.std]; 52 | v = som_denormalize(v,csS{i}.normalization); 53 | vstr = numtostring(v,6); 54 | sT.values(i,2:5) = vstr'; 55 | sT.values{i,6} = c_and_p_str(csS{i}.ntotal-csS{i}.nvalid,csS{i}.ntotal); 56 | if ~isnan(csS{1}.nunique), 57 | sT.values{i,7} = c_and_p_str(csS{i}.nunique,csS{i}.nvalid); 58 | end 59 | end 60 | sTstats = sT; 61 | 62 | % histograms 63 | csThist = cell(dim,1); 64 | for i=1:dim, 65 | sH = csS{i}.hist; 66 | nvalid = csS{i}.nvalid; 67 | nbins = length(sH.bins); 68 | sT = sTable; 69 | sT.headers = {[csS{i}.name ' values'],'frequency #','frequency %'}; 70 | sT.values = cell(nbins,length(sT.headers)); 71 | sT.span = ones(nbins,length(sT.headers),2); 72 | for j=1:nbins, 73 | if length(sH.bins) < csS{i}.nunique, sT.values{j,1} = sH.binlabels2{j}; 74 | else sT.values{j,1} = sH.binlabels{j}; end 75 | sT.values{j,2} = sprintf('%d',round(sH.counts(j))); 76 | sT.values{j,3} = p_str(sH.counts(j)/nvalid); 77 | end 78 | csThist{i} = sT; 79 | end 80 | 81 | return; 82 | 83 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%5 84 | %% subfunctions 85 | 86 | function vstr = numtostring(v,d) 87 | 88 | tp = (size(v,2)>1); 89 | if tp, v = v'; end 90 | nearzero = (abs(v)/(max(v)-min(v)) < 10.^-d); 91 | i1 = find(v > 0 & nearzero); 92 | i2 = find(v < 0 & nearzero); 93 | vstr = strrep(cellstr(num2str(v,d)),' ',''); 94 | vstr(i1) = {'0.0'}; 95 | vstr(i2) = {'-0.0'}; 96 | if tp, vstr = vstr'; end 97 | return; 98 | 99 | function str = c_and_p_str(n,m) 100 | % return a string of form # (%), e.g. '23 (12%)' 101 | if n==m, p = '100'; 102 | elseif n==0, p = '0'; 103 | else p = sprintf('%.2g',100*n/m); 104 | end 105 | str = sprintf('%d (%s%%)',round(n),p); 106 | return; 107 | 108 | function str = p_str(p) 109 | % return a string of form %, e.g. '12%' 110 | if round(p*100)>100, p = sprintf('%3g',100*p); 111 | elseif p==1, p = '100'; 112 | elseif abs(p)1 && ~isempty(D), 30 | if isstruct(D), D = D.data; end 31 | bmus = som_bmus(sM,D); 32 | else D = []; bmus = []; 33 | end 34 | 35 | % Col 36 | if nargin<3 || isempty(Col), Col = som_colorcode(sM); end 37 | if ischar(Col), Col = som_colorcode(sM,Col); end 38 | 39 | % comps 40 | if nargin<4 || isempty(comps), comps = 1:dim; end 41 | n = length(comps)+1; 42 | 43 | % histogram bins 44 | if ~isempty(D), C=D; else C=M; end 45 | cHbins = cell(dim,1); 46 | cAxis = cell(dim,1); 47 | for i=1:dim, 48 | if ~isempty(D), mima = [min(D(:,i)),max(D(:,i))]; 49 | else mima = [min(M(:,i)),max(M(:,i))]; 50 | end 51 | cAxis{i} = mima; 52 | [dummy,cHbins{i}] = hist(mima,20); 53 | end 54 | 55 | nt = 4; % number of ticks in scatter plots 56 | 57 | % visualization 58 | clf 59 | for i=1:n, 60 | for j=1:n, 61 | subplot(n,n,(i-1)*n+j); 62 | if j==1 && i==1, 63 | h=som_cplane(sM,Col); set(h,'edgecolor','none') 64 | elseif i==1, 65 | ind = comps(j-1); 66 | b = cHbins{ind}; 67 | hs = hist(M(:,ind),b); 68 | h = bar(b,hs,0.8); set(h,'EdgeColor','none','FaceColor','k'); 69 | axis on, axis tight 70 | set(gca,'XTick',[],'Box','on'); 71 | title(sM.comp_names{ind}); 72 | elseif j==1, 73 | ind = comps(i-1); 74 | if ~isempty(D), 75 | b = cHbins{ind}; 76 | hs = hist(D(:,ind),b); 77 | h = bar(b,hs,0.8); set(h,'EdgeColor','none','FaceColor','k'); 78 | axis on, axis tight 79 | set(gca,'XTick',[],'Box','on'); 80 | ylabel(sM.comp_names{ind}) 81 | else 82 | text(0.5,0.5,sM.comp_names{ind}); 83 | axis off 84 | end 85 | elseif i==j, 86 | ind = comps(i-1); 87 | h=som_cplane(sM,M(:,ind)); 88 | set(h,'edgecolor','none') 89 | a = cAxis{ind}; 90 | caxis(a); v = unique([a, min(M(:,ind)), max(M(:,ind))]); 91 | vn=som_denormalize(v,sM.comp_norm{ind})'; 92 | h=colorbar('vert'); 93 | set(h,'YTick',v,'YTickLabel',cellstr(num2str(vn,2))); 94 | elseif ij, i1 = i-1; i2 = j-1; else i1 = j-1; i2 = i-1; end 96 | ind1 = comps(i1); ind2 = comps(i2); 97 | if i 0 display additonal information 14 | % 15 | % codes (matrix) codebook vectors 16 | % clusters (vector) cluster number for each sample 17 | % err (scalar) total quantization error for the data set 18 | % 19 | % See also KMEANS_CLUSTERS, SOM_MAKE, SOM_BATCHTRAIN, SOM_SEQTRAIN. 20 | 21 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 22 | % Function has been renamed by Kimmo Raivio, because matlab65 also have 23 | % kmeans function 1.10.02 24 | %% input arguments 25 | 26 | if isstruct(D), 27 | switch D.type, 28 | case 'som_map', data = D.codebook; 29 | case 'som_data', data = D.data; 30 | end 31 | else 32 | data = D; 33 | end 34 | [l dim] = size(data); 35 | 36 | if nargin < 4 || isempty(epochs) || isnan(epochs), epochs = 100; end 37 | if nargin < 5, verbose = 0; end 38 | 39 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 40 | %% action 41 | 42 | rand('state', sum(100*clock)); % init rand generator 43 | 44 | lr = 0.5; % learning rate for sequential k-means 45 | temp = randperm(l); 46 | centroids = data(temp(1:k),:); 47 | res = zeros(k,l); 48 | clusters = zeros(1, l); 49 | 50 | if dim==1, 51 | [codes,clusters,err] = scalar_kmeans(data,k,epochs); 52 | return; 53 | end 54 | 55 | switch method 56 | case 'seq', 57 | len = epochs * l; 58 | l_rate = linspace(lr,0,len); 59 | order = randperm(l); 60 | for iter = 1:len 61 | x = D(order(rem(iter,l)+1),:); 62 | dx = x(ones(k,1),:) - centroids; 63 | [dist nearest] = min(sum(dx.^2,2)); 64 | centroids(nearest,:) = centroids(nearest,:) + l_rate(iter)*dx(nearest,:); 65 | end 66 | [dummy clusters] = min(((ones(k, 1) * sum((data.^2)', 1))' + ... 67 | ones(l, 1) * sum((centroids.^2)',1) - ... 68 | 2.*(data*(centroids')))'); 69 | 70 | case 'batch', 71 | iter = 0; 72 | old_clusters = zeros(k, 1); 73 | while iter2, qe = sum(abs(x-y(bm)))/n; end 137 | if any(nans), 138 | notnan = find(~nans); n = length(nans); 139 | y = full(sparse(notnan,1,y ,n,1)); y(nans) = NaN; 140 | bm = full(sparse(notnan,1,bm,n,1)); bm(nans) = NaN; 141 | if nargout>2, qe = full(sparse(notnan,1,qe,n,1)); qe(nans) = NaN; end 142 | end 143 | 144 | return; 145 | 146 | -------------------------------------------------------------------------------- /somtoolbox/som/som_kmeanscolor.m: -------------------------------------------------------------------------------- 1 | function [color,best,kmeans]=som_kmeanscolor(sM,C,initRGB,contrast) 2 | 3 | % SOM_KMEANSCOLOR Map unit color code according to K-means clustering 4 | % 5 | % [color, best, kmeans] = som_kmeanscolor(sM, C, [initRGB],[contrast]) 6 | % 7 | % color = som_kmeanscolor(sM,15,som_colorcode(sM,'rgb1'),'enhance'); 8 | % [color,best] = som_kmeanscolor(sM,15,[],'normal'); 9 | % 10 | % Input and output arguments ([]'s are optional): 11 | % sM (struct) map struct 12 | % C (scalar) maximum number of clusters 13 | % initRGB (string, matrix) color code string accepted by SOM_COLORCODE 14 | % or an Mx3 matrix of RGB triples, where M is the number 15 | % of map units. Default: SOM_COLORCODEs default 16 | % contrast (string) 'flat', 'enhanced' color contrast mode, default: 17 | % 'enhanced' 18 | % 19 | % color (matrix) MxCx3 of RGB triples 20 | % best (scalar) index for "best" clustering according to 21 | % Davies-Boulding index; color(:,:,best) includes the 22 | % corresponding color code. 23 | % kmeans (cell) output of KMEANS_CLUSTERS in a cell array. 24 | % 25 | % The function gives a set of color codings according to K-means 26 | % clustering. For clustering, it uses function KMEANS_CLUSTERS for map units, 27 | % and it calculates color codings for 1,2,...,C clusters. 28 | % The idea of coloring is that the color of a cluster is the mean of the 29 | % original colors (RGB values) of the map units belonging to that cluster, 30 | % see SOM_CLUSTERCOLOR. The original colors are defined by SOM_COLORCODE 31 | % by default. Input 'contrast' simply specifies whether or not 32 | % to linearly redistribute R,G, and B values so that minimum is 0 and 33 | % maximum 1 ('enahanced') or to use directly the output of 34 | % SOM_CLUSTERCOLOR ('flat'). KMEANS_CLUSTERS uses certain heuristics to 35 | % select the best of 5 trials for each number of clusters. Evaluating the 36 | % clustering multiple times may take some time. 37 | % 38 | % EXAMPLE 39 | % 40 | % load iris; % or any other map struct sM 41 | % [color,b]=som_kmeanscolor(sM,10); 42 | % som_show(sM,'color',color,'color',{color(:,:,b),'"Best clustering"'); 43 | % 44 | % See also SOM_SHOW, SOM_COLORCODE, SOM_CLUSTERCOLOR, KMEANS_CLUSTERS 45 | 46 | % Contributed to SOM Toolbox 2.0, April 1st, 2000 by Johan Himberg 47 | % Copyright (c) by Johan Himberg 48 | % http://www.cis.hut.fi/projects/somtoolbox/ 49 | 50 | % corrected help text 11032005 johan 51 | 52 | %%% Check number of inputs 53 | 54 | error(nargchk(2, 4, nargin)); % check no. of input args 55 | 56 | %%% Check input args & set defaults 57 | 58 | if isstruct(sM) && isfield(sM,'type') && strcmp(sM.type,'som_map'), 59 | [tmp,lattice,msize]=vis_planeGetArgs(sM); 60 | munits=prod(msize); 61 | if length(msize)>2 62 | error('Does not work with 3D maps.') 63 | end 64 | else 65 | error('Map struct requires for first input argument!'); 66 | end 67 | 68 | if ~vis_valuetype(C,{'1x1'}), 69 | error('Scalar value expect for maximum number of clusters.'); 70 | end 71 | 72 | % check initial color coding 73 | if nargin<3 || isempty(initRGB) 74 | initRGB=som_colorcode(sM); 75 | end 76 | 77 | % check contrast checking 78 | if nargin<4 || isempty(contrast), 79 | contrast='enhanced'; 80 | end 81 | 82 | if ~ischar(contrast), 83 | error('String input expected for input arg. ''contrast''.'); 84 | else 85 | switch lower(contrast) 86 | case {'flat','enhanced'} 87 | otherwise 88 | error(['''flat'' or ''enhanced'' expected for '... 89 | 'input argument ''contrast''.']); 90 | end 91 | end 92 | 93 | if ischar(initRGB), 94 | try 95 | initRGB=som_colorcode(sM,initRGB); 96 | catch 97 | error(['Color code ' initRGB ... 98 | 'was not recognized by SOM_COLORCODE.']); 99 | end 100 | elseif vis_valuetype(initRGB,{'nx3rgb',[munits 3]},'all'), 101 | else 102 | error(['The initial color code must be a string '... 103 | 'or an Mx3 matrix of RGB triples.']); 104 | end 105 | 106 | %%% Action %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 107 | 108 | disp('Wait...'); 109 | [c,p,err,ind]=kmeans_clusters(sM,C,5,0); % use 5 trials, verbose off 110 | 111 | % Store outputs to kmeans 112 | kmeans{1}=c; 113 | kmeans{2}=p; 114 | kmeans{3}=err; 115 | kmeans{4}=ind; 116 | 117 | %%% Build output 118 | color=som_clustercolor(sM,cat(2,p{:}),initRGB); 119 | [tmp,best]=min(ind); 120 | 121 | switch contrast 122 | case 'flat' 123 | case 'enhanced' 124 | warning off; 125 | ncolor=maxnorm(color); 126 | ncolor(~isfinite(ncolor))=color(~isfinite(ncolor)); 127 | color=ncolor; 128 | warning on; 129 | end 130 | 131 | %%% Subfunctions %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 132 | function X=maxnorm(x) 133 | % normalize columns of x between [0,1] 134 | 135 | x=x-repmat(min(x),[size(x,1) 1 1]); 136 | X=x./repmat(max(x),[size(x,1) 1 1]); 137 | -------------------------------------------------------------------------------- /lib/smoothts.m: -------------------------------------------------------------------------------- 1 | function vout = smoothts(vin, smethod, wsize, extarg) 2 | %SMOOTHTS smoothes a matrix of data using a specified method. 3 | % 4 | % VOUT = SMOOTHTS(VIN, SMETHOD, WSIZE, EXTARG) 5 | % 6 | % SMOOTHTS, using the specified method, will smooth the data 7 | % contained in a row-oriented matrix. Valid smoothing methods 8 | % (SMETHOD) are Exponential (e), Gaussian (g) or Box (b). Valid 9 | % SMETHOD's are in parentheses. A row-oriented matrix is one 10 | % where each row is a variable and each column is an observation 11 | % for the specific variable. 12 | % 13 | % VOUT = SMOOTHTS(VIN) smoothes the matrix VIN using the default 14 | % Box method with window size, WSIZE, of 5. 15 | % 16 | % VOUT = SMOOTHTS(VIN, 'b', WSIZE) smoothes the input matrix VIN 17 | % using the Box (simple, linear) method. WSIZE is an optional 18 | % integer (scalar) argument that specifies the width of the box 19 | % to be used. If WSIZE is not supplied, the default is 5. 20 | % 21 | % VOUT = SMOOTHTS(VIN, 'g', WSIZE, STDEV) smoothes the input matrix 22 | % VIN using Gaussian Window method. WSIZE and STDEV are optional 23 | % input arguments. WZISE is an integer (scalar) that specifies the 24 | % size of the windows used. STDEV is a scalar that represents the 25 | % standard deviation of the Gaussian Window. If WSIZE and STDEV are 26 | % not supplied the defaults are 5 and 0.65, respectively. 27 | % 28 | % VOUT = SMOOTHTS(VIN, 'e', WSIZE_OR_ALPHA) smoothes the input 29 | % matrix VIN using Exponential method. WZISE_OR_ALPHA is a value 30 | % that can specify either the window size (WSIZE) or exponential 31 | % factor (ALPHA). If WSIZE_OR_ALPHA is an integer greater than 1, 32 | % it is considered as the window size (WSIZE); however, if it is 33 | % between 0 and 1, it is considered as ALPHA, the exponential factor. 34 | % When it is 1, the effect is the same whether it is regarded as 35 | % WSIZE or ALPHA. If WSIZE_OR_ALPHA is not supplied the default 36 | % is WSIZE = 5 (thus, ALPHA = 0.3333). 37 | % 38 | % VOUT is always a row-oriented matrix of the same length as VIN. 39 | % 40 | % See also TSMOVAVG. 41 | 42 | % Copyright 1995-2005 The MathWorks, Inc. 43 | % $Revision: 1.1.6.5 $ $Date: 2012/08/21 00:14:33 $ 44 | 45 | switch nargin 46 | case 1 47 | smethod = 'b'; 48 | wsize = 5; 49 | case 2 50 | if isempty(smethod) 51 | smethod = 'b'; 52 | end 53 | wsize = 5; 54 | case {3, 4} 55 | if isempty(smethod) 56 | smethod = 'b'; 57 | end 58 | if isempty(wsize) 59 | wsize = 5; 60 | end 61 | otherwise 62 | error(message('finance:ftseries:ftseries_smoothts:InvalidNumberOfInputArguments')); 63 | end 64 | 65 | if any(double(wsize < 0)) | (prod(size(wsize)) ~= 1) 66 | error(message('finance:ftseries:ftseries_smoothts:WSIZEMustBePosScalar')); 67 | elseif length(wsize) == 1 68 | wsize = [1 wsize]; 69 | end 70 | 71 | overshoots = floor(wsize(2)/2); 72 | if overshoots*2 == wsize(2) 73 | downshoot = overshoots-1; 74 | upshoot = overshoots; 75 | else 76 | downshoot = overshoots; 77 | upshoot = overshoots; 78 | end 79 | 80 | vout = vin; 81 | switch lower(smethod(1)) 82 | case 'b' 83 | if nargin == 3 84 | if isempty(wsize) 85 | wsize = [1 5]; 86 | end 87 | elseif nargin == 4 88 | error(message('finance:ftseries:ftseries_smoothts:TooManyInputArguments')); 89 | end 90 | smoothfilt = ones(wsize) ./ prod(wsize); 91 | for hdx = 1:size(vin, 1) 92 | tvout = conv(vin(hdx, :), smoothfilt); 93 | vout(hdx, :) = tvout(downshoot+1:length(tvout)-upshoot); 94 | end 95 | case 'g' 96 | if nargin == 2 97 | extarg = 0.65; 98 | elseif nargin == 3 99 | if isempty(wsize) 100 | wsize = [1 5]; 101 | end 102 | extarg = 0.65; 103 | elseif nargin == 4 104 | if isempty(extarg) 105 | extarg = 0.65; 106 | end 107 | end 108 | x = -(wsize(2)-1)/2:(wsize(2)-1)/2; 109 | smoothfilt = exp(-(x.*x)/(2*extarg)); 110 | smoothfilt = smoothfilt/sum(smoothfilt(:)); 111 | for hdx = 1:size(vin, 1) 112 | tvout = conv(vin(hdx, :), smoothfilt); 113 | vout(hdx, :) = tvout(downshoot+1:length(tvout)-upshoot); 114 | end 115 | case 'e' 116 | if nargin == 2 117 | extarg = 2/(wsize + 1); 118 | elseif nargin == 3 119 | if isempty(wsize) 120 | wsize = [1 5]; 121 | end 122 | if wsize(2) > 1 123 | extarg = 2 / (wsize(2) + 1); 124 | elseif wsize(2) <= 1 125 | extarg = wsize(2); 126 | end 127 | elseif nargin == 4 128 | error(message('finance:ftseries:ftseries_smoothts:TooManyInputArguments')); 129 | end 130 | vout = vin; 131 | for idx = 2:size(vin,2) 132 | vout(:, idx) = extarg.*vin(:, idx) + (1-extarg).*vout(:, idx-1); 133 | end 134 | otherwise 135 | error(message('finance:ftseries:ftseries_smoothts:InvalidSmoothingMethod')); 136 | end 137 | 138 | % [EOF] 139 | -------------------------------------------------------------------------------- /somtoolbox/som/som_distortion.m: -------------------------------------------------------------------------------- 1 | function [adm,admu,tdmu] = som_distortion(sM, D, arg1, arg2) 2 | 3 | %SOM_DISTORTION Calculate distortion measure for the map. 4 | % 5 | % [adm,admu,tdmu] = som_distortion(sMap, D, [radius], ['prob']) 6 | % 7 | % adm = som_distortion(sMap,D); 8 | % [adm,admu] = som_distortion(sMap,D); 9 | % som_show(sMap,'color',admu); 10 | % 11 | % Input and output arguments: 12 | % sMap (struct) a map struct 13 | % D (struct) a data struct 14 | % (matrix) size dlen x dim, a data matrix 15 | % [radius] (scalar) neighborhood function radius to be used. 16 | % Defaults to the last radius_fin in the 17 | % trainhist field of the map struct, or 1 if 18 | % that is missing. 19 | % ['prob'] (string) If given, this argument forces the 20 | % neigborhood function values for each map 21 | % unit to be normalized so that they sum to 1. 22 | % 23 | % adm (scalar) average distortion measure (sum(dm)/dlen) 24 | % admu (vector) size munits x 1, average distortion in each unit 25 | % tdmu (vector) size munits x 1, total distortion for each unit 26 | % 27 | % The distortion measure is defined as: 28 | % 2 29 | % E = sum sum h(bmu(i),j) ||m(j) - x(i)|| 30 | % i j 31 | % 32 | % where m(i) is the ith prototype vector of SOM, x(j) is the jth data 33 | % vector, and h(.,.) is the neighborhood function. In case of fixed 34 | % neighborhood and discreet data, the distortion measure can be 35 | % interpreted as the energy function of the SOM. Note, though, that 36 | % the learning rule that follows from the distortion measure is 37 | % different from the SOM training rule, so SOM only minimizes the 38 | % distortion measure approximately. 39 | % 40 | % If the 'prob' argument is given, the distortion measure can be 41 | % interpreted as an expected quantization error when the neighborhood 42 | % function values give the likelyhoods of accidentally assigning 43 | % vector j to unit i. The normal quantization error is a special case 44 | % of this with zero incorrect assignement likelihood. 45 | % 46 | % NOTE: when calculating BMUs and distances, the mask of the given 47 | % map is used. 48 | % 49 | % See also SOM_QUALITY, SOM_BMUS, SOM_HITS. 50 | 51 | % Reference: Kohonen, T., "Self-Organizing Map", 2nd ed., 52 | % Springer-Verlag, Berlin, 1995, pp. 120-121. 53 | % 54 | % Graepel, T., Burger, M. and Obermayer, K., 55 | % "Phase Transitions in Stochastic Self-Organizing Maps", 56 | % Physical Review E, Vol 56, No 4, pp. 3876-3890 (1997). 57 | 58 | % Contributed to SOM Toolbox vs2, Feb 3rd, 2000 by Juha Vesanto 59 | % Copyright (c) by Juha Vesanto 60 | % http://www.cis.hut.fi/projects/somtoolbox/ 61 | 62 | % Version 2.0beta juuso 030200 63 | 64 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 65 | %% check arguments 66 | 67 | % input arguments 68 | if nargin < 2, error('Not enough input arguments.'); end 69 | 70 | % map 71 | M = sM.codebook; 72 | munits = prod(sM.topol.msize); 73 | 74 | % data 75 | if isstruct(D), D = D.data; end 76 | [dlen dim] = size(D); 77 | 78 | % arg1, arg2 79 | rad = NaN; 80 | normalize = 0; 81 | if nargin>2, 82 | if isnumeric(arg1), rad = arg1; 83 | elseif ischar(arg1) && strcmp(arg1,'prob'), normalize = 0; 84 | end 85 | end 86 | if nargin>3, 87 | if isnumeric(arg2), rad = arg2; 88 | elseif ischar(arg2) && strcmp(arg2,'prob'), normalize = 0; 89 | end 90 | end 91 | 92 | % neighborhood radius 93 | if isempty(rad) || isnan(rad), 94 | if ~isempty(sM.trainhist), rad = sM.trainhist(end).radius_fin; 95 | else rad = 1; 96 | end 97 | end 98 | if rad0); 129 | admu(ind) = admu(ind) ./ hits(ind); 130 | 131 | % average distortion measure 132 | adm = sum(tdmu)/dlen; 133 | 134 | return; 135 | 136 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 137 | 138 | 139 | -------------------------------------------------------------------------------- /somtoolbox/som/som_prototrain.m: -------------------------------------------------------------------------------- 1 | function [sM,sTrain] = som_prototrain(sM, D) 2 | 3 | %SOM_PROTOTRAIN Use sequential algorithm to train the Self-Organizing Map. 4 | % 5 | % [sM,sT] = som_prototrain(sM, D) 6 | % 7 | % sM = som_prototrain(sM,D); 8 | % 9 | % Input and output arguments: 10 | % sM (struct) map struct, the trained and updated map is returned 11 | % (matrix) codebook matrix of a self-organizing map 12 | % size munits x dim or msize(1) x ... x msize(k) x dim 13 | % The trained map codebook is returned. 14 | % D (struct) training data; data struct 15 | % (matrix) training data, size dlen x dim 16 | % 17 | % This function is otherwise just like SOM_SEQTRAIN except that 18 | % the implementation of the sequential training algorithm is very 19 | % straightforward (and slower). This should make it easy for you 20 | % to modify the algorithm, if you want to. 21 | % 22 | % For help on input and output parameters, try 23 | % 'type som_prototrain' or check out the help for SOM_SEQTRAIN. 24 | % See also SOM_SEQTRAIN, SOM_BATCHTRAIN. 25 | 26 | % Contributed to SOM Toolbox vs2, February 2nd, 2000 by Juha Vesanto 27 | % http://www.cis.hut.fi/projects/somtoolbox/ 28 | 29 | % Version 2.0beta juuso 080200 130300 30 | 31 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 32 | %% Check input arguments 33 | 34 | % map 35 | struct_mode = isstruct(sM); 36 | if struct_mode, 37 | M = sM.codebook; 38 | sTopol = sM.topol; 39 | mask = sM.mask; 40 | msize = sTopol.msize; 41 | neigh = sM.neigh; 42 | else 43 | M = sM; orig_size = size(M); 44 | if ndims(sM) > 2, 45 | si = size(sM); dim = si(end); msize = si(1:end-1); 46 | M = reshape(sM,[prod(msize) dim]); 47 | else 48 | msize = [orig_size(1) 1]; dim = orig_size(2); 49 | end 50 | sM = som_map_struct(dim,'msize',msize); sTopol = sM.topol; 51 | mask = ones(dim,1); 52 | neigh = 'gaussian'; 53 | end 54 | [munits dim] = size(M); 55 | 56 | % data 57 | if isstruct(D), data_name = D.name; D = D.data; 58 | else data_name = inputname(2); 59 | end 60 | D = D(find(sum(isnan(D),2) < dim),:); % remove empty vectors from the data 61 | [dlen ddim] = size(D); % check input dimension 62 | if dim ~= ddim, error('Map and data input space dimensions disagree.'); end 63 | 64 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 65 | %% initialize (these are default values, change as you will) 66 | 67 | % training length 68 | trainlen = 20*dlen; % 20 epochs by default 69 | 70 | % neighborhood radius 71 | radius_type = 'linear'; 72 | rini = max(msize)/2; 73 | rfin = 1; 74 | 75 | % learning rate 76 | alpha_type = 'inv'; 77 | alpha_ini = 0.2; 78 | 79 | % initialize random number generator 80 | rand('state',sum(100*clock)); 81 | 82 | % tracking 83 | start = clock; trackstep = 100; 84 | 85 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 86 | %% Action 87 | 88 | Ud = som_unit_dists(sTopol); % distance between map units on the grid 89 | mu_x_1 = ones(munits,1); % this is used pretty often 90 | 91 | for t = 1:trainlen, 92 | 93 | %% find BMU 94 | ind = ceil(dlen*rand(1)+eps); % select one vector 95 | x = D(ind,:); % pick it up 96 | known = ~isnan(x); % its known components 97 | Dx = M(:,known) - x(mu_x_1,known); % each map unit minus the vector 98 | dist2 = (Dx.^2)*mask(known); % squared distances 99 | [qerr bmu] = min(dist2); % find BMU 100 | 101 | %% neighborhood 102 | switch radius_type, % radius 103 | case 'linear', r = rini+(rfin-rini)*(t-1)/(trainlen-1); 104 | end 105 | if ~r, r=eps; end % zero neighborhood radius may cause div-by-zero error 106 | switch neigh, % neighborhood function 107 | case 'bubble', h = (Ud(:,bmu) <= r); 108 | case 'gaussian', h = exp(-(Ud(:,bmu).^2)/(2*r*r)); 109 | case 'cutgauss', h = exp(-(Ud(:,bmu).^2)/(2*r*r)) .* (Ud(:,bmu) <= r); 110 | case 'ep', h = (1 - (Ud(:,bmu).^2)/(r*r)) .* (Ud(:,bmu) <= r); 111 | end 112 | 113 | %% learning rate 114 | switch alpha_type, 115 | case 'linear', a = (1-t/trainlen)*alpha_ini; 116 | case 'inv', a = alpha_ini / (1 + 99*(t-1)/(trainlen-1)); 117 | case 'power', a = alpha_ini * (0.005/alpha_ini)^((t-1)/trainlen); 118 | end 119 | 120 | %% update 121 | M(:,known) = M(:,known) - a*h(:,ones(sum(known),1)).*Dx; 122 | 123 | %% tracking 124 | if t==1 || ~rem(t,trackstep), 125 | elap_t = etime(clock,start); tot_t = elap_t*trainlen/t; 126 | fprintf(1,'\rTraining: %3.0f/ %3.0f s',elap_t,tot_t) 127 | end 128 | 129 | end; % for t = 1:trainlen 130 | fprintf(1,'\n'); 131 | 132 | % outputs 133 | sTrain = som_set('som_train','algorithm','proto',... 134 | 'data_name',data_name,... 135 | 'neigh',neigh,... 136 | 'mask',mask,... 137 | 'radius_ini',rini,... 138 | 'radius_fin',rfin,... 139 | 'alpha_ini',alpha_ini,... 140 | 'alpha_type',alpha_type,... 141 | 'trainlen',trainlen,... 142 | 'time',datestr(now,0)); 143 | 144 | if struct_mode, 145 | sM = som_set(sM,'codebook',M,'mask',mask,'neigh',neigh); 146 | sM.trainhist(end+1) = sTrain; 147 | else 148 | sM = reshape(M,orig_size); 149 | end 150 | 151 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 152 | 153 | 154 | 155 | 156 | -------------------------------------------------------------------------------- /lib/SOMPredict.m: -------------------------------------------------------------------------------- 1 | % ========================================================================= 2 | % sinc(i) - http://fich.unl.edu.ar/sinc/ 3 | % Copyright 2017 Leandro Bugnon 4 | % lbugnon@sinc.unl.edu.ar 5 | % ========================================================================= 6 | % Methods for prediction using supervised self-organization maps (sSOM). 7 | function [outputs]=SOMPredict(testData,model,parameters,varargin) 8 | 9 | outputs={}; 10 | 11 | for p=1:length(parameters) 12 | switch parameters(p).name 13 | case 'maxNBMUs' 14 | maxNBMUs=parameters(p).val; 15 | case 'lambda' 16 | lambda=parameters(p).val; 17 | end 18 | end 19 | 20 | % Generate struct for testing. Target information is ignored from testData. 21 | [testStruct,ok,msg]=som_set('som_data','data',testData.features,... 22 | 'comp_names',testData.featNames,'comp_norm',cell(1,length(testData.featNames))); 23 | if ~isempty(find(ok==0)) 24 | errorMsg=msg(ok==0) 25 | error(0) 26 | end 27 | 28 | dtargets=model.dtargets; 29 | targetCentroids=model.som.codebook(:,end-dtargets+1:end); 30 | % Discard label information for classification 31 | model.som.codebook=model.som.codebook(:,1:end-dtargets); 32 | model.som.comp_norm=model.som.comp_norm(1:end-dtargets); 33 | model.som.comp_names=model.som.comp_names(1:end-dtargets); 34 | model.som.mask=model.som.mask(1:end-dtargets); 35 | 36 | % Find BMUS =========================================== 37 | % Choose best N BMUs (using test features and trained SOM) 38 | bmus=som_bmus(model.som,testStruct,1:maxNBMUs); 39 | % ========================================================= 40 | 41 | % Predict for each session ======================================== 42 | sessions=unique(testData.sessionLabels(:,1))'; 43 | 44 | for s=1:length(sessions) 45 | 46 | % Session index 47 | sind=testData.sessionLabels{s,2}:testData.sessionLabels{s,3}; 48 | 49 | % Define SOM output based on N BMUs. It has the same dimension of 50 | % targets, and each element contains the l-target for each test frame. 51 | 52 | % Obtain outputs based on weighted bmus. The weights are obtained by 53 | % minimizing distance between the weighted BMUs and the feature 54 | % point. 55 | soutput=zeros(length(sind),size(targetCentroids,2)); 56 | 57 | for n=1:length(sind) % for each frame... 58 | 59 | % Find optimal number N of BMUs to minimize distance in the feature 60 | % space. 61 | bestNbmu=getBestNBMUs(testData.features(sind(n),:),... 62 | model.som.codebook(bmus(sind(n),:),:)); 63 | 64 | soutput(n,:)=getAverageBMUsOutput(testData.features(sind(n),:),... 65 | model.som.codebook(bmus(sind(n),:),:),... 66 | targetCentroids(bmus(sind(n),:),:),bestNbmu); % Continuous value 67 | 68 | 69 | end 70 | 71 | % Desafecting the lambda factor. 72 | soutput=bsxfun(@rdivide,soutput,lambda); 73 | 74 | outputs=[outputs; soutput]; 75 | 76 | end 77 | end 78 | % ========================================================================= 79 | 80 | % ========================================================================= 81 | % Find SOM output for input vector given the set of N best BMUs. Thexs labels 82 | % average is weighted by their respective distances in the feature space. 83 | % features is [1xF], featureCentroids [maxNBMUsxF] and labelCentroids 84 | % [maxNBMUSxL], the N best labels asociated with this sample 85 | function output=getAverageBMUsOutput(features,featureCentroids,labelCentroids,nbmus) 86 | 87 | 88 | invNormDistance=zeros(nbmus,1); 89 | for j=1:nbmus 90 | invNormDistance(j)=norm(features-featureCentroids(j,:))^-1; 91 | end 92 | invNormDistance=invNormDistance/sum(invNormDistance); 93 | 94 | wMean=zeros(1,size(labelCentroids,2)); 95 | for j=1:nbmus 96 | lambda=1; 97 | if nbmus>1 98 | lambda=invNormDistance(j); 99 | end 100 | 101 | wMean=wMean+lambda*labelCentroids(j,:); 102 | end 103 | 104 | output=wMean; 105 | end 106 | % ========================================================================= 107 | 108 | % ========================================================================= 109 | % Find optimal number N of BMUs from SOM based on distance in feature 110 | % space. This is, select N so the weighted average of N-BestMatchingUnits A 111 | % for a given value V minimize norm(A,V), using only the feature space (the 112 | % visible informatino in train and test data). 113 | % maxN define the searching limit, if maxN=1, the algorithm is the classic 114 | % find the BMU. 115 | % This function is for 1 sample. features is [1xF], centroids [maxNBMUsxF] 116 | % are all BMU centroids. 117 | function bestNbmu=getBestNBMUs(features,centroids) 118 | 119 | % Get mean BMUs in features subspace 120 | meanBMUs=centroids; 121 | 122 | % Distance between feat. point and 1:m-BMUs average 123 | avgDistance=zeros(size(centroids,1),1); 124 | for m=size(centroids,1):-1:1 125 | 126 | meanBMUs(m,:)=getAverageBMUsOutput(features,centroids,centroids,m); 127 | 128 | avgDistance(m)=norm( features-mean(meanBMUs(m:-1:1,:))); 129 | end 130 | % Select best nbmu for weighting 131 | [~,bestNbmu]=min(avgDistance); 132 | end 133 | % ========================================================================= 134 | -------------------------------------------------------------------------------- /somtoolbox/som/som_clspread.m: -------------------------------------------------------------------------------- 1 | function base = som_clspread(sM,base,cldist,Ne,verbosity) 2 | 3 | % SOM_CLSPREAD Partition the given data by flooding. 4 | % 5 | % part = som_clspread(sM,part,cldist,[Ne],[verbos]) 6 | % 7 | % Input and output arguments ([]'s are optional): 8 | % sM (struct) map or data struct 9 | % (matrix) size dlen x dim, the data set 10 | % base (vector) initial partition, where if base(i) is 11 | % 0 i should be assigned to some cluster 12 | % NaN i should not be assigned to any cluster 13 | % otherwise i belongs to cluster base(i) 14 | % cldist (string) cluster distance measure: 'single', 'average', 15 | % 'complete', 'neighf', 'ward', 'centroid', 'BMU' 16 | % [Ne] (scalar) 0 = not constrined to neighborhood 17 | % 1 = constrained 18 | % (matrix) size dlen x dlen, indicating possible connections 19 | % [verbos] (scalar) 1 (default) = show status bar 20 | % 0 = don't 21 | % 22 | % See also SOM_CLDIST. 23 | 24 | % Copyright (c) 2000 by Juha Vesanto 25 | % Contributed to SOM Toolbox on XXX by Juha Vesanto 26 | % http://www.cis.hut.fi/projects/somtoolbox/ 27 | 28 | % Version 2.0beta juuso 220800 29 | 30 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 31 | %% input arguments 32 | 33 | q = 2; 34 | 35 | % map/data 36 | if isstruct(sM), 37 | switch sM.type, 38 | case 'som_map', M = sM.codebook; mask = sM.mask; sT = sM.topol; 39 | case 'som_data', M = sM.data; mask = []; sT = []; 40 | end 41 | else M = sM; mask = []; sT = []; 42 | end 43 | [dlen dim] = size(M); 44 | if isempty(mask), mask = ones(dim,1); end 45 | 46 | % simple option 47 | if any(strcmp(cldist,{'closest','BMU'})), 48 | i0 = find(base==0); 49 | i1 = find(base>0); 50 | bmus = som_bmus(M(i1,:),M(i0,:)); 51 | base(i0) = base(i1(bmus)); 52 | return; 53 | end 54 | 55 | % constrained clustering 56 | if nargin<4, Ne = []; end 57 | if numel(Ne)==1, 58 | if Ne && isempty(sT), 59 | warning('Cannot use constrained clustering.'); Ne = 0; 60 | end 61 | if Ne, Ne = som_unit_neighs(sT); else Ne = []; end 62 | end 63 | if ~isempty(Ne), 64 | Ne([0:dlen-1]*dlen+[1:dlen]) = 1; % set diagonal elements = 1 65 | if all(Ne(:)>0), Ne = []; end 66 | end 67 | 68 | if nargin<5, verbosity = 1; end 69 | 70 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 71 | %% initialize 72 | 73 | if size(base,1)==1, base = base'; end 74 | 75 | cid = unique(base(isfinite(base) & base~=0)); % cluster IDs 76 | nc = length(cid); 77 | uind = find(base==0); % unclustered points 78 | nu = length(uind); 79 | if nu==0, return; end 80 | 81 | % initial clusters 82 | clinds = cell(nc,1); for i=1:nc, clinds{i} = find(base==i); end 83 | clinds2 = cell(nu,1); for i=1:nu, clinds2{i} = uind(i); end 84 | 85 | % neighborhood function values 86 | if strcmp(cldist,'neighf') 87 | if isempty(sT), error('Cannot use neighf linkage.'); end 88 | q = som_unit_dists(sT).^2; 89 | r = sM.trainhist(end).radius_fin^2; 90 | if isnan(r) || isempty(r), r = 1; end 91 | switch sM.neigh, 92 | case 'bubble', q = (q <= r); 93 | case 'gaussian', q = exp(-q/(2*r)); 94 | case 'cutgauss', q = exp(-q/(2*r)) .* (q <= r); 95 | case 'ep', q = (1-q/r) .* (q <= r); 96 | end 97 | end 98 | 99 | % distance of each cluster to the unclustered points 100 | if any(strcmp(cldist,{'single','average','complete','neighf'})), 101 | M = som_mdist(M,2,mask,Ne); 102 | end 103 | Cd = som_cldist(M,clinds,clinds2,cldist,q,mask); 104 | 105 | % check out from Ne which of the clusters are not connected 106 | if ~isempty(Ne) && any(strcmp(cldist,{'centroid','ward'})), 107 | Clconn = sparse(nc,nu); 108 | for i=1:nc, for j=1:nu, Clconn(i,j) = any(any(Ne(clinds{i},uind(j)))); end, end 109 | Cd(Clconn==0) = Inf; 110 | else 111 | Clconn = []; 112 | end 113 | 114 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 115 | %% action 116 | 117 | if verbosity, 118 | nu0 = nu; 119 | h = waitbar(1-nu/nu0,'Assigning unclustered points'); % tracking 120 | end 121 | 122 | while 1, 123 | 124 | % find closest unclustered point 125 | [dk,k] = min(Cd,[],2); % min distance from each unclustered point 126 | [d,c] = min(dk); % cluster to which it is assigned 127 | k = k(c); 128 | 129 | if ~isfinite(d), 130 | break; 131 | end 132 | 133 | % add k to cluster c 134 | base(uind(k)) = cid(c); 135 | clinds{c} = [clinds{c}; uind(k)]; 136 | 137 | % remove point k 138 | notk = [1:k-1,k+1:nu]; 139 | nu = nu-1; if nu<=0, break; end 140 | Cd = Cd(:,notk); 141 | uind = uind(notk); 142 | clinds2 = clinds2(notk); 143 | if ~isempty(Clconn), Clconn = Clconn(:,notk); end 144 | 145 | % update cluster distances to c 146 | Cd(c,:) = som_cldist(M,clinds(c),clinds2,cldist,q,mask); 147 | if ~isempty(Clconn), 148 | for j=1:nu, Clconn(c,j) = any(any(Ne(clinds{c},uind(j)))); end 149 | Cd(c,find(Clconn(c,:)==0)) = Inf; 150 | end 151 | 152 | if verbosity, waitbar(1-nu/nu0,h); end % tracking 153 | 154 | end 155 | if verbosity, close(h); end 156 | 157 | return; 158 | 159 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 160 | 161 | 162 | -------------------------------------------------------------------------------- /somtoolbox/som/som_stats_plot.m: -------------------------------------------------------------------------------- 1 | function som_stats_plot(csS,plottype,varargin) 2 | 3 | %SOM_STATS_PLOT Plots of data set statistics. 4 | % 5 | % som_stats_plot(csS, plottype, [argID, value, ...]) 6 | % 7 | % som_stats_plot(csS,'stats') 8 | % som_stats_plot(csS,'stats','p','vert','color','r') 9 | % 10 | % Input and output arguments ([]'s are optional): 11 | % csS (cell array) of statistics structs 12 | % (struct) a statistics struct 13 | % plottype (string) some of the following 14 | % 'hist' histogram 15 | % 'box' min, max, mean, and std shown as a boxplot 16 | % 'stats' both histogram (with black) and the boxplot 17 | % [argID, (string) See below. The values which are unambiguous can 18 | % value] (varies) be given without the preceeding argID. 19 | % 20 | % Here are the valid argument IDs and corresponding values. The values which 21 | % are unambiguous (marked with '*') can be given without the preceeding argID. 22 | % 'counts' *(string) 'c' (for counts, the default) or 'p' (for percentages) 23 | % 'color' (vector) size 1 x 3, color to be used 24 | % (string) a color string 25 | % 'title' (string) 'on' (default) or 'off' 26 | % 'orientation' *(string) 'horiz' or 'vert' (default): orientation for the 27 | % bin values (horizontally or vertically) 28 | % 29 | % See also SOM_STATS, SOM_STATS_TABLE, SOM_TABLE_PRINT, SOM_STATS_REPORT. 30 | 31 | % Contributed to SOM Toolbox 2.0, December 31st, 2001 by Juha Vesanto 32 | % Copyright (c) by Juha Vesanto 33 | % http://www.cis.hut.fi/projects/somtoolbox/ 34 | 35 | % Version 2.0beta juuso 311201 36 | 37 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 38 | %% arguments 39 | 40 | % statistics 41 | if isstruct(csS), csS = {csS}; end 42 | 43 | % default values 44 | useprob = 0; 45 | color = [0 0 1]; 46 | showtitle = 1; 47 | horiz = 0; 48 | 49 | % varargin 50 | i=1; 51 | while i<=length(varargin), 52 | argok = 1; 53 | if ischar(varargin{i}), 54 | switch varargin{i}, 55 | % argument IDs 56 | case 'counts', i=i+1; useprob = strcmp(varargin{i}(1),'p'); 57 | case 'color', i=i+1; color = varargin{i}; 58 | case 'title', i=i+1; showtitle = strcmp(varargin{i},'on'); 59 | case 'orientation', i=i+1; horiz = strcmp(varargin{i},'horiz'); 60 | % unambiguous values 61 | case {'horiz','vert'}, horiz = strcmp(varargin{i},'horiz'); 62 | case {'c','p'}, useprob = strcmp(varargin{i}(1),'p'); 63 | otherwise argok=0; 64 | end 65 | elseif isstruct(varargin{i}) && isfield(varargin{i},'type'), 66 | argok = 0; 67 | else 68 | argok = 0; 69 | end 70 | if ~argok, 71 | disp(['(som_stats_plot) Ignoring invalid argument #' num2str(i+2)]); 72 | end 73 | i = i+1; 74 | end 75 | 76 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%5 77 | %% action 78 | 79 | ss = ceil(sqrt(length(csS))); ss = [ss, ceil(length(csS)/ss)]; 80 | 81 | for j = 1:length(csS), 82 | sS = csS{j}; 83 | subplot(ss(1),ss(2),j); 84 | switch plottype, 85 | case 'stats', 86 | cla, hold on 87 | Counts = sS.hist.counts; 88 | if useprob, for i=1:size(Counts,2), Counts(:,i) = Counts(:,i)/sum(Counts(:,i)); end, end 89 | hist_plot(sS.hist.bins,sS.hist.binlabels,Counts,color); 90 | box_plot(sS.min,sS.max,sS.mean,sS.std,[0 0 0]); 91 | case 'hist', 92 | cla, hold on 93 | Counts = sS.hist.counts; 94 | if useprob, for i=1:size(Counts,2), Counts(:,i) = Counts(:,i)/sum(Counts(:,i)); end, end 95 | hist_plot(sS.hist.bins,sS.hist.binlabels,Counts,color); 96 | case 'box', 97 | cla 98 | box_plot(sS.min,sS.max,sS.mean,sS.std,color); 99 | end 100 | if showtitle, title(sprintf('%s (valid: %d/%d)',sS.name,sS.nvalid,sS.ntotal)); end 101 | if ~horiz, view(90,-90); end 102 | a = axis; a(1) = sS.min; a(2) = sS.max; axis(a); 103 | end 104 | 105 | return; 106 | 107 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%5 108 | %% subfunctions 109 | 110 | function hist_plot(bins,binlabels,Counts,color) 111 | 112 | if nargin<4, color = jet(size(Counts,2)); end 113 | h = bar(bins,Counts); 114 | for j=1:length(h), set(h(j),'facecolor',color(j,:),'edgecolor','none'); end 115 | a = axis; a(3:4) = [0 max(Counts(:))]; axis(a); 116 | set(gca,'XTick',bins,'XTickLabel',binlabels); 117 | return; 118 | 119 | function vstr = numtostring(v,d) 120 | 121 | nearzero = (abs(v)/(max(v)-min(v)) < 10.^-d); 122 | i1 = find(v > 0 & nearzero); 123 | i2 = find(v < 0 & nearzero); 124 | vstr = strrep(cellstr(num2str(v,d)),' ',''); 125 | vstr(i1) = {'0.0'}; 126 | vstr(i2) = {'-0.0'}; 127 | return; 128 | 129 | function box_plot(mi,ma,me,st,Color) 130 | 131 | if nargin < 5, Color = jet(length(mi)); end 132 | a = axis; 133 | y = linspace(a(3),a(4),length(mi)+2); y = y(2:end); 134 | d = (y(2)-y(1))/20; 135 | for i=1:length(mi), 136 | h1 = line([mi(i) ma(i)],[y(i) y(i)]); 137 | h2 = line([mi(i) mi(i) NaN ma(i) ma(i)],[y(i)-d y(i)+d NaN y(i)-d y(i)+d]); 138 | h3 = line([me(i)-st(i) me(i)+st(i)],[y(i) y(i)]); 139 | h4 = line([me(i) me(i)],[y(i)-2*d y(i)+2*d]); 140 | set([h1 h2 h3 h4],'color',Color(i,:)); 141 | set([h1 h2],'linewidth',1); 142 | set([h3 h4],'linewidth',3); 143 | end 144 | return; 145 | -------------------------------------------------------------------------------- /somtoolbox/som/som_show_clear.m: -------------------------------------------------------------------------------- 1 | function som_show_clear(type, p) 2 | 3 | %SOM_SHOW_CLEAR Clear hit marks, labels or trajectories from current figure. 4 | % 5 | % som_show_clear([type], [p]) 6 | % 7 | % som_show_clear 8 | % som_show_clear('Traj',[1 2]) 9 | % 10 | % Input arguments ([]'s are optional): 11 | % [type] (string) which markers to delete (case insensitive) 12 | % 'hit' to remove hit marks 13 | % 'lab' to remove labels 14 | % 'traj' to remove line trajectories 15 | % 'comet' to remove comet trajectories 16 | % 'all' to remove all (the default) 17 | % [p] (vector) subplot number vector 18 | % (string) 'all' for all subplots (the default) 19 | % 20 | % This function removes the objects made by SOM_SHOW_ADD from a 21 | % figure. If no value is given for p, the function operates on every 22 | % axis in the current figure. It simply searches for the objects with 23 | % certain values in the 'Tag' field. It does not matter if the figure 24 | % objects are created by SOM Toolbox -functions or not. However, if 25 | % vector p or string 'all' _is_ given, the figure has to have been 26 | % created by SOM_SHOW. 27 | % 28 | % For more help, try 'type som_show_clear' or check out the helpdesk. 29 | % See also SOM_SHOW_ADD, SOM_SHOW. 30 | 31 | %%%%%%%%% DETAILED DESCRIPTION %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 32 | % 33 | % som_show_clear 34 | % 35 | % PURPOSE 36 | % 37 | % Clear hit marks, labels or trajectories created by SOM_SHOW_ADD 38 | % from the current figure. 39 | % 40 | % SYNTAX 41 | % 42 | % som_show_clear 43 | % som_show_clear([type],[p]) 44 | % 45 | % DESCRIPTION 46 | % 47 | % The function SOM_SHOW_ADD creates some markers on the top of 48 | % visualizations made by SOM_SHOW. These objects may be removed using 49 | % SOM_SHOW_CLEAR even if the object handles are not known. The function 50 | % removes the objects based on certain tags written to the 'Tag' property 51 | % field of the objects. 52 | % 53 | % If the function if called without input arguments it searches for 54 | % every object in the current figure that have string 55 | % 'Hit','Lab','Traj' or 'Comet' in their Tag property field and 56 | % deletes them. 57 | % 58 | % If input argument p is not specified, the function does not check that the 59 | % figure is created by function SOM_SHOW. 60 | % 61 | % OPTIONAL INPUT ARGUMENTS 62 | % 63 | % type (string) Which type of markers to delete 64 | % 'Hit' for removing hit marks 65 | % 'Lab' labels 66 | % 'Traj' line trajectories 67 | % 'Comet' comet trajectories 68 | % 'All' all (the default) 69 | % Strings are case insensitive. 70 | % 71 | % p (vector) Subplots from which the markers are removed 72 | % Specifies the subplots from which the markers are removed. 73 | % The valid values are 1...N where N is the number of subplots. 74 | % It is required that the figure has been created by 75 | % the SOM_SHOW function. 76 | % 77 | % EXAMPLES 78 | % 79 | % som_show_clear; 80 | % % deletes all labels, hit marks and trajectories in the figure 81 | % som_show_clear('hit'); 82 | % % deletes all the hit marks in the current figure 83 | % som_show_clear('lab',[1 2]); 84 | % % deletes labels in SOM_SHOW figure subplots 1 and 2. 85 | % 86 | % SEE ALSO 87 | % 88 | % som_show Basic map visualizations: component planes, u-matrix etc. 89 | % som_show_add Show hits, labels and trajectories on SOM_SHOW visualization. 90 | 91 | % Copyright (c) 1997-2000 by the SOM toolbox programming team. 92 | % http://www.cis.hut.fi/projects/somtoolbox/ 93 | 94 | % Version 1.0beta Johan 061197 95 | % Version 2.0beta Johan 061099 juuso 181199 96 | 97 | %%% Check number of arguments 98 | 99 | error(nargchk(0,2, nargin)) % check no. of input args is correct 100 | 101 | %%% Initialize & check & action %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 102 | 103 | if nargin == 0 || isempty(type) || strcmp(type,'all') % delete everything 104 | % in the gcf 105 | delete(findobj(gcf,'Tag','Hit')); 106 | delete(findobj(gcf, 'Tag','Lab')); 107 | delete(findobj(gcf, 'Tag','Traj')); 108 | delete(findobj(gcf, 'Tag','Comet')); 109 | return 110 | end 111 | 112 | if nargin < 2 || isempty(p) % check handles 113 | handle=gcf; 114 | else % check subplot handles if p is given 115 | [handle,msg]=vis_som_show_data(p,gcf); 116 | if ~isempty(msg) 117 | error('2nd argument invalid or figure not made by SOM_SHOW: try SOM_SHOW_CLEAR without arguments.'); 118 | end 119 | end 120 | 121 | switch lower(type) % check type & make proper tag names 122 | case 'hit' 123 | tag = 'Hit'; 124 | case 'lab' 125 | tag = 'Lab'; 126 | case 'traj' 127 | tag = 'Traj'; 128 | case 'comet' 129 | tag = 'Comet'; 130 | otherwise 131 | error('Invalid object tag. Must be {lab | hit | traj | comet}'); 132 | end 133 | 134 | %%% Action %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 135 | 136 | for i=1:length(handle), 137 | h=findobj(handle(i),'Tag',tag); % find object handles 138 | delete(h); % delete objects 139 | end 140 | 141 | %%% No output %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 142 | 143 | -------------------------------------------------------------------------------- /somtoolbox/som/som_clustercolor.m: -------------------------------------------------------------------------------- 1 | function color=som_clustercolor(m, class, colorcode) 2 | 3 | % SOM_CLUSTERCOLOR Sets map unit coloring according to classification 4 | % 5 | % syntax 1: color = som_clustercolor(m, class, [colorcode]) 6 | % syntax 2: color = som_clustercolor(class, colormatrix) 7 | % 8 | % Input and output arguments ([]'s are optional): 9 | % m (struct) map or topol struct 10 | % (cell array) of form {str,[m1 m2]} where str = 'hexa' 11 | % or 'rect' and [m1 m2] = msize. 12 | % class (matrix) Mxn matrix of integers (class labels) 13 | % where M is the number of map units and each 14 | % column gives some classification for the units. 15 | % colorcode (string) 'rgb1', 'rgb2' (default), 'rgb3', 'rgb4', 'hsv'. 16 | % colormatrix (matrix) Mx3 matrix of RGB triplets giving the 17 | % initial color code for each unit. 18 | % color (matrix) size Mx3xn of RGB triplets giving the 19 | % resulting color code for each unit 20 | % 21 | % The function gives a color coding by class and location for the 22 | % map units. The color is determined by calculating the mean of the 23 | % initial RGB values of units belonging to the same class. 24 | % 25 | % Function has two syntaxes: 26 | % 27 | % * If first argument gives the map topology, i.e. is map or topol struct 28 | % or cell indicating the topology, the initial color coding of the 29 | % units may be given by a string ('rgb1','rgb2','rgb3','rgb4', or 'hsv') 30 | % which describe a predefined coloring scheme. (see SOM_COLORCODE). 31 | % or an initial color matrix of size Mx3 with RGB triplets as rows. 32 | % * Another possibility is to give just the classification vector 33 | % of size Mx1 and an initial color matrix of size Mx3 with RGB 34 | % triplets as rows. 35 | % 36 | % EXAMPLE (requires Matlab Statistics Toolbox) 37 | % 38 | % % Do a 10-cluster single linkage hierachical clustering for SOM units 39 | % class=cluster(linkage(pdist(sM.codebook),'single'),10); 40 | % % Color code the clusters 41 | % C=som_clustercolor(sM, class, 'rgb2'); 42 | % % Visualize 43 | % som_show(sM,'color',C); 44 | % 45 | % See also SOM_COLORCODE, SOM_KMEANSCOLOR, SOM_CPLANE, SOM_SHOW 46 | 47 | % Contributed to SOM Toolbox 2.0, February 11th, 2000 by Johan Himberg 48 | % Copyright (c) by Johan Himberg 49 | % http://www.cis.hut.fi/projects/somtoolbox/ 50 | 51 | % Version 2.0beta Johan 100200 52 | 53 | %%% Check arguments %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 54 | 55 | error(nargchk(2, 3, nargin)); % check no. of input args is correct 56 | 57 | % Check 1s argument 58 | 59 | % Class matrix? 60 | if vis_valuetype(m, {'nxm'}); 61 | colorcode=class; 62 | class=m; 63 | if ~vis_valuetype(colorcode,{'nx3rgb',[size(class,1) 3]},'all'), 64 | error(['If map or topol is not specified the colorcode must be a' ... 65 | ' [size(class,1) 3] sized RGB matrix.']); 66 | end 67 | else 68 | [tmp,ok,tmp]=som_set(m); 69 | if isstruct(m) && all(ok) 70 | switch m.type 71 | case 'som_topol' % topol? 72 | msize=m.msize; 73 | lattice=m.lattice; 74 | case 'som_map' 75 | msize=m.topol.msize; % map? 76 | lattice=m.topol.lattice; 77 | otherwise 78 | error('Invalid map or topol struct.'); 79 | end 80 | % cell? 81 | elseif iscell(m) && vis_valuetype(size(m),{[1 2]}), 82 | if vis_valuetype(m{2},{[1 2]}) && vis_valuetype(m{1},{'string'}), 83 | lattice=m{1}; 84 | msize=m{2}; 85 | else 86 | error('Invalid map size information.'); 87 | end 88 | else 89 | % not known type 90 | error('Invalid first argument!'); 91 | end 92 | % Check map parameters 93 | switch lattice % lattice 94 | case 'hexa' 95 | case 'rect' 96 | otherwise 97 | error('Unknown lattice type'); 98 | end 99 | if length(msize)>2 % dimension 100 | error('Only 2D maps allowed!'); 101 | end 102 | % Check colorcode 103 | if nargin<3 || isempty(colorcode) 104 | colorcode='rgb2'; 105 | end 106 | end 107 | 108 | % Check class 109 | if any(class~=round(class)) 110 | error('Class labels must be integer numbers.'); 111 | end 112 | 113 | if min(class)<=0 114 | error('Class numbers should be greater than 0'); 115 | end 116 | 117 | if ischar(colorcode), 118 | switch colorcode 119 | case{'rgb1','rgb2','rgb3','rgb4','hsv'} 120 | colorcode=som_colorcode(m, colorcode); 121 | otherwise 122 | error(['Color code not known: should be ''rgb1'',''rgb2'',' ... 123 | ' ''rgb3'',''rgb4'' or ''hsv''.']); 124 | end 125 | elseif ~vis_valuetype(colorcode,{'nx3rgb',[size(class,1) 3]},'all'); 126 | error(['Invalid colorcode matrix: should be a ' ... 127 | '[length(class) 3] sized RGB matrix.']); 128 | end 129 | 130 | %% Action %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 131 | 132 | % Go through all i classifications (columns) 133 | for i=1:size(class,2), 134 | % Get unique class labels in ith classification 135 | c=unique(class(:,i))'; % row vector for loop indexing 136 | % Go through all class in ith classification 137 | for j=c; 138 | index=(class(:,i)==j); 139 | N=sum(index); 140 | colors=colorcode(index,:); 141 | % Calculate the mean color 142 | meancolor=repmat(mean(colors,1),N,1); 143 | % Select the original color that is closest to this mean 144 | dist=sum((meancolor-colors).^2,2); 145 | [tmp,min_dist_index]=min(dist); 146 | best_color=repmat(colors(min_dist_index,:),N,1); 147 | % Set the color to output variable 148 | color(index,:,i)=best_color; 149 | end 150 | end 151 | -------------------------------------------------------------------------------- /somtoolbox/som/som_neighborhood.m: -------------------------------------------------------------------------------- 1 | function Ne = som_neighborhood(Ne1,n) 2 | 3 | %SOM_NEIGHBORHOOD Calculate neighborhood matrix. 4 | % 5 | % Ne = som_neighborhood(Ne1,n) 6 | % 7 | % Ne = som_neighborhood(Ne1); 8 | % Ne = som_neighborhood(som_unit_neighs(topol),2); 9 | % 10 | % Input and output arguments ([]'s are optional): 11 | % Ne1 (matrix, size [munits m]) a sparse matrix indicating 12 | % the units in 1-neighborhood for each map unit 13 | % [n] (scalar) maximum neighborhood which is calculated, default=Inf 14 | % 15 | % Ne (matrix, size [munits munits]) neighborhood matrix, 16 | % each row (and column) contains neighborhood 17 | % values from the specific map unit to all other 18 | % map units, or Inf if the value is unknown. 19 | % 20 | % For more help, try 'type som_neighborhood' or check out online documentation. 21 | % See also SOM_UNIT_NEIGHS, SOM_UNIT_DISTS, SOM_UNIT_COORDS, SOM_CONNECTION. 22 | 23 | %%%%%%%%%%%%% DETAILED DESCRIPTION %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 24 | % 25 | % som_neighborhood 26 | % 27 | % PURPOSE 28 | % 29 | % Calculate to which neighborhood each map unit belongs to relative to 30 | % each other map unit, given the units in 1-neighborhood of each unit. 31 | % 32 | % SYNTAX 33 | % 34 | % Ne = som_neighborhood(Ne1); 35 | % Ne = som_neighborhood(Ne1,n); 36 | % 37 | % DESCRIPTION 38 | % 39 | % For each map unit, finds the minimum neighborhood to which it belongs 40 | % to relative to each other map unit. Or, equivalently, for each map 41 | % unit, finds which units form its k-neighborhood, where k goes from 42 | % 0 to n. 43 | % 44 | % The neighborhood is calculated iteratively using the reflexivity of 45 | % neighborhood. 46 | % let N1i be the 1-neighborhood set a unit i 47 | % and let N11i be the set of units in the 1-neighborhood of any unit j in N1i 48 | % then N2i (the 2-neighborhood set of unit i) is N11i \ N1i 49 | % 50 | % Consider, for example, the case of a 5x5 map. The neighborhood in case of 51 | % 'rect' and 'hexa' lattices (and 'sheet' shape) for the unit at the 52 | % center of the map are depicted below: 53 | % 54 | % 'rect' lattice 'hexa' lattice 55 | % -------------- -------------- 56 | % 4 3 2 3 4 3 2 2 2 3 57 | % 3 2 1 2 3 2 1 1 2 3 58 | % 2 1 0 1 2 2 1 0 1 2 59 | % 3 2 1 2 3 2 1 1 2 3 60 | % 4 3 2 3 4 3 2 2 2 3 61 | % 62 | % Because the iterative procedure is rather slow, the neighborhoods 63 | % are calculated upto given maximal value. The uncalculated values 64 | % in the returned matrix are Inf:s. 65 | % 66 | % REQUIRED INPUT ARGUMENTS 67 | % 68 | % Ne1 (matrix) Each row contains 1, if the corresponding unit is adjacent 69 | % for that map unit, 0 otherwise. This can be calculated 70 | % using SOM_UNIT_NEIGHS. The matrix can be sparse. 71 | % Size munits x munits. 72 | % 73 | % OPTIONAL INPUT ARGUMENTS 74 | % 75 | % n (scalar) Maximal neighborhood value which is calculated, 76 | % Inf by default (all neighborhoods). 77 | % 78 | % OUTPUT ARGUMENTS 79 | % 80 | % Ne (matrix) neighborhood values for each map unit, size is 81 | % [munits, munits]. The matrix contains the minimum 82 | % neighborhood of unit i, to which unit j belongs, 83 | % or Inf, if the neighborhood was bigger than n. 84 | % 85 | % EXAMPLES 86 | % 87 | % Ne = som_neighborhood(Ne1,1); % upto 1-neighborhood 88 | % Ne = som_neighborhood(Ne1,Inf); % all neighborhoods 89 | % Ne = som_neighborhood(som_unit_neighs(topol),4); 90 | % 91 | % SEE ALSO 92 | % 93 | % som_unit_neighs Calculate units in 1-neighborhood for each map unit. 94 | % som_unit_coords Calculate grid coordinates. 95 | % som_unit_dists Calculate interunit distances. 96 | % som_connection Connection matrix. 97 | 98 | % Copyright (c) 1999-2000 by the SOM toolbox programming team. 99 | % http://www.cis.hut.fi/projects/somtoolbox/ 100 | 101 | % Version 1.0beta juuso 141097 102 | % Version 2.0beta juuso 101199 103 | 104 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 105 | %% Check arguments 106 | 107 | error(nargchk(1, 2, nargin)); 108 | 109 | if nargin<2, n=Inf; end 110 | 111 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 112 | %% Action 113 | 114 | % initialize 115 | if issparse(Ne1), Ne = full(Ne1); else Ne = Ne1; end 116 | clear Ne1 117 | [munits dummy] = size(Ne); 118 | Ne(find(Ne==0)) = NaN; 119 | for i=1:munits, Ne(i,i)=0; end 120 | 121 | % Calculate neighborhood distance for each unit using reflexsivity 122 | % of neighborhood: 123 | % let N1i be the 1-neighborhood set a unit i 124 | % then N2i is the union of all map units, belonging to the 125 | % 1-neighborhood of any unit j in N1i, not already in N1i 126 | k=1; 127 | if n>1, 128 | fprintf(1,'Calculating neighborhood: 1 '); 129 | N1 = Ne; 130 | N1(find(N1~=1)) = 0; 131 | end 132 | while k1, fprintf(1,'\n'); end 146 | 147 | % finally replace all uncalculated distance values with Inf 148 | Ne(find(isnan(Ne))) = Inf; 149 | 150 | return; 151 | 152 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 153 | %% faster version? 154 | 155 | l = size(Ne1,1); Ne1([0:l-1]*(l+1)+1) = 1; Ne = full(Ne1); M0 = Ne1; k = 2; 156 | while any(Ne(:)==0), M1=(M0*Ne1>0); Ne(find(M1-M0))=k; M0=M1; k=k+1; end 157 | Ne([0:l-1]*(l+1)+1) = 0; 158 | -------------------------------------------------------------------------------- /lib/featureExtraction.m: -------------------------------------------------------------------------------- 1 | % ========================================================================= 2 | % sinc(i) - http://fich.unl.edu.ar/sinc/ 3 | % Copyright 2017 Leandro Bugnon 4 | % lbugnon@sinc.unl.edu.ar 5 | % ========================================================================= 6 | % Feature extraction from HR signal. 7 | function featureExtraction(hrDir,targetDir,outDir) 8 | 9 | sessions={}; 10 | dirs=dir([hrDir]); 11 | for f=1:length(dirs) 12 | if ~dirs(f).isdir 13 | sessions=[sessions; dirs(f).name(1:end-4)]; % remove extension 14 | end 15 | end 16 | 17 | % Constant definitions ======================= 18 | ws=20; 19 | overlap=ws-0.5; 20 | 21 | data=importdata(sprintf('%s%s.csv',hrDir,sessions{1})); 22 | time_phys=data.data(:,1); 23 | fs_phys=(time_phys(2)-time_phys(1))^-1; 24 | 25 | window=ws*fs_phys; 26 | nfft=window; 27 | noverlap=floor(overlap*fs_phys); 28 | % fs/2=N*df/2 => df=fs/N 29 | lfIndex=ceil(window/fs_phys*0.04)+1; 30 | hfIndex=ceil(window/fs_phys*0.15)+1; 31 | hhfIndex=ceil(window/fs_phys*0.5)+1; 32 | fcIndex=ceil(window/fs_phys*40)+1; % Max freq into account 33 | % Bands up to 1 hz 34 | spectBands=round(linspace(1,ceil(window/fs_phys*1)+1,5)); 35 | 36 | featNames={'meanHR','ampHR','skew','kurt','LF','HF','LFHF','totalP',... 37 | 'Pregr3','P0'}; 38 | for f=1:length(spectBands)-1 39 | featNames=[featNames sprintf('P%d',f)]; 40 | end 41 | targetNames={'arousal','valence'}; 42 | % ============================================= 43 | 44 | for s=sessions' 45 | s=s{:}; 46 | fprintf('Subject %s\n',s) 47 | 48 | % Load data and targets ================================================ 49 | filename=sprintf('%s%s.csv',hrDir,s); 50 | data=importdata(filename); 51 | time_phys=data.data(:,1); 52 | fs_phys=(time_phys(2)-time_phys(1))^-1; 53 | 54 | hr=data.data(:,3); 55 | 56 | originalTargets=[]; 57 | originalTimeStamp=[]; 58 | 59 | % Load labels (if available) 60 | for l=1:length(targetNames) 61 | 62 | filename=sprintf('%s%s/%s.arff',targetDir,targetNames{l},s); 63 | try 64 | data=arff_read(filename); 65 | data=squeeze(struct2cell(data)); 66 | originalTargets=[originalTargets cell2mat(data(3,:))']; 67 | if isempty(originalTimeStamp) 68 | originalTimeStamp=cell2mat(data(2,:))'; 69 | fs_targets=(originalTimeStamp(2)-originalTimeStamp(1))^-1; 70 | end 71 | catch 72 | originalTargets=[]; 73 | originalTimeStamp=[]; 74 | fs_targets=[]; 75 | end 76 | end 77 | % ===================================================================== 78 | 79 | % Reflect edges for each session, ws/2 at begining and end of session. 80 | startBorder=hr(1:ws*fs_phys/2); 81 | endBorder=hr(end-ws*fs_phys/2+1:end); 82 | hr=[startBorder(end:-1:1); hr; endBorder(end:-1:1)]; 83 | 84 | % targets for training are reflected as well 85 | targetr=[]; 86 | try 87 | for l=1:length(targetNames) 88 | startBorder=originalTargets(1:ws*fs_targets/2,l); 89 | endBorder=originalTargets(end-ws*fs_targets/2+1:end,l); 90 | targetr=[targetr [startBorder(end:-1:1); originalTargets(:,l); endBorder(end:-1:1)]]; 91 | end 92 | catch 93 | end 94 | % spectrogram 95 | [~,F,~,P]=spectrogram(hr,window,noverlap,nfft,fs_phys,'yaxis'); 96 | % Log scaling 97 | P=log(P); 98 | 99 | % Windowing... 100 | wcenter=window/2; % This is the 0 of original signal 101 | w=1; 102 | 103 | targets=[]; 104 | features=[]; 105 | timeStamp=[]; 106 | sessionLabels=[]; 107 | while wcenter<=length(hr)-window/2 108 | ind=(wcenter-floor(window/2))+1:(wcenter+floor(window/2)); 109 | 110 | x=hr(ind).*hamming(length(ind)); 111 | 112 | % Features in time scale 113 | meanHR=mean(x); 114 | meanHRNoWin=mean(hr(ind)); 115 | ampHR=abs(min(x)-max(x)); 116 | 117 | % High order statistics (maybe more data needed) 118 | skew=skewness(x); 119 | kurt=kurtosis(x); 120 | 121 | LF=sum(P(2:lfIndex,w)); 122 | HF=sum(P(lfIndex:hfIndex,w)); 123 | 124 | LFHF=LF/HF; 125 | totalP=sum(P(:,w)); 126 | P0=P(1,w); 127 | for h=1:length(spectBands)-1 128 | eval(sprintf('P%d=sum(P(spectBands(h):spectBands(h+1),w)/P0);',h)); 129 | end 130 | 131 | % cuadratic regression of spectral power in log scale. 132 | x=log(F(1:fcIndex)+1); 133 | y=P(1:fcIndex,w); 134 | p=polyfit(x,y,2); 135 | Pregr1=p(1); 136 | Pregr2=p(2); 137 | Pregr3=p(3); 138 | 139 | wfeat=zeros(1,length(featNames)); 140 | for f=1:length(wfeat) 141 | eval(sprintf('wfeat(f)=%s;',featNames{f})); 142 | end 143 | 144 | 145 | features=[features; wfeat]; 146 | 147 | % Here we take account of signal reflections, so d=wcenter/fs_phys is 148 | % the origin, and end-d is the end of signal 149 | timeStamp=[timeStamp wcenter/fs_phys-ws/2]; 150 | if length(timeStamp)==2 151 | fs_feat=(timeStamp(2)-timeStamp(1))^-1; 152 | end 153 | sessionLabels=[sessionLabels s]; 154 | 155 | % targets are taken from the center of the window 156 | try 157 | targetInd=ceil(ind(1)/fs_phys*fs_targets):ind(end)/fs_phys*fs_targets; 158 | targets=[targets; targetr(targetInd(end/2),:)]; 159 | catch 160 | end 161 | 162 | wcenter=wcenter+(window-noverlap); 163 | w=w+1; 164 | end 165 | 166 | 167 | 168 | % .mat 169 | if exist('features/')~=7 170 | mkdir('features/') 171 | end 172 | save([outDir,s,'.mat'],'timeStamp','sessionLabels','targetNames',... 173 | 'targets','features','featNames','originalTargets','fs_targets',... 174 | 'originalTimeStamp','fs_feat'); 175 | 176 | 177 | 178 | end 179 | 180 | end 181 | -------------------------------------------------------------------------------- /somtoolbox/som/som_unit_neighs.m: -------------------------------------------------------------------------------- 1 | function Ne1 = som_unit_neighs(topol,lattice,shape) 2 | 3 | %SOM_UNIT_NEIGHS Matrix indicating units in 1-neighborhood for each map unit. 4 | % 5 | % Ne1 = som_unit_neighs(topol,[lattice],[shape]) 6 | % 7 | % Ne1 = som_unit_neighs(sTopol); 8 | % Ne1 = som_unit_neighs(sMap.topol); 9 | % Ne1 = som_unit_neighs([10 4], 'hexa', 'cyl'); 10 | % Ne1 = som_unit_neighs(msize, 'rect', 'toroid'); 11 | % 12 | % Input and output arguments ([]'s are optional): 13 | % topol topology of the SOM grid 14 | % (struct) topology or map struct 15 | % (vector) the 'msize' field of topology struct 16 | % [lattice] (string) map lattice, 'rect' by default 17 | % [shape] (string) map shape, 'sheet' by default 18 | % 19 | % Ne1 (matrix, size [munits munits]) a sparse matrix 20 | % indicating the map units in 1-neighborhood 21 | % by value 1 (note: the unit itself also has value 0) 22 | % 23 | % For more help, try 'type som_unit_neighs' or check out online documentation. 24 | % See also SOM_NEIGHBORHOOD, SOM_UNIT_DISTS, SOM_UNIT_COORDS, SOM_CONNECTION. 25 | 26 | %%%%%%%%%%%%% DETAILED DESCRIPTION %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 27 | % 28 | % som_unit_neighs 29 | % 30 | % PURPOSE 31 | % 32 | % Find the adjacent (in 1-neighborhood) units for each map unit of a SOM 33 | % based on given topology. 34 | % 35 | % SYNTAX 36 | % 37 | % Ne1 = som_unit_neighs(sMap); 38 | % Ne1 = som_unit_neighs(sM.topol); 39 | % Ne1 = som_unit_neighs(msize); 40 | % Ne1 = som_unit_neighs(msize,'hexa'); 41 | % Ne1 = som_unit_neighs(msize,'rect','toroid'); 42 | % 43 | % DESCRIPTION 44 | % 45 | % For each map unit, find the units the distance of which from 46 | % the map unit is equal to 1. The distances are calculated 47 | % along the map grid. Consider, for example, the case of a 4x3 map. 48 | % The unit ('1' to 'C') positions for 'rect' and 'hexa' lattice (and 49 | % 'sheet' shape) are depicted below: 50 | % 51 | % 'rect' lattice 'hexa' lattice 52 | % -------------- -------------- 53 | % 1 5 9 1 5 9 54 | % 2 6 a 2 6 a 55 | % 3 7 b 3 7 b 56 | % 4 8 c 4 8 c 57 | % 58 | % The units in 1-neighborhood (adjacent units) for unit '6' are '2','5','7' 59 | % and 'a' in the 'rect' case and '5','2','7','9','a' and 'b' in the 'hexa' 60 | % case. The function returns a sparse matrix having value 1 for these units. 61 | % Notice that not all units have equal number of neighbors. Unit '1' has only 62 | % units '2' and '5' in its 1-neighborhood. 63 | % 64 | % REQUIRED INPUT ARGUMENTS 65 | % 66 | % topol Map grid dimensions. 67 | % (struct) topology struct or map struct, the topology 68 | % (msize, lattice, shape) of the map is taken from 69 | % the appropriate fields (see e.g. SOM_SET) 70 | % (vector) the vector which gives the size of the map grid 71 | % (msize-field of the topology struct). 72 | % 73 | % OPTIONAL INPUT ARGUMENTS 74 | % 75 | % lattice (string) The map lattice, either 'rect' or 'hexa'. Default 76 | % is 'rect'. 'hexa' can only be used with 1- or 77 | % 2-dimensional map grids. 78 | % shape (string) The map shape, either 'sheet', 'cyl' or 'toroid'. 79 | % Default is 'sheet'. 80 | % 81 | % OUTPUT ARGUMENTS 82 | % 83 | % Ne1 (matrix) sparse matrix indicating units in 1-neighborhood 84 | % by 1, all others have value 0 (including the unit itself!), 85 | % size is [munits munits] 86 | % 87 | % EXAMPLES 88 | % 89 | % Simplest case: 90 | % Ne1 = som_unit_neighs(sTopol); 91 | % Ne1 = som_unit_neighs(sMap.topol); 92 | % Ne1 = som_unit_neighs(msize); 93 | % Ne1 = som_unit_neighs([10 10]); 94 | % 95 | % If topology is given as vector, lattice is 'rect' and shape is 'sheet' 96 | % by default. To change these, you can use the optional arguments: 97 | % Ne1 = som_unit_neighs(msize, 'hexa', 'toroid'); 98 | % 99 | % The neighbors can also be calculated for high-dimensional grids: 100 | % Ne1 = som_unit_neighs([4 4 4 4 4 4]); 101 | % 102 | % SEE ALSO 103 | % 104 | % som_neighborhood Calculate N-neighborhoods of map units. 105 | % som_unit_coords Calculate grid coordinates. 106 | % som_unit_dists Calculate interunit distances. 107 | % som_connection Connection matrix. 108 | 109 | % Copyright (c) 1997-2000 by the SOM toolbox programming team. 110 | % http://www.cis.hut.fi/projects/somtoolbox/ 111 | 112 | % Version 1.0beta juuso 141097 113 | % Version 2.0beta juuso 101199 114 | 115 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 116 | %% Check arguments 117 | 118 | error(nargchk(1, 3, nargin)); 119 | 120 | % default values 121 | sTopol = som_set('som_topol','lattice','rect'); 122 | 123 | % topol 124 | if isstruct(topol), 125 | switch topol.type, 126 | case 'som_map', sTopol = topol.topol; 127 | case 'som_topol', sTopol = topol; 128 | end 129 | elseif iscell(topol), 130 | for i=1:length(topol), 131 | if isnumeric(topol{i}), sTopol.msize = topol{i}; 132 | elseif ischar(topol{i}), 133 | switch topol{i}, 134 | case {'rect','hexa'}, sTopol.lattice = topol{i}; 135 | case {'sheet','cyl','toroid'}, sTopol.shape = topol{i}; 136 | end 137 | end 138 | end 139 | else 140 | sTopol.msize = topol; 141 | end 142 | if prod(sTopol.msize)==0, error('Map size is 0.'); end 143 | 144 | % lattice 145 | if nargin>1 && ~isempty(lattice) && ~isnan(lattice), sTopol.lattice = lattice; end 146 | 147 | % shape 148 | if nargin>2 && ~isempty(shape) && ~isnan(shape), sTopol.shape = shape; end 149 | 150 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 151 | %% Action 152 | 153 | % distances between each map unit 154 | Ud = som_unit_dists(sTopol); 155 | 156 | % 1-neighborhood are those units the distance of which is equal to 1 157 | munits = prod(sTopol.msize); 158 | Ne1 = sparse(zeros(munits)); 159 | for i=1:munits, 160 | inds = find(Ud(i,:)<1.01 & Ud(i,:)>0); % allow for rounding error 161 | Ne1(i,inds) = 1; 162 | end 163 | 164 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 165 | -------------------------------------------------------------------------------- /somtoolbox/som/som_vis_coords.m: -------------------------------------------------------------------------------- 1 | function unit_coord=som_vis_coords(lattice, msize) 2 | 3 | %SOM_VIS_COORDS Unit coordinates used in visualizations. 4 | % 5 | % Co = som_vis_coords(lattice, msize) 6 | % 7 | % Co = som_vis_coords('hexa',[10 7]) 8 | % Co = som_vis_coords('rectU',[10 7]) 9 | % 10 | % Input and output arguments: 11 | % lattice (string) 'hexa', 'rect', 'hexaU' or 'rectU' 12 | % msize (vector) grid size in a 1x2 vector 13 | % 14 | % Co (matrix) Mx2 matrix of unit coordinates, where 15 | % M=prod(msize) for 'hexa' and 'rect', and 16 | % M=(2*msize(1)-1)*(2*msize(2)-1) for 'hexaU' and 'rectU' 17 | % 18 | % This function calculates the coordinates of map units on a 'sheet' 19 | % shaped map with either 'hexa' or 'rect' lattice as used in the 20 | % visualizations. Note that this slightly different from the 21 | % coordinates provided by SOM_UNIT_COORDS function. 22 | % 23 | % 'rectU' and 'hexaU' gives the coordinates of both units and the 24 | % connections for u-matrix visualizations. 25 | % 26 | % For more help, try 'type som_vis_coords' or check out online documentation. 27 | % See also SOM_UNIT_COORDS, SOM_UMAT, SOM_CPLANE, SOM_GRID. 28 | 29 | %%%%%%%%% DETAILED DESCRIPTION %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 30 | % 31 | % PURPOSE 32 | % 33 | % Returns coordinates of the map units for map visualization 34 | % 35 | % SYNTAX 36 | % 37 | % Co = som_vis_coords(lattice, msize) 38 | % 39 | % DESCRIPTION 40 | % 41 | % This function calculates the coordinates of map units in 'hexa' and 42 | % 'rect' lattices in 'sheet' shaped map for visualization purposes. It 43 | % differs from SOM_UNIT_COORDS in the sense that hexagonal lattice is 44 | % calculated in a "wrong" way in order to get integer coordinates for 45 | % the units. Another difference is that it may be used to calculate 46 | % the coordinates of units _and_ the center points of the lines 47 | % connecting them (edges) by using 'hexaU' or 'rectU' for lattice. 48 | % This property may be used for drawing u-matrices. 49 | % 50 | % The unit number 1 is set to (ij) coordinates (1,1)+shift 51 | % 2 (2,1)+shift 52 | % 53 | % ... columnwise 54 | % 55 | % n-1th (n1-1,n2)+shift 56 | % nth (n1,n2)+shift 57 | % 58 | % where grid size = [n1 n2] and shift is zero, except for 59 | % the even lines of 'hexa' lattice, for which it is +0.5. 60 | % 61 | % For 'rectU' and 'hexaU' the unit coordinates are the same and the 62 | % coordinates for connections are set according to these. In this case 63 | % the ordering of the coordinates is the following: 64 | % let 65 | % U = som_umat(sMap); U=U(:); % make U a column vector 66 | % Uc = som_vis_coords(sMap.topol.lattice, sMap.topol.msize); 67 | % now the kth row of matrix Uc, i.e. Uc(k,:), contains the coordinates 68 | % for value U(k). 69 | % 70 | % REQUIRED INPUT ARGUMENTS 71 | % 72 | % lattice (string) The local topology of the units: 73 | % 'hexa', 'rect', 'hexaU' or 'rectU' 74 | % msize (vector) size 1x2, defining the map grid size. 75 | % Notice that only 2-dimensional grids 76 | % are allowed. 77 | % 78 | % OUTPUT ARGUMENTS 79 | % 80 | % Co (matrix) size Mx2, giving the coordinates for each unit. 81 | % M=prod(msize) for 'hexa' and 'rect', and 82 | % M=(2*msize(1)-1)*(2*msize(2)-1) for 'hexaU' and 'rectU' 83 | % 84 | % FEATURES 85 | % 86 | % Only 'sheet' shaped maps are considered. If coordinates for 'toroid' 87 | % or 'cyl' topologies are required, you must use SOM_UNIT_COORDS 88 | % instead. 89 | % 90 | % EXAMPLES 91 | % 92 | % Though this is mainly a subroutine for visualizations it may be 93 | % used, e.g., in the following manner: 94 | % 95 | % % This makes a hexagonal lattice, where the units are rectangular 96 | % % instead of hexagons. 97 | % som_cplane('rect',som_vis_coords('hexa',[10 7]),'none'); 98 | % 99 | % % Let's make a map and calculate a u-matrix: 100 | % sM=som_make(data,'msize',[10 7],'lattice','hexa'); 101 | % u=som_umat(sM); u=u(:); 102 | % % Now, these produce equivalent results: 103 | % som_cplane('hexaU',[10 7],u); 104 | % som_cplane(vis_patch('hexa')/2,som_vis_coords('hexaU',[10 7]),u); 105 | % 106 | % SEE ALSO 107 | % 108 | % som_grid Visualization of a SOM grid 109 | % som_cplane Visualize a 2D component plane, u-matrix or color plane 110 | % som_barplane Visualize the map prototype vectors as bar diagrams 111 | % som_plotplane Visualize the map prototype vectors as line graphs 112 | % som_pieplane Visualize the map prototype vectors as pie charts 113 | % som_unit_coords Locations of units on the SOM grid 114 | 115 | % Copyright (c) 1999-2000 by the SOM toolbox programming team. 116 | % http://www.cis.hut.fi/projects/somtoolbox/ 117 | 118 | % Version 2.0beta Johan 201099 juuso 261199 119 | 120 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 121 | 122 | if ~vis_valuetype(msize,{'1x2'}), 123 | error('msize must be a 1x2 vector.') 124 | end 125 | 126 | if vis_valuetype(lattice,{'string'}) 127 | switch lattice 128 | case {'hexa', 'rect'} 129 | munits=prod(msize); 130 | unit_coord(:,1)=reshape(repmat((1:msize(2)),msize(1),1),1,munits)'; 131 | unit_coord(:,2)=repmat((1:msize(1))',msize(2),1); 132 | if strcmp(lattice,'hexa') 133 | % Move even rows by .5 134 | d=rem(unit_coord(:,2),2) == 0; 135 | unit_coord(d,1)=unit_coord(d,1)+.5; 136 | end 137 | case {'hexaU','rectU'} 138 | msize=2*msize-1; munits=prod(msize); 139 | unit_coord(:,1)=reshape(repmat((1:msize(2)),msize(1),1),1,munits)'; 140 | unit_coord(:,2)=repmat((1:msize(1))',msize(2),1); 141 | if strcmp(lattice,'hexaU') 142 | d=rem(unit_coord(:,2),2) == 0; 143 | unit_coord(d,1)=unit_coord(d,1)+.5; 144 | d=rem(unit_coord(:,2)+1,4) == 0; 145 | unit_coord(d,1)=unit_coord(d,1)+1; 146 | end 147 | unit_coord=unit_coord/2+.5; 148 | otherwise 149 | error([ 'Unknown lattice ''' lattice '''.']); 150 | end 151 | else 152 | error('Lattice must be a string.'); 153 | end 154 | --------------------------------------------------------------------------------