Skip to content

Commit

Permalink
More cleanup of the index() issue, and of the keywords as well.
Browse files Browse the repository at this point in the history
  • Loading branch information
mcg1969 committed Jul 2, 2013
1 parent 3ff2d97 commit 958b6d3
Show file tree
Hide file tree
Showing 21 changed files with 178 additions and 244 deletions.
15 changes: 7 additions & 8 deletions commands/cvx_end.m
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,11 @@
global cvx___
prob = evalin( 'caller', 'cvx_problem', '[]' );
if ~isa( prob, 'cvxprob' ),
error( 'No cvx problem exists in this scope.' );
error( 'No CVX model exists in this scope.' );
elseif isempty( cvx___.problems ) || cvx___.problems( end ).self ~= prob,
error( 'Internal CVX data corruption. Please CLEAR ALL and rebuild your model.' );
end
p = index( prob );
if p ~= length( cvx___.problems ),
error( 'Internal cvx data corruption.' );
end
pstr = cvx___.problems( p );
pstr = cvx___.problems( end );
estruc = [];

if isempty( pstr.objective ) && isempty( pstr.variables ) && isempty( pstr.duals ) && nnz( pstr.t_variable ) == 1,
Expand Down Expand Up @@ -80,7 +78,7 @@
solve( prob );
catch estruc
end
pstr = cvx___.problems( p );
pstr = cvx___.problems( end );

%
% Pause again!
Expand Down Expand Up @@ -126,7 +124,8 @@
% Determine the parent problem
%

if length( cvx___.problems ) < 2,
p = length( cvx___.problems );
if p < 2,
error( 'Internal cvx data corruption.' );
end
np = p - 1;
Expand Down
18 changes: 10 additions & 8 deletions keywords/binary.m
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ function binary( varargin )
%BINARY Declares an binary variable.
% BINARY VARIABLE x
% where x is a valid MATLAB variable name, declares a scalar variable for
% the current CVX problem, and constraints it to the set {0,1}. Put
% the current CVX problem, and constrains it to the set {0,1}. Put
% another way, it is equivalent to
% integer variable x
% 0 <= x <= 1
Expand All @@ -27,16 +27,18 @@ function binary( varargin )
%
% See also INTEGER, VARIABLE, VARIABLES.

if nargin < 2 || ~iscellstr( varargin ),
error( 'Syntax: binary variable <variable> or binary variables <variables>' );
elseif strcmpi( varargin{1}, 'variable' ),
evalin( 'caller', sprintf( '%s ', 'variable', varargin{2:end}, ' binary' ) );
elseif strcmpi( varargin{1}, 'variables' ),
if nargin < 2,
error( 'Incorrect syntax for BINARY VARIABLE(S). Type HELP BINARY for details.' );
elseif ~iscellstr( varargin ),
error( 'All arguments must be strings.' );
elseif strcmp( varargin{1}, 'variable' ),
evalin( 'caller', sprintf( '%s ', 'variable', varargin{2:end}, 'binary' ) );
elseif strcmp( varargin{1}, 'variables' ),
for k = 2 : nargin,
evalin( 'caller', sprintf( '%s ', 'variable', varargin{k}, ' binary' ) );
evalin( 'caller', sprintf( '%s ', 'variable', varargin{k}, 'binary' ) );
end
else
error( 'Syntax: binary variable <variable> or binary variables <variables>' );
error( 'Incorrect syntax for BINARY VARIABLE(S). Type HELP BINARY for details.' );
end

% Copyright 2012 CVX Research, Inc.
Expand Down
72 changes: 37 additions & 35 deletions keywords/dual.m
Original file line number Diff line number Diff line change
Expand Up @@ -46,55 +46,57 @@
%
% See also VARIABLE, VARIABLES.

if ~evalin( 'caller', 'exist(''cvx_problem'',''var'')', '0' ),
error( 'A cvx problem does not exist in this scope.' );
if nargin < 2,
error( 'Incorrect syntax for DUAL VARIABLE(S). Type HELP DUAL for details.' );
elseif nargout && nargout ~= length( varargin ) - 1,
error( 'Incorrect number of output arguments.' );
elseif ~iscellstr( varargin ),
error( 'All arguments must be strings.' );
end

prob = evalin( 'caller', 'cvx_problem' );
if strcmp( varargin{1}, 'variable' ),
error( nargchk( 2, 2, nargin ) ); %#ok
varargin(1) = [];
elseif strcmp( varargin{1}, 'variables' ),
error( nargchk( 2, Inf, nargin ) ); %#ok
varargin(1) = [];
global cvx___
prob = evalin( 'caller', 'cvx_problem', '[]' );
if ~isa( prob, 'cvxprob' ),
error( 'No CVX model exists in this scope.' );
elseif isempty( cvx___.problems ) || cvx___.problems( end ).self ~= prob,
error( 'Internal CVX data corruption. Please CLEAR ALL and rebuild your model.' );
end

