private static ArrayList<Point> generate_random_pointset(
			double pointset_sparsity, double noise_factor, double[] grid_size) {

		// Initialize the grid
		ArrayList<Point> pointset = new ArrayList<Point>();
		Random rand = new Random();
		int dimension = grid_size.length;		

		int[] current_coordinate = new int[dimension];

		for (int i = 0; i < current_coordinate.length; i++) {
			current_coordinate[i] = 0;
		}

		while (current_coordinate[0] < grid_size[0]) {
			
			// Possibly make a point at current_coordinate
			if (Math.random() < pointset_sparsity) {
				ArrayList<Double> coordinates = new ArrayList<Double>();

				for(int d = 0; d < dimension; d++){
					double coord = current_coordinate[d];
					double coord_exponent = rand.nextInt(2);
					
					coordinates.add(coord
							+ (Math.random() * noise_factor * Math.pow(-1.0,
									coord_exponent)));					
				}
				
				pointset.add(new Point(dimension, coordinates));
				
			}

			current_coordinate[dimension - 1] += 1;
			boolean done = false;
			int current_dim = dimension - 1;

			while (!done && current_dim > 0) {
				done = true;
				if (current_coordinate[current_dim] >= grid_size[current_dim]) {
					done = false;
					current_coordinate[current_dim] = 0;
					current_coordinate[current_dim - 1]++;
				}
				current_dim--;
			}
		}		

		// Log the grid statistics
		grid_log = "Grid: ";
		for (int i = 0; i < dimension; i++) {
			if (i == 0) {
				grid_log += grid_size[i];
			} else {
				grid_log += "x" + grid_size[i];
			}
		}
		grid_log += "\nS: " + pointset_sparsity + "\nN: " + noise_factor + "\n";

		return pointset;
	}