├── ORL_mtv.mat ├── SpectralClustering.m ├── bestMap.m ├── cnormalize.m ├── cnormalize_inplace.m ├── hungarian.m ├── main.m ├── nmi.m ├── solve_l1l2.m └── vararginParser.m /ORL_mtv.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/XIAOCHUN-CAS/Consistent-and-Specific-Multi-View-Subspace-Clustering/2dd419ac6c3a5fcbe1502a8a29df5180faf1393b/ORL_mtv.mat -------------------------------------------------------------------------------- /SpectralClustering.m: -------------------------------------------------------------------------------- 1 | function groups = SpectralClustering(W, n, varargin) 2 | %SPECTRALCLUSTERING Spectral clustering. 3 | % GROUPS = SpectralClustering(W, N, varargin) clusters data into N groups 4 | % with affinity W. 5 | 6 | % Input Arguments 7 | % W -- symmetric affinity matrix. 8 | % n -- number of groups. 9 | % 'Start' -- initial group for k-means. 10 | % 'sample'(default): 11 | % the same as the k-means 12 | % 'MaxIter' -- maximum number of iterations for KMeans 13 | % 1000(default): 14 | % positive integer 15 | % 'Replicates' -- number of replications for KMeans 16 | % 20(default): 17 | % positive integer 18 | % 'Eig_Solver' -- eig function of matlab 19 | % eig(default): 20 | % eigs 21 | 22 | % Algorithm (Ncut) 23 | % Ncut: min_{A_i} sum_i cut(A_i, bar(A)_i) / vol(A_i), 24 | % reformulate as min_{A_i} \sum_i h_i' L h_i 25 | % s.t. h_ij = 1 / sqrt(Vol(A_j)), if v_i \in A_j 26 | % relax as min_H tr(H' L H) s.t. H' D H = I 27 | % solution is H = D^{-0.5} eig(L_sym). 28 | % in this version, do another row normalization of H. 29 | 30 | % Copyright Chong You @ Johns Hopkins University, 2016 31 | % chong.you1987@gmail.com 32 | 33 | % check data 34 | if ~issymmetric(W) 35 | error(['In ''' mfilename ''': affinity matrix is not symmetric']) 36 | end 37 | % define defaults options 38 | % Set default 39 | vararg = {'Start', 'sample', ... 40 | 'MaxIter', 1000, ... 41 | 'Replicates', 20, ... 42 | 'Eig_Solver', 'eig'}; 43 | % Overwrite by input 44 | vararg = vararginParser(vararg, varargin); 45 | % Generate variables 46 | for pair = reshape(vararg, 2, []) % pair is {propName;propValue} 47 | eval([pair{1} '= pair{2};']); 48 | end 49 | 50 | % Normalized spectral clustering according to Ng & Jordan & Weiss 51 | % using Normalized Symmetric Laplacian L = I - D^{-1/2} W D^{-1/2} 52 | % The computation is equivalent to: 53 | % - compute the largest eigenvectors of D^{-1} W 54 | % - normalize the rows of the resultant matrix 55 | % - then apply kmeans to the rows. 56 | if strcmpi(Eig_Solver, 'eig') 57 | [V, D] = eig( cnormalize(full(W), 1)' ); 58 | [~, ord] = sort(real(diag(D)), 'descend'); 59 | kerN = V(:, ord(1:n)); 60 | clear V D; 61 | elseif strcmpi(Eig_Solver, 'eigs') 62 | [kerN, ~] = eigs( cnormalize(W, 1)', n, 'LR' ); 63 | end 64 | kerN = cnormalize_inplace(kerN')'; 65 | groups = kmeans(kerN, n, 'Start', Start, ... 66 | 'MaxIter', MaxIter, ... 67 | 'Replicates', Replicates, ... 68 | 'EmptyAction', 'singleton'); 69 | -------------------------------------------------------------------------------- /bestMap.m: -------------------------------------------------------------------------------- 1 | function [newL2] = bestMap(L1,L2) 2 | %bestmap: permute labels of L2 to match L1 as good as possible 3 | % [newL2] = bestMap(L1,L2); 4 | % 5 | % version 2.0 --May/2007 6 | % version 1.0 --November/2003 7 | % 8 | % Written by Deng Cai (dengcai AT gmail.com) 9 | 10 | 11 | %=========== 12 | 13 | L1 = L1(:); 14 | L2 = L2(:); 15 | if size(L1) ~= size(L2) 16 | error('size(L1) must == size(L2)'); 17 | end 18 | 19 | Label1 = unique(L1); 20 | nClass1 = length(Label1); 21 | Label2 = unique(L2); 22 | nClass2 = length(Label2); 23 | 24 | nClass = max(nClass1,nClass2); 25 | G = zeros(nClass); 26 | for i=1:nClass1 27 | for j=1:nClass2 28 | G(i,j) = length(find(L1 == Label1(i) & L2 == Label2(j))); 29 | end 30 | end 31 | 32 | [c,t] = hungarian(-G); 33 | newL2 = zeros(size(L2)); 34 | for i=1:nClass2 35 | newL2(L2 == Label2(i)) = Label1(c(i)); 36 | end -------------------------------------------------------------------------------- /cnormalize.m: -------------------------------------------------------------------------------- 1 | function [Y, Xnorm] = cnormalize(X, p) 2 | %CNORMALIZE normalizes columns. 3 | % 4 | % [Y, XNORM] = cnormalize(X, P) normalizes columns of matrix X to unit 5 | % ell_P norm, and returen the norm values to XNORM and data to Y. 6 | 7 | % Copyright Chong You @ Johns Hopkins University, 2016 8 | % chong.you1987@gmail.com 9 | 10 | if ~exist('p', 'var') 11 | p = 2; 12 | end 13 | 14 | if p == Inf 15 | Xnorm = max(abs(X), [], 1); 16 | else 17 | Xnorm = sum(abs(X) .^p, 1) .^(1/p); 18 | end 19 | Y = bsxfun(@rdivide, X, Xnorm + eps); -------------------------------------------------------------------------------- /cnormalize_inplace.m: -------------------------------------------------------------------------------- 1 | function [X, Xnorm] = cnormalize_inplace(X, p) 2 | %CNORMALIZE_INPLACE normalizes columns. 3 | % This is a inplace version of CNORMALIZE. 4 | 5 | % Copyright Chong You @ Johns Hopkins University, 2016 6 | % chong.you1987@gmail.com 7 | 8 | N = size( X, 2 ); 9 | if ~exist('p', 'var') 10 | p = 2; 11 | end 12 | 13 | if nargout > 1, Xnorm = zeros(1, N); end; 14 | 15 | for iN = 1:N 16 | if p == Inf 17 | cnorm = max(abs(X(:, iN)), [], 1); 18 | else 19 | cnorm = sum(abs(X(:, iN)) .^p, 1) .^(1/p); 20 | end 21 | X(:, iN) = X(:, iN) / (cnorm + eps); 22 | 23 | if nargout > 1, Xnorm(iN) = cnorm; end; 24 | end 25 | -------------------------------------------------------------------------------- /hungarian.m: -------------------------------------------------------------------------------- 1 | function [C,T]=hungarian(A) 2 | %HUNGARIAN Solve the Assignment problem using the Hungarian method. 3 | % 4 | %[C,T]=hungarian(A) 5 | %A - a square cost matrix. 6 | %C - the optimal assignment. 7 | %T - the cost of the optimal assignment. 8 | %s.t. T = trace(A(C,:)) is minimized over all possible assignments. 9 | 10 | % Adapted from the FORTRAN IV code in Carpaneto and Toth, "Algorithm 548: 11 | % Solution of the assignment problem [H]", ACM Transactions on 12 | % Mathematical Software, 6(1):104-111, 1980. 13 | 14 | % v1.0 96-06-14. Niclas Borlin, niclas@cs.umu.se. 15 | % Department of Computing Science, Ume? University, 16 | % Sweden. 17 | % All standard disclaimers apply. 18 | 19 | % A substantial effort was put into this code. If you use it for a 20 | % publication or otherwise, please include an acknowledgement or at least 21 | % notify me by email. /Niclas 22 | 23 | [m,n]=size(A); 24 | 25 | if (m~=n) 26 | error('HUNGARIAN: Cost matrix must be square!'); 27 | end 28 | 29 | % Save original cost matrix. 30 | orig=A; 31 | 32 | % Reduce matrix. 33 | A=hminired(A); 34 | 35 | % Do an initial assignment. 36 | [A,C,U]=hminiass(A); 37 | 38 | % Repeat while we have unassigned rows. 39 | while (U(n+1)) 40 | % Start with no path, no unchecked zeros, and no unexplored rows. 41 | LR=zeros(1,n); 42 | LC=zeros(1,n); 43 | CH=zeros(1,n); 44 | RH=[zeros(1,n) -1]; 45 | 46 | % No labelled columns. 47 | SLC=[]; 48 | 49 | % Start path in first unassigned row. 50 | r=U(n+1); 51 | % Mark row with end-of-path label. 52 | LR(r)=-1; 53 | % Insert row first in labelled row set. 54 | SLR=r; 55 | 56 | % Repeat until we manage to find an assignable zero. 57 | while (1) 58 | % If there are free zeros in row r 59 | if (A(r,n+1)~=0) 60 | % ...get column of first free zero. 61 | l=-A(r,n+1); 62 | 63 | % If there are more free zeros in row r and row r in not 64 | % yet marked as unexplored.. 65 | if (A(r,l)~=0 & RH(r)==0) 66 | % Insert row r first in unexplored list. 67 | RH(r)=RH(n+1); 68 | RH(n+1)=r; 69 | 70 | % Mark in which column the next unexplored zero in this row 71 | % is. 72 | CH(r)=-A(r,l); 73 | end 74 | else 75 | % If all rows are explored.. 76 | if (RH(n+1)<=0) 77 | % Reduce matrix. 78 | [A,CH,RH]=hmreduce(A,CH,RH,LC,LR,SLC,SLR); 79 | end 80 | 81 | % Re-start with first unexplored row. 82 | r=RH(n+1); 83 | % Get column of next free zero in row r. 84 | l=CH(r); 85 | % Advance "column of next free zero". 86 | CH(r)=-A(r,l); 87 | % If this zero is last in the list.. 88 | if (A(r,l)==0) 89 | % ...remove row r from unexplored list. 90 | RH(n+1)=RH(r); 91 | RH(r)=0; 92 | end 93 | end 94 | 95 | % While the column l is labelled, i.e. in path. 96 | while (LC(l)~=0) 97 | % If row r is explored.. 98 | if (RH(r)==0) 99 | % If all rows are explored.. 100 | if (RH(n+1)<=0) 101 | % Reduce cost matrix. 102 | [A,CH,RH]=hmreduce(A,CH,RH,LC,LR,SLC,SLR); 103 | end 104 | 105 | % Re-start with first unexplored row. 106 | r=RH(n+1); 107 | end 108 | 109 | % Get column of next free zero in row r. 110 | l=CH(r); 111 | 112 | % Advance "column of next free zero". 113 | CH(r)=-A(r,l); 114 | 115 | % If this zero is last in list.. 116 | if(A(r,l)==0) 117 | % ...remove row r from unexplored list. 118 | RH(n+1)=RH(r); 119 | RH(r)=0; 120 | end 121 | end 122 | 123 | % If the column found is unassigned.. 124 | if (C(l)==0) 125 | % Flip all zeros along the path in LR,LC. 126 | [A,C,U]=hmflip(A,C,LC,LR,U,l,r); 127 | % ...and exit to continue with next unassigned row. 128 | break; 129 | else 130 | % ...else add zero to path. 131 | 132 | % Label column l with row r. 133 | LC(l)=r; 134 | 135 | % Add l to the set of labelled columns. 136 | SLC=[SLC l]; 137 | 138 | % Continue with the row assigned to column l. 139 | r=C(l); 140 | 141 | % Label row r with column l. 142 | LR(r)=l; 143 | 144 | % Add r to the set of labelled rows. 145 | SLR=[SLR r]; 146 | end 147 | end 148 | end 149 | 150 | % Calculate the total cost. 151 | T=sum(orig(logical(sparse(C,1:size(orig,2),1)))); 152 | 153 | 154 | function A=hminired(A) 155 | %HMINIRED Initial reduction of cost matrix for the Hungarian method. 156 | % 157 | %B=assredin(A) 158 | %A - the unreduced cost matris. 159 | %B - the reduced cost matrix with linked zeros in each row. 160 | 161 | % v1.0 96-06-13. Niclas Borlin, niclas@cs.umu.se. 162 | 163 | [m,n]=size(A); 164 | 165 | % Subtract column-minimum values from each column. 166 | colMin=min(A); 167 | A=A-colMin(ones(n,1),:); 168 | 169 | % Subtract row-minimum values from each row. 170 | rowMin=min(A')'; 171 | A=A-rowMin(:,ones(1,n)); 172 | 173 | % Get positions of all zeros. 174 | [i,j]=find(A==0); 175 | 176 | % Extend A to give room for row zero list header column. 177 | A(1,n+1)=0; 178 | for k=1:n 179 | % Get all column in this row. 180 | cols=j(k==i)'; 181 | % Insert pointers in matrix. 182 | A(k,[n+1 cols])=[-cols 0]; 183 | end 184 | 185 | 186 | function [A,C,U]=hminiass(A) 187 | %HMINIASS Initial assignment of the Hungarian method. 188 | % 189 | %[B,C,U]=hminiass(A) 190 | %A - the reduced cost matrix. 191 | %B - the reduced cost matrix, with assigned zeros removed from lists. 192 | %C - a vector. C(J)=I means row I is assigned to column J, 193 | % i.e. there is an assigned zero in position I,J. 194 | %U - a vector with a linked list of unassigned rows. 195 | 196 | % v1.0 96-06-14. Niclas Borlin, niclas@cs.umu.se. 197 | 198 | [n,np1]=size(A); 199 | 200 | % Initalize return vectors. 201 | C=zeros(1,n); 202 | U=zeros(1,n+1); 203 | 204 | % Initialize last/next zero "pointers". 205 | LZ=zeros(1,n); 206 | NZ=zeros(1,n); 207 | 208 | for i=1:n 209 | % Set j to first unassigned zero in row i. 210 | lj=n+1; 211 | j=-A(i,lj); 212 | 213 | % Repeat until we have no more zeros (j==0) or we find a zero 214 | % in an unassigned column (c(j)==0). 215 | 216 | while (C(j)~=0) 217 | % Advance lj and j in zero list. 218 | lj=j; 219 | j=-A(i,lj); 220 | 221 | % Stop if we hit end of list. 222 | if (j==0) 223 | break; 224 | end 225 | end 226 | 227 | if (j~=0) 228 | % We found a zero in an unassigned column. 229 | 230 | % Assign row i to column j. 231 | C(j)=i; 232 | 233 | % Remove A(i,j) from unassigned zero list. 234 | A(i,lj)=A(i,j); 235 | 236 | % Update next/last unassigned zero pointers. 237 | NZ(i)=-A(i,j); 238 | LZ(i)=lj; 239 | 240 | % Indicate A(i,j) is an assigned zero. 241 | A(i,j)=0; 242 | else 243 | % We found no zero in an unassigned column. 244 | 245 | % Check all zeros in this row. 246 | 247 | lj=n+1; 248 | j=-A(i,lj); 249 | 250 | % Check all zeros in this row for a suitable zero in another row. 251 | while (j~=0) 252 | % Check the in the row assigned to this column. 253 | r=C(j); 254 | 255 | % Pick up last/next pointers. 256 | lm=LZ(r); 257 | m=NZ(r); 258 | 259 | % Check all unchecked zeros in free list of this row. 260 | while (m~=0) 261 | % Stop if we find an unassigned column. 262 | if (C(m)==0) 263 | break; 264 | end 265 | 266 | % Advance one step in list. 267 | lm=m; 268 | m=-A(r,lm); 269 | end 270 | 271 | if (m==0) 272 | % We failed on row r. Continue with next zero on row i. 273 | lj=j; 274 | j=-A(i,lj); 275 | else 276 | % We found a zero in an unassigned column. 277 | 278 | % Replace zero at (r,m) in unassigned list with zero at (r,j) 279 | A(r,lm)=-j; 280 | A(r,j)=A(r,m); 281 | 282 | % Update last/next pointers in row r. 283 | NZ(r)=-A(r,m); 284 | LZ(r)=j; 285 | 286 | % Mark A(r,m) as an assigned zero in the matrix . . . 287 | A(r,m)=0; 288 | 289 | % ...and in the assignment vector. 290 | C(m)=r; 291 | 292 | % Remove A(i,j) from unassigned list. 293 | A(i,lj)=A(i,j); 294 | 295 | % Update last/next pointers in row r. 296 | NZ(i)=-A(i,j); 297 | LZ(i)=lj; 298 | 299 | % Mark A(r,m) as an assigned zero in the matrix . . . 300 | A(i,j)=0; 301 | 302 | % ...and in the assignment vector. 303 | C(j)=i; 304 | 305 | % Stop search. 306 | break; 307 | end 308 | end 309 | end 310 | end 311 | 312 | % Create vector with list of unassigned rows. 313 | 314 | % Mark all rows have assignment. 315 | r=zeros(1,n); 316 | rows=C(C~=0); 317 | r(rows)=rows; 318 | empty=find(r==0); 319 | 320 | % Create vector with linked list of unassigned rows. 321 | U=zeros(1,n+1); 322 | U([n+1 empty])=[empty 0]; 323 | 324 | 325 | function [A,C,U]=hmflip(A,C,LC,LR,U,l,r) 326 | %HMFLIP Flip assignment state of all zeros along a path. 327 | % 328 | %[A,C,U]=hmflip(A,C,LC,LR,U,l,r) 329 | %Input: 330 | %A - the cost matrix. 331 | %C - the assignment vector. 332 | %LC - the column label vector. 333 | %LR - the row label vector. 334 | %U - the 335 | %r,l - position of last zero in path. 336 | %Output: 337 | %A - updated cost matrix. 338 | %C - updated assignment vector. 339 | %U - updated unassigned row list vector. 340 | 341 | % v1.0 96-06-14. Niclas Borlin, niclas@cs.umu.se. 342 | 343 | n=size(A,1); 344 | 345 | while (1) 346 | % Move assignment in column l to row r. 347 | C(l)=r; 348 | 349 | % Find zero to be removed from zero list.. 350 | 351 | % Find zero before this. 352 | m=find(A(r,:)==-l); 353 | 354 | % Link past this zero. 355 | A(r,m)=A(r,l); 356 | 357 | A(r,l)=0; 358 | 359 | % If this was the first zero of the path.. 360 | if (LR(r)<0) 361 | ...remove row from unassigned row list and return. 362 | U(n+1)=U(r); 363 | U(r)=0; 364 | return; 365 | else 366 | 367 | % Move back in this row along the path and get column of next zero. 368 | l=LR(r); 369 | 370 | % Insert zero at (r,l) first in zero list. 371 | A(r,l)=A(r,n+1); 372 | A(r,n+1)=-l; 373 | 374 | % Continue back along the column to get row of next zero in path. 375 | r=LC(l); 376 | end 377 | end 378 | 379 | 380 | function [A,CH,RH]=hmreduce(A,CH,RH,LC,LR,SLC,SLR) 381 | %HMREDUCE Reduce parts of cost matrix in the Hungerian method. 382 | % 383 | %[A,CH,RH]=hmreduce(A,CH,RH,LC,LR,SLC,SLR) 384 | %Input: 385 | %A - Cost matrix. 386 | %CH - vector of column of 'next zeros' in each row. 387 | %RH - vector with list of unexplored rows. 388 | %LC - column labels. 389 | %RC - row labels. 390 | %SLC - set of column labels. 391 | %SLR - set of row labels. 392 | % 393 | %Output: 394 | %A - Reduced cost matrix. 395 | %CH - Updated vector of 'next zeros' in each row. 396 | %RH - Updated vector of unexplored rows. 397 | 398 | % v1.0 96-06-14. Niclas Borlin, niclas@cs.umu.se. 399 | 400 | n=size(A,1); 401 | 402 | % Find which rows are covered, i.e. unlabelled. 403 | coveredRows=LR==0; 404 | 405 | % Find which columns are covered, i.e. labelled. 406 | coveredCols=LC~=0; 407 | 408 | r=find(~coveredRows); 409 | c=find(~coveredCols); 410 | 411 | % Get minimum of uncovered elements. 412 | m=min(min(A(r,c))); 413 | 414 | % Subtract minimum from all uncovered elements. 415 | A(r,c)=A(r,c)-m; 416 | 417 | % Check all uncovered columns.. 418 | for j=c 419 | % ...and uncovered rows in path order.. 420 | for i=SLR 421 | % If this is a (new) zero.. 422 | if (A(i,j)==0) 423 | % If the row is not in unexplored list.. 424 | if (RH(i)==0) 425 | % ...insert it first in unexplored list. 426 | RH(i)=RH(n+1); 427 | RH(n+1)=i; 428 | % Mark this zero as "next free" in this row. 429 | CH(i)=j; 430 | end 431 | % Find last unassigned zero on row I. 432 | row=A(i,:); 433 | colsInList=-row(row<0); 434 | if (length(colsInList)==0) 435 | % No zeros in the list. 436 | l=n+1; 437 | else 438 | l=colsInList(row(colsInList)==0); 439 | end 440 | % Append this zero to end of list. 441 | A(i,l)=-j; 442 | end 443 | end 444 | end 445 | 446 | % Add minimum to all doubly covered elements. 447 | r=find(coveredRows); 448 | c=find(coveredCols); 449 | 450 | % Take care of the zeros we will remove. 451 | [i,j]=find(A(r,c)<=0); 452 | 453 | i=r(i); 454 | j=c(j); 455 | 456 | for k=1:length(i) 457 | % Find zero before this in this row. 458 | lj=find(A(i(k),:)==-j(k)); 459 | % Link past it. 460 | A(i(k),lj)=A(i(k),j(k)); 461 | % Mark it as assigned. 462 | A(i(k),j(k))=0; 463 | end 464 | 465 | A(r,c)=A(r,c)+m; -------------------------------------------------------------------------------- /main.m: -------------------------------------------------------------------------------- 1 | %clc; 2 | clear all; 3 | 4 | % load('yale_mtv.mat'); % gt:165x1, 15 clusters; X: 4096 3304 6750(3)x165 5 | % load('HOG_yale.mat'); % 2700x165 6 | % X{4}=H; 7 | views = 3; 8 | % load('yaleB_mtv.mat'); % gt:650x1, 10 clusters; X: 2500 3304 6750(3)x165 9 | load('ORL_mtv.mat'); % gt:400x1, 40 clusters; X: 4096 3304 6750(3) 10 | % load('NH_interval9_mtv.mat'); % gt:550x1, 5 clusters; X: 2000 3304 6750(3) 11 | % load('bbcsport_2view.mat'); % gt:544x1, 5 clusters; X: 3183 3203(2) 12 | 13 | iter = 100; 14 | M = 4; 15 | nmix = zeros(M,1); 16 | accr = zeros(M,1); 17 | spa = zeros(M,1); 18 | pur = zeros(M,1); 19 | Fscore = zeros(M,1); 20 | RandIdx = zeros(M,1); 21 | Prec = zeros(M,1); 22 | Rec = zeros(M,1); 23 | ar = zeros(M,1); 24 | err=zeros(iter,1); 25 | 26 | lambda_c = 0.05; 27 | lambda_d = 0.1; 28 | % c d 29 | % yale 0.05 1 30 | % orl 0.05 0.1 31 | % nh 0.5 1 32 | % bbc 0.1 1 33 | 34 | for m = 1:M 35 | tol=10^-7; 36 | clusters = size(unique(gt),1); 37 | N = size(gt,1); 38 | mu = 10^-6; 39 | rho=1.1; 40 | maxmu=10^6; 41 | C = zeros(N,N); 42 | Y2 = zeros(N,N); 43 | for v = 1:views 44 | X{v} = X{v}./repmat(sqrt(sum(X{v}.^2,1)),size(X{v},1),1); 45 | D{v} = rand(N,N); 46 | E{v} = zeros(size(X{v})); 47 | W{v} = zeros(size(X{v})); 48 | Y1{v} = zeros(size(X{v})); 49 | Y3{v} = zeros(size(X{v})); 50 | end 51 | 52 | x = zeros(views, 1); 53 | for i = 1:views 54 | x(i) = norm(X{i},'fro')^2; 55 | end 56 | xx=sum(x); 57 | for s = 1:iter 58 | tic; 59 | 60 | for i=1:views 61 | %% D 62 | Ad = zeros(N,N); 63 | Cd = zeros(N,N); 64 | Ad = mu*X{i}'*X{i}+2*lambda_d.*eye(N); 65 | Cd = mu*X{i}'*(X{i}+Y1{i}/mu-X{i}*C-E{i}); 66 | D{i} = Ad\Cd; 67 | 68 | %% E 69 | E{i} = (X{i}+Y1{i}/mu-X{i}*C-X{i}*D{i}+W{i}-Y3{i}/mu)/2; 70 | 71 | %% W 72 | temp = E{i}+Y3{i}/mu; 73 | W{i} = solve_l1l2(temp,1/mu); 74 | end 75 | 76 | %% K 77 | [U,S,V] = svd(C + Y2./mu); 78 | a = diag(S)-lambda_c/mu; 79 | a(a<0)=0; 80 | T = diag(a); 81 | K = U*T*V'; 82 | 83 | %% C 84 | A = zeros(N,N); 85 | B = zeros(N,N); 86 | for i=1:views 87 | A = A + X{i}'*X{i}; 88 | B = B + X{i}'*(X{i}+Y1{i}/mu-X{i}*D{i}-E{i}); 89 | end 90 | C = (A+eye(N,N))\(B+K-Y2/mu); 91 | 92 | %% check if converge 93 | for i = 1:views 94 | p(i) = norm(X{i}-X{i}*(C+D{i}),'fro')^2; 95 | eq2{i} = X{i}-X{i}*(C+D{i})-E{i}; 96 | eq3{i} = E{i}-W{i}; 97 | end 98 | P = sum(p); 99 | eq1=C-K; 100 | err(s)=abs(xx-P); 101 | %eq=[norm(eq1,Inf),norm(eq2{1},Inf),norm(eq2{2},Inf),norm(eq2{3},Inf),err(s)]; 102 | % bbcsport 103 | %eq=[norm(eq1,Inf),norm(eq2{1},Inf),norm(eq2{2},Inf),err(s)]; 104 | %stop=max(eq); 105 | if s==iter || err(s)lambda 13 | x = (nw-lambda)*w/nw; 14 | else 15 | x = zeros(length(w),1); 16 | end 17 | end -------------------------------------------------------------------------------- /vararginParser.m: -------------------------------------------------------------------------------- 1 | function vararg = vararginParser(vararg, vararg_in) 2 | %VARARGINPARSER Input parser. 3 | 4 | % How to use: 5 | % % Set default 6 | % vararg = {'firstparameter', 1, 'secondparameter', magic(3)}; 7 | % % Overwrite by input 8 | % vararg = vararginParser(vararg, varargin); 9 | % % Generate variables 10 | % for pair = reshape(vararg, 2, []) % pair is {propName;propValue} 11 | % eval([pair{1} '= pair{2};']); 12 | % end 13 | 14 | % Copyright Chong You @ Johns Hopkins University, 2016 15 | % chong.you1987@gmail.com 16 | 17 | % count arguments 18 | if mod(length(vararg_in), 2) ~= 0 19 | error('varargin needs propertyName/propertyValue pairs') 20 | end 21 | % overwrite vararg. 22 | optionNames = vararg(1:2:end); 23 | for pair = reshape(vararg_in, 2, []) % pair is {propName;propValue} 24 | optName = pair{1}; 25 | index = find( strcmpi(optName, optionNames) ); 26 | if ~isempty(index) 27 | vararg{index * 2} = pair{2}; 28 | else 29 | error('%s is not a recognized parameter name', optName) 30 | end 31 | end 32 | 33 | end --------------------------------------------------------------------------------