nargs = length( varargin );
if nargout > 0,
error( nargoutchk( nargs, nargs, nargout ) ); %#ok
if strcmp( varargin{1}, 'variable' ),
if nargin > 2,
error( 'Too many input arguments.\nTrying to declare multiple dual variables? Use the DUAL VARIABLES command instead.', 1 ); %#ok
end
elseif ~strcmp( varargin{1}, 'variables' ),
error( 'Incorrect syntax for DUAL VARIABLE(S). Type HELP DUAL for details.' );
end

for k = 1 : nargs,
nm = varargin{k};
xt = find( nm == '{' );
if isempty( xt ),
x.name = nm;
x.size = [];
elseif nm(end) ~= '}',
error( 'Invalid dual variable specification: %s', nm );
else
x.name = nm( 1 : xt( 1 ) - 1 );
x.size = nm( xt( 1 ) + 1 : end - 1 );
for k = 2 : nargin,
arg = varargin{k};
toks = regexp( arg, '^\s*([a-zA-Z]\w*)\s*({.*})?\s*$', 'tokens' );
if isempty( toks ),
error( 'Invalid dual variable specification: %s', arg );
end
if ~isvarname( x.name ),
error( 'Invalid dual variable specification: %s', nm );
elseif x.name( end ) == '_',
error( 'Invalid dual variable specification: %s\n Variables ending in underscores are reserved for internal use.', nm );
nam = toks{1}{1};
siz = toks{1}{2};
if nam(end) == '_',
error( 'Invalid dual variable specification: %s\n Variables ending in underscores are reserved for internal use.', arg );
end
if ischar( x.size ),
x.size = evalin( 'caller', [ '[', x.size, '];' ], 'NaN' );
[ temp, x.size ] = cvx_check_dimlist( x.size, true );
if ~isempty( siz ),
try
siz = evalin( 'caller', [ '[', siz(2:end-1), ']' ] );
catch exc
throw( MException( exc.identifier, sprintf( 'Error attempting to determine size of: %s\n %s', arg, exc.message ) ) );
end
[ temp, siz ] = cvx_check_dimlist( siz, true );
if ~temp,
error( 'Invalid variable specification: %s\n Dimension list must be a vector of finite nonnegative integers.', nm );
error( 'Invalid dual variable specification: %s\n Dimension list must be a vector of finite nonnegative integers.', arg );
end
end
temp = newdual( prob, x.name, x.size );
if nargout > 0,
varargout{k} = temp; %#ok
temp = newdual( prob, nam, siz );
if nargout,
varargout{k-1} = temp; %#ok
end
assignin( 'caller', x.name, temp );
assignin( 'caller', nam, temp );
end

% Copyright 2012 CVX Research, Inc.
Expand Down
15 changes: 7 additions & 8 deletions keywords/epigraph.m
Original file line number Diff line number Diff line change
Expand Up @@ -31,15 +31,14 @@ function epigraph( varargin )
%
% See also VARIABLE, HYPOGRAPH.

if ~iscellstr( varargin ),
error( 'EPIGRAPH must be used in command mode.' );
elseif nargin ~= 2 || ~strcmpi( varargin{1}, 'variable' ),
error( 'Syntax: epigraph variable <variable>' );
elseif ~isa( evalin( 'caller', 'cvx_problem', '[]' ), 'cvxprob' ),
error( 'EPIGRAPH can only be used within a CVX model.' );
else
evalin( 'caller', sprintf( '%s ', 'variable', varargin{2:end}, ' epigraph_' ) );
if nargin < 2,
error( 'Incorrect syntax for EPIGRAPH VARIABLE. Type HELP EPIGRAPH for details.' );
elseif ~iscellstr( varargin ),
error( 'All arguments must be strings.' );
elseif ~strcmp( varargin{1}, 'variable' ),
error( 'Incorrect syntax for EPIGRAPH VARIABLE. Type HELP EPIGRAPH for details.' );
end
evalin( 'caller', sprintf( '%s ', 'variable', varargin{2:end}, ' epigraph_' ) );

% Copyright 2012 CVX Research, Inc.
% See the file COPYING.txt for full copyright information.
Expand Down
48 changes: 22 additions & 26 deletions keywords/expression.m
Original file line number Diff line number Diff line change
Expand Up @@ -20,50 +20,46 @@
%
% See also EXPRESSIONS.

