package com.nativelibs4java.opencl.util;
import org.bridj.Pointer;
import static org.bridj.Pointer.*;
import com.nativelibs4java.opencl.JavaCL;
import org.junit.Assert;
import org.junit.Test;
/**
*
* @author ochafik
*/
public class ParallelRandomTest {
int nPoints = 1024 * 1024;
int nLoops = 10;
long seed = 1;
static final int mask = 0x00ffffff;
static final double divid = (1 << 24);
//static final int mask = (1 << 30) - 1;
//static final double divid = (1 << 30);
/**
* http://fr.wikipedia.org/wiki/M%C3%A9thode_de_Monte-Carlo#Exemples
*/
@Test
public void testPICircle() {
try {
ParallelRandom random = new ParallelRandom(
JavaCL.createBestContext().createDefaultQueue(),
nPoints * 2,
seed
);
int nInside = 0, nTotalPoints = 0;
for (int iLoop = 0; iLoop < nLoops; iLoop++) {
Pointer<Integer> values = random.next();
for (int iPoint = 0; iPoint < nPoints; iPoint++) {
int offset = iPoint * 2;
int ix = values.get(offset), iy = values.get(offset + 1);
float x = (float)((ix & mask) / divid);
float y = (float)((iy & mask) / divid);
float dist = x * x + y * y;
if (dist <= 1)
nInside++;
}
nTotalPoints += nPoints;
//checkPICircleProba(nInside, nTotalPoints);
}
checkPICircleProba(nInside, nTotalPoints);
} catch (Exception ex) {
throw new RuntimeException(ex);
}
}
void checkPICircleProba(int nInside, int nTotalPoints) {
double piRef = Math.PI;
double probaInside = nInside / (double)nTotalPoints; // = Pi / 4
double piApprox = probaInside * 4;
double error = Math.abs(piApprox - piRef);
double relError = error / piRef;
System.out.println(nInside + " points inside the circle quarter over " + nTotalPoints);
System.out.println("Approximated PI = " + piApprox);
System.out.println(" Reference PI = " + piRef);
System.out.println("\tAbsolute error = " + error);
System.out.println("\tRelative error = " + (relError * 100) + " %");
Assert.assertEquals(piRef, piApprox, 0.001);
}
}