Fun with benchmarking. Reverted to using built-in trigonometric functions!

This commit is contained in:
mindv0rtex 2021-02-26 11:25:54 -05:00
parent fe795b536f
commit cbc3fcbe06
8 changed files with 493 additions and 19 deletions

425
Cargo.lock generated
View File

@ -14,6 +14,17 @@ version = "1.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "aae1277d39aeec15cb388266ecc24b11c80469deae6067e17a1a7aa9e5c1f234" checksum = "aae1277d39aeec15cb388266ecc24b11c80469deae6067e17a1a7aa9e5c1f234"
[[package]]
name = "atty"
version = "0.2.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8"
dependencies = [
"hermit-abi",
"libc",
"winapi",
]
[[package]] [[package]]
name = "autocfg" name = "autocfg"
version = "1.0.1" version = "1.0.1"
@ -26,6 +37,24 @@ version = "1.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693" checksum = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693"
[[package]]
name = "bstr"
version = "0.2.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a40b47ad93e1a5404e6c18dec46b628214fee441c70f4ab5d6942142cc268a3d"
dependencies = [
"lazy_static",
"memchr",
"regex-automata",
"serde",
]
[[package]]
name = "bumpalo"
version = "3.6.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "63396b8a4b9de3f4fdfb320ab6080762242f66a8ef174c49d8e19b674db4cdbe"
[[package]] [[package]]
name = "bytemuck" name = "bytemuck"
version = "1.5.1" version = "1.5.1"
@ -38,6 +67,15 @@ version = "1.4.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ae44d1a3d5a19df61dd0c8beb138458ac2a53a7ac09eba97d55592540004306b" checksum = "ae44d1a3d5a19df61dd0c8beb138458ac2a53a7ac09eba97d55592540004306b"
[[package]]
name = "cast"
version = "0.2.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4b9434b9a5aa1450faa3f9cb14ea0e8c53bb5d2b3c1bfd1ab4fc03e9f33fbfb0"
dependencies = [
"rustc_version",
]
[[package]] [[package]]
name = "cc" name = "cc"
version = "1.0.67" version = "1.0.67"
@ -50,6 +88,17 @@ version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
[[package]]
name = "clap"
version = "2.33.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "37e58ac78573c40708d45522f0d80fa2f01cc4f9b4e2bf749807255454312002"
dependencies = [
"bitflags",
"textwrap",
"unicode-width",
]
[[package]] [[package]]
name = "color_quant" name = "color_quant"
version = "1.1.0" version = "1.1.0"
@ -65,6 +114,42 @@ dependencies = [
"cfg-if", "cfg-if",
] ]
[[package]]
name = "criterion"
version = "0.3.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ab327ed7354547cc2ef43cbe20ef68b988e70b4b593cbd66a2a61733123a3d23"
dependencies = [
"atty",
"cast",
"clap",
"criterion-plot",
"csv",
"itertools 0.10.0",
"lazy_static",
"num-traits",
"oorandom",
"plotters",
"rayon",
"regex",
"serde",
"serde_cbor",
"serde_derive",
"serde_json",
"tinytemplate",
"walkdir",
]
[[package]]
name = "criterion-plot"
version = "0.4.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e022feadec601fba1649cfa83586381a4ad31c6bf3a9ab7d408118b05dd9889d"
dependencies = [
"cast",
"itertools 0.9.0",
]
[[package]] [[package]]
name = "crossbeam-channel" name = "crossbeam-channel"
version = "0.5.0" version = "0.5.0"
@ -112,6 +197,28 @@ dependencies = [
"loom", "loom",
] ]
[[package]]
name = "csv"
version = "1.1.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f9d58633299b24b515ac72a3f869f8b91306a3cec616a602843a383acd6f9e97"
dependencies = [
"bstr",
"csv-core",
"itoa",
"ryu",
"serde",
]
[[package]]
name = "csv-core"
version = "0.1.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2b2466559f260f48ad25fe6317b3c8dac77b5bdb5763ac7d9d6103530663bc90"
dependencies = [
"memchr",
]
[[package]] [[package]]
name = "deflate" name = "deflate"
version = "0.8.6" version = "0.8.6"
@ -162,6 +269,12 @@ dependencies = [
"weezl", "weezl",
] ]
[[package]]
name = "half"
version = "1.7.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "62aca2aba2d62b4a7f5b33f3712cb1b0692779a56fb510499d5c0aa594daeaf3"
[[package]] [[package]]
name = "hermit-abi" name = "hermit-abi"
version = "0.1.18" version = "0.1.18"
@ -190,6 +303,15 @@ dependencies = [
"tiff", "tiff",
] ]
[[package]]
name = "itertools"
version = "0.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "284f18f85651fe11e8a991b2adb42cb078325c996ed026d994719efcfca1d54b"
dependencies = [
"either",
]
[[package]] [[package]]
name = "itertools" name = "itertools"
version = "0.10.0" version = "0.10.0"
@ -199,6 +321,12 @@ dependencies = [
"either", "either",
] ]
[[package]]
name = "itoa"
version = "0.4.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dd25036021b0de88a0aff6b850051563c6516d0bf53f8638938edbb9de732736"
[[package]] [[package]]
name = "jpeg-decoder" name = "jpeg-decoder"
version = "0.1.22" version = "0.1.22"
@ -208,6 +336,15 @@ dependencies = [
"rayon", "rayon",
] ]
[[package]]
name = "js-sys"
version = "0.3.47"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5cfb73131c35423a367daf8cbd24100af0d077668c8c2943f0e7dd775fef0f65"
dependencies = [
"wasm-bindgen",
]
[[package]] [[package]]
name = "lazy_static" name = "lazy_static"
version = "1.4.0" version = "1.4.0"
@ -240,6 +377,12 @@ dependencies = [
"scoped-tls", "scoped-tls",
] ]
[[package]]
name = "memchr"
version = "2.3.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0ee1c47aaa256ecabcaea351eae4a9b01ef39ed810004e298d2511ed284b1525"
[[package]] [[package]]
name = "memoffset" name = "memoffset"
version = "0.6.1" version = "0.6.1"
@ -319,16 +462,51 @@ dependencies = [
"libc", "libc",
] ]
[[package]]
name = "oorandom"
version = "11.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0ab1bc2a289d34bd04a330323ac98a1b4bc82c9d9fcb1e66b63caa84da26b575"
[[package]] [[package]]
name = "physarum" name = "physarum"
version = "0.1.0" version = "0.1.0"
dependencies = [ dependencies = [
"criterion",
"image", "image",
"itertools", "itertools 0.10.0",
"rand", "rand",
"rayon", "rayon",
] ]
[[package]]
name = "plotters"
version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "45ca0ae5f169d0917a7c7f5a9c1a3d3d9598f18f529dd2b8373ed988efea307a"
dependencies = [
"num-traits",
"plotters-backend",
"plotters-svg",
"wasm-bindgen",
"web-sys",
]
[[package]]
name = "plotters-backend"
version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b07fffcddc1cb3a1de753caa4e4df03b79922ba43cf882acc1bdd7e8df9f4590"
[[package]]
name = "plotters-svg"
version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b38a02e23bd9604b842a812063aec4ef702b57989c37b655254bb61c471ad211"
dependencies = [
"plotters-backend",
]
[[package]] [[package]]
name = "png" name = "png"
version = "0.16.8" version = "0.16.8"
@ -347,6 +525,24 @@ version = "0.2.10"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ac74c624d6b2d21f425f752262f42188365d7b8ff1aff74c82e45136510a4857" checksum = "ac74c624d6b2d21f425f752262f42188365d7b8ff1aff74c82e45136510a4857"
[[package]]
name = "proc-macro2"
version = "1.0.24"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1e0704ee1a7e00d7bb417d0770ea303c1bccbabf0ef1667dae92b5967f5f8a71"
dependencies = [
"unicode-xid",
]
[[package]]
name = "quote"
version = "1.0.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c3d0b9745dc2debf507c8422de05d7226cc1f0644216dfdfead988f9b1ab32a7"
dependencies = [
"proc-macro2",
]
[[package]] [[package]]
name = "rand" name = "rand"
version = "0.8.3" version = "0.8.3"
@ -412,12 +608,60 @@ dependencies = [
"num_cpus", "num_cpus",
] ]
[[package]]
name = "regex"
version = "1.4.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d9251239e129e16308e70d853559389de218ac275b515068abc96829d05b948a"
dependencies = [
"regex-syntax",
]
[[package]]
name = "regex-automata"
version = "0.1.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ae1ded71d66a4a97f5e961fd0cb25a5f366a42a41570d16a763a69c092c26ae4"
dependencies = [
"byteorder",
]
[[package]]
name = "regex-syntax"
version = "0.6.22"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b5eb417147ba9860a96cfe72a0b93bf88fee1744b5636ec99ab20c1aa9376581"
[[package]]
name = "rustc_version"
version = "0.2.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "138e3e0acb6c9fb258b19b67cb8abd63c00679d2851805ea151465464fe9030a"
dependencies = [
"semver",
]
[[package]] [[package]]
name = "rustversion" name = "rustversion"
version = "1.0.4" version = "1.0.4"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cb5d2a036dc6d2d8fd16fde3498b04306e29bd193bf306a57427019b823d5acd" checksum = "cb5d2a036dc6d2d8fd16fde3498b04306e29bd193bf306a57427019b823d5acd"
[[package]]
name = "ryu"
version = "1.0.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "71d301d4193d031abdd79ff7e3dd721168a9572ef3fe51a1517aba235bd8f86e"
[[package]]
name = "same-file"
version = "1.0.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502"
dependencies = [
"winapi-util",
]
[[package]] [[package]]
name = "scoped-tls" name = "scoped-tls"
version = "1.0.0" version = "1.0.0"
@ -436,6 +680,79 @@ version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd" checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd"
[[package]]
name = "semver"
version = "0.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1d7eb9ef2c18661902cc47e535f9bc51b78acd254da71d375c2f6720d9a40403"
dependencies = [
"semver-parser",
]
[[package]]
name = "semver-parser"
version = "0.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3"
[[package]]
name = "serde"
version = "1.0.123"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "92d5161132722baa40d802cc70b15262b98258453e85e5d1d365c757c73869ae"
[[package]]
name = "serde_cbor"
version = "0.11.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1e18acfa2f90e8b735b2836ab8d538de304cbb6729a7360729ea5a895d15a622"
dependencies = [
"half",
"serde",
]
[[package]]
name = "serde_derive"
version = "1.0.123"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9391c295d64fc0abb2c556bad848f33cb8296276b1ad2677d1ae1ace4f258f31"
dependencies = [
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "serde_json"
version = "1.0.63"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "43535db9747a4ba938c0ce0a98cc631a46ebf943c9e1d604e091df6007620bf6"
dependencies = [
"itoa",
"ryu",
"serde",
]
[[package]]
name = "syn"
version = "1.0.60"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c700597eca8a5a762beb35753ef6b94df201c81cca676604f547495a0d7f0081"
dependencies = [
"proc-macro2",
"quote",
"unicode-xid",
]
[[package]]
name = "textwrap"
version = "0.11.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d326610f408c7a4eb6f51c37c330e496b08506c9457c9d34287ecc38809fb060"
dependencies = [
"unicode-width",
]
[[package]] [[package]]
name = "tiff" name = "tiff"
version = "0.6.1" version = "0.6.1"
@ -447,12 +764,109 @@ dependencies = [
"weezl", "weezl",
] ]
[[package]]
name = "tinytemplate"
version = "1.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a2ada8616fad06a2d0c455adc530de4ef57605a8120cc65da9653e0e9623ca74"
dependencies = [
"serde",
"serde_json",
]
[[package]]
name = "unicode-width"
version = "0.1.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9337591893a19b88d8d87f2cec1e73fad5cdfd10e5a6f349f498ad6ea2ffb1e3"
[[package]]
name = "unicode-xid"
version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f7fe0bb3479651439c9112f72b6c505038574c9fbb575ed1bf3b797fa39dd564"
[[package]]
name = "walkdir"
version = "2.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "777182bc735b6424e1a57516d35ed72cb8019d85c8c9bf536dccb3445c1a2f7d"
dependencies = [
"same-file",
"winapi",
"winapi-util",
]
[[package]] [[package]]
name = "wasi" name = "wasi"
version = "0.10.2+wasi-snapshot-preview1" version = "0.10.2+wasi-snapshot-preview1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fd6fbd9a79829dd1ad0cc20627bf1ed606756a7f77edff7b66b7064f9cb327c6" checksum = "fd6fbd9a79829dd1ad0cc20627bf1ed606756a7f77edff7b66b7064f9cb327c6"
[[package]]
name = "wasm-bindgen"
version = "0.2.70"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "55c0f7123de74f0dab9b7d00fd614e7b19349cd1e2f5252bbe9b1754b59433be"
dependencies = [
"cfg-if",
"wasm-bindgen-macro",
]
[[package]]
name = "wasm-bindgen-backend"
version = "0.2.70"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7bc45447f0d4573f3d65720f636bbcc3dd6ce920ed704670118650bcd47764c7"
dependencies = [
"bumpalo",
"lazy_static",
"log",
"proc-macro2",
"quote",
"syn",
"wasm-bindgen-shared",
]
[[package]]
name = "wasm-bindgen-macro"
version = "0.2.70"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3b8853882eef39593ad4174dd26fc9865a64e84026d223f63bb2c42affcbba2c"
dependencies = [
"quote",
"wasm-bindgen-macro-support",
]
[[package]]
name = "wasm-bindgen-macro-support"
version = "0.2.70"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4133b5e7f2a531fa413b3a1695e925038a05a71cf67e87dafa295cb645a01385"
dependencies = [
"proc-macro2",
"quote",
"syn",
"wasm-bindgen-backend",
"wasm-bindgen-shared",
]
[[package]]
name = "wasm-bindgen-shared"
version = "0.2.70"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dd4945e4943ae02d15c13962b38a5b1e81eadd4b71214eee75af64a4d6a4fd64"
[[package]]
name = "web-sys"
version = "0.3.47"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c40dc691fc48003eba817c38da7113c15698142da971298003cac3ef175680b3"
dependencies = [
"js-sys",
"wasm-bindgen",
]
[[package]] [[package]]
name = "weezl" name = "weezl"
version = "0.1.4" version = "0.1.4"
@ -475,6 +889,15 @@ version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
[[package]]
name = "winapi-util"
version = "0.1.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "70ec6ce85bb158151cae5e5c87f95a8e97d2c0c4b001223f33a334e3ce5de178"
dependencies = [
"winapi",
]
[[package]] [[package]]
name = "winapi-x86_64-pc-windows-gnu" name = "winapi-x86_64-pc-windows-gnu"
version = "0.4.0" version = "0.4.0"

