diff options
author | Stan Seibert <stan@mtrr.org> | 2011-09-03 09:19:55 -0400 |
---|---|---|
committer | Stan Seibert <stan@mtrr.org> | 2011-09-03 09:19:55 -0400 |
commit | 48550062440c5b7f1479ecbe17fd4b024a90fca2 (patch) | |
tree | 6b64979c375d98fee4a11fbd4ab4ab86d0507d51 /src | |
parent | b8e7b443242c716c12006442c2738e09ed77c0c9 (diff) | |
download | chroma-48550062440c5b7f1479ecbe17fd4b024a90fca2.tar.gz chroma-48550062440c5b7f1479ecbe17fd4b024a90fca2.tar.bz2 chroma-48550062440c5b7f1479ecbe17fd4b024a90fca2.zip |
GPU-based sampling from an arbitrary distribition.
The sample_cdf() device function will draw random numbers from an arbitrary
disribution given a cumulative distribution function in the form of
a list of x,y points, beginning with y=0 and ending with y=1. For an
example of how to convert a ROOT histogram to this form, see the unit
test in test_sample_cdf.py
Diffstat (limited to 'src')
-rw-r--r-- | src/random.h | 24 |
1 files changed, 24 insertions, 0 deletions
diff --git a/src/random.h b/src/random.h index b084c19..6abc415 100644 --- a/src/random.h +++ b/src/random.h @@ -19,6 +19,30 @@ __device__ float3 uniform_sphere(curandState *s) return make_float3(c*cosf(theta), c*sinf(theta), u); } +// Draw a random sample given a cumulative distribution function +// Assumptions: ncdf >= 2, cdf_y[0] is 0.0, and cdf_y[ncdf-1] is 1.0 +__device__ float sample_cdf(curandState *rng, int ncdf, + float *cdf_x, float *cdf_y) +{ + float u = curand_uniform(rng); + + // Find u in cdf_y with binary search + // list must contain at least 2 elements: 0.0 and 1.0 + int lower=0; + int upper=ncdf-1; + while(lower < upper-1) { + int half = (lower+upper) / 2; + if (u < cdf_y[half]) + upper = half; + else + lower = half; + } + + float frac = (u - cdf_y[lower]) / (cdf_y[upper] - cdf_y[lower]); + return cdf_x[lower] * frac + cdf_x[upper] * (1.0f - frac); +} + + extern "C" { |