using optimizer with parameter bounds on general nonlinear expression

86 views
Skip to first unread message

YY

unread,
Mar 5, 2018, 12:33:17 PM3/5/18
to YALMIP
The blogpost mentions that
when there are general callback nonlinearities acting on parameters (functions such as exp, log etc), they can (currently) only act on simple parametric variables, i.e., not on any kind of compound expression involving parameters.
So apparently this also includes inequality/constraint expressions involving parameters, like
>> b=sdpvar(2,3,'full'); blim=sdpvar(1,1);
>> P=optimizer([blim<=b<=1-blim], sum(b.^2), [], blim, b); % this is OK
>> P=optimizer([blim<=b<=1-blim], -entropy(b), [], blim, b); % this fails
Error using optimizer (line 303)
Parameters are currently only allowed to enter function such as exp, sin etc as exp(a), sin(b) etc.

I just want to verify that this the intended behavior, not a bug.



Now, in my actual problem, I somehow bypassed this error and created an optimizer, but then optimizer crashes when given a problem, basically like this:
>> x=sdpvar(1,3); xlim=sdpvar(3,1); b=sdpvar(5,3,'full'); c=sdpvar(3,1); cons=[mean(b)==x, c >= x(:) .* xlim];
>> P=optimizer(cons, -sum(entropy(b))+sum(c), [], xlim, {x,c})
Optimizer object with 3 inputs (1 blocks) and 6 outputs (2 blocks). Solver: FMINCON-STANDARD
>> P([0.1 0.2 0.3]')
Matrix dimensions must agree.
Error in optimizer/subsref (line 302)
self.model.evalMap{k}.variableIndex = find(self.model.evalMap{k}.variableIndex == keptvariablesIndex);
Error in optimizer/subsref (line 9)
[varargout{1:nargout}] = subsref(self,subs);

But if I change the objective to something simple, then it works:
>> P=optimizer(cons, -sum(sum(b.^2))+sum(c), [], xlim, {x,c})
Optimizer object with 3 inputs (1 blocks) and 6 outputs (2 blocks). Solver: FMINCON-STANDARD
>> P([0.1 0.2 0.3]')
ans =
  1×2 cell array
    {1×3 double}    {3×1 double}

Is this a bug?

Johan Löfberg

unread,
Mar 5, 2018, 12:44:32 PM3/5/18
to YALMIP
Are you really using the latest version?

Your first example crashes due to strange dimension on the objective, and the second case passes through.

However, there appears to be issues with nonlinear R^n->R operators as you've noticed (such as entropy). Not intended to crash

YY

unread,
Mar 5, 2018, 12:58:43 PM3/5/18
to YALMIP
Hi Johan,
Yes, I'm using the latest version.
Sorry the first example should have been:
>> b=sdpvar(2,3,'full'); blim=sdpvar(1,1);
>> P=optimizer([blim<=b<=1-blim], sum(sum(b.^2)), [], blim, b); % this is OK
>> P=optimizer([blim<=b<=1-blim], -sum(entropy(b)), [], blim, b);
Error using optimizer (line 303)
Parameters are currently only allowed to enter function such as exp, sin etc as exp(a), sin(b) etc.

Are you saying YALMIP actually should be able to handle the second case? Is there anything I can do to try to fix the crash?
I noticed similar crash from logsumexp too.

YY

unread,
Mar 5, 2018, 1:01:49 PM3/5/18
to YALMIP
I downloaded YALMIP .zip file from the website (https://yalmip.github.io/download/) a week ago, so I'm actually not sure if it's the "latest version".
Should I try cloning the git repo instead?

YY

unread,
Mar 5, 2018, 1:07:48 PM3/5/18
to YALMIP
Just to clarify, in the second case (with "P=optimizer(cons, -sum(entropy(b))+sum(c), [], xlim, {x,c})"), the call to create the optimizer passes through, but I'm seeing it crash ("Matrix dimensions must agree" etc.) when being invoked on a parameter value.

YY

unread,
Mar 5, 2018, 1:13:53 PM3/5/18
to YALMIP
FYI I just tried my examples on the current master branch (https://github.com/yalmip/YALMIP), and I observed the same behavior.

Johan Löfberg

unread,
Mar 5, 2018, 1:58:24 PM3/5/18
to YALMIP
I thought you received "Parameters are currently only allowed to enter function such as exp, sin etc as exp(a), sin(b) etc"?
Message has been deleted

YY

unread,
Mar 5, 2018, 2:14:06 PM3/5/18
to YALMIP
Not in my second example:

>> x=sdpvar(1,3); xlim=sdpvar(3,1); b=sdpvar(5,3,'full'); c=sdpvar(3,1); cons=[mean(b)==x, c >= x(:) .* xlim];
>> P=optimizer(cons, -sum(entropy(b))+sum(c), [], xlim, {x,c})    % this call passes through
Optimizer object with 3 inputs (1 blocks) and 6 outputs (2 blocks). Solver: FMINCON-STANDARD
>> P([0.1 0.2 0.3]')    % this crashes

Johan Löfberg

unread,
Mar 5, 2018, 2:15:10 PM3/5/18
to YALMIP
Did you get the message in any example?

The crash is of course something I will have to look into.

To circumvent this, simply use sum(b.*log(b)) instead. It will be slightly less efficient in the solver as the derivatives etc will be done using n calls instead of 1 call, but nothing major I think

YY

unread,
Mar 5, 2018, 3:58:21 PM3/5/18
to YALMIP
Like I mentioned, there's two type of error messages. One is when when an optimizer fails to be created ("Error using optimizer (line 303) Parameters are currently only allowed to enter function such as exp, sin etc as exp(a), sin(b) etc."), the other is after I successfully create an optimizer and try to call it on an input ("Matrix dimensions must agree. Error in optimizer/subsref (line 302) self.model.evalMap{k}.variableIndex = find(self.model.evalMap{k}.variableIndex == keptvariablesIndex); Error in optimizer/subsref (line 9) [varargout{1:nargout}] = subsref(self,subs);"). In my problems I always get the second type.

Thanks for the solution of using "sum(b.*log(b))"; it seems to work for the entropy.

I tried the same trick on logsumexp on another problem of mine, but it doesn't seem to work. One reason might be that YALMIP somehow automatically recognizes the 'log(sum(exp( )))' call as 'logsumexp': e.g., I replaced "A=logsumexp(temp)" with "A=log(sum(exp(temp)))", but the result is still a "Nonlinear scalar (real, models 'logsumexp', 1 variable)". I can post the full example if you want.



Johan Löfberg

unread,
Mar 6, 2018, 2:01:18 AM3/6/18
to YALMIP
Yes, YALMIP outsmarts you there :-) You would have to do something like log(eps+sum(exp(x))) or somehow make an epsilon change ot trick YALMIP into not detecting logsumexp
Reply all
Reply to author
Forward
0 new messages