global cvx___
prob = evalin( 'caller', 'cvx_problem', '[]' );
if ~isa( prob, 'cvxprob' ),
error( 'A cvx problem does not exist in this scope.' );
error( 'No CVX model exists in this scope.' );
elseif isempty( cvx___.problems ) || cvx___.problems( end ).self ~= prob,
error( 'Internal CVX data corruption. Please CLEAR ALL and rebuild your model.' );
elseif nargin > 1,
error( 'Too many input arguments.\nTrying to declare multiple expression holders? Use the EXPRESSIONS keyword instead.', 1 ); %#ok
end

%
% Step 1: separate the name from the parenthetical
% Step 1: separate the name from the parenthetical, verify the name
%

xt = find( nm == '(' );
if isempty( xt ),
x.name = nm;
x.size = [1,1];
elseif nm( end ) ~= ')',
error( 'Invalid expression specification: %s', nm );
else
x.name = nm( 1 : xt( 1 ) - 1 );
x.size = nm( xt( 1 ) + 1 : end - 1 );
end
if ~isvarname( x.name ),
error( 'Invalid expression specification: %s', nm );
elseif x.name( end ) == '_',
error( 'Invalid expression specification: %s\n Variables ending in underscores are reserved for internal use.', nm );
elseif exist( [ 'cvx_s_', x.name ], 'file' ) == 2,
error( [ 'Invalid expression specification: %s\n', ...
' The name "%s" is reserved as a matrix structure modifier,\n', ...
' which can be used only with the VARIABLE keyword.' ], nm, x.name );
toks = regexp( nm, '^\s*([a-zA-Z]\w*)\s*(\(.*\))?\s*$', 'tokens' );
if isempty( toks ),
error( 'Invalid variable specification: %s', nm );
end
tt = evalin( 'caller', x.name, '[]' );
if isa( tt, 'cvxobj' ) && cvx_id( tt ) >= cvx_id( prob ),
error( 'Invalid expression specification: %s\n Name already used for another CVX object.', nm );
toks = toks{1};
x.name = toks{1};
x.size = toks{2};
if x.name(end) == '_',
error( 'Invalid expression specification: %s\n Names ending in underscores are reserved for internal use.', nm );
end

%
% Step 2: Parse the size. In effect, all we do here is surround what is
% replace the surrounding parentheses with square braces and evaluate. All
% that matters is the result is a valid size vector. In particular, it
% need no be a simple comma-delimited list.
% need to be a simple comma-delimited list.
%

if ischar( x.size ),
x.size = evalin( 'caller', [ '[', x.size, '];' ], 'NaN' );
if isempty( x.size ),
x.size = [];
else
try
x.size = evalin( 'caller', [ '[', x.size(2:end-1), '];' ] );
catch exc
throw( MException( exc.identifier, exc.message ) );
end
[ temp, x.size ] = cvx_check_dimlist( x.size, true );
if ~temp,
error( 'Invalid expression specification: %s\n Dimension list must be a vector of finite nonnegative integers.', nm );
Expand Down
6 changes: 4 additions & 2 deletions keywords/expressions.m
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,10 @@ function expressions( varargin )
%
% See also EXPRESSION.

if ~iscellstr( varargin ),
error( 'EXPRESSIONS must be used in command mode.' );
if nargin < 1,
error( 'Incorrect syntax for EXPRESSIONS. Type HELP EXPRESSIONS for details.' );
elseif ~iscellstr( varargin ),
error( 'All arguments must be strings.' );
end
for k = 1 : nargin,
evalin( 'caller', [ 'expression ', varargin{k} ] );
Expand Down
15 changes: 7 additions & 8 deletions keywords/hypograph.m
Original file line number Diff line number Diff line change
Expand Up @@ -31,15 +31,14 @@ function hypograph( varargin )
%
% See also VARIABLE, EPIGRAPH.

if ~iscellstr( varargin ),
error( 'HYPOGRAPH must be used in command mode.' );
elseif nargin ~= 2 || ~strcmpi( varargin{1}, 'variable' ),
error( 'Syntax: hypograph variable <variable>' );
elseif ~isa( evalin( 'caller', 'cvx_problem', '[]' ), 'cvxprob' ),
error( 'HYPOGRAPH can only be used within a CVX model.' );
else
evalin( 'caller', sprintf( '%s ', 'variable', varargin{2:end}, ' hypograph_' ) );
if nargin < 2,
error( 'Incorrect syntax for HYPOGRAPH VARIABLE. Type HELP HYPOGRAPH for details.' );
elseif ~iscellstr( varargin ),
error( 'All arguments must be strings.' );
elseif ~strcmp( varargin{1}, 'variable' ),
error( 'Incorrect syntax for HYPOGRAPH VARIABLE. Type HELP HYPOGRAPH for details.' );
end
evalin( 'caller', sprintf( '%s ', 'variable', varargin{2:end}, ' hypograph_' ) );

