int main(int argc, char *argv[]) {

	// generate seeds
	uint32_t seeds[624];
	init_genrand(0);
	generate_numbers();
	get_mt_state(seeds);

	// get hardware random numbers
	hls::stream<uint32_t> random_numbers;
	mersenne_twister(seeds, random_numbers);

	// compare with software model
	for (int i = 0; i < 1000 - 396 - 1; ++i) {
		uint32_t rn_sw = genrand_int32();
		uint32_t rn_hw = random_numbers.read();
		if (rn_sw != rn_hw) {
			std::cout << i << ": " << rn_sw << " != " << rn_hw << std::endl;
			return -1;
		}
	}

	std::cout << "test passed." << std::endl;

	return 0;
}
int main(int argc, char* argv[]) {
   int do_single_run;

   if(argc == 2) do_single_run = atoi(argv[1]);
   else if(argc == 1) do_single_run = 0;
   else {
      std::cout << "Invalid number of args." << std::endl;
      return -1;
   }
   
   if(do_single_run == 1) { 
      number_of_points = 10;

      std::vector<Coordinate> points;
      points.reserve(number_of_points);
      std::vector<Coordinate> hull_points;

      // Random number generator
      std::mt19937 mersenne_twister(std::chrono::high_resolution_clock::now().time_since_epoch().count());

      // Generate random points
      for (int i = 0; i < number_of_points; ++i) {
         Coordinate pt;
         pt.x = (float)(mersenne_twister() % 1000);
         pt.y = (float)(mersenne_twister() % 1000);
         points.push_back(pt);
      }

      // Find the time take for algorithm
      srand(time(NULL));
      clock_t start, end;

      std::sort(points.begin(), points.end());

      start = clock();
      quick_hull(points, hull_points);
      end = clock();

      // Save all points to a file
      {
         FILE *fp = fopen("points.csv", "w");
         for (const auto &pt : points) {
            fprintf(fp, "%.1f,%.1f\n", pt.x, pt.y);
         }
         fclose(fp);
      }

      // Save only convex hull points
      {
         FILE *fp = fopen("hull.csv", "w");
         for (const auto &pt : hull_points) {
            fprintf(fp, "%.1f,%.1f\n", pt.x, pt.y);
         }
         fclose(fp);
      }

      std::cout << "Time Taken(" << number_of_points << "): " << clock_time(start,end) << TIME_UNIT << std::endl;
      return 0;
   }

   std::ofstream my_file;
   my_file.open("convex_hull_results.csv");
   my_file << "No. of Points,Time (" << TIME_UNIT << ")" << std::endl;

   std::cout << "Generating..." << std::endl;
   while(number_of_points <= FINAL_SIZE) {
      std::cout << "  " << number_of_points << std::endl;

      std::vector<Coordinate> points;
      points.reserve(number_of_points);
      std::vector<Coordinate> hull_points;

      // Random number generator
      std::mt19937 mersenne_twister(std::chrono::high_resolution_clock::now().time_since_epoch().count());

      // Generate random points
      for (int i = 0; i < number_of_points; ++i) {
         Coordinate pt;
         pt.x = (float)(mersenne_twister() % 1000);
         pt.y = (float)(mersenne_twister() % 1000);
         points.push_back(pt);
      }

      // Find the time take for algorithm
      srand(time(NULL));
      clock_t start, end;

      std::sort(points.begin(), points.end());

      start = clock();
      quick_hull(points, hull_points);
      end = clock();
   
      my_file << number_of_points << "," << clock_time(start,end) << std::endl; 

      number_of_points += INCREMENT;
   }
   
   my_file.close();
   return 0;
}