summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorStan Seibert <stan@mtrr.org>2011-09-03 09:19:55 -0400
committerStan Seibert <stan@mtrr.org>2011-09-03 09:19:55 -0400
commit48550062440c5b7f1479ecbe17fd4b024a90fca2 (patch)
tree6b64979c375d98fee4a11fbd4ab4ab86d0507d51 /src
parentb8e7b443242c716c12006442c2738e09ed77c0c9 (diff)
downloadchroma-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.h24
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"
{