The implies function and "One or more output arguments not assigned during call to "varargout""

481 views
Skip to first unread message

bin sun

unread,
Sep 25, 2017, 10:26:45 PM9/25/17
to YALMIP

Hi, Johan,


I have a problem like what is shown in picture below. I have three lines, first two are put in position 1 and 2, but line3 can be putted in position 3/4/5. I want to the best position of line3. Now I know I need to use a binary variable to represent the position and use the implies to convert nonlinear to linear. 




I write a yalmip code like this and use gurobi to solve:


clear all

close all


c=[0,0.6058,0.4665,0.3857,0.3293;0.6058,0,0.6058,0.4665,0.3857;0.4665,0.6058,0,0.6058,0.4665;0.3857,0.4665,0.6058,0,0.6058;0.3293,0.3857,0.4665,0.6058,0];

d=[4.019335684198116e+05,4.019335684198116e+05,4.019335684198116e+05,4.019335684198116e+05,4.019335684198116e+05];


I=sdpvar(1,3);  

pos=binvar(1,3);         % so three 0/1, which is 1 means the line3 is here

f=-I(1)-I(2)-I(3);

F=[sum(pos)==1];       % only choose one from three


for k=1:3                      % k=1 means position 3 so k+2 later

F=[F,implies(pos{k}, 1/d(1)*I(1,1)*I(1,1)+c(1,2)/d(1)*I(1,2)*I(1,2)+c(1,k+2)/d(1)*I(1,3)*I(1,3)<=1,

      c(2,1)/d(2)*I(1,1)*I(1,1)+1/d(2)*I(1,2)*I(1,2)+c(2,k+2)/d(2)*I(1,3)*I(1,3)<=1, c(k+2,1)/d(k+2)*I(1,1)*I(1,1)+c(k+2,2)/d(k+2)*I(1,2)*I(1,2)+1/d(k+2)*I(1,3)*I(1,3)<=1)];  

                               % I use implies here means if pos{k}=1, then c(1,k); c(2,k) and d(k) in constraint can be decided and constraint can be write. if pos{k}=0, no constraints added because line3 no here

end

sol=optimize(F,f);

I=value(I) 


But when I run it, MATLAB said "One or more output arguments not assigned during call to "varargout"".
Could you tell me if my method use implies is correct? If wrong, could you please help me correct that constraint line?

Thank you very much for your time and patience,
Best Regards,
Bin

bin sun

unread,
Sep 25, 2017, 10:46:00 PM9/25/17
to YALMIP
I=intvar(1,3), in my question int or sdp results both ok as long as it can be solved.

Johan Löfberg

unread,
Sep 26, 2017, 4:28:10 AM9/26/17
to YALMIP
Why don't you simply force at least two elements to be zero

I = intvar(5,1);
d = binvar(3,1);

[implies(d(1),I(3) == 0), implies(d(2),I(4) == 0), implies(d(3),I(5) == 0), sum(d)==2]


Johan Löfberg

unread,
Sep 26, 2017, 4:30:27 AM9/26/17
to YALMIP
You have more than 2 arguments to implies. implies takes two arguments only.

bin sun

unread,
Sep 26, 2017, 10:40:08 AM9/26/17
to YALMIP
Thank you very much for your reply. Force two empty will be very helpful for my next step's coding.
I still have some questions:
1. You said "I have more than 2 arguments", what do you mean more than two arguments here? like implies(X,Y), Y is the arguments you mean?
2. To force two empty, I change my code like this:
clear all
close all
c=[0,0.6058,0.4665,0.3857,0.3293;0.6058,0,0.6058,0.4665,0.3857;0.4665,0.6058,0,0.6058,0.4665;0.3857,0.4665,0.6058,0,0.6058;0.3293,0.3857,0.4665,0.6058,0];
d=[4.019335684198116e+05,4.019335684198116e+05,4.019335684198116e+05,4.019335684198116e+05,4.019335684198116e+05]

I=intvar(1,5);                  % sdpvar is ok too depend on which can be solved
pos=binvar(1,3);             % these three positions have two empty now
f=-I(1)-I(2)-I(3)-I(4)-I(5);

