function [w, run_time,Loss] = OMVFS(X, option) % Multi view feature selection % X cell array, contains multi view data. each matrix is N by d_v % option.block_size % option.buffer_size % option.beta vector of size n_v % option.num_cluster % option.pass % option.maxiter % option.tol num_passes = option.pass; max_buffer_size = option.buffer_size; beta = option.beta; alpha = option.alpha; lambda = option.lambda; maxIter = option.maxiter; num_clusters = option.num_cluster; block_size = option.block_size; tol = option.tol; gamma = option.gamma; num_views = numel(X); num_feature = zeros(num_views,1); total = size(X{1},1); for i = 1:num_views num_feature(i) = size(X{i},2); end current_buffer_size = 0; % Initialize U and V U_buff = []; V = cell(num_views,1); for i = 1:num_views V{i} = rand(num_feature(i),num_clusters); end A = cell(num_views,1); B = cell(num_views,2); for i =1:num_views A{i} = zeros(size(V{i})); B{i} = zeros(num_clusters, num_clusters); end num_block = ceil(total/block_size); Loss = zeros(num_passes, num_block); index_sofa = 0; U_sofar = cell(num_views,1); for i = 1:num_views U_sofa{i} = []; end for pass = 1:num_passes X_buff = cell(num_views,1); for i = 1:num_views X_buff{i} = []; end for block_index = 1:num_block data_range = (block_index-1)*block_size+1:block_index*block_size; if block_index == num_block data_range = (block_index-1)*block_size+1:total; end X_i = cell(num_views,1); D = cell(num_views, 1); L = cell(num_views, 1); DD = cell(num_views, 1); SS = cell(num_views, 1); for i = 1:num_views if size(X_buff{i},1) + numel(data_range) <= max_buffer_size X_buff{i} = [X_buff{i}; X{i}(data_range,:)]; else X_buff{i} = [X_buff{i}; X{i}(data_range,:)]; X_buff{i} = X_buff{i}(end- max_buffer_size+1:end,:); end X_i{i} = X{i}(data_range,:); [L{i}, DD{i}, SS{i}] = construct_Laplacian(X_buff{i}); D{i} = diag(sparse(ones(1,num_feature(i)))); end for i = 1:num_views U_buff{i} = rand(size(X_buff{i},1), num_clusters); U_i{i} = U_buff{i}(end-numel(data_range)+1:end,:); if size( U_buff{i},1 ) > max_buffer_size U_buff{i} = U_buff{i}(end- max_buffer_size+1:end,:); end U_sofar{i} = [U_sofar{i}; U_i{i}]; end U_star_buff = rand(size(U_buff{1})); index_sofa = index_sofa + numel(data_range); M = alpha(1)*L{1}; for ii = 2:num_views M = M + alpha(ii)*L{ii}; end M_plus = 0.5*(abs(M) + M); M_minus = 0.5*(abs(M) - M); iter = 0; converge = 0; step_u = 0.5; step_v = ones(num_views,1); beta_search = 0.1; while iter < maxIter && converge ==0 % update U_star_buff U_star_buff = lambda(1)*U_buff{1}; for i = 2:num_views U_star_buff = U_star_buff + lambda(i)*U_buff{2}; end U_star_buff = U_star_buff/sum(lambda); % Update U_i for i = 1:num_views upper_tmp = X_buff{i}*V{i} + U_star_buff + gamma*U_buff; lower_tmp = U_buff{i}*(V{i}'*V{i}) + alpha(i)*L{i}*U_buff{i} + U_buff{i}+ gamma*U_buff*(U_buff'*U_buff); U_buff{i} = U_buff{i}.*(upper_tmp./max(lower_tmp,1e-20)).^step_u; end U_i{i} = U_buff(end-numel(data_range)+1:end,:); % Update V_i for i = 1:num_views upper_tmp = A{i} + X_i{i}' * U_i{i}; lower_tmp = V{i} * (B{i} + (U_i{i}' * U_i{i})); % construct D D{i} = diag(sparse(0.5./max(sqrt(sum(V{i}.^2,2)),1e-20))); lower_tmp = lower_tmp + beta(i) * D{i} * V{i}; V{i} = V{i} .* (upper_tmp./max(lower_tmp, 1e-20)).^step_u; end for i = 1:num_views U_sofar{i}(data_range,:) = U_i{i}; end iter = iter + 1; end log = 0; % Update A and B for i = 1:num_views A{i} = A{i} + X_i{i}' * U_i{i}; B{i} = B{i} + U_i{i}' * U_i{i}; end fprintf('Done with block %d in %d iterations and log is %d\n', block_index, iter, log); end fprintf('Done with pass %d\n', pass); end for i = 1:num_views w{i} = sqrt(sum(V{i}.^2,2)); end end function [result] = L21(X) % L2,1 norm of X, the sum of row norms result = sum(sqrt(sum(X.^2,2))); end function [L,V,S] = construct_Laplacian(X) n=size(X,1); S = kernelmatrix(X,1); V = zeros(size(S)); for i = 1:size(V,1) V(i,i) = sum(S(:,i)); end L = V - S; end function K = kernelmatrix(coord, sig) n=size(coord,1); K=coord*coord'/sig^2; d=diag(K); K=K-ones(n,1)*d'/2; K=K-d*ones(1,n)/2; K=exp(K); end