* オーバーサンプリング -(by [[K]], 2008.03.05) *** (0) -僕の探し方が悪いんだと思うけど、以下の内容のページをうまく見つけられなかったのでここに書いておくことにした。 *** (1) -たとえばここに z = f(x, y) で表せるような標高データがあったとする。ここでfは関数のように表現しているが実際はただのデータのかたまりみたいなものだと思ってほしい(たとえば2次元配列のようなもので、東西・南北に軸を取って、それぞれ1mきざみで標高を観測して記録してあるとか)。 -この標高データを適当な平面で切って、その断面を取り出したいとしよう。たとえば、 x = 3 の面(今は3次元空間で考えて、yとzには拘束条件が無いからこれは平面になる)で z = f(x, y) を切れば z = f(3, y) になるから、断面図は容易に得られる。 y = 5 の面で切った断面も簡単に得られるだろう。これらは配列データから必要なデータを取り出してグラフをかくこともできる。 -しかし断面図は常に東西や南北に平行に必要になるとは限らない。時には、 y = 2 x + 3 の面で切りたくなるかもしれない。このとき f(0, 3), f(1, 5), f(2, 7) のデータは存在するから、これを結んでいけばとりあえず断面図は作れる。しかしこの断面図は点の間隔が2.236mであり、先ほどまでの1m間隔とは異なる。もし1m間隔でのデータがほしいとなればいったいどうしたらいいだろう。・・・さらに、切り出したい平面がもし y = 2 x + 3.4 だったらどうだろう。これはデータのある点を一つも通らない。これじゃあグラフをかくことができない。 -そこで2つの考え方があると思う。一つは y = 2 x + 3 ならそのまま2.236m間隔のデータでいいのでグラフをかき、その後でそのグラフの間の隙間を埋めて(たとえば点を線で結んでいけばとりあえず間のデータは作り出せる)、それで1m間隔のデータを得る。 y = 2 x + 3.4 なら y = 2 x + 3 と y = 2 x + 4 のグラフをそれぞれ作って同じことをし、この2枚の断面から y = 2 x + 3.4 の断面を推測する。このようなやり方を「補間」という(と思う)。 -そしてもう一つの方法がこれから紹介するオーバーサンプリングである。オーバーサンプリングでは、 y = 2 x + 3 の断面を書くときに、まず f(0, 3) のデータを使うが、次に必要なのは、1m先の f(0.4472, 3.8944) のデータだとする(この座標は、ベクトル (1 2) を単位ベクトルに規格化すれば簡単に算出できる)。そして1m間隔でしか用意されていない(=1m間隔でしかサンプルされていない)データから、サンプルされていない点のデータを強引に算出しようというわけだ。 *** (2) -0次のオーバーサンプリング --0次のオーバーサンプリングは極めて簡単である。その点に最も近いサンプル点のデータをそのまま使う。上記例のように格子状にデータがそろっているのなら、座標を四捨五入してしまえばいい。 f(0.4472, 3.8944) なら、 f(0, 4) のデータで代用するというわけだ。 -1次のオーバーサンプリング --0次はあまりにひどいというかふざけているので、もうちょっとましな方法を考える。上記のような2次元平面状にデータがある場合、おそらく近傍に4つの格子点がある(1次元なら2点だし、3次元なら8点だ)。格子点を求めるのは簡単だ、それぞれの座標を切り上げたり切り捨てたりして、すべての組み合わせを作ればいい。たとえば f(0.4472, 3.8944) なら、f(0, 3), f(1, 3), f(0, 4), f(1, 4) の4点のデータを使う。 --計算式は1次元の2点の方式が簡単で分かりやすいのでまずはそれを示したい。 f(1.23) を f(1) と f(2) から計算するならこうなる。 f(1.23) = f(1) * (1 - 0.23) + f(2) * 0.23 --要するにただ内分しているだけだ。だから結果も直線補間となんら違わない。 --これを2次元の4点方式に拡張するとこうなる。 f(0.4472, 3.8944) = f(0, 3) * (1 - 0.4472) * (1 - 0.8944) + f(1, 3) * 0.4472 * (1 - 0.8944) + f(0, 4) * (1 - 0.4472) * 0.8944 + f(1, 4) * 0.4472 * 0.8944 --この式で端数(0.4472や0.8944など)が0や1のとき(つまり計算の必要のない格子状のデータをこの式で計算しようとしたとき)、多くの項が消えて適切な格子点だけが残ることに注意すると理解しやすいかもしれない。 --近傍4点を通る平面が存在するとは限らないので、必然的に線形補間とは違ってくる。もちろん4点から近傍3点を選んで線形補間でやってもいいとは思うが、手間が増えるくせに精度が上がるというわけでもないので、上式のほうがよく使われている〈と思う)。 --近傍4点を通る平面が存在するとは限らないので、必然的に線形補間とは違ってくる。もちろん4点から近傍3点を選んで線形補間でやってもいいとは思うが、手間が増えるくせに精度が上がるというわけでもないので、上式のほうがよく使われている(と思う)。 --3次元以上の場合もこれで推測できると思う。 -2次のオーバーサンプリング --やったことがないのでわからないが、要するに利用するサンプル点をもっと増やしてより高次の計算をするのだろう。たとえばこんな感じだろうか。 f(1.23) = f(-1) * なんか + f(0) * なんか + f(1) * なんか + f(2) * なんか --この「なんか」というのは、端数が特定の格子点になったときに1でそれ以外の格子点では0になるような関数だと思う。たとえば (x+1)x(x-1)(x-2) という式を考えてみる。これはx=-1,0,1,2で0になる。これからxを取り除いてみよう。すると (x+1)(x-1)(x-2) という式になる。これはx=-1,1,2で0になるが、x=0では0にはならない。2になる。したがってこの式を2で割った式は、「端数が特定の格子点になったときに1でそれ以外の格子点では0になるような関数」を満たしている。 * こめんと欄 #comment