#include "Intel_Compatibility.h"
#include "dSFMT.h"
#include <iostream>
#include <ctime>
#include <vector>

#define HEIGHT 64
#define LEVELS 4

using namespace std;

int main()
{
	cout << "RUNNING EAGLE = HYBRID with HEIGHT = " << HEIGHT << std::endl;
	
	dsfmt_t dsfmt;
	dsfmt_init_gen_rand(&dsfmt, 10235);
	
	int sizeOfAlpha = 17043522;
	int bottom = 266306;
	
	double *alpha = new double[sizeOfAlpha];
	//vector<double> alpha;
	for(int i = 0; i <= sizeOfAlpha; i++)
	//	alpha.push_back(0.0);
		alpha[i] = 0.0;
	
	double sum = 0.0;
	
	for(int i = bottom; i <= sizeOfAlpha; i++)
	{
		alpha[i] = dsfmt_genrand_close_open(&dsfmt);
		sum += alpha[i];
	}
	
	for(int i = bottom; i <= sizeOfAlpha; i++)
	{
		alpha[i] /= sum;
		
		int t = i;
		while(t > 1)
		{
			t = (t - 2)/(HEIGHT)  + 1;
			alpha[t] += alpha[i];
		}
		
		if(t != 1)
		{
			cout << "t != 1! for i = " << i << std::endl;
			return 0;
		}
	}
	
	cout << "alpha[1] = " << alpha[1] << std::endl;
	
	int numTimes = 1000000000;
	
	cout << "Timing Eagle for " << numTimes << std::endl;
	
	int p = 0;
	
	// Start timing here
	long timeStart = clock();
	
	// Now do this like 1000000 times
	for(int i = 0; i < numTimes; i++)
	{
		// Generate a random number, and try to find it in alpha
		double randNum = dsfmt_genrand_close_open(&dsfmt);
		
		int t = 2;
		
		for(int j = 5; --j; )
			for(int k = 0; k < HEIGHT; ++k)
				if(randNum <= alpha[t + k])
				{
					// Move to child of this node
					t = (HEIGHT)*((t + k)-1) + 2;
				}
				else
				{
					randNum -= alpha[t + k];
				}
	}
	
	// End Timing here
	long timeEnd = clock();

	cout << "Consumed a total of " << timeEnd - timeStart << " milliseconds." << std::endl;
	
	return 0;
}
