% Given a Poisson singular value decomposition, project some new vectors % onto it. % x: vectors to be projected % u: from Poisson SVD u*v % iters: computation limit % start: starting point for y % Returns y such that u*y is close to log(x). function y = newpproject(x, u, iters, start); % starting point for optimization [n, d] = size(x); [n, l] = size(u); y = randn(l,d) / sum(sum(abs(u))); % process input parameters if (nargin < 3) iters = 50; end if (nargin >= 4) y = start; end % this loop can be terminated early if convergence check is passed converge = 1e-5; for iter = 1:iters % save parameters for convergence check lasty = y; % Newton step to improve y as a predictor of x given u for i = 1:d % residual for i-th column of x linpred = u*y(:,i); expectx = exp(linpred); err = x(:,i) - expectx; % rescale residual by derivative of link adjx = linpred; mask = (expectx > 0); adjx(mask) = linpred(mask) + err(mask) ./ expectx(mask); % weighted regression (regularized in case v is underdetermined) uwts = repmat(expectx, [1 l]) .* u; y(:,i) = (u' * uwts + 1e-15*speye(l)) \ (uwts' * adjx); end % check convergence % TODO: should probably check for convergence of expectx instead of y curnorm = sum(sum(abs(y))) / prod(size(y)); change = sum(sum(abs(y - lasty))) / prod(size(y)); % fprintf('%3d: %g\n', iter, change); if (change / (curnorm + converge) < converge) % fprintf('converged %d\n', iter); break; end end