numkong 7.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (294) hide show
  1. package/LICENSE +201 -0
  2. package/README.md +495 -0
  3. package/binding.gyp +540 -0
  4. package/c/dispatch.h +512 -0
  5. package/c/dispatch_bf16.c +389 -0
  6. package/c/dispatch_bf16c.c +52 -0
  7. package/c/dispatch_e2m3.c +263 -0
  8. package/c/dispatch_e3m2.c +243 -0
  9. package/c/dispatch_e4m3.c +276 -0
  10. package/c/dispatch_e5m2.c +272 -0
  11. package/c/dispatch_f16.c +376 -0
  12. package/c/dispatch_f16c.c +58 -0
  13. package/c/dispatch_f32.c +378 -0
  14. package/c/dispatch_f32c.c +99 -0
  15. package/c/dispatch_f64.c +296 -0
  16. package/c/dispatch_f64c.c +98 -0
  17. package/c/dispatch_i16.c +96 -0
  18. package/c/dispatch_i32.c +89 -0
  19. package/c/dispatch_i4.c +150 -0
  20. package/c/dispatch_i64.c +86 -0
  21. package/c/dispatch_i8.c +289 -0
  22. package/c/dispatch_other.c +330 -0
  23. package/c/dispatch_u1.c +148 -0
  24. package/c/dispatch_u16.c +124 -0
  25. package/c/dispatch_u32.c +118 -0
  26. package/c/dispatch_u4.c +150 -0
  27. package/c/dispatch_u64.c +102 -0
  28. package/c/dispatch_u8.c +303 -0
  29. package/c/numkong.c +950 -0
  30. package/include/README.md +573 -0
  31. package/include/module.modulemap +129 -0
  32. package/include/numkong/attention/sapphireamx.h +1361 -0
  33. package/include/numkong/attention/sme.h +2066 -0
  34. package/include/numkong/attention.h +49 -0
  35. package/include/numkong/capabilities.h +748 -0
  36. package/include/numkong/cast/README.md +262 -0
  37. package/include/numkong/cast/haswell.h +975 -0
  38. package/include/numkong/cast/icelake.h +470 -0
  39. package/include/numkong/cast/neon.h +1192 -0
  40. package/include/numkong/cast/rvv.h +1021 -0
  41. package/include/numkong/cast/sapphire.h +262 -0
  42. package/include/numkong/cast/serial.h +2262 -0
  43. package/include/numkong/cast/skylake.h +856 -0
  44. package/include/numkong/cast/v128relaxed.h +180 -0
  45. package/include/numkong/cast.h +230 -0
  46. package/include/numkong/curved/README.md +223 -0
  47. package/include/numkong/curved/genoa.h +182 -0
  48. package/include/numkong/curved/haswell.h +276 -0
  49. package/include/numkong/curved/neon.h +205 -0
  50. package/include/numkong/curved/neonbfdot.h +212 -0
  51. package/include/numkong/curved/neonhalf.h +212 -0
  52. package/include/numkong/curved/rvv.h +305 -0
  53. package/include/numkong/curved/serial.h +207 -0
  54. package/include/numkong/curved/skylake.h +457 -0
  55. package/include/numkong/curved/smef64.h +506 -0
  56. package/include/numkong/curved.h +517 -0
  57. package/include/numkong/curved.hpp +144 -0
  58. package/include/numkong/dot/README.md +425 -0
  59. package/include/numkong/dot/alder.h +563 -0
  60. package/include/numkong/dot/genoa.h +315 -0
  61. package/include/numkong/dot/haswell.h +1688 -0
  62. package/include/numkong/dot/icelake.h +883 -0
  63. package/include/numkong/dot/neon.h +818 -0
  64. package/include/numkong/dot/neonbfdot.h +244 -0
  65. package/include/numkong/dot/neonfhm.h +360 -0
  66. package/include/numkong/dot/neonhalf.h +198 -0
  67. package/include/numkong/dot/neonsdot.h +508 -0
  68. package/include/numkong/dot/rvv.h +714 -0
  69. package/include/numkong/dot/rvvbb.h +72 -0
  70. package/include/numkong/dot/rvvbf16.h +123 -0
  71. package/include/numkong/dot/rvvhalf.h +129 -0
  72. package/include/numkong/dot/sapphire.h +141 -0
  73. package/include/numkong/dot/serial.h +838 -0
  74. package/include/numkong/dot/sierra.h +405 -0
  75. package/include/numkong/dot/skylake.h +1084 -0
  76. package/include/numkong/dot/sve.h +379 -0
  77. package/include/numkong/dot/svebfdot.h +74 -0
  78. package/include/numkong/dot/svehalf.h +123 -0
  79. package/include/numkong/dot/v128relaxed.h +1258 -0
  80. package/include/numkong/dot.h +1070 -0
  81. package/include/numkong/dot.hpp +94 -0
  82. package/include/numkong/dots/README.md +496 -0
  83. package/include/numkong/dots/alder.h +114 -0
  84. package/include/numkong/dots/genoa.h +94 -0
  85. package/include/numkong/dots/haswell.h +295 -0
  86. package/include/numkong/dots/icelake.h +171 -0
  87. package/include/numkong/dots/neon.h +120 -0
  88. package/include/numkong/dots/neonbfdot.h +58 -0
  89. package/include/numkong/dots/neonfhm.h +94 -0
  90. package/include/numkong/dots/neonhalf.h +57 -0
  91. package/include/numkong/dots/neonsdot.h +108 -0
  92. package/include/numkong/dots/rvv.h +2486 -0
  93. package/include/numkong/dots/sapphireamx.h +3973 -0
  94. package/include/numkong/dots/serial.h +2844 -0
  95. package/include/numkong/dots/sierra.h +97 -0
  96. package/include/numkong/dots/skylake.h +196 -0
  97. package/include/numkong/dots/sme.h +5372 -0
  98. package/include/numkong/dots/smebi32.h +461 -0
  99. package/include/numkong/dots/smef64.h +1318 -0
  100. package/include/numkong/dots/smehalf.h +47 -0
  101. package/include/numkong/dots/v128relaxed.h +294 -0
  102. package/include/numkong/dots.h +2804 -0
  103. package/include/numkong/dots.hpp +639 -0
  104. package/include/numkong/each/README.md +469 -0
  105. package/include/numkong/each/haswell.h +1658 -0
  106. package/include/numkong/each/icelake.h +272 -0
  107. package/include/numkong/each/neon.h +1104 -0
  108. package/include/numkong/each/neonbfdot.h +212 -0
  109. package/include/numkong/each/neonhalf.h +410 -0
  110. package/include/numkong/each/rvv.h +1121 -0
  111. package/include/numkong/each/sapphire.h +477 -0
  112. package/include/numkong/each/serial.h +260 -0
  113. package/include/numkong/each/skylake.h +1562 -0
  114. package/include/numkong/each.h +2146 -0
  115. package/include/numkong/each.hpp +434 -0
  116. package/include/numkong/geospatial/README.md +147 -0
  117. package/include/numkong/geospatial/haswell.h +593 -0
  118. package/include/numkong/geospatial/neon.h +571 -0
  119. package/include/numkong/geospatial/rvv.h +701 -0
  120. package/include/numkong/geospatial/serial.h +309 -0
  121. package/include/numkong/geospatial/skylake.h +577 -0
  122. package/include/numkong/geospatial/v128relaxed.h +613 -0
  123. package/include/numkong/geospatial.h +453 -0
  124. package/include/numkong/geospatial.hpp +235 -0
  125. package/include/numkong/matrix.hpp +336 -0
  126. package/include/numkong/maxsim/README.md +187 -0
  127. package/include/numkong/maxsim/alder.h +511 -0
  128. package/include/numkong/maxsim/genoa.h +115 -0
  129. package/include/numkong/maxsim/haswell.h +553 -0
  130. package/include/numkong/maxsim/icelake.h +480 -0
  131. package/include/numkong/maxsim/neonsdot.h +394 -0
  132. package/include/numkong/maxsim/sapphireamx.h +877 -0
  133. package/include/numkong/maxsim/serial.h +490 -0
  134. package/include/numkong/maxsim/sme.h +929 -0
  135. package/include/numkong/maxsim/v128relaxed.h +280 -0
  136. package/include/numkong/maxsim.h +571 -0
  137. package/include/numkong/maxsim.hpp +133 -0
  138. package/include/numkong/mesh/README.md +227 -0
  139. package/include/numkong/mesh/haswell.h +2235 -0
  140. package/include/numkong/mesh/neon.h +1329 -0
  141. package/include/numkong/mesh/neonbfdot.h +842 -0
  142. package/include/numkong/mesh/neonhalf.h +616 -0
  143. package/include/numkong/mesh/rvv.h +916 -0
  144. package/include/numkong/mesh/serial.h +742 -0
  145. package/include/numkong/mesh/skylake.h +1135 -0
  146. package/include/numkong/mesh/v128relaxed.h +1052 -0
  147. package/include/numkong/mesh.h +652 -0
  148. package/include/numkong/mesh.hpp +762 -0
  149. package/include/numkong/numkong.h +78 -0
  150. package/include/numkong/numkong.hpp +57 -0
  151. package/include/numkong/probability/README.md +173 -0
  152. package/include/numkong/probability/haswell.h +267 -0
  153. package/include/numkong/probability/neon.h +225 -0
  154. package/include/numkong/probability/rvv.h +409 -0
  155. package/include/numkong/probability/serial.h +169 -0
  156. package/include/numkong/probability/skylake.h +324 -0
  157. package/include/numkong/probability.h +383 -0
  158. package/include/numkong/probability.hpp +120 -0
  159. package/include/numkong/random.h +50 -0
  160. package/include/numkong/random.hpp +285 -0
  161. package/include/numkong/reduce/README.md +547 -0
  162. package/include/numkong/reduce/alder.h +632 -0
  163. package/include/numkong/reduce/genoa.h +201 -0
  164. package/include/numkong/reduce/haswell.h +3783 -0
  165. package/include/numkong/reduce/icelake.h +549 -0
  166. package/include/numkong/reduce/neon.h +3841 -0
  167. package/include/numkong/reduce/neonbfdot.h +353 -0
  168. package/include/numkong/reduce/neonfhm.h +665 -0
  169. package/include/numkong/reduce/neonhalf.h +157 -0
  170. package/include/numkong/reduce/neonsdot.h +357 -0
  171. package/include/numkong/reduce/rvv.h +3407 -0
  172. package/include/numkong/reduce/serial.h +757 -0
  173. package/include/numkong/reduce/sierra.h +338 -0
  174. package/include/numkong/reduce/skylake.h +3792 -0
  175. package/include/numkong/reduce/v128relaxed.h +2302 -0
  176. package/include/numkong/reduce.h +1597 -0
  177. package/include/numkong/reduce.hpp +633 -0
  178. package/include/numkong/scalar/README.md +89 -0
  179. package/include/numkong/scalar/haswell.h +113 -0
  180. package/include/numkong/scalar/neon.h +122 -0
  181. package/include/numkong/scalar/neonhalf.h +70 -0
  182. package/include/numkong/scalar/rvv.h +211 -0
  183. package/include/numkong/scalar/sapphire.h +63 -0
  184. package/include/numkong/scalar/serial.h +332 -0
  185. package/include/numkong/scalar/v128relaxed.h +56 -0
  186. package/include/numkong/scalar.h +683 -0
  187. package/include/numkong/set/README.md +179 -0
  188. package/include/numkong/set/haswell.h +334 -0
  189. package/include/numkong/set/icelake.h +485 -0
  190. package/include/numkong/set/neon.h +364 -0
  191. package/include/numkong/set/rvv.h +226 -0
  192. package/include/numkong/set/rvvbb.h +117 -0
  193. package/include/numkong/set/serial.h +174 -0
  194. package/include/numkong/set/sve.h +185 -0
  195. package/include/numkong/set/v128relaxed.h +240 -0
  196. package/include/numkong/set.h +457 -0
  197. package/include/numkong/set.hpp +114 -0
  198. package/include/numkong/sets/README.md +149 -0
  199. package/include/numkong/sets/haswell.h +63 -0
  200. package/include/numkong/sets/icelake.h +66 -0
  201. package/include/numkong/sets/neon.h +61 -0
  202. package/include/numkong/sets/serial.h +43 -0
  203. package/include/numkong/sets/smebi32.h +1099 -0
  204. package/include/numkong/sets/v128relaxed.h +58 -0
  205. package/include/numkong/sets.h +339 -0
  206. package/include/numkong/sparse/README.md +156 -0
  207. package/include/numkong/sparse/icelake.h +463 -0
  208. package/include/numkong/sparse/neon.h +288 -0
  209. package/include/numkong/sparse/serial.h +117 -0
  210. package/include/numkong/sparse/sve2.h +507 -0
  211. package/include/numkong/sparse/turin.h +322 -0
  212. package/include/numkong/sparse.h +363 -0
  213. package/include/numkong/sparse.hpp +113 -0
  214. package/include/numkong/spatial/README.md +435 -0
  215. package/include/numkong/spatial/alder.h +607 -0
  216. package/include/numkong/spatial/genoa.h +290 -0
  217. package/include/numkong/spatial/haswell.h +960 -0
  218. package/include/numkong/spatial/icelake.h +586 -0
  219. package/include/numkong/spatial/neon.h +773 -0
  220. package/include/numkong/spatial/neonbfdot.h +165 -0
  221. package/include/numkong/spatial/neonhalf.h +118 -0
  222. package/include/numkong/spatial/neonsdot.h +261 -0
  223. package/include/numkong/spatial/rvv.h +984 -0
  224. package/include/numkong/spatial/rvvbf16.h +123 -0
  225. package/include/numkong/spatial/rvvhalf.h +117 -0
  226. package/include/numkong/spatial/sapphire.h +343 -0
  227. package/include/numkong/spatial/serial.h +346 -0
  228. package/include/numkong/spatial/sierra.h +323 -0
  229. package/include/numkong/spatial/skylake.h +606 -0
  230. package/include/numkong/spatial/sve.h +224 -0
  231. package/include/numkong/spatial/svebfdot.h +122 -0
  232. package/include/numkong/spatial/svehalf.h +109 -0
  233. package/include/numkong/spatial/v128relaxed.h +717 -0
  234. package/include/numkong/spatial.h +1425 -0
  235. package/include/numkong/spatial.hpp +183 -0
  236. package/include/numkong/spatials/README.md +580 -0
  237. package/include/numkong/spatials/alder.h +94 -0
  238. package/include/numkong/spatials/genoa.h +94 -0
  239. package/include/numkong/spatials/haswell.h +219 -0
  240. package/include/numkong/spatials/icelake.h +113 -0
  241. package/include/numkong/spatials/neon.h +109 -0
  242. package/include/numkong/spatials/neonbfdot.h +60 -0
  243. package/include/numkong/spatials/neonfhm.h +92 -0
  244. package/include/numkong/spatials/neonhalf.h +58 -0
  245. package/include/numkong/spatials/neonsdot.h +109 -0
  246. package/include/numkong/spatials/rvv.h +1960 -0
  247. package/include/numkong/spatials/sapphireamx.h +1149 -0
  248. package/include/numkong/spatials/serial.h +226 -0
  249. package/include/numkong/spatials/sierra.h +96 -0
  250. package/include/numkong/spatials/skylake.h +184 -0
  251. package/include/numkong/spatials/sme.h +1901 -0
  252. package/include/numkong/spatials/smef64.h +465 -0
  253. package/include/numkong/spatials/v128relaxed.h +240 -0
  254. package/include/numkong/spatials.h +3021 -0
  255. package/include/numkong/spatials.hpp +508 -0
  256. package/include/numkong/tensor.hpp +1592 -0
  257. package/include/numkong/trigonometry/README.md +184 -0
  258. package/include/numkong/trigonometry/haswell.h +652 -0
  259. package/include/numkong/trigonometry/neon.h +639 -0
  260. package/include/numkong/trigonometry/rvv.h +699 -0
  261. package/include/numkong/trigonometry/serial.h +703 -0
  262. package/include/numkong/trigonometry/skylake.h +721 -0
  263. package/include/numkong/trigonometry/v128relaxed.h +666 -0
  264. package/include/numkong/trigonometry.h +467 -0
  265. package/include/numkong/trigonometry.hpp +166 -0
  266. package/include/numkong/types.h +1384 -0
  267. package/include/numkong/types.hpp +5603 -0
  268. package/include/numkong/vector.hpp +698 -0
  269. package/javascript/README.md +246 -0
  270. package/javascript/dist/cjs/numkong-wasm.d.ts +166 -0
  271. package/javascript/dist/cjs/numkong-wasm.js +617 -0
  272. package/javascript/dist/cjs/numkong.d.ts +343 -0
  273. package/javascript/dist/cjs/numkong.js +523 -0
  274. package/javascript/dist/cjs/package.json +3 -0
  275. package/javascript/dist/cjs/types.d.ts +284 -0
  276. package/javascript/dist/cjs/types.js +653 -0
  277. package/javascript/dist/esm/numkong-wasm.d.ts +166 -0
  278. package/javascript/dist/esm/numkong-wasm.js +595 -0
  279. package/javascript/dist/esm/numkong.d.ts +343 -0
  280. package/javascript/dist/esm/numkong.js +452 -0
  281. package/javascript/dist/esm/package.json +3 -0
  282. package/javascript/dist/esm/types.d.ts +284 -0
  283. package/javascript/dist/esm/types.js +630 -0
  284. package/javascript/dist-package-cjs.json +3 -0
  285. package/javascript/dist-package-esm.json +3 -0
  286. package/javascript/node-gyp-build.d.ts +1 -0
  287. package/javascript/numkong-wasm.ts +756 -0
  288. package/javascript/numkong.c +689 -0
  289. package/javascript/numkong.ts +575 -0
  290. package/javascript/tsconfig-base.json +39 -0
  291. package/javascript/tsconfig-cjs.json +8 -0
  292. package/javascript/tsconfig-esm.json +8 -0
  293. package/javascript/types.ts +674 -0
  294. package/package.json +87 -0