F=[implies(pos{1},I(3) == 0), implies(pos{2},I(4) == 0), implies(pos{3},I(5) == 0), sum(pos)==2];   %force two empty and after this step there are two I are 0, like I3 and I4 so following constraints                                                                                                                                                            %   can contain these currents, if it's empty, that part should be zero
F=[1/d(1)*I(1)*I(1)+c(1,2)/d(1)*I(2)*I(2)+c(1,3)/d(1)*I(3)*I(3)+c(1,4)/d(1)*I(4)*I(4)+c(1,5)/d(1)*I(5)*I(5)<=1]+       [c(2,1)/d(2)*I(1)*I(1)+1/d(2)*I(2)*I(2)+c(2,3)/d(2)*I(3)*I(3)+c(2,4)/d(2)*I(4)*I(4)+c(2,5)/d(2)*I(5)*I(5)<=1]+[c(3,1)/d(3)*I(1)*I(1)+c(3,2)/d(3)*I(2)*I(2)+1/d(3)*I(3)*I(3)+c(3,4)/d(3)*I(4)*I(4)+c(3,5)/d(3)*I(5)*I(5)<=1]+[c(4,1)/d(4)*I(1)*I(1)+c(4,2)/d(4)*I(2)*I(2)+c(4,3)/d(4)*I(3)*I(3)+1/d(4)*I(4)*I(4)+c(4,5)/d(4)*I(5)*I(5)<=1]+[c(5,1)/d(5)*I(1)*I(1)+c(5,2)/d(5)*I(2)*I(2)+c(5,3)/d(5)*I(3)*I(3)+c(5,4)/d(5)*I(4)*I(4)+1/d(5)*I(5)*I(5)<=1];      %fixed, don't need to change based on different position arrangement, because the                                                                                                                                                                              % first F, two currents already be zero here.

sol=optimize(F,f);
I=value(I)   %double(I)

I think this should be good but when I run it MATLAB still said: One or more output arguments not assigned during call to "varargout" about this line: 
F=[implies(pos{1},I(3) == 0), implies(pos{2},I(4) == 0), implies(pos{3},I(5) == 0), sum(pos)==2];

Could you please tell me how to figure this problem out?

Thank you very much for your time,
Best Regards,
Bin

Johan Löfberg

unread,
Sep 26, 2017, 11:45:57 AM9/26/17
to YALMIP
You're indexing pos using cells.


and your constraint are simply (I(:).^2 + c*(I(:).^2)./d(:) <= 1) (which could have been even more easily written as c*(I.^2)./d<= 1 had you had compatible dimensions on c,d and I, and had 1 in the diagonal of c)

bin sun

unread,
Sep 26, 2017, 12:21:26 PM9/26/17
to YALMIP
Dear Johan,

Thank you very much. After your help, I get the results. Appreciate for your time.

But I get a result use: I=value(I)   %double(I)
and the results show: 435.0000  326.0000  311.0000  325.0000  435.0000

I think I already for two position empty, so the results should have two 0s, why here the result have no 0 and have four totally? Is that mean, if choose pos3 then I =311, if choose pos4 then I=325, if choose pos5 then I=435

Thank you very much for your time,
Bin

Johan Löfberg

unread,
Sep 26, 2017, 12:37:34 PM9/26/17
to YALMIP
You would have to supply the final code you are running now

Johan Löfberg

unread,
Sep 26, 2017, 12:38:43 PM9/26/17
to YALMIP
...but in the code you show above, you are not concatenting the constraints together

bin sun

unread,
Sep 26, 2017, 3:29:17 PM9/26/17
to YALMIP
Dear Johan,

