简体   繁体   中英

Error using fmincon matlab

I want to solve a simple problem with fmincon but It returns an error message. I have 2 functions f_2 and f_1 and I want to minimize each of them individually. I want to write f_1 and f_2 in a one matlab function ie, my fun.m. Then I want to call each of them using an index from the main code. Here is the code you can see:

main code: 
 AA=[1 2 -1 -0.5 1];bb=-2;
      xo=[1 1 1 1 1]; 
      VLB=[-1 -1 -1 -1 -1]; 
      VUB=[100 100 100 100 100]; 
  for F_index = 1:2

      [x,fval]=fmincon(@myfun,xo,AA,bb,[],[],VLB,VUB)
      end

%% here is the function

function f = myfun(x, F_index) 
 if F_index == 1
   f = norm(x)^2 - 4*x(4)*(x(2) + 3.4*x(5))^2  ;
 end 
 if F_index == 2
  f = 100*(x(3) - x(5)) + (3*x(1)+2*x(2) - x(3)/3)^2 + 0.01*(x(4) - x(5))
 end 

Undefined function or variable 'F_index'.

Error in myfun (line 2) if F_index == 1

Error in fmincon (line 564) initVals.f = feval(funfcn{3},X,varargin{:});

Error in main (line 6) [x,fval]=fmincon(@myfun,xo,AA,bb,[],[],VLB,VUB) Caused by: Failure in initial user-supplied objective function evaluation. FMINCON cannot continue.

The error message clearly states the problem: The variable F_index is undefined within the function myfun . Variables in Matlab have a scope restricted to the function (or rather "workspace") within which they are defined. They can be made "global", but that's not something you normally want to do.

A workaround is to use nested functions, where variables of the enclosing function become available in the nested function:

function main_function
    AA=[1 2 -1 -0.5 1];bb=-2;
    xo=[1 1 1 1 1]; 
    VLB=[-1 -1 -1 -1 -1]; 
    VUB=[100 100 100 100 100]; 
    F_index = 1;

    for F_index = 1:2
        [x,fval]=fmincon(@myfun,xo,AA,bb,[],[],VLB,VUB)
    end

    function f = myfun(x) 
       if F_index == 1
           f = norm(x)^2 - 4*x(4)*(x(2) + 3.4*x(5))^2  ;
       end
       if F_index == 2
           f = 100*(x(3) - x(5)) + (3*x(1)+2*x(2) - x(3)/3)^2 + 0.01*(x(4) - x(5))
       end
    end 
end

Now myfun is nested in main_function and has access to its variables.

You can bind extra arguments using anonymous functions :

fmincon(@(x) myfun(x, F_index), ...)

Here, the value of F_index is evaluated and becomes part of the anonymous function.

However, these look like completely independent functions. Why not separate them all the way, and use a cell array of handles for the iteration?

fcns = {@fun1, @fun2};
for F_index = 1:2
    [x,fval]=fmincon(fcns{F_index},xo,AA,bb,[],[],VLB,VUB)
end

You need to learn about variables in/out functions.

Practically in any programming language, when you enter a function, that function can only access the variables that are created inside, or that are passed as an argument as x , y , z and potato in the next example: myfun(x,y,z, potato) .

This means that in:

function f = myfun(x) 
 if F_index == 1
   f = norm(x)^2 - 4*x(4)*(x(2) + 3.4*x(5))^2  ;
 end 
end 

myfun does not have any idea what F_index is.

One of the ways of solving it is declaring F_index as global , but I would recommend you rather change the function somehow, so it doesn't access out of function variables.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM