Sep
18
2009
Monte-Carlo Integration using Thrust
Bored. Wrote a numerical integrator using Thrust for fun.
Solves, numerically, the integral from 0 to 1 for (x^2)*cos(x).
Analytically, we can solve and get: 2*cos(1) – sin(1) = 0.239133627
So, the code is as follows:
#include <vector_functions.h> #include <thrust/host_vector.h> #include <thrust/device_vector.h> #include <thrust/generate.h> #include <thrust/transform.h> #include <thrust/count.h> #include <cstdlib> #include <math.h> float2 bottomLeft; float2 topRight; __device__ float f(float x) { return (x*x*__cosf(x)); } struct above_below_function { __device__ float operator()(float2 p) const { return (p.y < f(p.x)) ? 1 : 0; } }; float2 make_random_float2(){ return make_float2( (rand() / (float)RAND_MAX) * (float)(topRight.x - bottomLeft.x) + (float)bottomLeft.x, (rand() / (float)RAND_MAX) * (float)(topRight.y - bottomLeft.y) + (float)bottomLeft.y); } int main() { srand(time(0)); bottomLeft.x = 0; bottomLeft.y = 0; topRight.x = 1; topRight.y = 1; int numPoints = 10000000; // find the area of our bounding square float area = (topRight.x - bottomLeft.x) * (topRight.y - bottomLeft.y); // generate our points thrust::host_vector<float2> h_locations(numPoints); thrust::generate(h_locations.begin(), h_locations.end(), make_random_float2); // create two device vectors -- one for our locations, and another to create a count thrust::device_vector<float2> d_locations = h_locations; thrust::device_vector<unsigned int> d_boolean(numPoints); // for each element, if the y is below f(x), then put a 1 in the array. otherwise, put a 0 thrust::transform(d_locations.begin(), d_locations.end(), d_boolean.begin(), above_below_function()); int total = thrust::count(d_boolean.begin(), d_boolean.end(), 1); std::cout << "Area under curve: " << area * (total / (float)numPoints) << std::endl; return 0; }
The solutions? Here are a few sample runs…
Area under curve: 0.239177
Area under curve: 0.238916
Area under curve: 0.239181
Area under curve: 0.239129
Pretty accurate, and pretty damn fast too.
