1

私はMatlabに少し問題があります.Matlabの精度に関係していると思いますが、本当に解決したいと思います. 私は 3 つのマトリックスを持っています。1 つはf次元 296x3118 で呼び出され、もう1 つは次元 1x3118 でmapping.mean呼び出され、最後はmapping.M次元 3118x100 で呼び出されます。
次の操作の結果は 1 になるはずですが、そうではありません。結果の行列f_s_1f_s_2は、10^-12 の範囲でのみ異なる値を持ちます。理由、またはこれを修正する方法を知っている人はいますか?

f_s_1 = ((f(1:296,:)-repmat(mapping.mean,296,1))*mapping.M)';
f_s_2 = ((f(1:295,:)-repmat(mapping.mean,295,1))*mapping.M)';
isequal(f_s_1(:,1:295),f_s_2)

ans =

 0
4

1 に答える 1

3

表示されているのは、MATLAB の丸め誤差の結果であり、大規模な行列演算の並列化に起因する可能性があります。非常に大規模な行列演算の場合、MATLAB は自動的に演算子の並列バージョンに切り替えて速度を上げます。これは、解の一部をすべて同時に計算し、最後に結合できることを意味します。さまざまな部分が遅かれ早かれ終了するか、元の問題のさまざまな部分で構成されるため、さまざまな結果が得られる可能性があります。

お使いのコンピューターは数値を表すために少数のビットのみを使用するため (お使いのバージョンの matlab ではおそらく 64 ビットを使用します)、演算を行うときに切り捨てられる 10 進数の小さな部分がしばしばあります。実際、非常に大きな数を非常に小さな数に加算すると、コンピュータは結果として非常に大きな数のみを返す場合があります。これは、小さい数を表す「余地がなくなる」ためです。

たとえば、次のコードを実行してみてください。

mybase = 1e17;

sum1 = mybase + sum(1e-4*ones(2^14,1)) - mybase
sum2 = mybase - mybase + sum(1e-4*ones(2^14,1))

あなたは得るべきです:

sum1 =

     0


sum2 =

    1.6384

合計が並べ替えられただけでも、結果は異なる数値になります。これをいじってみると、MATLAB が数値を左から右に加算し、数値の大きさが大きく異なる場合に問題が発生し始めることがわかります。1.6384 は 1e17 のごく一部なので、実際のエラーではないと考えるかもしれませんが、明らかに答えは間違っています。

なぜこれがここに関係するのですか?前に述べたように、MATLAB が操作を並列化することを選択した場合、問題の各部分が同時に計算されてから結合されます。ピースは、多くのこと (問題のサイズ、コンピューターが実行していることなど) に応じて異なる順序で追加される場合があります。これは、結果がわずかに異なることを意味します。私のバージョン(R2012a)で行列を同じサイズに設定すると、同じ答えが得られるかもしれません...またはそうでないかもしれません。また、サイズにもよります。

この振る舞いは「特徴」であり、使用しても同じ答えが得られましたmaxNumCompThreads(1)

于 2012-07-02T18:12:42.970 に答える