Building Functions using CVX

This question concerns using CVX within a custom MatLab function (i.e. an .m file). Specifically, I’m wondering if there’s a way to pass optimization constraints as an argument of the custom function.

For simplicity, consider something such as $$\min_{\beta} | X\beta|2^2 - 2\langle y, X\beta\rangle \text{ subject to } |
\beta |
{\infty} \leq 1, \beta \succeq 0$$ which would be coded as perhaps

function [ b ] = HS(X, y, C)

d = min(size(X));

    cvx_begin
        variable b(d)
        minimize( (X*b)'*(X*b) - 2*(X*b)'*y )
        subject to
           C
    cvx_end

end

where C = [ norm(b, inf) <= 1 ; b >= 0]. I’ve tried creating C using MatLab’s symbolic toolbox, but this didn’t work within the function itself. CVX either ignored the constraint (which happens if when the constraint is in the line below subject to) or returned an error message along the lines of function of too many variables when the constraint was expressed as subject to C.

Generally, I think its important for CVX to be able to be easily embedded into functions such as this so that complicated functions can be packaged by practitioners and specialists and passed onto decision-makers and other non-technical managers.

CVX is not compatible in any way with Matlab’s symbolic toolbox. But why didn’t this work?

function [ b ] = HS(X, y, C)
    d = min(size(X));
    cvx_begin
        variable b(d)
        minimize( (X*b)'*(X*b) - 2*(X*b)'*y )
        subject to
            norm(b,inf) <= 1
            b >= 0
    cvx_end
end

I mean, that’s how you would build the model outside of a function, I don’t see why it has to be different inside one.

Incidentally, if \beta\geq 0, then \|\beta\|_\infty = \sum_i \beta_i. To simplify your model I would replace norm(b,inf) <=1 with sum(b) <= 1.

Perhaps I was not clear in my initial question. What I’m asking is if it’s possible for arbitrary constraints (that abide by the CVX ruleset), specified as an argument of the function, can be passed to the CVX program embedded in the function. The fact that I chose the two constraints I chose was just simply for example. I want to be able to pass any constraint through C so that an individual not familiar with CVX can simply use a function pre-built by a practitioner.

Please let me know if you’d like me to elaborate more.

And to be clear, the purpose of this thread is to inquire as to which way one would be able to specify these constraints in a function call so that CVX acknowledges them and implements them successfully.

Perhaps you can do what you want using MATLAB strings. So pass a string into your function and/or modify/build up the string as needed (for instance with numerical values), using strcat, sprintf, or whatever. . Then eval the string inside CVX. Here is a simple example showing that it works.

k = 4.14587;
joeblow = sprintf(‘x >= %g’,k);
cvx_begin
variable x
minimize(x)
eval(joeblow)
cvx_end

Calling SeDuMi 1.34: 1 variables, 1 equality constraints

SeDuMi 1.34 (beta) by AdvOL, 2005-2008 and Jos F. Sturm, 1998-2003.
Alg = 2: xz-corrector, Adaptive Step-Differentiation, theta = 0.250, beta = 0.500
Split 1 free variables
eqs m = 1, order n = 3, dim = 3, blocks = 1
nnz(A) = 2 + 0, nnz(ADA) = 1, nnz(L) = 1
it : by gap delta rate t/tP t/tD* feas cg cg prec
0 : 7.19E+00 0.000
1 : 4.19E+00 2.00E-01 0.000 0.0278 0.9900 0.9900 0.51 1 1 1.6E-01
2 : 4.15E+00 8.13E-06 0.000 0.0000 1.0000 1.0000 0.99 1 1
iter seconds digits cx by
2 0.0 Inf 4.1458700000e+00 4.1458700000e+00
|Ax-b| = 1.1e-15, [Ay-c]_+ = 0.0E+00, |x|= 1.0e+01, |y|= 1.0e+00

Detailed timing (sec)
Pre IPM Post
6.005E-03 1.400E-02 9.958E-04
Max-norms: ||b||=4.145870e+00, ||c|| = 1,
Cholesky |add|=0, |skip| = 0, ||L.L|| = 1.

Status: Solved
Optimal value (cvx_optval): +4.14587

OK, I understand what you’re saying now; and unfortunately that is not going to be possible with CVX, unless you use the string approach that Mark is advocating. It is not likely something that we are going to be able to add for architectural reasons.

Sound good, let me give it a shot.

Thanks for the help you two.

Good luck.

Actually, i made my example more complicated than it needed to be. The following accomplishes exactly the same thing.

k = 4.14587;
joeblow = ‘x >= k’;
cvx_begin
variable x
minimize(x)
eval(joeblow)
cvx_end

1 Like