約 1000 行と 1000 列の 2 つの大きな配列があります。これらの配列の各要素を比較し、対応する要素が等しい場合は別の配列に 1 を格納する必要があります。
forループでこれを行うことができますが、それには長い時間がかかります。どうすればこれをより速く行うことができますか?
約 1000 行と 1000 列の 2 つの大きな配列があります。これらの配列の各要素を比較し、対応する要素が等しい場合は別の配列に 1 を格納する必要があります。
forループでこれを行うことができますが、それには長い時間がかかります。どうすればこれをより速く行うことができますか?
与えられた答えはすべて正しいです。浮動小数点テストに関するgnoviceの発言について詳しく説明したいと思います。
浮動小数点数が等しいかどうかを比較するときは、許容値を使用する必要があります。絶対公差と相対公差の2種類の公差比較が一般的に使用されます。(ソース)
の絶対許容誤差の比較は次のようにa
なりb
ます。
|a-b| < tol
相対的な許容誤差の比較は次のようになります。
|a-b| < tol*max(|a|,|b|) + tol_floor
上記の2つを無名関数として実装できます。
%# absolute tolerance equality
isequalAbs = @(x,y,tol) ( abs(x-y) <= tol );
%# relative tolerance equality
isequalRel = @(x,y,tol) ( abs(x-y) <= ( tol*max(abs(x),abs(y)) + eps) );
次に、それらを次のように使用できます。
%# let x and y be scalars/vectors/matrices of same size
x == y
isequalAbs(x, y, 1e-6)
isequalRel(x, y, 1e-6)
2 つの行列A
とB
が同じサイズの場合、これを行うことができます。
index = A == B;
andindex
は論理配列A
になり、 andのすべての要素が1 になり、それ以外のB
場合は 0 になります。
警告の言葉...
A
とB
に整数が含まれている場合は、上記で問題ありません。ただし、浮動小数点値が含まれていると、望ましくない結果になる可能性があります。上記のコードは、正確に等しい要素に対して 1 の値のみを持ちます。わずかな違いでも、要素が等しくないと見なされます。
「浮動小数点演算の危険性」に対処する方法の詳細については、この質問の回答を参照してください。1 つの解決策は、次のように、配列要素が互いに所定の許容範囲内にあることを確認することです。
tolerance = 0.0001;
index = abs(A-B) <= tolerance;
上記は、とindex
の要素が互いに 0.0001 以内にあり、それ以外の場合はゼロである論理配列を提供します。A
B
通常の==
演算子を使用するだけです:
>> [1 2; 3 4] == [1 5; 6 4]
ans =
1 0
0 1