Attached is my final code and it works perfect. Thank you very much. Appreciate for your time.
I have two sets of codes.
Code I:
clear all
close all
c=[0,0.195,0.1502,0.1242,0.3293;1.3795,0,0.4441,0.342,0.8784;1.0622,0.4441,0,0.4441,1.0622;0.8784,0.342,0.441,0,1.3795;0.3293,0.1242,0.1502,0.195,0];
d=[4.019335684198116e+05,9.1523e+05,9.1523e+05,9.1523e+05,4.019335684198116e+05];
I=intvar(1,5);               %int ok too depend on which is simple
pos=binvar(1,3);  
f=-I(1)-I(2)-I(3)-I(4)-I(5);
F=[implies(pos(1),I(3) == 0), implies(pos(2),I(4) == 0), implies(pos(3),I(5) == 0), sum(pos)==2]    %force two empty
F=F+[1/d(1)*I(1)*I(1)+c(1,2)/d(1)*I(2)*I(2)+c(1,3)/d(1)*I(3)*I(3)+c(1,4)/d(1)*I(4)*I(4)+c(1,5)/d(1)*I(5)*I(5)<=1]+[c(2,1)/d(2)*I(1)*I(1)+1/d(2)*I(2)*I(2)+c(2,3)/d(2)*I(3)*I(3)+c(2,4)/d(2)*I(4)*I(4)+c(2,5)/d(2)*I(5)*I(5)<=1]+[c(3,1)/d(3)*I(1)*I(1)+c(3,2)/d(3)*I(2)*I(2)+1/d(3)*I(3)*I(3)+c(3,4)/d(3)*I(4)*I(4)+c(3,5)/d(3)*I(5)*I(5)<=1]+[c(4,1)/d(4)*I(1)*I(1)+c(4,2)/d(4)*I(2)*I(2)+c(4,3)/d(4)*I(3)*I(3)+1/d(4)*I(4)*I(4)+c(4,5)/d(4)*I(5)*I(5)<=1]+[c(5,1)/d(5)*I(1)*I(1)+c(5,2)/d(5)*I(2)*I(2)+c(5,3)/d(5)*I(3)*I(3)+c(5,4)/d(5)*I(4)*I(4)+1/d(5)*I(5)*I(5)<=1];

sol=optimize(F,f);
I=value(I)   %double(I)
pos=double(pos)

Code II:
clear all
close all
% only thing different is here: I write a loop to build the c and d matrix:
L=1000; 
dist=100;  
n=5;   
N=[3,1,1,1,3];
R=[0.079e-3,0.0763e-3,0.0763e-3,0.0763e-3,0.079e-3];
lamda1=[0,0,0,0,0];
lamda2=[0,0,0,0,0];
Tamb=[15,15,15,15,15];
Tmax=[90-Tamb(1),90-Tamb(2),90-Tamb(3),90-Tamb(4),90-Tamb(5)];  
u=[1,1,1,1,1];   
rous=[1,1,1,1,1];   
Wd=[0,0,0,0,0];
De=[72.9,35.8,35.8,35.8,72.9];
T1=[0.325,0.214,0.214,0.214,0.325];
T2=[0.042,0.109,0.109,0.109,0.042];
T3=[0,0,0,0,0];
T4=[0.637,0.751,0.751,0.751,0.637];
c= zeros(n,n);
d= zeros(1,n);     
deno=zeros(1,n);
a=zeros(1,n);
sum=0

for i=1:n
    for j=1:n 
        if j~=i
            dprim=sqrt((i-j)^2*dist^2+4*L^2)
            d0=dist*abs(i-j)
            c(i,j)=(N(j)*R(j)*(1+lamda1(j)+lamda2(j))*u(j)*(rous(j)/(2*pi))*log(dprim/d0))/(R(i)*T1(i)+N(i)*R(i)*(1+lamda1(i))*T2(i)+N(i)*R(i)*(1+lamda1(i)+lamda2(i))*(T3(i)+T4(i)))
            sum=sum+N(j)*Wd(j)*log(dprim/d0);
        else
            c(i,j)=0
        end
    end
    d(i)=(Tmax(i)-Wd(i)*(0.5*T1(i)+N(i)*(T2(i)+T3(i)+T4(i)))-(rous(j)/(2*pi))*sum)/(R(i)*T1(i)+N(i)*R(i)*(1+lamda1(i))*T2(i)+N(i)*R(i)*(1+lamda1(i)+lamda2(i))*(T3(i)+T4(i)))
end
% end of calculating matrix c and d, which will give me the same c and d as CODE I.

