projfunc.m

来自「NMFs算法(带稀疏度约束的非负稀疏矩阵分解)用于实现基于人脸局部特征的人脸识别」· M 代码 · 共 66 行

M
66
字号
function [v,usediters] = projfunc( s, k1, k2, nn )% Solves the following problem:% Given a vector s, find the vector v having sum(abs(v))=k1 % and sum(v.^2)=k2 which is closest to s in the euclidian sense.% If the binary flag nn is set, the vector v is additionally% restricted to being non-negative (v>=0).%    % Written 2.7.2004 by Patrik O. Hoyer%    % Problem dimensionN = length(s);% If non-negativity flag not set, record signs and take absif ~nn,    isneg = s<0;    s = abs(s);end% Start by projecting the point to the sum constraint hyperplanev = s + (k1-sum(s))/N;% Initialize zerocoeff (initially, no elements are assumed zero)zerocoeff = [];j = 0;while 1,    % This does the proposed projection operator    midpoint = ones(N,1)*k1/(N-length(zerocoeff));    midpoint(zerocoeff) = 0;    w = v-midpoint;    a = sum(w.^2);    b = 2*w'*v;    c = sum(v.^2)-k2;    alphap = (-b+real(sqrt(b^2-4*a*c)))/(2*a);    v = alphap*w + v;        if all(v>=0),	% We've found our solution	usediters = j+1;	break;    end            j = j+1;            % Set negs to zero, subtract appropriate amount from rest    zerocoeff = find(v<=0);    v(zerocoeff) = 0;    tempsum = sum(v);    v = v + (k1-tempsum)/(N-length(zerocoeff));    v(zerocoeff) = 0;            end% If non-negativity flag not set, return signs to solutionif ~nn,    v = (-2*isneg + 1).*v;end% Check for problemsif max(max(abs(imag(v))))>1e-10,    error('Somehow got imaginary values!');end

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?