0

Matlab のルート検索問題で十分な精度を達成するのに苦労しています。関数 があり、 whereLik(k)の値を見つけたいと考えています。基本的に、問題は、さまざまな組み込みの Matlab ソルバー ( 、、) が、私が望む、または期待するほど解に近づいていないことです。kLik(k)=L0fzerofminbndfmincon

Lik()は、数値逆ラプラス変換などを計算するための広範なコーディングを伴うユーザー定義関数であるため、完全なコードは含めません。しかし、私はこの機能を広範囲に使用しており、適切に機能しているようです。 Lik()は実際にはいくつかの入力パラメーターを取りますが、現在のステップでは、これらは を除いてすべて固定されてkいます。したがって、これは実際には 1 次元の求根問題です。

k >= 165.95whichの値を見つけたいですLik(k)-L0 = 0Lik(165.95)よりも小さく、ここから単調に増加するL0と予想しています。Lik(k)実際、Lik(k)-L0関心のある範囲で評価でき、スムーズにゼロを横切るように見えますLik(165.95)-L0 = -0.7465, ..., Lik(170.5)-L0 = -0.1594, Lik(171)-L0 = -0.0344, Lik(171.5)-L0 = 0.1015, ... Lik(173)-L0 = 0.5730, ..., Lik(200)-L0 = 19.80。したがって、関数は適切に動作しているように見えます。

ただし、いくつかの異なる方法でルートを「自動的に」見つけようとしましたが、精度は期待したほど良くありません...

Using fzero(@(k) Lik(k)-L0): interval に制約されている場合は(165.95,173)、 を返しfzeroます。さて、素晴らしいことではありませんが。そして実用的な目的のために、多くの手作業による試行錯誤がなければ、そのような正確な上限を知ることはできません. interval を使用すると、where が返されますが、これはかなり貧弱です。Displayをiterに設定してこれらのテストを実行したので、何が起こっているのかがわかります。4 回目の反復でヒットし、5 回目の反復でそこにとどまっているように見えます。つまり、1 つの反復から次の反復への変化が少ないことを意味します。よりもk=170.96Lik(k)-L0=-0.045(165.95,200)fzerok=167.19Lik(k)-L0 = -0.65fzero167.19kTolX(0.001 に設定) し、手順は終了します。終了フラグは、解に正常に収束したことを示します。

また、 ( の上限と下限を指定) と( の開始点を指定)abs(Lik(k)-L0)を使用して最小化を試みたところ、同様の精度の問題が発生しました。特に、 との両方を設定できますが、これら (10^-6 まで下げると、必要以上に高い精度) をいじっても、違いはありませんでした。紛らわしいことに、オプティマイザーは、以前の反復で、返される最終的な k 値よりも目的関数をゼロにすることに近い k 値を見つけることさえあります。fminbndkfminconkfminconTolXTolFun

そのため、アルゴリズムは特定のポイントまで反復しているように見えますが、より良い解決策を見つけるのに十分なサイズのステップをそれ以上実行できません。アルゴリズムが別の大きな一歩を踏み出さない理由を誰か知っていますか? これを変更するために調整できるものはありますか?( optimsetの下のリストを見ましたが、有用なものは何も思いつきませんでした。)

どうもありがとう!

4

3 に答える 3

1

この地域では単調に見える「野生の」機能を持っているようで、関心の範囲がかなり狭く、精度の要件がそれほど高くないため、ブルートフォースアプローチを推奨するためのすべての基準が満たされていると思います。

ポイント内の関数を評価するのにそれほど時間がかからないと仮定して、これを試してください:

xmax上限と下限を見つけ、xmin優先を選択しstepsizeて関数を評価します

xmin:stepsize:xmax 

必要に応じて (単調性が実際に適用される場合)、これを実行して別の上限と下限を取得し、このプロセスを繰り返して精度を高めることができます。

于 2013-02-21T14:34:24.693 に答える
1

fmincon の使用中にもこの問題が発生しました。これが私がそれを修正した方法です。

最適化ループ (複数の変数) 内で関数 (単一の変数) の解を見つける必要がありました。このため、単一変数関数の解には大きな間隔を設ける必要がありました。問題は、探索間隔が大きすぎると fmincon (または fzero) が解に収束しないことです。これを乗り越えるために、while ループ内で問題を解決します。開始上限 (1e200) を大きくし、ソルバーから得られる fval 値に制約を加えます。結果の fval が十分に小さくない場合、上限を 1 倍減らします。コードは次のようになります。

fval = 1;
factor = 1;
while fval>1e-7
    UB = factor*1e200;
    [x,fval,exitflag] = fminbnd(@(x)function(x,...),LB,UB,options);
    factor = factor * 0.001;
end

適切な解が見つかると、ソルバーは終了します。もちろん、別の因子を導入したり、因子のステップを増やしたりすることで、LB で遊ぶこともできます。私の母国語は英語ではないので、間違いをお詫びします。

乾杯、クリスチャン

于 2015-02-24T13:29:03.460 に答える
0

単純な二分法を使用しないのはなぜですか? 常に特定の間隔の中央を評価し、これを右側または左側の部分に減らして、常に一方の境界が負の値を与え、もう一方の境界が正の値を与えるようにします。非常に迅速に任意の精度に減らすことができます。毎回間隔を半分に減らすので、非常に迅速に収束するはずです。

しかし、不連続性があるという点で、その機能には他の問題があると思います。fzero がうまく機能しないのは奇妙に思えます。決定論的な関数ですよね?

于 2013-02-22T11:45:58.170 に答える