1+ classdef MISAK < handle
2+ % MISA using Kotz distribution and intrinsic source scaling
3+ properties
4+ C % Vector, number of components per dataset
5+ K % Number, number of non-empty subspaces
6+ M % Vector, indices of datasets to be used in the analysis
7+ N % Number, number of observations/measurements/samples
8+ S % Matrix, subspace assignment matrix (K x Cm)
9+ V % Vector, dimensionality of each dataset (number of sensors)
10+ W % Matrix, unmixing matrices (1 per dataset)
11+ X % Matrix, all datasets
12+ Y % Matrix, source estimates (network output)
13+ beta % Vector, Kotz beta parameter for each subspace
14+ d % Vector, dimensionality of each subspace
15+ d_k % Vector, dimensionality of each subspace per dataset
16+ eta % Vector, Kotz eta parameter for each subspace
17+ gradtype % String, type of gradient used: regular, relative, or natural
18+ sc % Logical, scale-control option: true or false
19+ lambda % Vector, Kotz lambda parameter for each subspace
20+ nes % Vector, non-empty subspace indexes
21+ nu % Vector, Kotz nu parameter for each subspace
22+ a % Vector, scaling factor to convers inverse cov. into inverse dispersion mtx.
23+ preX % Logical, preprocessing option: true, false, or empty
24+ end
25+ properties (Access = protected )
26+ ut % Container for utility static functions
27+ end
28+ methods
29+ function obj = MISAK(w0 , M , S , X , beta , eta , lambda , gradtype , sc , preX )
30+
31+ % %% Test nu for all subspaces!!
32+ Sfull = full(sum([S{M }],2 ));
33+ Smask = Sfull ~= 0 ;
34+ if any(beta(Smask ) <= 0 ), error(' All beta parameters should be positive.' ); end
35+ if ~isempty(lambda )
36+ if any(lambda(Smask ) <= 0 ), error(' All lambda parameters should be positive.' ); end
37+ end
38+ if any(eta(Smask ) <= ((2 - Sfull(Smask ))./2 )), error(' All eta parameters should be lagerer than (2-d)/2.' ); end
39+ nu = (2 * eta + Sfull - 2 )./(2 * beta );
40+ if any(nu(Smask ) <= 0 ), error(' All nu parameter derived from eta and d should be positive.' ); end
41+
42+ obj.M = M ; % Indices of datasets to be used in the analysis
43+ obj.S = S ; % Subspace assignment matrix (K x Cm)
44+ obj.X = X ; % All datasets
45+ obj.beta = beta ; % Kotz beta parameter
46+ obj.eta = eta ; % Kotz eta parameter
47+ obj.lambda = lambda ; % Kotz lambda parameter
48+ obj.nu = nu ; % Kotz nu parameter
49+
50+ if ~isempty(preX ) && preX == true
51+ % Remove mean from all datasets:
52+ obj.preX.mean = cellfun(@(x ) mean(x ,2 ), obj .X , ' Un' , 0 );
53+ obj.X = cellfun(@(x ,mx ) bsxfun(@minus ,x ,mx ), obj .X , obj .preX .mean , ' Un' , 0 );
54+
55+ % Standardize all datasets:
56+ obj.preX.std = cellfun(@(x ) std(x ,[],2 ), obj .X , ' Un' , 0 );
57+ obj.X = cellfun(@(sx ,x ) bsxfun(@times ,1 ./ sx ,x ), obj .preX .std , obj .X , ' Un' , 0 );
58+
59+ else obj .preX = false ;
60+ end
61+
62+ obj.C = cellfun(@(s ) size(s ,2 ), obj .S ); % Number of components per dataset
63+ obj.V = cellfun(@(x ) size(x ,1 ), obj .X ); % Dimensionality of each dataset (number of sensors)
64+
65+ obj.ut = utils ;
66+
67+ % Unmixing matrices (1 per dataset):
68+ obj.W = cell(1 ,max(obj .M ));
69+ obj .W(obj .M ) = obj .unstackW(w0 );% , obj.M, obj.C(obj.M), obj.V(obj.M));
70+
71+ % Compute source estimates (network output):
72+ obj.Y = cell(1 ,max(obj .M ));
73+ obj .Y(obj .M ) = cellfun(@mtimes , obj .W(obj .M ), obj .X(obj .M ), ' Un' , 0 );
74+
75+ obj.N = size(obj.X{obj .M(1 )},2 );% Number of samples
76+
77+ obj.d = full(sum([obj.S{obj .M }],2 )); % Dimensionality of each subspace
78+ obj.nes = obj .d ~= 0 ; % Non-empty subspace indexes
79+ obj.d_k = cellfun(@(s ) full(sum(s ,2 )), obj .S ,' Un' ,0 );
80+ obj .auto_tune(' lambda' , lambda );
81+
82+ obj.a = (obj .lambda .^(-1 ./(obj .beta )) .* gamma(obj .nu + 1 ./ obj .beta )) ./ ...
83+ (obj .d .* gamma(obj .nu ));
84+
85+ obj.K = sum(obj .nes ); % Number of non-empty subspaces
86+ if ~isempty(sc )
87+ updatesc(obj ,sc ); % Determines if scale-control is used: true or false
88+ else
89+ updatesc(obj ,true ); % Determines if scale-control is used: true or false
90+ end
91+ updategradtype(obj ,gradtype ); % Determines the type of gradient used: regular, relative, natural
92+
93+ end
94+ [J , gJ ] = objective_(O ) % Compute objective function value at current W
95+ [J , gJ ] = objective_sc_(O ) % Compute scale-control objective function value at current W
96+ [J , gJ ] = objective(O ,w ) % Compute objective function value at provided W
97+ W = unstackW(O ,w )
98+ w = stackW(O ,W )
99+ update(O ,S ,M ,b ,l ,e ) % Subset the data
100+ Sold = IVAfy(O ) % Turn problem into Unidimensional-type
101+ updateCS(O ,S )
102+ updategradtype(O ,gradtype ) % Set gradient type
103+ combinatorial_optim(O ,myM ) % Solve combinatorial optimization
104+ w0 = greedysearch(O ,myM )
105+ [w0 , shuff ] = sub_perm_analysis(O , w0 )
106+ [shuff ] = greedy_sub_perm_analysis(O )
107+ mISI = MISI(O ,A ) % Compute joint ISI of current W. A is provided.
108+ mmd = MMD(O ,A )
109+ mmse = MMSE(O ,Y )
110+ end
111+ methods (Access = private )
112+ % output = myFunc(obj,arg1,arg2)
113+ end
114+ methods (Static )
115+ % w = stackW(W)
116+ % W = unstackW(w,M,C,V)
117+ % Vt = myorth(Y)
118+ end
119+ end % End of classdef
120+
121+ % function myUtilityFcn
122+ % end
0 commit comments