Moved the haversine code to a subdirectory
This commit is contained in:
		
							
								
								
									
										100
									
								
								haversine/cpp/fscanf.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										100
									
								
								haversine/cpp/fscanf.cpp
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,100 @@
 | 
			
		||||
#include "haversine.h"
 | 
			
		||||
#include <bits/types/FILE.h>
 | 
			
		||||
#include <stdio.h>
 | 
			
		||||
#include <stdlib.h>
 | 
			
		||||
#include <string.h>
 | 
			
		||||
#include <time.h>
 | 
			
		||||
 | 
			
		||||
#define DEBUG 0
 | 
			
		||||
 | 
			
		||||
#define EARTH_RADIUS_KM 6371.0
 | 
			
		||||
 | 
			
		||||
#if DEBUG
 | 
			
		||||
#define ITEM_COUNT 2
 | 
			
		||||
#else
 | 
			
		||||
#define ITEM_COUNT 10000000
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
struct Item {
 | 
			
		||||
  double x0;
 | 
			
		||||
  double y0;
 | 
			
		||||
  double x1;
 | 
			
		||||
  double y1;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
int main(int argc, char *argv[]) {
 | 
			
		||||
#if DEBUG
 | 
			
		||||
  FILE *fp = fopen("../test_data.json", "rb");
 | 
			
		||||
#else
 | 
			
		||||
  FILE *fp = fopen("../data_10000000_flex.json", "rb");
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
  Item *items = (Item *)malloc(ITEM_COUNT * sizeof(Item));
 | 
			
		||||
  int index = 0;
 | 
			
		||||
 | 
			
		||||
  clock_t start_time = clock();
 | 
			
		||||
 | 
			
		||||
  {
 | 
			
		||||
    char buf[256];
 | 
			
		||||
    int read = fread(buf, 1, 256, fp);
 | 
			
		||||
 | 
			
		||||
    for (int i = 1; i < read; ++i) {
 | 
			
		||||
      if (buf[i] == '{') {
 | 
			
		||||
        fseek(fp, i, SEEK_SET);
 | 
			
		||||
        break;
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  while (true) {
 | 
			
		||||
    fscanf(fp, "{\n");
 | 
			
		||||
 | 
			
		||||
    int scanned = fscanf(fp,
 | 
			
		||||
                         "      \"x0\": %lf,\n      \"y0\": %lf,\n      "
 | 
			
		||||
                         "\"x1\": %lf,\n      \"y1\": %lf\n    },\n    ",
 | 
			
		||||
                         &(items[index].x0), &(items[index].y0),
 | 
			
		||||
                         &(items[index].x1), &(items[index].y1));
 | 
			
		||||
 | 
			
		||||
    if (scanned == 0) {
 | 
			
		||||
      break;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    ++index;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  clock_t mid_time = clock();
 | 
			
		||||
 | 
			
		||||
  double sum = 0.0;
 | 
			
		||||
 | 
			
		||||
  for (int i = 0; i < ITEM_COUNT; ++i) {
 | 
			
		||||
    sum += haversine_of_degrees(items[i].x0, items[i].y0, items[i].x1,
 | 
			
		||||
                                items[i].y1, EARTH_RADIUS_KM);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  double average = sum / ITEM_COUNT;
 | 
			
		||||
 | 
			
		||||
  clock_t end_time = clock();
 | 
			
		||||
 | 
			
		||||
  printf("Result: %.16f\n", average);
 | 
			
		||||
  printf("Input = %.16f seconds\n",
 | 
			
		||||
         (double)(mid_time - start_time) / CLOCKS_PER_SEC);
 | 
			
		||||
  printf("Math = %.16f seconds\n",
 | 
			
		||||
         (double)(end_time - mid_time) / CLOCKS_PER_SEC);
 | 
			
		||||
  printf("Total = %.16f seconds\n",
 | 
			
		||||
         (double)(end_time - start_time) / CLOCKS_PER_SEC);
 | 
			
		||||
  printf("Throughput = %.16f haversines/second\n",
 | 
			
		||||
         ITEM_COUNT / ((double)(end_time - start_time) / CLOCKS_PER_SEC));
 | 
			
		||||
 | 
			
		||||
#if DEBUG
 | 
			
		||||
  for (int i = 0; i < ITEM_COUNT; ++i) {
 | 
			
		||||
    printf("%.16f\n%.16f\n%.16f\n%.16f\n\n", items[i].x0, items[i].y0,
 | 
			
		||||
           items[i].x1, items[i].y1);
 | 
			
		||||
  }
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
  free(items);
 | 
			
		||||
 | 
			
		||||
  fclose(fp);
 | 
			
		||||
 | 
			
		||||
  return 0;
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										24
									
								
								haversine/cpp/haversine.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										24
									
								
								haversine/cpp/haversine.cpp
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,24 @@
 | 
			
		||||
#include "haversine.h"
 | 
			
		||||
#include <math.h>
 | 
			
		||||
 | 
			
		||||
#define PI 3.14159265358979323845
 | 
			
		||||
#define SQUARE(X) ((X) * (X))
 | 
			
		||||
 | 
			
		||||
double radians(double degrees);
 | 
			
		||||
 | 
			
		||||
double haversine_of_degrees(double x0, double y0, double x1, double y1,
 | 
			
		||||
                            double radius) {
 | 
			
		||||
  double dy = radians(y1 - y0);
 | 
			
		||||
  double dx = radians(x1 - x0);
 | 
			
		||||
  y0 = radians(y0);
 | 
			
		||||
  y1 = radians(y1);
 | 
			
		||||
 | 
			
		||||
  double root_term =
 | 
			
		||||
      SQUARE(sin(dy / 2.0)) + cos(y0) * cos(y1) * SQUARE(sin(dx / 2.0));
 | 
			
		||||
 | 
			
		||||
  double result = 2.0 * radius * asin(sqrt(root_term));
 | 
			
		||||
 | 
			
		||||
  return result;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
double radians(double degrees) { return (degrees * PI) / 180.0; }
 | 
			
		||||
							
								
								
									
										7
									
								
								haversine/cpp/haversine.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										7
									
								
								haversine/cpp/haversine.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,7 @@
 | 
			
		||||
#ifndef HAVERSINE_H
 | 
			
		||||
#define HAVERSINE_H
 | 
			
		||||
 | 
			
		||||
double haversine_of_degrees(double x0, double y0, double x1, double y1,
 | 
			
		||||
                            double radius);
 | 
			
		||||
 | 
			
		||||
#endif // !HAVERSINE_H
 | 
			
		||||
							
								
								
									
										112
									
								
								haversine/cpp/strtok.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										112
									
								
								haversine/cpp/strtok.cpp
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,112 @@
 | 
			
		||||
#include "haversine.h"
 | 
			
		||||
#include <bits/types/FILE.h>
 | 
			
		||||
#include <stdio.h>
 | 
			
		||||
#include <stdlib.h>
 | 
			
		||||
#include <string.h>
 | 
			
		||||
#include <time.h>
 | 
			
		||||
 | 
			
		||||
#define DEBUG 0
 | 
			
		||||
 | 
			
		||||
#define EARTH_RADIUS_KM 6371.0
 | 
			
		||||
 | 
			
		||||
#if DEBUG
 | 
			
		||||
#define ITEM_COUNT 2
 | 
			
		||||
#else
 | 
			
		||||
#define ITEM_COUNT 10000000
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
struct Item {
 | 
			
		||||
  double x0;
 | 
			
		||||
  double y0;
 | 
			
		||||
  double x1;
 | 
			
		||||
  double y1;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
int main(int argc, char *argv[]) {
 | 
			
		||||
#if DEBUG
 | 
			
		||||
  FILE *fp = fopen("../test_data.json", "rb");
 | 
			
		||||
#else
 | 
			
		||||
  FILE *fp = fopen("../data_10000000_flex.json", "rb");
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
  Item *items = (Item *)malloc(ITEM_COUNT * sizeof(Item));
 | 
			
		||||
  int index = 0;
 | 
			
		||||
  double *elem = nullptr;
 | 
			
		||||
 | 
			
		||||
  fseek(fp, 0, SEEK_END);
 | 
			
		||||
 | 
			
		||||
  long length = (long)ftell(fp);
 | 
			
		||||
 | 
			
		||||
  fseek(fp, 0, SEEK_SET);
 | 
			
		||||
 | 
			
		||||
  char *text = (char *)malloc(length + 1);
 | 
			
		||||
  memset(text, 0, length + 1);
 | 
			
		||||
 | 
			
		||||
  fread(text, 1, length, fp);
 | 
			
		||||
 | 
			
		||||
  clock_t start_time = clock();
 | 
			
		||||
 | 
			
		||||
  const char *delim = "{}[]:,\"\n ";
 | 
			
		||||
 | 
			
		||||
  char *token = strtok(text, delim);
 | 
			
		||||
 | 
			
		||||
  while (token) {
 | 
			
		||||
    if (strcmp(token, "x0") == 0) {
 | 
			
		||||
      elem = &(items[index].x0);
 | 
			
		||||
    } else if (strcmp(token, "y0") == 0) {
 | 
			
		||||
      elem = &(items[index].y0);
 | 
			
		||||
    } else if (strcmp(token, "x1") == 0) {
 | 
			
		||||
      elem = &(items[index].x1);
 | 
			
		||||
    } else if (strcmp(token, "y1") == 0) {
 | 
			
		||||
      elem = &(items[index].y1);
 | 
			
		||||
      ++index;
 | 
			
		||||
    } else {
 | 
			
		||||
      if (elem) {
 | 
			
		||||
        char *end = &(token[strlen(token)]);
 | 
			
		||||
        *elem = strtod(token, &end);
 | 
			
		||||
        elem = nullptr;
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    token = strtok(NULL, delim);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  clock_t mid_time = clock();
 | 
			
		||||
 | 
			
		||||
  double sum = 0.0;
 | 
			
		||||
 | 
			
		||||
  for (int i = 0; i < ITEM_COUNT; ++i) {
 | 
			
		||||
    sum += haversine_of_degrees(items[i].x0, items[i].y0, items[i].x1,
 | 
			
		||||
                                items[i].y1, EARTH_RADIUS_KM);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  double average = sum / ITEM_COUNT;
 | 
			
		||||
 | 
			
		||||
  clock_t end_time = clock();
 | 
			
		||||
 | 
			
		||||
  printf("Result: %.16f\n", average);
 | 
			
		||||
  printf("Input = %.16f seconds\n",
 | 
			
		||||
         (double)(mid_time - start_time) / CLOCKS_PER_SEC);
 | 
			
		||||
  printf("Math = %.16f seconds\n",
 | 
			
		||||
         (double)(end_time - mid_time) / CLOCKS_PER_SEC);
 | 
			
		||||
  printf("Total = %.16f seconds\n",
 | 
			
		||||
         (double)(end_time - start_time) / CLOCKS_PER_SEC);
 | 
			
		||||
  printf("Throughput = %.16f haversines/second\n",
 | 
			
		||||
         ITEM_COUNT / ((double)(end_time - start_time) / CLOCKS_PER_SEC));
 | 
			
		||||
 | 
			
		||||
#if DEBUG
 | 
			
		||||
  int precision = 16;
 | 
			
		||||
  for (int i = 0; i < ITEM_COUNT; ++i) {
 | 
			
		||||
    printf("%.*f\n%.*f\n%.*f\n%.*f\n\n", precision, items[i].x0, precision,
 | 
			
		||||
           items[i].y0, precision, items[i].x1, precision, items[i].y1);
 | 
			
		||||
  }
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
  free(text);
 | 
			
		||||
 | 
			
		||||
  free(items);
 | 
			
		||||
 | 
			
		||||
  fclose(fp);
 | 
			
		||||
 | 
			
		||||
  return 0;
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										14
									
								
								haversine/python/haversine_algorithm.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										14
									
								
								haversine/python/haversine_algorithm.py
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,14 @@
 | 
			
		||||
from math import radians, sin, cos, sqrt, asin
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def haversine_of_degrees(x0, y0, x1, y1, radius):
 | 
			
		||||
    dy = radians(y1 - y0)
 | 
			
		||||
    dx = radians(x1 - x0)
 | 
			
		||||
    y0 = radians(y0)
 | 
			
		||||
    y1 = radians(y1)
 | 
			
		||||
 | 
			
		||||
    root_term = (sin(dy / 2) ** 2) + cos(y0) * cos(y1) * (sin(dx / 2) ** 2)
 | 
			
		||||
 | 
			
		||||
    result = 2 * radius * asin(sqrt(root_term))
 | 
			
		||||
 | 
			
		||||
    return result
 | 
			
		||||
							
								
								
									
										40
									
								
								haversine/python/haversine_json.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										40
									
								
								haversine/python/haversine_json.py
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,40 @@
 | 
			
		||||
# Naive Python version of the code
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
import os
 | 
			
		||||
from haversine_algorithm import haversine_of_degrees
 | 
			
		||||
import time
 | 
			
		||||
import json
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
filepath = os.path.join(
 | 
			
		||||
    os.path.dirname(os.path.dirname(os.path.abspath(__file__))),
 | 
			
		||||
    "data_10000000_flex.json",
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
with open(filepath, "r") as json_file:
 | 
			
		||||
    start_time = time.time()
 | 
			
		||||
    json_input = json.load(json_file)
 | 
			
		||||
    mid_time = time.time()
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
earth_radius_km = 6371
 | 
			
		||||
sum = 0
 | 
			
		||||
count = 0
 | 
			
		||||
 | 
			
		||||
for pair in json_input["pairs"]:
 | 
			
		||||
    sum += haversine_of_degrees(
 | 
			
		||||
        pair["x0"], pair["y0"], pair["x1"], pair["y1"], earth_radius_km
 | 
			
		||||
    )
 | 
			
		||||
 | 
			
		||||
    count += 1
 | 
			
		||||
 | 
			
		||||
average = sum / count
 | 
			
		||||
 | 
			
		||||
end_time = time.time()
 | 
			
		||||
 | 
			
		||||
print(f"Result: {average}")
 | 
			
		||||
print(f"Input = {mid_time - start_time} seconds")
 | 
			
		||||
print(f"Math = {end_time - mid_time} seconds")
 | 
			
		||||
print(f"Total = {end_time - start_time} seconds")
 | 
			
		||||
print(f"Throughput = {count / (end_time - start_time)} haversines/second")
 | 
			
		||||
							
								
								
									
										16
									
								
								haversine/test_data.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										16
									
								
								haversine/test_data.json
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,16 @@
 | 
			
		||||
{
 | 
			
		||||
  "pairs": [
 | 
			
		||||
    {
 | 
			
		||||
      "x0": -4.618412003630709,
 | 
			
		||||
      "y0": 135.8153583196389,
 | 
			
		||||
      "x1": -12.383220322958223,
 | 
			
		||||
      "y1": 85.20071945064029
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
      "x0": 47.817641963713584,
 | 
			
		||||
      "y0": 111.40590001495877,
 | 
			
		||||
      "x1": -34.52607922832944,
 | 
			
		||||
      "y1": -127.52991299863771
 | 
			
		||||
    }
 | 
			
		||||
	]
 | 
			
		||||
}
 | 
			
		||||
		Reference in New Issue
	
	Block a user