% Copyright 2012 CVX Research, Inc.
% See the file COPYING.txt for full copyright information.
Expand Down
14 changes: 8 additions & 6 deletions keywords/integer.m
Original file line number Diff line number Diff line change
Expand Up @@ -25,16 +25,18 @@ function integer( varargin )
%
% See also BINARY, VARIABLE, VARIABLES.

if nargin < 2 || ~iscellstr( varargin ),
error( 'Syntax: integer variable <variable> or integer variables <variables>' );
elseif strcmpi( varargin{1}, 'variable' ),
if nargin < 2,
error( 'Incorrect syntax for INTEGER VARIABLE(S). Type HELP INTEGER for details.' );
elseif ~iscellstr( varargin ),
error( 'All arguments must be strings.' );
elseif strcmp( varargin{1}, 'variable' ),
evalin( 'caller', sprintf( '%s ', 'variable', varargin{2:end}, ' integer' ) );
elseif strcmpi( varargin{1}, 'variables' ),
elseif strcmp( varargin{1}, 'variables' ),
for k = 2 : nargin,
evalin( 'caller', sprintf( '%s ', 'variable', varargin{k}, ' integer' ) );
end
else
error( 'Syntax: integer variable <variable> or integer variables <variables>' );
else
error( 'Incorrect syntax for INTEGER VARIABLE(S). Type HELP INTEGER for details.' );
end

% Copyright 2012 CVX Research, Inc.
Expand Down
17 changes: 9 additions & 8 deletions keywords/maximise.m
Original file line number Diff line number Diff line change
Expand Up @@ -2,22 +2,23 @@ function maximise( varargin )

%MAXIMISE Specifiies a concave (or affine) objective to be maximized.

cvx_problem = evalin( 'caller', 'cvx_problem', '[]' );
if isempty( cvx_problem ) || ~isa( cvx_problem, 'cvxprob' ),
error( 'A cvx problem does not exist in this scope.' );
end
if nargin < 1,
global cvx___
prob = evalin( 'caller', 'cvx_problem', '[]' );
if ~isa( prob, 'cvxprob' ),
error( 'No CVX model exists in this scope.' );
elseif isempty( cvx___.problems ) || cvx___.problems( end ).self ~= prob,
error( 'Internal CVX data corruption. Please CLEAR ALL and rebuild your model.' );
elseif nargin < 1,
error( 'Objective expression missing.' );
elseif iscellstr( varargin ),
x = sprintf( '%s,', varargin{:} );
x = evalin( 'caller', x(1:end-1) );
x = evalin( 'caller', sprintf( '%s ', varargin{:} ) );
elseif nargin > 1,
error( 'Too many input arguments.' );
else
x = varargin{1};
end
try
newobj( cvx_problem, 'maximize', x );
newobj( prob, 'maximize', x );
catch exc
rethrow( exc )
end
Expand Down
17 changes: 9 additions & 8 deletions keywords/maximize.m
Original file line number Diff line number Diff line change
Expand Up @@ -2,22 +2,23 @@ function maximize( varargin )

%MAXIMIZE Specifiies a concave (or affine) objective to be maximized.

cvx_problem = evalin( 'caller', 'cvx_problem', '[]' );
if isempty( cvx_problem ) || ~isa( cvx_problem, 'cvxprob' ),
error( 'A cvx problem does not exist in this scope.' );
end
if nargin < 1,
global cvx___
prob = evalin( 'caller', 'cvx_problem', '[]' );
if ~isa( prob, 'cvxprob' ),
error( 'No CVX model exists in this scope.' );
elseif isempty( cvx___.problems ) || cvx___.problems( end ).self ~= prob,
error( 'Internal CVX data corruption. Please CLEAR ALL and rebuild your model.' );
elseif nargin < 1,
error( 'Objective expression missing.' );
elseif iscellstr( varargin ),
x = sprintf( '%s,', varargin{:} );
x = evalin( 'caller', x(1:end-1) );
x = evalin( 'caller', sprintf( '%s ', varargin{:} ) );
elseif nargin > 1,
error( 'Too many input arguments.' );
else
x = varargin{1};
end
try
newobj( cvx_problem, 'maximize', x );
newobj( prob, 'maximize', x );
catch exc
rethrow( exc )
end
Expand Down
Loading

0 comments on commit 958b6d3

Please sign in to comment.