View File

@ -4,10 +4,15 @@ version = "0.1.0"
authors = ["mindv0rtex <mindv0rtex@users.noreply.github.com>"] authors = ["mindv0rtex <mindv0rtex@users.noreply.github.com>"]
edition = "2018" edition = "2018"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies] [dependencies]
image = "*" image = "*"
itertools = "*" itertools = "*"
rand = "*" rand = "*"
rayon = "*" rayon = "*"
[dev-dependencies]
criterion = "0.3"
[[bench]]
name = "trig"
harness = false

16
benches/trig.rs Normal file
View File

@ -0,0 +1,16 @@
use physarum::trig;
use criterion::{black_box, criterion_group, criterion_main, Criterion};
fn bench_cos_appr(c: &mut Criterion) {
c.bench_function("Approximate cosine", |b| {
b.iter(|| trig::cos(black_box(1.0)))
});
}
fn bench_cos_exact(c: &mut Criterion) {
c.bench_function("Exact cosine", |b| b.iter(|| f32::cos(black_box(1.0))));
}
criterion_group!(benches, bench_cos_appr, bench_cos_exact);
criterion_main!(benches);

View File

@ -9,7 +9,7 @@ pub struct Grid {
height: usize, height: usize,
data: Vec<f32>, data: Vec<f32>,
// The scratch space for the blur operation. // Scratch space for the blur operation.
buf: Vec<f32>, buf: Vec<f32>,
blur: Blur, blur: Blur,
} }

