1

私は勾配降下を試みています、私は次のように書きましたが、何の答えも得られませんでした、

n=0;            %initialize iteration counter 
eps=1;          %initialize error 
a=0.8;         %set iteration parameter 
x=[1;1];        %set starting value
f=6*x(1)^2+8*x(2)^2-3*x(1)*x(2);
%Computation loop 
while eps>1e-12||n<100 
   gradf=[12*x(1)-3*x(2); 16*x(2)-3*x(1)];  %gradf(x) 
   eps=(norm(gradf)/(1+abs(f)));                                %error 
   y=x-a*gradf;                                                 %iterate 
   x=y;                                                         %update x 
   n=n+1;                                                       %counter+1 
end 
n;x;eps;        %display end values

このファイルをパスに追加して x と入力すると、NaN、NaN と表示されます。なにが問題ですか?

4

1 に答える 1

5

コードにいくつかのエラーがあります。これを考慮してください(修正が必要な場所にコメントを入れました)

 n=0;            
 eps=1;         
 a=0.1;                    %You need a way smaller parameter to converge!
 x=[1;1];       

 A = [6 -3/2 ; -3/2 8];     %You have a bilinear positive definite form,
                            %you may use matrix form for convenience


while eps>1e-12 && n<100    %You had wrong termination conditions!!
    gradf=2*A*x;            %(gradf in terms of matrix)
    f=x'*A*x;               %you need to update f every iteration!!
    eps=(norm(gradf)/(1+abs(f)))                              
    disp(eps > 1e-12)
    x=x-a*gradf;                                               

       %Now you can see the orbit  towards minimum                                     
    plot(x(1),x(2),'o'); hold on        
    n=n+1;                                                        
end 
n
x
eps        

たとえば、a=.1私が得る現在の値で

n = 100
eps = 1.2308e-011

x = 
  1.0e-012 *

  -0.2509
  0.4688

つまり、イプシロンがまだしきい値を超えているため、100 回の反復を実行する必要がありました。200回の反復を許可すると、

n =  110
eps = 
   7.9705e-013

x = 
1.0e-013 *
  -0.1625
   0.3036

つまり、110 回の繰り返しで十分です。

解 <code>(0,0)</code> の周りに点が密集する


一般の場合f(つまり、二次形式ではない)。

たとえば、関数ハンドルを使用できます。つまり、(の前にwhile)定義します

foo = @(x) 6*x(1)^2+8*x(2)^2-3*x(1)*x(2);
foo_x = @(x) 12*x(1)-3*x(2); 
foo_y = @(x) 16*x(2)-3*x(1);

次に、whileあなたの代わりに

gradf = [foo_x(x);foo_y(x)];
f = foo(x);

PS サイクルに関するものについては、精度に満足していない間 ( )かつ反復の合計回数が所定のしきい値 ( ) を下回っているwhile、反復を続けることに注意してください。eps>1e-12n<100

また、有限精度で作業していることも考慮してください。数値アルゴリズムは解析解 (つまり、無限精度と無限反復で得られるもの) に決して到達できないため、常にしきい値を設定する必要があります( eps、これはマシン精度よりも高くする必要があります)。 \approx 1e-16) であり、それあなたの0.

于 2012-10-27T17:46:55.893 に答える