这个目标并不是那么复杂。但是你写它看起来很复杂。
首先,欧米茄是一个标量!为什么要写 inv(omega)?除以 omega 是一个更好的主意,因为它不会涉及反函数的开销。
接下来,tau 是一个已知的常数标量,Passetcovar 也是如此。为什么每次调用函数时都要计算矩阵的逆矩阵 (tau*Passetcovar)?不仅如此,您还可以在一行中计算相同的逆矩阵三次。学习预先计算这些东西。它将为您节省很多时间和很多麻烦。
不管怎样,你对 inv 很着迷。它在一行中被调用了 6 次,并且大多数调用都是多余的。
让我们重写你的那一行。首先,预先计算 inv(Passetcovar),将整个事情传递给你的目标,所以你只需要做一次。
注意基本身份:
inv(k*A) = inv(A)/k
这对任何非零标量 k 都有效。
IP = inv(Passetcovar);
同样,不要在每次调用目标函数时重复 inv(Passetcovar) 的计算。相反,在开始优化之前计算一次。
所以计算变得更容易阅读:
wcalc = IP./lambda*inv(IP./tau + PMat(i,:)'*PMat(i,:)/omega)*(IP*Pi./tau + PMat(i,:)'*Q(i,:)/omega);
编辑:
最后我们知道 Pi 是一个向量。我想它必须是一个 8x1 向量,以便数组乘法符合。
我们可以通过分解出一些常数并在方便的地方插入括号来节省更多的除法和乘法。请注意,通过首先计算矩阵*向量乘法,然后乘以 IP,我们将 8x8 * 8x8 乘法转换为 8x8 X 8x1 乘法。对于像这样的小数组,差异并不大,但值得记住这个想法。
wcalc = IP*(inv(IP + tau*PMat(i,:)'*PMat(i,:)/omega)*(IP*Pi + PMat(i,:)'*Q(i,:)/omega*tau))/(lambda*tau^2);
目标是最小化 wcalc 和 wk 之间的平方和,服从正 omega。现在这是一个标量。
我建议首先绘制函数,只是为了了解它的形状,看看什么可能是 omega 的一个好的起始值。因此,通过在 myfun 周围包装一个函数句柄,ezplot 将很好地绘制绘图,这里对于 omega 的范围为 [0,100]。如果不合理,请选择您自己的 omega 上限。
ezplot(@(omega) myfun3(wk,omega,lambda,Passetcovar,tau,PMat,i,Pi,Q),[0,100])
因此,简单的解决方案是使用 fminbnd,为上限提供一些合理但足够大的值。fminbnd 的一个好处是它不需要起始值。您需要为 omega 选择一个合理的上限。关键是,使用旨在最小化标量函数的工具。不需要像 fmincon 这样的通用优化器,并且需要一个起始值。
finalomega = fminbnd(@(omega) myfun3(wk,omega,lambda,Passetcovar,tau,PMat,i,Pi,Q),[0,100])
您还可以使用在文件交换中找到的fminsearchbnd 。它可以最小化仅受下限约束的函数,但 fminsearchbnd 将需要 omega 的起始值。