改组和NRooks约束保存

Ste*_*ini 7 algorithm raytracing

我正在实现一个光线跟踪器,我正在实现采样器.采样器是方形x = 0:1,y = 0:1上的随机点的生成器.每个采样器保存多组"随机"样本,每组包含给定数量的样本.

现在,其中一个采样器是NRooks.它以n x n块为单位划分表面,沿对角线选择块,在每个对角线块中提取一个随机点,最后先将x它们自身混洗,然后再对其进行随机抽样y.

在此输入图像描述

这一切都很干净.然而,当提取点数时,我正在遵循的书提出了这些额外的要求,以打破后续像素和采样之间的相关性.第一个要求是每次设置耗尽时,随机选取一个新的样本集.为实现此目的而实现的代码如下:

 Point2D Sampler::sample_unit_square(void) { 
    if (count % num_samples == 0) jump = (rand_int() % num_sets) * num_samples;
    return (samples[jump + count++ % num_samples]
 }
Run Code Online (Sandbox Code Playgroud)

其中samples是Point2D的矢量大小num_samples*num_sets(它是线性化的).每次完成一个像素(计数可被num_samples整除)时,将提取新的跳转并用于指示线性阵列以开始新的集合.

由于我使用python,我的策略使用迭代器:

def __iter__(self):

    while True:
        for sample_set in random.choice(self._samples_sets):
            for sample in sample_set:
                yield sample
Run Code Online (Sandbox Code Playgroud)

这是微不足道的,并且工作正常.

第二个需要是改变指数,这就是我的问题所在.该书修改了如下代码

 Point2D Sampler::sample_unit_square(void) { 
    if (count % num_samples == 0) jump = (rand_int() % num_sets) * num_samples;
    return (samples[jump + shuffled_indices[ jump + count++ % num_samples]]
 }
Run Code Online (Sandbox Code Playgroud)

其中,混洗索引是一个如下计算的数组

 void Sampler::setup_shuffled_indices(void) {
     shuffled_indices.reserve(num_samples*num_sets);
     vector<int> indices;

     for (int j=0; j<num_samples; j++) indices.push_back(j);

     for (int p=0; p<num_sets; p++) {
          random_shuffle(indices.begin(), indices.end());
          for (int j=0; j<num_samples; j++) {
              shuffled_indices.push_back(indices[j]);
          }
     }
 }
Run Code Online (Sandbox Code Playgroud)

这是一种非常C++的方法,可以从1到n中取一个数字列表并对它们进行混洗.我想在python中实现以下代码

def __iter__(self):

    while True:
        sample_set = random.choice(self._samples_sets):
        shuffled_set = sample_set[:]
        random.shuffle(shuffled_set)
        for sample in shuffled_set:
            yield sample
Run Code Online (Sandbox Code Playgroud)

我还可以实现一个迭代集合的随机迭代器,保存列表副本,但这不是重点.我的问题来自书中的以下短语:

... [除去相关性]的另一种可能性是在每组的样本上使用最终的随机播放,但这会破坏n-rooks条件[...].最好的方法是随机混洗sample_unit_square每个集合中使用的索引,但保证使用所有样本.

我不明白的是:为什么它说每套样品的最后洗牌打破了n-rooks?关键是他正在使用间接索引到点数组中.这个间接索引是在从1到集合的所有索引的混洗中创建的,但这相当于每个集合中所有样本的混洗.作为恕我直言,我不明白为什么第一个配方应该打破n-rooks,为什么第二个配方不会.

据记载,这本书由凯文·萨弗恩(Kevin Suffern)撰写的"雷从头开始追踪".

tug*_*ugs 1

在我看来就像

...对每组样本进行最后的洗牌..

建议在洗牌后将每组独立洗牌。

def __iter__(self):

    while True:
        for sample_set in random.choice(self._samples_sets):
            for sample in random.choice(sample_set):
                yield sample
Run Code Online (Sandbox Code Playgroud)

就像这样。我不是 Python 专家,所以请原谅任何代码错误。这会破坏 n-rooks,尽管这可能只是一个坏主意。这取决于你的目的。