From c80e6b6b1ebc3caca2d0ca4e84339c8d51f99e52 Mon Sep 17 00:00:00 2001 From: Patrick Stevens Date: Sat, 3 Jun 2023 20:04:13 +0100 Subject: [PATCH] Add data generator (#20) --- .gitignore | 3 + Cargo.lock | 275 ++++++++++++++++++++++--------------- Cargo.toml | 6 +- computer_enhance | 2 +- generator/Cargo.toml | 15 ++ generator/src/main.rs | 227 ++++++++++++++++++++++++++++++ haversine/Cargo.toml | 11 ++ haversine/src/distance.rs | 23 ++++ haversine/src/earth.rs | 1 + haversine/src/haversine.rs | 14 ++ haversine/src/lib.rs | 3 + wrapper/Cargo.toml | 4 +- 12 files changed, 472 insertions(+), 112 deletions(-) create mode 100644 generator/Cargo.toml create mode 100644 generator/src/main.rs create mode 100644 haversine/Cargo.toml create mode 100644 haversine/src/distance.rs create mode 100644 haversine/src/earth.rs create mode 100644 haversine/src/haversine.rs create mode 100644 haversine/src/lib.rs diff --git a/.gitignore b/.gitignore index 3864e7b..e342029 100644 --- a/.gitignore +++ b/.gitignore @@ -4,3 +4,6 @@ target/ .vscode/ .profile* .DS_Store + +data_*_flex.json +data_*_haveranswer.f64 diff --git a/Cargo.lock b/Cargo.lock index 31c9d59..cb68ce2 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4,42 +4,51 @@ version = 3 [[package]] name = "anstream" -version = "0.2.6" +version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "342258dd14006105c2b75ab1bd7543a03bdf0cfc94383303ac212a04939dff6f" +checksum = "0ca84f3628370c59db74ee214b3263d58f9aadd9b4fe7e711fd87dc452b7f163" dependencies = [ "anstyle", "anstyle-parse", + "anstyle-query", "anstyle-wincon", - "concolor-override", - "concolor-query", + "colorchoice", "is-terminal", "utf8parse", ] [[package]] name = "anstyle" -version = "0.3.5" +version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "23ea9e81bd02e310c216d080f6223c179012256e5151c41db88d12c88a1684d2" +checksum = "41ed9a86bf92ae6580e0a31281f65a1b1d867c0cc68d5346e2ae128dddfa6a7d" [[package]] name = "anstyle-parse" -version = "0.1.1" +version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a7d1bb534e9efed14f3e5f44e7dd1a4f709384023a4165199a4241e18dff0116" +checksum = "e765fd216e48e067936442276d1d57399e37bce53c264d6fefbe298080cb57ee" dependencies = [ "utf8parse", ] [[package]] -name = "anstyle-wincon" -version = "0.2.0" +name = "anstyle-query" +version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3127af6145b149f3287bb9a0d10ad9c5692dba8c53ad48285e5bec4063834fa" +checksum = "5ca11d4be1bab0c8bc8734a9aa7bf4ee8316d462a08c6ac5052f888fef5b494b" +dependencies = [ + "windows-sys", +] + +[[package]] +name = "anstyle-wincon" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "180abfa45703aebe0093f79badacc01b8fd4ea2e35118747e5811127f926e188" dependencies = [ "anstyle", - "windows-sys 0.45.0", + "windows-sys", ] [[package]] @@ -66,6 +75,12 @@ version = "1.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" +[[package]] +name = "byteorder" +version = "1.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610" + [[package]] name = "cc" version = "1.0.79" @@ -73,10 +88,16 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "50d30906286121d95be3d479533b458f87493b30a4b5f79a607db8f5d11aa91f" [[package]] -name = "clap" -version = "4.2.1" +name = "cfg-if" +version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "046ae530c528f252094e4a77886ee1374437744b2bff1497aa898bbddbbb29b3" +checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" + +[[package]] +name = "clap" +version = "4.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b4ed2379f8603fa2b7509891660e802b88c70a79a6427a70abb5968054de2c28" dependencies = [ "clap_builder", "clap_derive", @@ -85,9 +106,9 @@ dependencies = [ [[package]] name = "clap_builder" -version = "4.2.1" +version = "4.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "223163f58c9a40c3b0a43e1c4b50a9ce09f007ea2cb1ec258a687945b4b7929f" +checksum = "72394f3339a76daf211e57d4bcb374410f3965dcc606dd0e03738c7888766980" dependencies = [ "anstream", "anstyle", @@ -98,9 +119,9 @@ dependencies = [ [[package]] name = "clap_derive" -version = "4.2.0" +version = "4.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3f9644cd56d6b87dbe899ef8b053e331c0637664e9e21a33dfcdc36093f5c5c4" +checksum = "59e9ef9a08ee1c0e1f2e162121665ac45ac3783b0f897db7244ae75ad9a8f65b" dependencies = [ "heck", "proc-macro2", @@ -110,24 +131,15 @@ dependencies = [ [[package]] name = "clap_lex" -version = "0.4.1" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a2dd5a6fe8c6e3502f568a6353e5273bbb15193ad9a89e457b9970798efbea1" +checksum = "2da6da31387c7e4ef160ffab6d5e7f00c42626fe39aea70a7b0f1773f7dd6c1b" [[package]] -name = "concolor-override" +name = "colorchoice" version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a855d4a1978dc52fb0536a04d384c2c0c1aa273597f08b77c8c4d3b2eec6037f" - -[[package]] -name = "concolor-query" -version = "0.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "88d11d52c3d7ca2e6d0040212be9e4dbbcd78b6447f535b6b561f449427944cf" -dependencies = [ - "windows-sys 0.45.0", -] +checksum = "acbf1af155f9b9ef647e42cdc158db4b64a1b61f743629225fde6f3e0be2a7c7" [[package]] name = "const_panic" @@ -157,7 +169,7 @@ checksum = "4bcfec3a70f97c962c307b2d2c56e358cf1d00b558d74262b5f929ee8cc7e73a" dependencies = [ "errno-dragonfly", "libc", - "windows-sys 0.48.0", + "windows-sys", ] [[package]] @@ -170,6 +182,36 @@ dependencies = [ "libc", ] +[[package]] +name = "generator" +version = "0.1.0" +dependencies = [ + "byteorder", + "clap", + "haversine", + "rand", + "serde", + "serde_json", +] + +[[package]] +name = "getrandom" +version = "0.2.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c85e1d9ab2eadba7e5040d4e09cbd6d072b76a557ad64e797c2cb9d4da21d7e4" +dependencies = [ + "cfg-if", + "libc", + "wasi", +] + +[[package]] +name = "haversine" +version = "0.1.0" +dependencies = [ + "serde", +] + [[package]] name = "heck" version = "0.4.1" @@ -190,7 +232,7 @@ checksum = "9c66c74d2ae7e79a5a8f7ac924adbe38ee42a859c6539ad869eb51f0b52dc220" dependencies = [ "hermit-abi", "libc", - "windows-sys 0.48.0", + "windows-sys", ] [[package]] @@ -202,9 +244,15 @@ dependencies = [ "hermit-abi", "io-lifetimes", "rustix", - "windows-sys 0.48.0", + "windows-sys", ] +[[package]] +name = "itoa" +version = "1.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "453ad9f582a441959e5f0d088b02ce04cfe8d51a8eaf077f12ac6d3e94164ca6" + [[package]] name = "konst_kernel" version = "0.3.4" @@ -251,6 +299,12 @@ version = "1.17.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b7e5500299e16ebb147ae15a00a942af264cf3688f47923b8fc2cd5858f23ad3" +[[package]] +name = "ppv-lite86" +version = "0.2.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de" + [[package]] name = "proc-macro2" version = "1.0.56" @@ -269,6 +323,36 @@ dependencies = [ "proc-macro2", ] +[[package]] +name = "rand" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" +dependencies = [ + "libc", + "rand_chacha", + "rand_core", +] + +[[package]] +name = "rand_chacha" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" +dependencies = [ + "ppv-lite86", + "rand_core", +] + +[[package]] +name = "rand_core" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" +dependencies = [ + "getrandom", +] + [[package]] name = "rustix" version = "0.37.11" @@ -280,7 +364,44 @@ dependencies = [ "io-lifetimes", "libc", "linux-raw-sys", - "windows-sys 0.48.0", + "windows-sys", +] + +[[package]] +name = "ryu" +version = "1.0.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f91339c0467de62360649f8d3e185ca8de4224ff281f66000de5eb2a77a79041" + +[[package]] +name = "serde" +version = "1.0.163" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2113ab51b87a539ae008b5c6c02dc020ffa39afd2d83cffcb3f4eb2722cebec2" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde_derive" +version = "1.0.163" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8c805777e3930c8883389c602315a24224bcc738b63905ef87cd1420353ea93e" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.14", +] + +[[package]] +name = "serde_json" +version = "1.0.96" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "057d394a50403bcac12672b2b18fb387ab6d289d957dab67dd201875391e52f1" +dependencies = [ + "itoa", + "ryu", + "serde", ] [[package]] @@ -334,13 +455,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "711b9620af191e0cdc7468a8d14e709c3dcdb115b36f838e601583af800a370a" [[package]] -name = "windows-sys" -version = "0.45.0" +name = "wasi" +version = "0.11.0+wasi-snapshot-preview1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "75283be5efb2831d37ea142365f009c02ec203cd29a3ebecbc093d52315b66d0" -dependencies = [ - "windows-targets 0.42.2", -] +checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" [[package]] name = "windows-sys" @@ -348,22 +466,7 @@ version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" dependencies = [ - "windows-targets 0.48.0", -] - -[[package]] -name = "windows-targets" -version = "0.42.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e5180c00cd44c9b1c88adb3693291f1cd93605ded80c250a75d472756b4d071" -dependencies = [ - "windows_aarch64_gnullvm 0.42.2", - "windows_aarch64_msvc 0.42.2", - "windows_i686_gnu 0.42.2", - "windows_i686_msvc 0.42.2", - "windows_x86_64_gnu 0.42.2", - "windows_x86_64_gnullvm 0.42.2", - "windows_x86_64_msvc 0.42.2", + "windows-targets", ] [[package]] @@ -372,93 +475,51 @@ version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7b1eb6f0cd7c80c79759c929114ef071b87354ce476d9d94271031c0497adfd5" dependencies = [ - "windows_aarch64_gnullvm 0.48.0", - "windows_aarch64_msvc 0.48.0", - "windows_i686_gnu 0.48.0", - "windows_i686_msvc 0.48.0", - "windows_x86_64_gnu 0.48.0", - "windows_x86_64_gnullvm 0.48.0", - "windows_x86_64_msvc 0.48.0", + "windows_aarch64_gnullvm", + "windows_aarch64_msvc", + "windows_i686_gnu", + "windows_i686_msvc", + "windows_x86_64_gnu", + "windows_x86_64_gnullvm", + "windows_x86_64_msvc", ] -[[package]] -name = "windows_aarch64_gnullvm" -version = "0.42.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "597a5118570b68bc08d8d59125332c54f1ba9d9adeedeef5b99b02ba2b0698f8" - [[package]] name = "windows_aarch64_gnullvm" version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "91ae572e1b79dba883e0d315474df7305d12f569b400fcf90581b06062f7e1bc" -[[package]] -name = "windows_aarch64_msvc" -version = "0.42.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e08e8864a60f06ef0d0ff4ba04124db8b0fb3be5776a5cd47641e942e58c4d43" - [[package]] name = "windows_aarch64_msvc" version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b2ef27e0d7bdfcfc7b868b317c1d32c641a6fe4629c171b8928c7b08d98d7cf3" -[[package]] -name = "windows_i686_gnu" -version = "0.42.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c61d927d8da41da96a81f029489353e68739737d3beca43145c8afec9a31a84f" - [[package]] name = "windows_i686_gnu" version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "622a1962a7db830d6fd0a69683c80a18fda201879f0f447f065a3b7467daa241" -[[package]] -name = "windows_i686_msvc" -version = "0.42.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "44d840b6ec649f480a41c8d80f9c65108b92d89345dd94027bfe06ac444d1060" - [[package]] name = "windows_i686_msvc" version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4542c6e364ce21bf45d69fdd2a8e455fa38d316158cfd43b3ac1c5b1b19f8e00" -[[package]] -name = "windows_x86_64_gnu" -version = "0.42.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8de912b8b8feb55c064867cf047dda097f92d51efad5b491dfb98f6bbb70cb36" - [[package]] name = "windows_x86_64_gnu" version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ca2b8a661f7628cbd23440e50b05d705db3686f894fc9580820623656af974b1" -[[package]] -name = "windows_x86_64_gnullvm" -version = "0.42.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26d41b46a36d453748aedef1486d5c7a85db22e56aff34643984ea85514e94a3" - [[package]] name = "windows_x86_64_gnullvm" version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7896dbc1f41e08872e9d5e8f8baa8fdd2677f29468c4e156210174edc7f7b953" -[[package]] -name = "windows_x86_64_msvc" -version = "0.42.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9aec5da331524158c6d1a4ac0ab1541149c0b9505fde06423b02f5ef0106b9f0" - [[package]] name = "windows_x86_64_msvc" version = "0.48.0" diff --git a/Cargo.toml b/Cargo.toml index ff5f571..b398290 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,10 +1,12 @@ [workspace] members = [ "sim_8086", - "wrapper" + "wrapper", + "generator", + "haversine" ] [profile.release] lto = true strip = true -panic = 'abort' \ No newline at end of file +panic = 'abort' diff --git a/computer_enhance b/computer_enhance index 727d993..a6e9cb2 160000 --- a/computer_enhance +++ b/computer_enhance @@ -1 +1 @@ -Subproject commit 727d9936dd00e39fbb6a504fc3388adbc6560e0c +Subproject commit a6e9cb2a7b57e450ba2e7b75d0fd3e36ffa72d7d diff --git a/generator/Cargo.toml b/generator/Cargo.toml new file mode 100644 index 0000000..b33ec36 --- /dev/null +++ b/generator/Cargo.toml @@ -0,0 +1,15 @@ +[package] +name = "generator" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + + +[dependencies] +clap = { version = "4.3.1", features = [ "derive" ] } +rand = "0.8.5" +haversine = { path = "../haversine" } +serde_json = "1.0.96" +serde = "1.0.163" +byteorder = "1.4.3" diff --git a/generator/src/main.rs b/generator/src/main.rs new file mode 100644 index 0000000..e0cf5bc --- /dev/null +++ b/generator/src/main.rs @@ -0,0 +1,227 @@ +use byteorder::{ByteOrder, LittleEndian}; +use clap::{builder::PossibleValue, Parser, ValueEnum}; +use haversine::haversine::{CoordinatePair, HaversineData}; +use haversine::{distance, earth}; +use rand::distributions::Distribution; +use rand::rngs::StdRng; +use rand::{Rng, SeedableRng}; +use std::fmt::{Display, Formatter}; +use std::fs::File; +use std::io::{BufWriter, Read, Write}; +use std::str::FromStr; + +#[derive(Clone, Debug)] +enum SelectionAlgorithm { + Cluster, + Uniform, +} + +impl Display for SelectionAlgorithm { + fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { + match self { + Self::Cluster => f.write_str("cluster"), + Self::Uniform => f.write_str("uniform"), + } + } +} + +impl FromStr for SelectionAlgorithm { + type Err = (); + + fn from_str(s: &str) -> Result { + match s.to_ascii_lowercase().as_str() { + "cluster" => Ok(SelectionAlgorithm::Cluster), + "uniform" => Ok(SelectionAlgorithm::Uniform), + _ => Err(()), + } + } +} + +impl ValueEnum for SelectionAlgorithm { + fn value_variants<'a>() -> &'a [Self] { + &[SelectionAlgorithm::Cluster, SelectionAlgorithm::Uniform] + } + fn to_possible_value(&self) -> Option { + match self { + SelectionAlgorithm::Cluster => Some(PossibleValue::new("cluster")), + SelectionAlgorithm::Uniform => Some(PossibleValue::new("uniform")), + } + } +} + +#[derive(Parser, Debug)] +struct Args { + #[arg(value_name = "RANDOM_SEED", required = true)] + seed: u64, + #[arg(value_name = "COUNT", required = true)] + count: usize, + #[arg(default_value_t = SelectionAlgorithm::Cluster, long)] + algorithm: SelectionAlgorithm, +} + +fn write_json(data: &HaversineData, json_filename: &str) { + let output_file = File::create(json_filename).unwrap(); + let mut writer = BufWriter::new(output_file); + + serde_json::to_writer(&mut writer, &data).unwrap(); + writer.flush().unwrap(); +} + +fn write_answer(data: &HaversineData, binary_filename: &str) { + let output_file = File::create(binary_filename).unwrap(); + let mut writer = BufWriter::new(output_file); + + let mut expected_sum: f64 = 0.0; + + let mut buf = [0u8; 8]; + for point in &data.pairs { + let distance = distance::naive(point, earth::RADIUS); + LittleEndian::write_f64(&mut buf, distance); + + let written = writer.write(&buf).unwrap(); + if written < buf.len() { + panic!("Failed to write everything") + } + + expected_sum += distance; + } + + println!("Expected sum: {}", expected_sum); + + LittleEndian::write_f64(&mut buf, expected_sum); + let written = writer.write(&buf).unwrap(); + if written < buf.len() { + panic!("Failed to write everything") + } + + writer.flush().unwrap(); +} + +#[allow(dead_code)] +fn read_answer(binary_filename: &str) -> (Vec, f64) { + let mut file = File::create(binary_filename).unwrap(); + let file_size = file.metadata().unwrap().len(); + if file_size % 8 != 0 { + panic!( + "Malformed input file of size {} is not a multiple of 8", + file_size + ) + } + let num_floats = file_size / 8; + assert_ne!(num_floats, 0, "Empty file"); + let num_bytes = num_floats - 1; + + let mut data = Vec::with_capacity(num_bytes as usize); + let mut buf = [0u8, 8]; + + for _ in 0..num_floats { + let bytes_read = file.read(&mut buf).unwrap(); + if bytes_read < 8 { + panic!("Not enough bytes read") + } + + data.push(LittleEndian::read_f64(&buf)); + } + + let bytes_read = file.read(&mut buf).unwrap(); + if bytes_read < 8 { + panic!("Not enough bytes read") + } + + (data, LittleEndian::read_f64(&buf)) +} + +fn point_within( + point: &CoordinatePair, + cluster_centre_x: f64, + cluster_centre_y: f64, + cluster_radius: f64, +) -> bool { + let mut distance = CoordinatePair { + x0: point.x0, + y0: point.y0, + x1: cluster_centre_x, + y1: cluster_centre_y, + }; + if distance::naive(&distance, 1.0) > cluster_radius { + return false; + } + + distance.x0 = point.x1; + distance.y0 = point.y1; + + distance::naive(&distance, 1.0) <= cluster_radius +} + +const CLUSTER_COUNT: usize = 20; + +fn main() { + let args = Args::parse(); + println!("Method: {}", args.algorithm); + println!("Random seed: {}", args.seed); + println!("Pair count: {}", args.count); + + let mut v = Vec::with_capacity(args.count); + let mut rng = StdRng::seed_from_u64(args.seed); + + let x_range = rand::distributions::Uniform::from(-180.0..180.0); + let y_range = rand::distributions::Uniform::from(-90.0..90.0); + + match args.algorithm { + SelectionAlgorithm::Uniform => { + for _ in 0usize..args.count { + let point = CoordinatePair { + x0: x_range.sample(&mut rng), + y0: y_range.sample(&mut rng), + x1: x_range.sample(&mut rng), + y1: y_range.sample(&mut rng), + }; + + v.push(point); + } + } + SelectionAlgorithm::Cluster => { + if args.count % CLUSTER_COUNT != 0 { + panic!( + "Number of points {} is not a multiple of cluster count {CLUSTER_COUNT}", + args.count + ); + } + + for _ in 0..CLUSTER_COUNT { + // Uniformly sampling over lat/long pairs is dumb and biased towards the poles, + // but :shrug: we'll just bias it away a bit by hand. + let cluster_centre_x = x_range.sample(&mut rng); + // Bias a bit away from the pole by shrinking it + let cluster_centre_y = y_range.sample(&mut rng) * 0.9; + let cluster_radius = rng.gen_range(0.1..0.4); + + for _ in 0..args.count / CLUSTER_COUNT { + let mut point = CoordinatePair { + x0: 0.0, + y0: 0.0, + x1: 0.0, + // too big to ever be in the right place, so a suitable uninitialised value + y1: 1000.0, + }; + while !point_within(&point, cluster_centre_x, cluster_centre_y, cluster_radius) + { + point.x0 = x_range.sample(&mut rng); + point.y0 = y_range.sample(&mut rng); + point.x1 = x_range.sample(&mut rng); + point.y1 = y_range.sample(&mut rng); + } + + v.push(point); + } + } + } + } + + let data = HaversineData { pairs: v }; + let json_filename = format!("data_{}_flex.json", args.count); + write_json(&data, &json_filename); + + let answer_filename = format!("data_{}_haveranswer.f64", args.count); + write_answer(&data, &answer_filename); +} diff --git a/haversine/Cargo.toml b/haversine/Cargo.toml new file mode 100644 index 0000000..5cff0f1 --- /dev/null +++ b/haversine/Cargo.toml @@ -0,0 +1,11 @@ +[package] +name = "haversine" +version = "0.1.0" +edition = "2021" + +[lib] + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +serde = { version = "1.0.163", features = [ "derive" ] } diff --git a/haversine/src/distance.rs b/haversine/src/distance.rs new file mode 100644 index 0000000..68e5d96 --- /dev/null +++ b/haversine/src/distance.rs @@ -0,0 +1,23 @@ +use crate::haversine::CoordinatePair; + +fn square(x: f64) -> f64 { + x * x +} + +pub fn naive(point: &CoordinatePair, earth_radius: f64) -> f64 { + let lat1 = point.y0; + let lat2 = point.y1; + let lon1 = point.x0; + let lon2 = point.x1; + + let lat_deg = (lat2 - lat1).to_radians(); + let lon_deg = (lon2 - lon1).to_radians(); + let lat1 = lat1.to_radians(); + let lat2 = lat2.to_radians(); + + let a = square(f64::sin(lat_deg / 2.0)) + + f64::cos(lat1) * f64::cos(lat2) * square(f64::sin(lon_deg / 2.0)); + let c = 2.0 * f64::asin(f64::sqrt(a)); + + earth_radius * c +} diff --git a/haversine/src/earth.rs b/haversine/src/earth.rs new file mode 100644 index 0000000..889f56c --- /dev/null +++ b/haversine/src/earth.rs @@ -0,0 +1 @@ +pub const RADIUS: f64 = 6372.8; diff --git a/haversine/src/haversine.rs b/haversine/src/haversine.rs new file mode 100644 index 0000000..4f84fd8 --- /dev/null +++ b/haversine/src/haversine.rs @@ -0,0 +1,14 @@ +use serde::Serialize; + +#[derive(Serialize)] +pub struct CoordinatePair { + pub x0: f64, + pub y0: f64, + pub x1: f64, + pub y1: f64, +} + +#[derive(Serialize)] +pub struct HaversineData { + pub pairs: Vec, +} diff --git a/haversine/src/lib.rs b/haversine/src/lib.rs new file mode 100644 index 0000000..67c3bbb --- /dev/null +++ b/haversine/src/lib.rs @@ -0,0 +1,3 @@ +pub mod distance; +pub mod earth; +pub mod haversine; diff --git a/wrapper/Cargo.toml b/wrapper/Cargo.toml index bb2da4c..9d82a21 100644 --- a/wrapper/Cargo.toml +++ b/wrapper/Cargo.toml @@ -6,5 +6,5 @@ edition = "2021" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] -clap = { version = "4.2.1", features = [ "derive" ] } -sim_8086 = { path = "../sim_8086" } \ No newline at end of file +clap = { version = "4.3.1", features = [ "derive" ] } +sim_8086 = { path = "../sim_8086" }