Skip to content

Commit

Permalink
Allowing proj_nuclear to take vector input as long as size variable is
Browse files Browse the repository at this point in the history
included
  • Loading branch information
stephenbeckr committed Jan 30, 2014
1 parent b2e24fc commit 4ee1c42
Showing 1 changed file with 26 additions and 5 deletions.
31 changes: 26 additions & 5 deletions proj_nuclear.m
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
function op = proj_nuclear( q )
function op = proj_nuclear( q, sz )

%PROJ_NUCLEAR Projection onto the set of matrices with nuclear norm less than or equal to q.
% OP = PROJ_NUCLEAR( q ) returns a function that implements the
Expand All @@ -8,6 +8,13 @@
% This function is like proj_psdUTrace.m but does not assume
% that inputs are square Hermitian positive semidefinite matrices.
%
% OP = PROJ_NUCLEAR( ..., SZ )
% where SZ = [n1,n2], will assume the input has been vectorized
% and thus will reshape it into a matrix of size n1 x n2. TFOCS
% can handle matrix variables so this form of PROJ_NUCLEAR is not
% always necessary, but it can be easier to find bugs if using
% only vector variables.
%
% This version uses a dense svd decomposition; future versions
% of TFOCS will take advantage of low-rank and/or sparse structure.
% Dual function: prox_spectral.m
Expand All @@ -20,10 +27,11 @@
elseif ~isnumeric( q ) || ~isreal( q ) || numel( q ) ~= 1 || q <= 0,
error( 'Argument must be positive.' );
end
if nargin < 2, sz = []; end
q = proj_simplex( q );
op = @(varargin)proj_nuclear_q( q, varargin{:} );
op = @(varargin)proj_nuclear_q( q, sz, varargin{:} );

function [ v, X ] = proj_nuclear_q( eproj, X, t )
function [ v, X ] = proj_nuclear_q( eproj, sz, X, t )

VECTORIZE = false;
% Input must be a matrix
Expand All @@ -39,13 +47,26 @@
% X = reshape(X, n, n );
% VECTORIZE = true;
% end

% Update, Jan 2014, allowing vector variables, as long
% as the 'sz' variable has been given
if ~isempty(sz)
if size(X,2) > 1
error('proj_nuclear: when using an explicit size value "sz", variable should be a vector');
end
X = reshape(X, sz(1), sz(2) );
VECTORIZE = true;
elseif size(X,2) == 1
warning('proj_nuclear: appears variable is a vector not a matrix. Are you sure you want the SVD of a vector?');
end

v = 0;
if nargin > 2 && t > 0,
if nargin > 3 && t > 0,
[U,D,V] = svd(X,'econ');
[dum,D] = eproj(diag(D),t);
tt = D > 0;
X = U(:,tt)*diag(D(tt))*V(:,tt)';
% if VECTORIZE, X = X(:); end
if VECTORIZE, X = X(:); end
elseif any(svd(X)<0),
v = Inf;
end
Expand Down

0 comments on commit 4ee1c42

Please sign in to comment.