@@ -0,0 +1,309 @@
1
+ /**
2
+ * @brief Serial Geospatial Distances.
3
+ * @file include/numkong/geospatial/serial.h
4
+ * @author Ash Vardanian
5
+ * @date February 6, 2026
6
+ *
7
+ * @sa include/numkong/geospatial.h
8
+ */
9
+ #ifndef NK_GEOSPATIAL_SERIAL_H
10
+ #define NK_GEOSPATIAL_SERIAL_H
11
+
12
+ #include "numkong/types.h"
13
+ #include "numkong/spatial/serial.h" // `nk_f64_sqrt_serial`, `nk_f32_sqrt_serial`
14
+ #include "numkong/trigonometry/serial.h" // `nk_f64_sin`, `nk_f64_cos`, `nk_f64_atan2`, etc.
15
+
16
+ #if defined(__cplusplus)
17
+ extern "C" {
18
+ #endif
19
+
20
+ /* Serial implementations of geospatial distance functions.
21
+ * These use the trigonometric functions from trigonometry.h for sin, cos, and atan2.
22
+ */
23
+
24
+ NK_PUBLIC void nk_haversine_f64_serial( //
25
+ nk_f64_t const *a_lats, nk_f64_t const *a_lons, //
26
+ nk_f64_t const *b_lats, nk_f64_t const *b_lons, //
27
+ nk_size_t n, nk_f64_t *results) {
28
+
29
+ nk_f64_t const earth_radius = NK_EARTH_MEDIATORIAL_RADIUS;
30
+
31
+ for (nk_size_t i = 0; i != n; ++i) {
32
+ nk_f64_t first_latitude = a_lats[i];
33
+ nk_f64_t first_longitude = a_lons[i];
34
+ nk_f64_t second_latitude = b_lats[i];
35
+ nk_f64_t second_longitude = b_lons[i];
36
+
37
+ nk_f64_t latitude_delta = second_latitude - first_latitude;
38
+ nk_f64_t longitude_delta = second_longitude - first_longitude;
39
+
40
+ // Haversine formula: a = sin²(Δlat/2) + cos(lat1)×cos(lat2)×sin²(Δlon/2)
41
+ nk_f64_t sin_latitude_delta_half = nk_f64_sin(latitude_delta * 0.5);
42
+ nk_f64_t sin_longitude_delta_half = nk_f64_sin(longitude_delta * 0.5);
43
+ nk_f64_t cos_first_latitude = nk_f64_cos(first_latitude);
44
+ nk_f64_t cos_second_latitude = nk_f64_cos(second_latitude);
45
+
46
+ // Use FMA for improved precision
47
+ nk_f64_t sin_lat_sq = sin_latitude_delta_half * sin_latitude_delta_half;
48
+ nk_f64_t sin_lon_sq = sin_longitude_delta_half * sin_longitude_delta_half;
49
+ nk_f64_t cos_product = cos_first_latitude * cos_second_latitude;
50
+ nk_f64_t haversine_term = nk_f64_fma_serial(cos_product, sin_lon_sq, sin_lat_sq);
51
+ // Clamp haversine_term to [0, 1] to prevent NaN from sqrt of negative values
52
+ haversine_term = (haversine_term < 0.0) ? 0.0 : ((haversine_term > 1.0) ? 1.0 : haversine_term);
53
+
54
+ // Central angle: c = 2 × atan2(√a, √(1-a))
55
+ nk_f64_t sqrt_haversine = nk_f64_sqrt_serial(haversine_term);
56
+ nk_f64_t sqrt_complement = nk_f64_sqrt_serial(1.0 - haversine_term);
57
+ nk_f64_t central_angle = 2.0 * nk_f64_atan2(sqrt_haversine, sqrt_complement);
58
+
59
+ results[i] = earth_radius * central_angle;
60
+ }
61
+ }
62
+
63
+ NK_PUBLIC void nk_haversine_f32_serial( //
64
+ nk_f32_t const *a_lats, nk_f32_t const *a_lons, //
65
+ nk_f32_t const *b_lats, nk_f32_t const *b_lons, //
66
+ nk_size_t n, nk_f32_t *results) {
67
+
68
+ nk_f32_t const earth_radius = (nk_f32_t)NK_EARTH_MEDIATORIAL_RADIUS;
69
+
70
+ for (nk_size_t i = 0; i != n; ++i) {
71
+ nk_f32_t first_latitude = a_lats[i];
72
+ nk_f32_t first_longitude = a_lons[i];
73
+ nk_f32_t second_latitude = b_lats[i];
74
+ nk_f32_t second_longitude = b_lons[i];
75
+
76
+ nk_f32_t latitude_delta = second_latitude - first_latitude;
77
+ nk_f32_t longitude_delta = second_longitude - first_longitude;
78
+
79
+ // Haversine formula: a = sin²(Δlat/2) + cos(lat1)×cos(lat2)×sin²(Δlon/2)
80
+ nk_f32_t sin_latitude_delta_half = nk_f32_sin(latitude_delta * 0.5f);
81
+ nk_f32_t sin_longitude_delta_half = nk_f32_sin(longitude_delta * 0.5f);
82
+ nk_f32_t cos_first_latitude = nk_f32_cos(first_latitude);
83
+ nk_f32_t cos_second_latitude = nk_f32_cos(second_latitude);
84
+
85
+ // Use FMA for improved precision
86
+ nk_f32_t sin_lat_sq = sin_latitude_delta_half * sin_latitude_delta_half;
87
+ nk_f32_t sin_lon_sq = sin_longitude_delta_half * sin_longitude_delta_half;
88
+ nk_f32_t cos_product = cos_first_latitude * cos_second_latitude;
89
+ nk_f32_t haversine_term = nk_f32_fma_serial(cos_product, sin_lon_sq, sin_lat_sq);
90
+
91
+ // Clamp to [0, 1] to avoid NaN from sqrt of negative numbers (due to floating point errors)
92
+ if (haversine_term < 0.0f) haversine_term = 0.0f;
93
+ if (haversine_term > 1.0f) haversine_term = 1.0f;
94
+
95
+ // Central angle: c = 2 × atan2(√a, √(1-a))
96
+ nk_f32_t sqrt_haversine = nk_f32_sqrt_serial(haversine_term);
97
+ nk_f32_t sqrt_complement = nk_f32_sqrt_serial(1.0f - haversine_term);
98
+ nk_f32_t central_angle = 2.0f * nk_f32_atan2(sqrt_haversine, sqrt_complement);
99
+
100
+ results[i] = earth_radius * central_angle;
101
+ }
102
+ }
103
+
104
+ NK_PUBLIC void nk_vincenty_f64_serial( //
105
+ nk_f64_t const *a_lats, nk_f64_t const *a_lons, //
106
+ nk_f64_t const *b_lats, nk_f64_t const *b_lons, //
107
+ nk_size_t n, nk_f64_t *results) {
108
+
109
+ nk_f64_t const equatorial_radius = NK_EARTH_ELLIPSOID_EQUATORIAL_RADIUS;
110
+ nk_f64_t const polar_radius = NK_EARTH_ELLIPSOID_POLAR_RADIUS;
111
+ nk_f64_t const flattening = 1.0 / NK_EARTH_ELLIPSOID_INVERSE_FLATTENING;
112
+
113
+ for (nk_size_t i = 0; i != n; ++i) {
114
+ nk_f64_t first_latitude = a_lats[i];
115
+ nk_f64_t second_latitude = b_lats[i];
116
+ nk_f64_t longitude_difference = b_lons[i] - a_lons[i];
117
+
118
+ // Reduced latitudes on the auxiliary sphere
119
+ nk_f64_t tan_reduced_first = (1.0 - flattening) * (nk_f64_sin(first_latitude) / nk_f64_cos(first_latitude));
120
+ nk_f64_t tan_reduced_second = (1.0 - flattening) * (nk_f64_sin(second_latitude) / nk_f64_cos(second_latitude));
121
+ nk_f64_t cos_reduced_first = 1.0 / nk_f64_sqrt_serial(1.0 + tan_reduced_first * tan_reduced_first);
122
+ nk_f64_t sin_reduced_first = tan_reduced_first * cos_reduced_first;
123
+ nk_f64_t cos_reduced_second = 1.0 / nk_f64_sqrt_serial(1.0 + tan_reduced_second * tan_reduced_second);
124
+ nk_f64_t sin_reduced_second = tan_reduced_second * cos_reduced_second;
125
+
126
+ // Iterative convergence of lambda (difference in longitude on auxiliary sphere)
127
+ nk_f64_t lambda = longitude_difference;
128
+ nk_f64_t lambda_previous = longitude_difference;
129
+ nk_f64_t sin_angular_distance, cos_angular_distance, angular_distance;
130
+ nk_f64_t sin_azimuth, cos_squared_azimuth, cos_double_angular_midpoint;
131
+ nk_u32_t iteration = 0;
132
+
133
+ // Check for coincident points early
134
+ nk_u32_t coincident = 0;
135
+ do {
136
+ nk_f64_t sin_lambda = nk_f64_sin(lambda);
137
+ nk_f64_t cos_lambda = nk_f64_cos(lambda);
138
+
139
+ nk_f64_t cross_term = cos_reduced_second * sin_lambda;
140
+ nk_f64_t mixed_term = cos_reduced_first * sin_reduced_second -
141
+ sin_reduced_first * cos_reduced_second * cos_lambda;
142
+ sin_angular_distance = nk_f64_sqrt_serial(cross_term * cross_term + mixed_term * mixed_term);
143
+
144
+ if (sin_angular_distance == 0.0) {
145
+ coincident = 1;
146
+ break;
147
+ }
148
+
149
+ cos_angular_distance = sin_reduced_first * sin_reduced_second +
150
+ cos_reduced_first * cos_reduced_second * cos_lambda;
151
+ angular_distance = nk_f64_atan2(sin_angular_distance, cos_angular_distance);
152
+
153
+ sin_azimuth = cos_reduced_first * cos_reduced_second * sin_lambda / sin_angular_distance;
154
+ cos_squared_azimuth = 1.0 - sin_azimuth * sin_azimuth;
155
+
156
+ // Handle equatorial geodesic case
157
+ cos_double_angular_midpoint = (cos_squared_azimuth != 0.0)
158
+ ? cos_angular_distance -
159
+ 2.0 * sin_reduced_first * sin_reduced_second / cos_squared_azimuth
160
+ : 0.0;
161
+
162
+ nk_f64_t correction_factor = flattening / 16.0 * cos_squared_azimuth *
163
+ (4.0 + flattening * (4.0 - 3.0 * cos_squared_azimuth));
164
+
165
+ lambda_previous = lambda;
166
+ lambda = longitude_difference + (1.0 - correction_factor) * flattening * sin_azimuth *
167
+ (angular_distance + correction_factor * sin_angular_distance *
168
+ (cos_double_angular_midpoint +
169
+ correction_factor * cos_angular_distance *
170
+ (-1.0 + 2.0 * cos_double_angular_midpoint *
171
+ cos_double_angular_midpoint)));
172
+
173
+ iteration++;
174
+ } while (nk_f64_abs_(lambda - lambda_previous) > NK_VINCENTY_CONVERGENCE_THRESHOLD_F64 &&
175
+ iteration < NK_VINCENTY_MAX_ITERATIONS);
176
+
177
+ if (coincident) {
178
+ results[i] = 0.0;
179
+ continue;
180
+ }
181
+
182
+ // Final distance calculation
183
+ nk_f64_t u_squared = cos_squared_azimuth *
184
+ (equatorial_radius * equatorial_radius - polar_radius * polar_radius) /
185
+ (polar_radius * polar_radius);
186
+ nk_f64_t series_a = 1.0 + u_squared / 16384.0 *
187
+ (4096.0 + u_squared * (-768.0 + u_squared * (320.0 - 175.0 * u_squared)));
188
+ nk_f64_t series_b = u_squared / 1024.0 * (256.0 + u_squared * (-128.0 + u_squared * (74.0 - 47.0 * u_squared)));
189
+
190
+ nk_f64_t angular_correction =
191
+ series_b * sin_angular_distance *
192
+ (cos_double_angular_midpoint +
193
+ series_b / 4.0 *
194
+ (cos_angular_distance * (-1.0 + 2.0 * cos_double_angular_midpoint * cos_double_angular_midpoint) -
195
+ series_b / 6.0 * cos_double_angular_midpoint *
196
+ (-3.0 + 4.0 * sin_angular_distance * sin_angular_distance) *
197
+ (-3.0 + 4.0 * cos_double_angular_midpoint * cos_double_angular_midpoint)));
198
+
199
+ results[i] = polar_radius * series_a * (angular_distance - angular_correction);
200
+ }
201
+ }
202
+
203
+ NK_PUBLIC void nk_vincenty_f32_serial( //
204
+ nk_f32_t const *a_lats, nk_f32_t const *a_lons, //
205
+ nk_f32_t const *b_lats, nk_f32_t const *b_lons, //
206
+ nk_size_t n, nk_f32_t *results) {
207
+
208
+ nk_f32_t const equatorial_radius = (nk_f32_t)NK_EARTH_ELLIPSOID_EQUATORIAL_RADIUS;
209
+ nk_f32_t const polar_radius = (nk_f32_t)NK_EARTH_ELLIPSOID_POLAR_RADIUS;
210
+ nk_f32_t const flattening = 1.0f / (nk_f32_t)NK_EARTH_ELLIPSOID_INVERSE_FLATTENING;
211
+ nk_f32_t const convergence_threshold = 1e-7f;
212
+
213
+ for (nk_size_t i = 0; i != n; ++i) {
214
+ nk_f32_t first_latitude = a_lats[i];
215
+ nk_f32_t second_latitude = b_lats[i];
216
+ nk_f32_t longitude_difference = b_lons[i] - a_lons[i];
217
+
218
+ // Reduced latitudes on the auxiliary sphere
219
+ nk_f32_t tan_reduced_first = (1.0f - flattening) * (nk_f32_sin(first_latitude) / nk_f32_cos(first_latitude));
220
+ nk_f32_t tan_reduced_second = (1.0f - flattening) * (nk_f32_sin(second_latitude) / nk_f32_cos(second_latitude));
221
+ nk_f32_t cos_reduced_first = 1.0f / nk_f32_sqrt_serial(1.0f + tan_reduced_first * tan_reduced_first);
222
+ nk_f32_t sin_reduced_first = tan_reduced_first * cos_reduced_first;
223
+ nk_f32_t cos_reduced_second = 1.0f / nk_f32_sqrt_serial(1.0f + tan_reduced_second * tan_reduced_second);
224
+ nk_f32_t sin_reduced_second = tan_reduced_second * cos_reduced_second;
225
+
226
+ // Iterative convergence of lambda (difference in longitude on auxiliary sphere)
227
+ nk_f32_t lambda = longitude_difference;
228
+ nk_f32_t lambda_previous = longitude_difference;
229
+ nk_f32_t sin_angular_distance, cos_angular_distance, angular_distance;
230
+ nk_f32_t sin_azimuth, cos_squared_azimuth, cos_double_angular_midpoint;
231
+ nk_u32_t iteration = 0;
232
+
233
+ // Check for coincident points early
234
+ nk_u32_t coincident = 0;
235
+ do {
236
+ nk_f32_t sin_lambda = nk_f32_sin(lambda);
237
+ nk_f32_t cos_lambda = nk_f32_cos(lambda);
238
+
239
+ nk_f32_t cross_term = cos_reduced_second * sin_lambda;
240
+ nk_f32_t mixed_term = cos_reduced_first * sin_reduced_second -
241
+ sin_reduced_first * cos_reduced_second * cos_lambda;
242
+ sin_angular_distance = nk_f32_sqrt_serial(cross_term * cross_term + mixed_term * mixed_term);
243
+
244
+ if (sin_angular_distance == 0.0f) {
245
+ coincident = 1;
246
+ break;
247
+ }
248
+
249
+ cos_angular_distance = sin_reduced_first * sin_reduced_second +
250
+ cos_reduced_first * cos_reduced_second * cos_lambda;
251
+ angular_distance = nk_f32_atan2(sin_angular_distance, cos_angular_distance);
252
+
253
+ sin_azimuth = cos_reduced_first * cos_reduced_second * sin_lambda / sin_angular_distance;
254
+ cos_squared_azimuth = 1.0f - sin_azimuth * sin_azimuth;
255
+
256
+ // Handle equatorial geodesic case
257
+ cos_double_angular_midpoint = (cos_squared_azimuth != 0.0f)
258
+ ? cos_angular_distance -
259
+ 2.0f * sin_reduced_first * sin_reduced_second / cos_squared_azimuth
260
+ : 0.0f;
261
+
262
+ nk_f32_t correction_factor = flattening / 16.0f * cos_squared_azimuth *
263
+ (4.0f + flattening * (4.0f - 3.0f * cos_squared_azimuth));
264
+
265
+ lambda_previous = lambda;
266
+ lambda = longitude_difference +
267
+ (1.0f - correction_factor) * flattening * sin_azimuth *
268
+ (angular_distance +
269
+ correction_factor * sin_angular_distance *
270
+ (cos_double_angular_midpoint +
271
+ correction_factor * cos_angular_distance *
272
+ (-1.0f + 2.0f * cos_double_angular_midpoint * cos_double_angular_midpoint)));
273
+
274
+ iteration++;
275
+ } while (nk_f32_abs_(lambda - lambda_previous) > convergence_threshold &&
276
+ iteration < NK_VINCENTY_MAX_ITERATIONS);
277
+
278
+ if (coincident) {
279
+ results[i] = 0.0;
280
+ continue;
281
+ }
282
+
283
+ // Final distance calculation
284
+ nk_f32_t u_squared = cos_squared_azimuth *
285
+ (equatorial_radius * equatorial_radius - polar_radius * polar_radius) /
286
+ (polar_radius * polar_radius);
287
+ nk_f32_t series_a = 1.0f + u_squared / 16384.0f *
288
+ (4096.0f + u_squared * (-768.0f + u_squared * (320.0f - 175.0f * u_squared)));
289
+ nk_f32_t series_b = u_squared / 1024.0f *
290
+ (256.0f + u_squared * (-128.0f + u_squared * (74.0f - 47.0f * u_squared)));
291
+
292
+ nk_f32_t angular_correction =
293
+ series_b * sin_angular_distance *
294
+ (cos_double_angular_midpoint +
295
+ series_b / 4.0f *
296
+ (cos_angular_distance * (-1.0f + 2.0f * cos_double_angular_midpoint * cos_double_angular_midpoint) -
297
+ series_b / 6.0f * cos_double_angular_midpoint *
298
+ (-3.0f + 4.0f * sin_angular_distance * sin_angular_distance) *
299
+ (-3.0f + 4.0f * cos_double_angular_midpoint * cos_double_angular_midpoint)));
300
+
301
+ results[i] = polar_radius * series_a * (angular_distance - angular_correction);
302
+ }
303
+ }
304
+
305
+ #if defined(__cplusplus)
306
+ } // extern "C"
307
+ #endif
308
+
309
+ #endif // NK_GEOSPATIAL_SERIAL_H