【问题标题】:Solving for multiple parameters in matlab在matlab中求解多个参数
【发布时间】:2015-08-11 17:11:05
【问题描述】:

我对 matlab 还很陌生。我了解如何使用fminsearch,这对于查找单个参数非常有效。但是,我想优化一些参数。有人可以帮助演示我如何实现以下内容。在这种情况下,SolveForParameters 通过最小化从CalculateResidual 计算的残差返回最优参数abc。我意识到可能有多种方法可以做到这一点(例如,nlsmle 等),但任何示例都值得赞赏。在这个例子中,input1input2input3在优化过程中是常数,也是向量。

function [a,b,c] = SolveForParameters(input1, input2, input3, a, b, c) 
     %finds the parameters a, b, and c by minimizing the function CalculateResidual

     startA = 3; 
     startB = 1;
     startC = 0;

     %...EXAMPLE IMPLEMENTATION HERE...
end

function residual = CalculateResidual(input1, input2, input3, a, b, c)
    %for example
    residual = (sum(input1*(a-b)) + sum(input2)*sqrt(a*1.5)*a) / (sum(input3+b) + sum(input2/log(sum(input1))/(a+c)))
end

谢谢!

【问题讨论】:

  • input1, input2input3 都是静态的吗?也就是说,这些是否会随着时间而变化?......或者它们在优化过程中是否保持不变?您没有指定这些参数是什么。
  • 抱歉,它们是静态的。

标签: matlab optimization


【解决方案1】:

你已经很接近了。您所要做的就是将您想要优化的所有参数放入 单个向量 中。此外,在要最小化的残差函数内,输入也必须在向量中。因此,a, b, c 将作为向量传递到您的残差函数中,而input1, input2, input3 是恒定的,不会随着搜索的演变而改变。这些也是相同长度的向量。

因此,您真的只需要这样做。首先,改变你的残差函数,让它接受输入的向量参数:

function residual = CalculateResidual(x, input1, input2, input3)
%for example
a = x(1); b = x(2); c = x(3); %// Change here
residual = (sum(input1*(a-b)) + sum(input2)*sqrt(a*1.5)*a) / (sum(input3+b) + sum(input2/log(sum(input1))/(a+c)));
end

现在,只需正常调用fminsearch,但指定一个参数向量作为起始位置:

X = fminsearch(@(x) CalculateResidual(x, input1, input2, input3), [startA;startB;startC]);

第一个输入是您试图最小化的函数。在这种情况下,我们为CalculateResidual 提供了一个句柄,其中input1, input2, input3 都是静态的。这是必需的,因为您要为 fminsearch 最小化的函数只能接受带有一个输入参数的签名 - 即要在某个迭代中优化的参数。然后将初始起点指定为向量。

一旦你拥有了它,那么你应该是坚实的!然后,您将从输出中解开参数并将它们分配给a,b,c,因此:

a = X(1); b = X(2); c = X(3);

将它们拼凑在一起,您的代码将如下所示:

function [a,b,c] = SolveForParameters(input1, input2, input3) 
     %finds the parameters a, b, and c by minimizing the function CalculateResidual

     startA = 3; 
     startB = 1;
     startC = 0;

     X = fminsearch(@(x) CalculateResidual(x, input1, input2, input3), [startA;startB;startC]);

    a = X(1); b = X(2); c = X(3); %// Final assignment
end

function residual = CalculateResidual(x, input1, input2, input3)
    %for example
    a = x(1); b = x(2); c = x(3); %// Change here
    residual = (sum(input1*(a-b)) + sum(input2)*sqrt(a*1.5)*a) / (sum(input3+b) + sum(input2/log(sum(input1))/(a+c)));
end

在给定起始位置的情况下,使用input1 = sin(1:10), input2 = cos(1:10), input3 = tan(1:10) 运行上述代码会得到以下a,b,c

>> format long g;
>> [a,b,c] = SolveForParameters(1:10, 11:20, 21:30)

Exiting: Maximum number of function evaluations has been exceeded
         - increase MaxFunEvals option.
         Current function value: -5.127366 


a =

   2.6014e-06


b =

  325.4224


c =

   -2.0911

您会收到退出警告,因为在给定默认迭代次数的情况下,我们无法将残差最小化。您可以通过增加优化例程采用的函数评估次数和最大迭代次数来增加迭代总数。这可以通过optimset 完成。因此,让我们稍微修改一下代码:

function [a,b,c] = SolveForParameters(input1, input2, input3) 
     %finds the parameters a, b, and c by minimizing the function CalculateResidual

     startA = 3; 
     startB = 1;
     startC = 0;

     %// New - Change optimization options
    options = optimset('fminsearch');
    options.MaxFunEvals = 10000;
    options.MaxIter = 10000;

     %// New - also include options for optimization
     X = fminsearch(@(x) CalculateResidual(x, input1, input2, input3), [startA;startB;startC], options);

    a = X(1); b = X(2); c = X(3); %// Final assignment
end

function residual = CalculateResidual(x, input1, input2, input3)
    %for example
    a = x(1); b = x(2); c = x(3); %// Change here
    residual = (sum(input1*(a-b)) + sum(input2)*sqrt(a*1.5)*a) / (sum(input3+b) + sum(input2/log(sum(input1))/(a+c)));
end

执行options = optimset('fminsearch'); 会生成fminsearch 中使用的默认参数。然后,我们通过将函数评估次数和迭代次数更改为 10000 来覆盖默认值。我们还将其作为附加参数提供给 fminsearch,以让函数知道我们正在为优化例程的默认参数提供一些更改。

通过这样做,我们现在得到:

>> [a,b,c] = SolveForParameters(1:10, 11:20, 21:30)

a =

   7.4210e-07


b =

  325.4225


c =

   -2.0911

【讨论】:

  • 非常抱歉。 input1、2 和 3 本来是向量。我更新了上面的代码。可以修改吗?
  • @CodeGuy - 完成。看看吧。
  • 问题:假设我希望“a”是一个整数。例如,假设在我的残差中,我需要从 input1 中获取元素“a”。我怎么能这样做?如何强制优化器为其中一个参数找到一个整数?
  • 如果你想强制a 为整数,那是完全不同的球赛。你会想看看混合整数线性规划。试试 MATLAB 的 intlinprog 函数:mathworks.com/help/optim/ug/intlinprog.html。如果您希望 a 是整数,那将需要我更改我的整个答案....我认为您应该将其作为一个新问题发布。
  • 好的,这里有新问题:stackoverflow.com/questions/31951010/…
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多