I=intvar(1,5);               %int ok too depend on which is simple
pos=binvar(1,3);  
f=-I(1)-I(2)-I(3)-I(4)-I(5);
F=[implies(pos(1),I(3) == 0), implies(pos(2),I(4) == 0), implies(pos(3),I(5) == 0), sum(pos)==2]    %force two empty
F=F+[1/d(1)*I(1)*I(1)+c(1,2)/d(1)*I(2)*I(2)+c(1,3)/d(1)*I(3)*I(3)+c(1,4)/d(1)*I(4)*I(4)+c(1,5)/d(1)*I(5)*I(5)<=1]+[c(2,1)/d(2)*I(1)*I(1)+1/d(2)*I(2)*I(2)+c(2,3)/d(2)*I(3)*I(3)+c(2,4)/d(2)*I(4)*I(4)+c(2,5)/d(2)*I(5)*I(5)<=1]+[c(3,1)/d(3)*I(1)*I(1)+c(3,2)/d(3)*I(2)*I(2)+1/d(3)*I(3)*I(3)+c(3,4)/d(3)*I(4)*I(4)+c(3,5)/d(3)*I(5)*I(5)<=1]+[c(4,1)/d(4)*I(1)*I(1)+c(4,2)/d(4)*I(2)*I(2)+c(4,3)/d(4)*I(3)*I(3)+1/d(4)*I(4)*I(4)+c(4,5)/d(4)*I(5)*I(5)<=1]+[c(5,1)/d(5)*I(1)*I(1)+c(5,2)/d(5)*I(2)*I(2)+c(5,3)/d(5)*I(3)*I(3)+c(5,4)/d(5)*I(4)*I(4)+1/d(5)*I(5)*I(5)<=1];

sol=optimize(F,f);
I=value(I)   %double(I)
pos=double(pos)


You can see that code I and code II are exactly same but only code II add a loop to calculate the Matrix c and d. But when run code I, the result is perfect.
But if I run the code II, MATLAB will say:  Function 'subsindex' is not defined for values of class 'sdpvar'. about this line:
F=[implies(pos(1),I(3) == 0), implies(pos(2),I(4) == 0), implies(pos(3),I(5) == 0), sum(pos)==2];

I try to figure out why this happened but failed. Could you please tell me how to correct it?

Thank you very much,
Best Regards,
Bin

Johan Löfberg

unread,
Sep 26, 2017, 3:40:54 PM9/26/17
to YALMIP
>> sum

sum =

     0


...

and write vectorized code. why write it as the unreadable unvectorized version when it simply is c*I.^2./d <=1 once you use the right dimensions

bin sun

unread,
Sep 26, 2017, 3:44:20 PM9/26/17
to YALMIP
Yeah, you are write. I will simple my code. Thank you very much.

sum = 0 is correct since wd are all zero here, so 0+0 always 0 in this code. But even sum is wrong, c and d result matrix are the same as CODE I, why the Code II can't run?

Johan Löfberg

unread,
Sep 26, 2017, 3:46:12 PM9/26/17
to YALMIP
what is sum([1 2 3])...

bin sun

unread,
Sep 26, 2017, 3:53:28 PM9/26/17
to YALMIP

In fact, the c and d is using these two equations to calculate, the sum mean the "sum part" in di equation.


But even my code is wrong, the resulting c and d matrix are the same as CODE I. It should be ok to run. This really confused me.


Thank you very much for your time.

Bin


Johan Löfberg

unread,
Sep 26, 2017, 3:55:17 PM9/26/17
to YALMIP
you have defined sum = 0, then you try to use the function sum...

bin sun

unread,
Sep 26, 2017, 3:58:23 PM9/26/17
to YALMIP
Oh, exactly. Now the code works perfect. Thank you very much. I am so sorry to bother you.

I will simply the code now.

Thank you very much for your help,
Best Regards,
Bin
Message has been deleted

LukasChen

unread,
Jul 1, 2020, 7:25:04 PM7/1/20
to YALMIP
Hi Dr.Johan

I encountered the same error here. But there is no hint which line it is. any method to check which line is issue ?

Literally I use implies operator in this way. The whole code is quite long so I don't post here.

y and x are binvar.  y = binvar(n,m); x = binvar(z,m,m);

for i = 1:n
    for k = 1:m
        C = [C , implies(y(i,k)==1, sum(sum(x(:,k,:))) > 0)];
    end
end

or like this

