Cleaning up Sobol sampling code.
In particular, removing some things I tried when the golden ratio sampling was causing problems, but that are now no longer needed.
This commit is contained in:
parent
3916043f33
commit
e46fc5a4d6
|
@ -7,7 +7,7 @@ use std::{env, fs::File, io::Write, path::Path};
|
||||||
const NUM_DIMENSIONS: usize = 1024;
|
const NUM_DIMENSIONS: usize = 1024;
|
||||||
|
|
||||||
/// What file to generate the numbers from.
|
/// What file to generate the numbers from.
|
||||||
const DIRECTION_NUMBERS_TEXT: &str = include_str!("direction_numbers/joe-kuo-other-2.1024.txt");
|
const DIRECTION_NUMBERS_TEXT: &str = include_str!("direction_numbers/new-joe-kuo-5.1024.txt");
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
let out_dir = env::var("OUT_DIR").unwrap();
|
let out_dir = env::var("OUT_DIR").unwrap();
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -54,24 +54,33 @@ pub fn sample_owen(dimension: u32, index: u32, scramble: u32) -> f32 {
|
||||||
u32_to_0_1_f32(owen_scramble_u32(sobol_u32(dimension, index), scramble))
|
u32_to_0_1_f32(owen_scramble_u32(sobol_u32(dimension, index), scramble))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Same as `sample()` except applies both Owen scrambling and
|
/// Same as `sample_owen()` except uses a slower more full version of
|
||||||
/// Cranley-Patterson rotation using the given scramble parameter.
|
/// Owen scrambling.
|
||||||
///
|
///
|
||||||
/// For the technically curious: this first does Owen scrambling, and then
|
/// This is mainly intended to help validate the faster Owen scrambling,
|
||||||
/// Cranley-Patterson. If it were done the other way around it would
|
/// and likely shouldn't be used for real things. It is significantly
|
||||||
/// invalidate the Owen scrambling.
|
/// slower.
|
||||||
///
|
|
||||||
/// To get proper scrambling and rotation, you need to use a different scramble
|
|
||||||
/// value for each dimension, and those values should be generated more-or-less
|
|
||||||
/// randomly. For example, using a 32-bit hash of the dimension parameter
|
|
||||||
/// works well.
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn sample_owen_cranley(dimension: u32, index: u32, scramble: u32) -> f32 {
|
pub fn sample_owen_slow(dimension: u32, index: u32, scramble: u32) -> f32 {
|
||||||
// Reusing the same scramble parameter for both the Owen scrambling and
|
let mut n = sobol_u32(dimension, index);
|
||||||
// the Cranely-Patterson rotation actually works fine, because the Owen
|
n ^= scramble;
|
||||||
// scrambling is implemented as a sort of hash, so they don't end up being
|
for i in 0..16 {
|
||||||
// correlated.
|
let mask = (1 << (31 - i)) - 1;
|
||||||
u32_to_0_1_f32(owen_scramble_u32(sobol_u32(dimension, index), scramble).wrapping_add(scramble))
|
let hash = {
|
||||||
|
let mut hash = n & (!mask);
|
||||||
|
let seed = scramble + i;
|
||||||
|
let perms = [0x29aaaaa7, 0x736caf6f, 0x54aad35b, 0x2ab35aaa];
|
||||||
|
for p in perms.iter().cycle().take(6) {
|
||||||
|
hash = hash.wrapping_mul(*p);
|
||||||
|
hash ^= hash.wrapping_shr(16);
|
||||||
|
hash ^= seed;
|
||||||
|
}
|
||||||
|
hash
|
||||||
|
};
|
||||||
|
n ^= hash & mask;
|
||||||
|
}
|
||||||
|
|
||||||
|
u32_to_0_1_f32(n)
|
||||||
}
|
}
|
||||||
|
|
||||||
//----------------------------------------------------------------------
|
//----------------------------------------------------------------------
|
||||||
|
|
Loading…
Reference in New Issue
Block a user