matlaboptimizationfminsearch

Optimizing for more than one argument in Matlab


Consider the following Matlab function

function [f, dfx1, dfx2] = optifun(x1,x2)
f = x1(1)^2 + x1(2)^2 + x2^2;

% Gradients
dfx1(1) = 2*x1(1);
dfx1(2) = 2*x1(2);
dfx2    = 2*x2;

My objective is to optimize the above function with respect to x1 and x2 using function `fminunc, which also incorporates gradients. I do not know whether it is possible to optimize the function if it's defined in above fashion.

My approach would be(but I know that it won't work):

options = optimoptions('fmincon', 'SpecifyObjectiveGradient',true);
% Initializing 
x10 = [1, 1];
x20 = 1;

[t1, t2] = fminunc(@(x1, x2)optifun(x1,x2), x10, x20, options);

Edits: I have made corrections as pointed out by user:@m7913d


Solution

  • Main problem

    Your function signature does not correspond with the expectations of fminunc: you can only specify one (initial) x vector and one gradient vector, which should contain all the variables/gradients. If you do not want to optifun (which is the preferred solution), you can define a helper function as follows:

    function [f, df] = optifun_helper(x)
      [f, dfx1, dfx2] = optifun(x(1:2),x(3));
      df = [dfx1 dfx2];
    end
    

    And use this function to solve your optimisation problem:

    [x] = fminunc(@(x) optifun_helper(x), [x10 x20], options);
    

    Minor issues

    There are other problems with your code. The first error I get is:

    Error using optimoptions (line 118)
    Invalid solver specified. Provide a solver name or handle (such as 'fmincon' or @fminunc).
    Type DOC OPTIMOPTIONS for a list of solvers.
    

    As the error message suggested, you should specify your solver as the first argument:

    options = optimoptions('fminunc','SpecifyObjectiveGradient',true);
    

    The second problem is that some output variables of optifun are never defined due to spelling issue (you define df1 instead of dfx1):

    function [f, dfx1, dfx2] = optifun(x1,x2)
      f = x1(1)^2 + x1(2)^2 + x2^2;
    
      % Gradients
      dfx1(1) = 2*x1(1);
      dfx1(2) = 2*x1(2);
      dfx2    = 2*x2;
    end
    

    As a conclusion, always read the error messages and documentation carefully and try to fit your code in the expected syntax.