for i = 1:z
    if stop_flag == 1 && i+1 <= z
         C = [C, implies( sum(sum(x(i,:,:))) == 0, sum(sum(x(i+1,:,:))) == 0 )];
         continue;
    end
    for k = 1:m
        for s = 1:m
            if i+1 < z
                C = [C, implies( x(i,k,s) == 1, sum(x(i+1,s,:)) == 1 )]; 
            end
            if i-1 > 0
                C = [C, implies( sum(sum(x(i,:,:))) == 0, sum(x(i-1,:,dst)) == 1 )];
            end
            C = [C, implies( sum(sum(x(i,:,:))) == 0, stop_flag ==1) ];  %% if a panel is 0, means we finished
            if stop_flag == 1 %% if once x(i,:,:) is 0, no need to go on
                break;
            end
        end
        if stop_flag ==1
            break;
        end
    end
end


Error info:
One or more output arguments not assigned during call to "varargout".

Error in implies (line 62)
        varargout{1} = implies_internal(varargin{3:end});

Error in lmi/expandmeta (line 7)
    Fnew{i} = feval(F.clauses{i}.data{1},'expand',[],F.clauses{i}.data{2:end});

Error in expandmodel (line 48)
        F = expandmeta(F);

Error in compileinterfacedata (line 116)
    [F,failure,cause,operators] = expandmodel(F,h,options);

Error in solvesdp (line 231)
[interfacedata,recoverdata,solver,diagnostic,F,Fremoved,ForiginalQuadratics] =
compileinterfacedata(F,[],logdetStruct,h,options,0,solving_parametric);

Error in optimize (line 31)
[varargout{1:nargout}] = solvesdp(varargin{:});

Error in main (line 179)
optimize(C,objective, options);

Error in run (line 91)
evalin('caller', strcat(script, ';'));
 
cheers.

Johan Löfberg

unread,
Jul 2, 2020, 2:34:41 AM7/2/20
to YALMIP
supply reproducible code that runs

LukasChen

unread,
Jul 2, 2020, 3:40:45 AM7/2/20
to YALMIP
Hi Johan

You can find the whole code in attachment, and call it by run main.m, it gonna take a few minutes.

cheers
cplex.rar

Johan Löfberg

unread,
Jul 2, 2020, 5:58:51 AM7/2/20
to YALMIP
First, don't you get a lot of complaints from a sad cat telling you that you cannot use strict inequalities?


This
C = [C, implies( sum(sum(x(i,:,:))) == 0, stop_flag ==1) ]

makes no sense. stop_flag is a constant so either the implications is redundant or impossible (although in practice it won't even run, as you've seen)

the whole code segment makes no sense. you initialize stop_flag to 0, and then never change it, but still check if it is equal to 1 on some places. you seem to have some weird notion of a variable being both a constant in the code, and a decision variable in the resulting optimization problem at the same time
Message has been deleted

LukasChen

unread,
Jul 2, 2020, 6:55:22 AM7/2/20
to YALMIP
Thanks for your answer, Johan

I intend to force stop_flag ==1 when  sum(sum(x(i,:,:))) == 0.  can the implies operator do this ?

second, when you I mention " there is some weird notion of a variable", which one is  it ?

cheers




Johan Löfberg

unread,
Jul 2, 2020, 7:04:41 AM7/2/20
to YALMIP
if you want to control stopflag by the value of the decision variable x, then stopflag also has to be a decision varialbe (sdpvar) so that the solver actually can affect its value

if stopflag is an sdpvar, it cannot be used in the control logic of the code that sets up the model (if stopflag == 1 etc)

Johan Löfberg

unread,
Jul 2, 2020, 7:06:59 AM7/2/20
to YALMIP
It sort of look like you want to have a model whose structure depends on the value of some of the values of the optimal solution (if the solution x has some property, you want to stop constructing the model). that is simply not possible. You setup a model of fixed size and structure using YALMIP, and that model is then sent to the model to compute the optimal value on all variables

LukasChen

unread,
Jul 2, 2020, 7:16:15 AM7/2/20
to YALMIP
So, literally the problem should be 'static', all I can use are static arrays, variables, static values.

Thanks Johan, I will try to find another way.

Johan Löfberg

unread,
Jul 2, 2020, 7:18:39 AM7/2/20
to YALMIP
The only thing that can be sent to a solver is basically (A,b,E,f) in the model Ax<=b, Ex==f, and YALMIP is a tool to create those constant matrices from the high-level representation

LukasChen

unread,
Jul 2, 2020, 7:35:15 AM7/2/20
to YALMIP
Ok, thanks very much.
Reply all
Reply to author
Forward
0 new messages