Main Content

传递额外参数

额外参数、固定变量或数据

有时目标函数或约束函数除了自变量之外还有参数。额外的参数可以是数据,也可以表示在优化过程中不变的变量。传递这些参数有三种方法:

全局变量比较麻烦,因为它们不允许在函数间重用名称。最好使用另外两种方法。

通常,对于基于问题的优化,您可以以自然的方式传递额外的参数。请参阅在基于问题的方法中传递额外的参数

例如,假设您要对最小化以下函数

f(x)=(abx12+x14/3)x12+x1x2+(c+cx22)x22(1)

其中,a、b 和 c 使用不同值。求解器接受仅依赖于单个变量(本例中为 x)的目标函数。以下各节显示如何提供附加参数 a、b 和 c。这些解是参数值为 a = 4b = 2.1c = 4 时,使用 fminunc 求得的在 x0 = [0.5 0.5] 附近的解。

匿名函数

要使用匿名函数传递参数,请执行以下操作:

  1. 编写包含以下代码的文件:

    function y = parameterfun(x,a,b,c)
    y = (a - b*x(1)^2 + x(1)^4/3)*x(1)^2 + x(1)*x(2) + ...
        (-c + c*x(2)^2)*x(2)^2;

  2. 通过在 MATLAB® 提示符下输入以下命令,为参数赋值并定义匿名函数的函数句柄 f

    a = 4; b = 2.1; c = 4; % Assign parameter values
    x0 = [0.5,0.5];
    f = @(x)parameterfun(x,a,b,c);

  3. 使用匿名函数调用求解器 fminunc

    [x,fval] = fminunc(f,x0)
    在命令行窗口中显示以下输出:
    Local minimum found.
    
    Optimization completed because the size of the gradient is less than
    the default value of the function tolerance.
    
    x =
       -0.0898    0.7127
    
    fval =
       -1.0316

注意

匿名函数中传递的参数是那些在匿名函数创建时存在的参数。例如

a = 4; b = 2.1; c = 4;
f = @(x)parameterfun(x,a,b,c)

假设您随后将 a 更改为 3,然后运行

[x,fval] = fminunc(f,x0)

您会得到与之前相同的答案,因为 parameterfun 使用的是 a = 4,这是 f 创建时的值。

要更改传递给函数的参数,请重新输入匿名函数来进行更新:

a = 3;
f = @(x)parameterfun(x,a,b,c)

您可以创建包含多个参数的匿名函数。例如,要使用 lsqcurvefit,请首先创建一个接受两个输入参数 xxdata 的函数:

fh = @(x,xdata)(sin(x).*xdata +(x.^2).*cos(xdata));
x = pi; xdata = pi*[4;2;3];
fh(x, xdata)
ans =

    9.8696
    9.8696
   -9.8696
现在调用 lsqcurvefit
% Assume ydata exists
x = lsqcurvefit(fh,x,xdata,ydata)

嵌套函数

要通过嵌套函数传递公式 1 的参数,请编写一个文件,该文件

  • 接受 abcx0 作为输入

  • 包含目标函数作为嵌套函数

  • 调用 fminunc

以下是此示例的函数文件的代码:

function [x,fval] =  runnested(a,b,c,x0) 
[x,fval] = fminunc(@nestedfun,x0);
% Nested function that computes the objective function     
    function y = nestedfun(x)
        y = (a - b*x(1)^2 + x(1)^4/3)*x(1)^2 + x(1)*x(2) +...
            (-c + c*x(2)^2)*x(2)^2;     
    end
end
目标函数是嵌套函数 nestedfun,它可以访问变量 abc

要运行优化,请输入:

a = 4; b = 2.1; c = 4;% Assign parameter values
x0 = [0.5,0.5];
[x,fval] = runnested(a,b,c,x0)
输出与在匿名函数中相同。

全局变量

全局变量可能会比较麻烦,因此最好避免使用它们。而且,全局变量在并行计算中会失败。请参阅Factors That Affect Results

要使用全局变量,请在工作区和使用变量的函数中声明变量是全局的。

  1. 编写函数文件:

    function y = globalfun(x)
    global a b c
    y = (a - b*x(1)^2 + x(1)^4/3)*x(1)^2 + x(1)*x(2) + ...
        (-c + c*x(2)^2)*x(2)^2;

  2. 在您的 MATLAB 工作区中,定义变量并运行 fminunc

    global a b c;
    a = 4; b = 2.1; c = 4; % Assign parameter values
    x0 = [0.5,0.5];
    [x,fval] = fminunc(@globalfun,x0)

输出与在匿名函数中相同。

相关主题