How to add self-defined convex function to atom library?

Dear all, I tried to add the following function to the atom library and got an error message.

f(x, y)=\begin{cases} y \cdot 2^{\frac{x}{y}}, & x > 0, y > 0\\ 0, & y = 0, x \geq 0\\ +\infty, & \text{otherwise} \end{cases}

The error message is given as:

Undefined function ‘newcnstr’ for input arguments of type ‘cvx’.
Error in < (line 22)
b = newcnstr( evalin( ‘caller’, ‘cvx_problem’, ‘[]’ ), x, y, ‘<’ );
Error in myfoo (line 8)
t1 = y < 0 | x <= 0;

I read the FAQ and instructions about adding functions to the atom library. Firstly, I tried to prove f(x, y) is (jointly) convex by verifing the Hessian semidefinite. The Hessian of f is given by

H(f)=\frac{\left(\ln 2\right)^2}{y} 2^{\frac{x}{y}}\begin{bmatrix} 1 & -\frac{x}{y}\\ -\frac{x}{y} & \frac{x^2}{y^2} \end{bmatrix}

Therefore it’s semidefinite. Thus, f(x, y) is convex. I imitated rel_entr in cvx functions and wrote the self-defined function as follows:

function z = myfoo(x, y)

narginchk(2,2);
if ~isreal( x ) || ~isreal( y ),
    error( 'Arguments must be real.' );
end

t1 = y < 0 | x <= 0;
t2 = y == 0 & x >= 0;

x  = max( x, realmin );
y  = max( y, realmin );

z  = y .* 2.^( x ./ y );
z( t1 ) = +Inf;
z( t2 ) = 0;

I also tried to add this function under path cvx/functions, however no difference.

Please enlighten me about this problem. Thanks in advance.

Regards,
Frank

http://cvxr.com/cvx/doc/advanced.html#new-functions-via-the-dcp-ruleset

Let us emphasize that when defining a function this way, the expressions you use must conform to the DCP ruleset, just as they would if they had been inserted directly into a CVX model.

Your function has multiple violations of the DCP ruleset (starting with t1, where you get an error message). I am not optimistic that it can be written in a compliant manner, given that it is not convex over the entirety of its natural domain (to include negative y).

Thanks for your reply. There are two versions of rel-entr in cvx package, one in cvx\functions and the other in cvx\functions\@cvx. I’ll check on the version in cvx\functions\@cvx.

Thanks again for Mark’s suggestion. I reread the user’s guide and found a concept of perspective of a function from Boyd’s book (Page 103, 3.2.6). Actually, my function is a perspective of 2^x, thus it’s convex. On the other hand, thanks to the guidance from Michael C. Grant in another post, I found a way to develop my own function follows DCP ruleset as follows:

function cvx_optval = myFoo( x, y )
cvx_begin
    variables z;
    minimize( z );
    subject to
        {x * log(2), y, z} == exponential;
cvx_end

And it works for me. :slight_smile:

In addition, I’d like to share my understandings about “adding new functions to the atom library” for those who might have the same issue with me. Actually, the code I posted in my question is only suitable for numerical inputs but not for CVX expressions, same with the functions under cvx/functions. The functions under cvx/functions/@cvx are suitable for CVX expressions, thus cvx/functions/@cvx is where atom library located at, i think.

1 Like

Thanks for posting your solution.