2

そのため、一部の入力データに対してMATLAB のsvds()関数を使用すると、次のようになります。

[U, S, V, flag] = svds(data, nSVDs, 'L')

同じデータを使用して実行するたびに、実行ごとに大幅に異なる出力 SVD サイズが得られることに気付きました。「フラグ」が設定されているかどうかを確認したところ、SVD が収束していないことがわかりました。ここでの私の通常のシステムでは、本当に収束する必要がある場合は、次のようにします。

flag = 1
svdOpts = struct('tol', 1e-10, 'maxit', 600, 'disp', 0);
while flag:
    if svdOpts.maxit > 1e6
        error('There''s a real problem here.')
    end

    [U, S, V, flag] = svds(data, nSVDs, 'L', svdOpts)
    svdOpts.maxit = svdOpts.maxit*2
end

しかし、私が知る限り、「L」を 3 番目の引数として使用すると、4 番目の引数は無視されます。つまり、収束していないという事実に対処する必要があるということですか? 「L」引数の代わりに「シグマ」引数を使用する方法もよくわかりません。また、計算されたSVDの数を無駄に減らしてみました。この問題について何か助けていただければ幸いです。

編集 以下のコメントをフォローアップしているときに、問題がデータマトリックスの構築方法に関係していることがわかりました。誤って行列を逆にして、(20x200) ではなく (4000x1) のサイズの入力があったことが判明しました。これが収束を拒否していた原因でした。 これは問題ではありませんでした

2番目の編集 誰かがまだこれに従っている場合、私は実際には間違っていました.入力を間違ってスケーリングしたため、データは収束しただけです. これは、私がデータを生成しているときにデータを生成するプログラムです。

%  Generate data for SVD failure to converge
% Kernel functions
data_fun1 = @(t, tau)(exp(-t*(1./tau)));
t = linspace(0, 10, 26)';
tau1 = logspace(-1, log10(5), 150); 
k1 = data_fun1(t, tau1);

gamma = 4257;
n = 6;
tau = 0.075;
A = -(2/3)*(2*pi*gamma)^2*n*tau.^3;

data_fun2 = @(V, t)exp(A*t*(V.^2));
V = linspace(0, 0.4, 29);
tau3 = logspace(-1, log10(5), 150)';
tau3 = tau3*1e-5;
k2 = data_fun2(V, tau3)';

svdOpts = struct('tol', 1e-10, 'maxit', 1e3, 'disp', 0);
svdOpts2 = svdOpts;
flag = 1;
while flag
    if svdOpts2.maxit > 1e8
        break
    end

    [U1, S1, V1, flag] = svds(k1, length(t), 'L', svdOpts);
    svdOpts2.maxit = svdOpts2.maxit * 2;
end
flag
% flag == 0
flag = 1;

while flag
    if svdOpts2.maxit > 1e8
        break
    end

    [U2, S2, V2, flag] = svds(k2, length(V), 'L', svdOpts);
    svdOpts2.maxit = svdOpts2.maxit * 2;
end
flag
% flag == 1

また、svdOpts2.maxit > 1e9 まで実行してみましたが、週末中ずっと実行され、4.096e8 を超えることはありませんでした。アドバイスをいただければ幸いです。

4

1 に答える 1

0

svds(A,k)提供する例は、の場合にのみ使用する必要がある完全なSVD分解を計算しようとしているため失敗しますk < min(size(A))そして、私ははるかに少ない量を追加する必要があります。

あなたの例のsvd()ために使用されるべきです。

k2上記のコードで計算

>> tic, [U2, S2, V2, flag] = svds(k2, length(V), 'L'); toc         
Elapsed time is 0.830326 seconds.
>> flag

flag =

     1

>> tic, [U2, S2, V2] = svd(k2); toc      
Elapsed time is 0.002851 seconds.
>> norm(U2*S2*V2'-k2)/norm(k2)

ans =

   8.4982e-16


>> max(max(abs(U2*S2*V2'./k2-1)))

ans =

   5.8111e-12

長方形の行列Aには特異値しかないmin(size(A))ため、実際にはすべての特異値を計算することに関心があることに注意してください。正方形 に興味がある場合は、S2を使用する必要がありますsvd(k2, 'econ')

于 2012-10-05T21:18:53.747 に答える