优化以查找复数作为输入

时间:2012-07-13 16:58:29

标签: c++ c matlab mathematical-optimization numerical-methods

我想知道是否有使用最小化求解器确定实数和复数的C / C ++库或Matlab代码技术。这是一个代码片段,显示了我想要做的事情。例如,假设我知道Utilde,但不知道xU变量。我想使用优化(fminsearch)来确定xU,给定Utilde。请注意,Utilde是一个复数。

x = 1.5;
U = 50 + 1i*25;
x0 = [1 20];  % starting values
Utilde = U * (1 / exp(2 * x)) * exp( 1i * 2 * x);
xout = fminsearch(@(v)optim(v, Utilde), x0);

function diff = optim(v, Utilde)
x = v(1);
U = v(2);
diff =  abs( -(Utilde/U) + (1 / exp(2 * x)) * exp( 1i * 2 * x  ) );

上面的代码没有收敛到正确的值,xout = 1.7318 88.8760。但是,如果U = 50(不是复数),则为xout = 1.5000 50.0000,这是正确的值。

在给定Utilde作为复数时,Matlab或C / C ++中是否存在确保正确收敛的方法?也许我必须更改上面的代码?

  • 如果没有办法在Matlab中本地执行此操作,那么可能就是一个 问题的要点是:是否存在多变量(即 Nelder-Mead或类似算法)能够实现的优化库 使用真实和复杂的输入和输出?

  • 另一个问题是函数是否收敛。一世 不知道是算法还是函数。我可能需要在Utilde = U * (1 / exp(2 * x)) * exp( 1i * 2 * x)表达式中更改某些内容以使其收敛吗?

3 个答案:

答案 0 :(得分:2)

fminsearch的文档介绍了如何处理limitations部分中的复杂数字:

  

fminsearch仅最小化实数,即x必须仅由实数组成,f(x)必须仅返回实数。当x具有复杂变量时,它们必须分为实部和虚部。

您可以使用函数realimag分别提取实部和虚部。

答案 1 :(得分:2)

这里的主要问题是这种优化或参数拟合问题没有独特的解决方案。例如,查看上面的预期和实际结果,Utilde对于两个(xU)对来说是等效的(忽略舍入差异),即

Utilde(x = 1.5, U = 50 + 25i) = Utilde(x = 1.7318, U = 88.8760)

虽然我没有深入研究过,但我甚至怀疑,对于x的任何值,您都可以找到计算到U的{​​{1}}。

这里的解决方案是进一步约束参数拟合问题,以便求解器产生任何可被认为可接受的解决方案。或者,重新制定Utilde(x, U) = Utilde(x = 1.5, U = 50 + 25i)以使任何(Utildex)对具有唯一值。

更新,8月1日

给定合理的起始值,实际上似乎将U限制为实值是足够的。使用上面给出的x函数执行无约束的非线性优化,得到以下结果:

diff

但是,将起始猜测更改为距离所需值更远的值会产生不同的解决方案,因此将x = 1.50462926953244 U = 50.6977768845879 + 24.7676554234729i diff = 3.18731710515855E-06 限制为实值并不能单独为问题提供唯一的解决方案。

我已经使用BOBYQA优化器在C#中实现了这个,但是数字应该与上面相同。如果你想在Matlab之外尝试,使用std::complex类和你自己选择的(无约束)非线性C ++优化器,将下面的C#代码转换为C ++代码也应该相对简单。你可以找到一些不需要梯度计算的C ++兼容代码here,并且在Numerical Recipes中也有各种各样的实现。例如,您可以在线访问N版C here

供参考,以下是我的C#代码的相关部分:

x

答案 2 :(得分:0)

即使xU都是实数,也似乎没有简单的方法可以做到这一点。 Utilde的等式不适用于优化问题,因此必须进行修改。

我尝试编写自己的Nelder-Mead优化算法版本,并尝试使用Powell的方法。即使我试图修改这些方法,这两个似乎都不能很好地解决这个问题。