2020年5月1日 星期五

Low-discrepancy sequence (準亂數列)


  • 前言
在上一章介紹了如何使用一個2維變數 (ξ12)來得到一個 GGX 分布的法線向量,

在這裡衍生了一個問題,

要如何找到一個合適的2維變數陣列作為積分用的採樣點的法線向量。

本章節就是介紹使用 Low-discrepancy sequence (準亂數列) 

作為 Quasi Monte Carlo Method 取樣點的優點與實作方法。


  • Monte Carlo Method
Monte Carlo Method 是使用亂數取樣點作為積分計算的數列,

若使用 N 個樣本數,則他的積分誤差的收斂速度為 O(N−0.5)[1]

這代表著如果我要提升2倍的精度,我需要提供4倍的樣本數。


  • Quasi Monte Carlo Method
不同於 Monte Carlo Method 使用亂數列作為採樣點,

 Quasi Monte Carlo Method 使用了 Low-discrepancy sequence 作為採樣點,

使得其積分誤差的收斂速度為 O(log(N)dim/N), 其中 dim 為 dimension(次元數)。

這代表著如果在 2 維空間使用 Quasi Monte Carlo Method 做積分,

要提升2倍的精度,只需要提供2倍的樣本數。

因此可以得知若在低次元空間下做積分,

Quasi Monte Carlo Method 比 Monte Carlo Method 有著更高的收斂速度。


  • Hammersley Sequence
回到了一開始的問題,如何找到一個合適的2維變數陣列作為積分用的採樣點的法線向量。

在這裡就是使用 Quasi Monte Carlo Method,

利用 Low-discrepancy sequence 找出採樣點陣列做積分計算。

本章節接下來會說明並實作一個常用的 Low-discrepancy sequence,

也就是 Hammersley Sequence。


基本理論很簡單


我給定一個索引值 α,先將其轉為2進制,

再依序將2進制的每個位數由後往前依序放入小數點後,在由前往後乘以2的倒數,

就是回傳結果。

ex.

0.1     = 1 * 2−1 = 0.5
0.01   = 0 * 2−1 + 1 * 2−2 = 0.25
0.11   = 1 * 2−1 + 1 * 2−2 = 0.75
0.001 = 0 * 2−1 + 0 * 2−2 + 1 * 2−3= 0.125
...

如此可以得到一個在 [0,1] 數列。

下圖為  Hammersley Sequence 的2維採樣結果


從上圖可知,這是一個非隨機的數列,

但是它的結果分布卻是有著微小差異(不知情的人可能會認為他是一個隨機採樣結果)。

這種數列就叫做 Low-discrepancy sequence。


2維 Hammersley Sequence 的實作方式如下

float RadicalInverse_VdC(uint bits) 
{
    bits = (bits << 16u) | (bits >> 16u);
    bits = ((bits & 0x55555555u) << 1u) | ((bits & 0xAAAAAAAAu) >> 1u);
    bits = ((bits & 0x33333333u) << 2u) | ((bits & 0xCCCCCCCCu) >> 2u);
    bits = ((bits & 0x0F0F0F0Fu) << 4u) | ((bits & 0xF0F0F0F0u) >> 4u);
    bits = ((bits & 0x00FF00FFu) << 8u) | ((bits & 0xFF00FF00u) >> 8u);
    return float(bits) * 2.3283064365386963e-10; // / 0x100000000
}

float2 Hammersley(uint i, uint N)
{
    return float2(float(i)/float(N), RadicalInverse_VdC(i));
}  



  • References
1. Søren Asmussen and Peter W. Glynn, Stochastic Simulation: Algorithms and Analysis, Springer, 2007, 476 pages

沒有留言:

張貼留言