MATLAB Answers

KENji
0

コロン関数でインクリ​メントした数列から,​一致する要素の検索の​仕方がわかりません

Asked by KENji
on 3 Oct 2018
Latest activity Commented on by KENji
on 4 Oct 2018
基礎的な問題なのかもしれませんが,よろしくお願いします.
私は二つの数値配列の中で,一致するインデックスを求めたいのですが,intersect関数を使用すると検知できない数値があります. 以下のコードの場合は,Aと一致する数値をBから20個見つけ出せます.
A=[0.425 0.475 0.525 0.575 0.625 0.675 0.725 0.775 0.825 0.875 0.925 0.975 1.025 1.075 1.125 1.175 1.225 1.275 1.325 1.375];
B=[0.3 0.325 0.35 0.375 0.4 0.425 0.45 0.475 0.5 0.525 0.55 0.575 0.6 0.625 0.65 0.675 0.7 0.725 0.75 0.775 0.8 0.825 0.85 0.875 0.9 0.925 0.95 0.975 1 1.025 1.05 1.075 1.1 1.125 1.15 1.175 1.2 1.225 1.25 1.275 1.3 1.325 1.35 1.375 1.4 1.425];
[G,ia,ib] = intersect(A,B,'stable')
しかし,以下のようなコロン演算子を使用したインクリメントでの配列を作成したものをintersect関数に使用すると,ほとんどは見つけることができますが,見つからないものが出てきます.
C=0.425:0.05:1.375;
D=0.3:0.025:2;
[GG,ic,id] = intersect(C,D,'stable')
上記の場合は,Dの中のCと一致するものを見つけ出したいのですが, icに20個の分のインデックスが返ってくるはずが17個しか見つかりません. C及びDには同じ数値が入っていることは確認済みです.
ismemberやfind関数でも同様になってしまいます. この問題の回避方法はないでしょうか? 宜しくお願い致します。

  0 Comments

Sign in to comment.

2 Answers

Yoshio
Answer by Yoshio
on 3 Oct 2018
 Accepted Answer

1.175に見えるデータの内部表現を16進表現で見てみると
>> format hex
>> C(16)
ans =
3ff2cccccccccccd
>> D(36)
ans =
3ff2cccccccccccc
となっており、厳密には同一ではありません。
>> C(16) == D(36)
ans =
logical
0
コロン関数では数値演算を行なって要素を計算していますので、浮動小数点での比較は危険です。今の場合、これを回避する一つの方法は、数値をString型にして文字列で比較することです。
[GG,ic,id] = intersect(string(C),string(D),'stable')
GG =
1×20 string 配列
しかし、CやDのデータがより一般的な浮動小数点データの場合、文字列に変換して比較するのではなく、誤差を計算した上で、許容範囲を設定し、その範囲内で一致するものを抜き出すようにした方が良いかと思います。

  1 Comment

KENji
on 4 Oct 2018
お二方とも回答いただき,ありがとうございます. 細かな誤差の比較までは行っていませんでした.

Sign in to comment.


Answer by Hirokazu Tanaka on 3 Oct 2018

Yoshioさんのおっしゃる通りです。
R2015aから使える関数ですが、誤算の許容範囲を設定できる関数 ismembertol が便利かと。
C=0.425:0.05:1.375;
D=0.3:0.025:2;
ismembertol(C,D)
と実行すると
ans =
1×20 logical 配列
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
20個の分のインデックスが返ってきます。
詳細はこちら:
調べていたら、unique にも同様の関数がありました。

  0 Comments

Sign in to comment.