4
src/lib.rs Normal file
View File

@ -0,0 +1,4 @@
mod blur;
mod grid;
pub mod model;
pub mod trig;

View File

@ -1,7 +1,4 @@
mod blur; use physarum::model;
mod grid;
mod model;
mod trig;
fn main() { fn main() {
let model = model::Model::new(4, 4, 20, 1); let model = model::Model::new(4, 4, 20, 1);

View File

@ -1,4 +1,4 @@
use crate::{grid::Grid, trig}; use crate::grid::Grid;
use rand::{thread_rng, Rng}; use rand::{thread_rng, Rng};
@ -97,17 +97,18 @@ impl Model {
} }
} }
/// Perform a single simulation step.
pub fn step(&mut self) { pub fn step(&mut self) {
let sensor_distance = self.config.sensor_distance; let sensor_distance = self.config.sensor_distance;
let sensor_angle = self.config.sensor_angle; let sensor_angle = self.config.sensor_angle;
for agent in self.agents.iter_mut() { for agent in self.agents.iter_mut() {
let xc = agent.x + trig::cos(agent.angle) * sensor_distance; let xc = agent.x + agent.angle.cos() * sensor_distance;
let yc = agent.y + trig::sin(agent.angle) * sensor_distance; let yc = agent.y + agent.angle.sin() * sensor_distance;
let xl = agent.x + trig::cos(agent.angle - sensor_angle) * sensor_distance; let xl = agent.x + (agent.angle - sensor_angle).cos() * sensor_distance;
let yl = agent.y + trig::sin(agent.angle - sensor_angle) * sensor_distance; let yl = agent.y + (agent.angle - sensor_angle).sin() * sensor_distance;
let xr = agent.x + trig::cos(agent.angle + sensor_angle) * sensor_distance; let xr = agent.x + (agent.angle + sensor_angle).cos() * sensor_distance;
let yr = agent.y + trig::sin(agent.angle + sensor_angle) * sensor_distance; let yr = agent.y + (agent.angle + sensor_angle).sin() * sensor_distance;
// Sense // Sense
let trail_c = self.grid.get(xc, yc); let trail_c = self.grid.get(xc, yc);

View File

@ -1,10 +1,12 @@
/// From https://bits.stephan-brumme.com/absFloat.html /// From https://bits.stephan-brumme.com/absFloat.html
pub(crate) fn abs(x: f32) -> f32 { #[inline(always)]
fn abs(x: f32) -> f32 {
f32::from_bits(x.to_bits() & 0x7FFF_FFFF) f32::from_bits(x.to_bits() & 0x7FFF_FFFF)
} }
/// Branchless floor implementation /// Branchless floor implementation
pub(crate) fn floor(x: f32) -> f32 { #[inline(always)]
fn floor(x: f32) -> f32 {
let mut x_trunc = (x as i32) as f32; let mut x_trunc = (x as i32) as f32;
x_trunc -= (x < x_trunc) as i32 as f32; x_trunc -= (x < x_trunc) as i32 as f32;
x_trunc x_trunc
@ -12,7 +14,7 @@ pub(crate) fn floor(x: f32) -> f32 {
/// Approximates `cos(x)` in radians with the maximum error of `0.002` /// Approximates `cos(x)` in radians with the maximum error of `0.002`
/// https://stackoverflow.com/posts/28050328/revisions /// https://stackoverflow.com/posts/28050328/revisions
pub(crate) fn cos(mut x: f32) -> f32 { pub fn cos(mut x: f32) -> f32 {
const ALPHA: f32 = 0.5 * std::f32::consts::FRAC_1_PI; const ALPHA: f32 = 0.5 * std::f32::consts::FRAC_1_PI;
x *= ALPHA; x *= ALPHA;
x -= 0.25_f32 + floor(x + 0.25_f32); x -= 0.25_f32 + floor(x + 0.25_f32);
@ -22,6 +24,32 @@ pub(crate) fn cos(mut x: f32) -> f32 {
} }
/// Approximates `sin(x)` in radians with the maximum error of `0.002` /// Approximates `sin(x)` in radians with the maximum error of `0.002`
pub(crate) fn sin(x: f32) -> f32 { pub fn sin(x: f32) -> f32 {
cos(x - std::f32::consts::FRAC_PI_2) cos(x - std::f32::consts::FRAC_PI_2)
} }
#[cfg(test)]
mod tests {
use super::*;
use itertools::repeat_n;
#[test]
fn test_cos() {
let n_points = 1000;
let x: Vec<f32> = repeat_n(std::f32::consts::TAU / (n_points - 1) as f32, n_points)
.enumerate()
.map(|(i, delta)| i as f32 * delta)
.collect();
let exact: Vec<f32> = x.iter().map(|v| v.cos()).collect();
let appr: Vec<f32> = x.iter().map(|v| cos(*v)).collect();
let mut max_error = 0.0_f32;
for (y_exact, y_appr) in exact.iter().zip(&appr) {
max_error = (y_exact - y_appr).abs().max(max_error);
}
// The error bound is even better!
assert!(max_error <= 0.0011);
}
}