# 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.

Regards,
Frank

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.

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