Calling CVX inside a function


#1

Hello -

First off, thanks to all who contribute to this forum, it’s been a big help as I’m learning CVX.

My question: I’m wrapping my CVX model in a for loop and calling CVX inside another function, e.g.,

for n = 1:N
    w = call_cvx(n);
end

where

function w = call_cvx(n)
    cvx_begin
          variable w(n)
          minimize "some function that involves w"
    cvx_end

However, I get the following error when I try to call call_cvx:

Undefined function 'variable' for input arguments of type 'char'.

I’ve seen in other posts about how CVX cannot be used in a parfor loop, but is this true for general for loops?


#2

Yes, it is possible.
You are doing wrong something else.


(Mark L. Stone) #3

After assigning a value to N, I executed your function and calling sequence EXACTLY as written, where I put in the lines

minimize(norm(w))
w >= 0

in place of your placeholder

minimize "some function that involves w"

It worked correctly, and on each function exit, w contained the argmin from the optimization. That being said, the MATLAB editor did display some warnings (for instance, the variable declaration), presumably because it doesn’t “understand” what CVX is doing.


#4

@Mark L. Stone: Thanks for checking. I don’t always get the error, but oddly enough it runs fine if I just paste the loop directly into the Matlab window. I’m not doing anything funny before the CVX call, only running cvx_clear and cvx_solver_settings('MSK_IPAR_NUM_THREADS',2).


(Michael C. Grant) #5

Let me ask you this: is the function defined inside its own file, or is it nested inside another function?


#6

@mcg: The function I’m optimizing is defined inside call_cvx as minimize norm(w) + (C/M)*sum(log_sum_exp(tmp')) where tmp = [zeros(M,1) -Y.*(S'*HAm*w+w0)] (i.e., just standard logistic regression).


(Michael C. Grant) #7

No, my question is: is that the only thing inside the file, or is there something else? CVX is known not to work inside nested functions, for instance.


#8

@mcg: Got ya. I have a main script that calls call_cvx, which is it’s own file and not nested within another function. So is there something simple I’m missing? In my main script, I call cvx_clear to reset things before I iterate, and I also make sure CVX is in my path.


(Michael C. Grant) #9

I’m honestly not sure what’s going on. I embed CVX models into functions all the time. Heck, most CVX functions do that. I am stumped at the moment.


#10

I am a new user, also wondering if cvx could be made compatible with nested functions. If you have any nested functions in your code, then your workspace is static and cvx’s calls to assignin() and evalin() cause a series of errors.

To hopefully overcome this, one by one I initialized variables in my nested code:

% problem setup
m = 16; n = 8;
A = complex(randn(m,n),randn(m,n));
b = complex(randn(m,1),randn(m,1));

% local initializations
x = []; % decision variable
cvx_problem = [];
cvx_status = [];
cvx_optval = [];
cvx_optbnd = [];
cvx_slvitr = [];
cvx_slvtol = [];
cvx_cputime = [];
Aeq = [];
pop = @() 0;

% cvx
cvx_begin
    variable x(n) complex
    minimize( norm(A*x-b) )
cvx_end

Actually, this got me pretty far. The problem is entered and solved. But… pop() throws a curveball. pop() is a method found in cvx/lib/@cvxprob. It’s called by cvx_end.m as evalin(‘caller’,‘pop(…)’). So, I tried two things:

  1. copied pop.m to the local dir
  2. added assignin(‘caller’,‘pop’,@pop) to cvx_end.m before the evalin().

For some reason, doing either of these caused matlab to crash instantly (segmentation violation).

So, I gave up. Maybe it’s just my machine and it will work for others, or perhaps someone could solve the problem with pop()?

  • Peter

PS As a new user I have to say wow, CVX is really nice!