From 713b68adef9a7c8dbce04d820d6e86f2d68b2d30 Mon Sep 17 00:00:00 2001 From: Quaternions Date: Fri, 23 Aug 2024 13:00:22 -0700 Subject: [PATCH 001/227] Initial commit --- .gitignore | 1 + Cargo.lock | 77 ++++++++++++++++++++++++++++++++++++++++++ Cargo.toml | 8 +++++ fixed_wide/Cargo.lock | 69 +++++++++++++++++++++++++++++++++++++ fixed_wide/Cargo.toml | 8 +++++ fixed_wide/src/lib.rs | 1 + fixed_wide/src/wide.rs | 4 +++ src/lib.rs | 37 ++++++++++++++++++++ 8 files changed, 205 insertions(+) create mode 100644 .gitignore create mode 100644 Cargo.lock create mode 100644 Cargo.toml create mode 100644 fixed_wide/Cargo.lock create mode 100644 fixed_wide/Cargo.toml create mode 100644 fixed_wide/src/lib.rs create mode 100644 fixed_wide/src/wide.rs create mode 100644 src/lib.rs diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..ea8c4bf --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +/target diff --git a/Cargo.lock b/Cargo.lock new file mode 100644 index 0000000..b0d4fcb --- /dev/null +++ b/Cargo.lock @@ -0,0 +1,77 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "az" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7b7e4c2464d97fe331d41de9d5db0def0a96f4d823b8b32a2efd503578988973" + +[[package]] +name = "bnum" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3e31ea183f6ee62ac8b8a8cf7feddd766317adfb13ff469de57ce033efd6a790" + +[[package]] +name = "bytemuck" +version = "1.17.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6fd4c6dcc3b0aea2f5c0b4b82c2b15fe39ddbc76041a310848f4706edf76bb31" + +[[package]] +name = "cfg-if" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" + +[[package]] +name = "crunchy" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a81dae078cea95a014a339291cec439d2f232ebe854a9d672b796c6afafa9b7" + +[[package]] +name = "fixed" +version = "1.28.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85c6e0b89bf864acd20590dbdbad56f69aeb898abfc9443008fd7bd48b2cc85a" +dependencies = [ + "az", + "bytemuck", + "half", + "typenum", +] + +[[package]] +name = "fixed_linear_algebra" +version = "0.1.0" +dependencies = [ + "fixed", + "fixed_wide", +] + +[[package]] +name = "fixed_wide" +version = "0.1.0" +dependencies = [ + "bnum", + "fixed", +] + +[[package]] +name = "half" +version = "2.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6dd08c532ae367adf81c312a4580bc67f1d0fe8bc9c460520283f4c0ff277888" +dependencies = [ + "cfg-if", + "crunchy", +] + +[[package]] +name = "typenum" +version = "1.17.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825" diff --git a/Cargo.toml b/Cargo.toml new file mode 100644 index 0000000..b9efe84 --- /dev/null +++ b/Cargo.toml @@ -0,0 +1,8 @@ +[package] +name = "fixed_linear_algebra" +version = "0.1.0" +edition = "2021" + +[dependencies] +fixed = "1.28.0" +fixed_wide = { version = "0.1.0", path = "fixed_wide" } diff --git a/fixed_wide/Cargo.lock b/fixed_wide/Cargo.lock new file mode 100644 index 0000000..6e5c37e --- /dev/null +++ b/fixed_wide/Cargo.lock @@ -0,0 +1,69 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "az" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7b7e4c2464d97fe331d41de9d5db0def0a96f4d823b8b32a2efd503578988973" + +[[package]] +name = "bnum" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3e31ea183f6ee62ac8b8a8cf7feddd766317adfb13ff469de57ce033efd6a790" + +[[package]] +name = "bytemuck" +version = "1.17.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6fd4c6dcc3b0aea2f5c0b4b82c2b15fe39ddbc76041a310848f4706edf76bb31" + +[[package]] +name = "cfg-if" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" + +[[package]] +name = "crunchy" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a81dae078cea95a014a339291cec439d2f232ebe854a9d672b796c6afafa9b7" + +[[package]] +name = "fixed" +version = "1.28.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85c6e0b89bf864acd20590dbdbad56f69aeb898abfc9443008fd7bd48b2cc85a" +dependencies = [ + "az", + "bytemuck", + "half", + "typenum", +] + +[[package]] +name = "fixed_wide" +version = "0.1.0" +dependencies = [ + "bnum", + "fixed", +] + +[[package]] +name = "half" +version = "2.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6dd08c532ae367adf81c312a4580bc67f1d0fe8bc9c460520283f4c0ff277888" +dependencies = [ + "cfg-if", + "crunchy", +] + +[[package]] +name = "typenum" +version = "1.17.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825" diff --git a/fixed_wide/Cargo.toml b/fixed_wide/Cargo.toml new file mode 100644 index 0000000..89be919 --- /dev/null +++ b/fixed_wide/Cargo.toml @@ -0,0 +1,8 @@ +[package] +name = "fixed_wide" +version = "0.1.0" +edition = "2021" + +[dependencies] +bnum = "0.11.0" +fixed = "1.28.0" diff --git a/fixed_wide/src/lib.rs b/fixed_wide/src/lib.rs new file mode 100644 index 0000000..4472d7e --- /dev/null +++ b/fixed_wide/src/lib.rs @@ -0,0 +1 @@ +pub mod wide; diff --git a/fixed_wide/src/wide.rs b/fixed_wide/src/wide.rs new file mode 100644 index 0000000..98ab750 --- /dev/null +++ b/fixed_wide/src/wide.rs @@ -0,0 +1,4 @@ +pub struct Fixed{ + bits:I, + phantom:std::marker::PhantomData, +} diff --git a/src/lib.rs b/src/lib.rs new file mode 100644 index 0000000..d1507fe --- /dev/null +++ b/src/lib.rs @@ -0,0 +1,37 @@ +use bnum::cast::As; + +type Planar64=fixed::types::I32F32; +type Planar64Wide1=fixed::types::I64F64; +type Planar64Wide2=bnum::types::I256; +type Planar64Wide3=bnum::types::I512; +//wouldn't that be nice +//type Planar64Wide2=fixed::FixedI256; +//type Planar64Wide3=fixed::FixedI512; + +pub fn wide_mul(left: Planar64, right: Planar64) -> Planar64Wide1 { + left.wide_mul(right) +} +pub fn wide_mul_2(left: Planar64Wide1, right: Planar64Wide1) -> Planar64Wide2 { + Planar64Wide2::from(left.to_bits())*Planar64Wide2::from(right.to_bits()) +} +pub fn wide_mul_3(left: Planar64Wide2, right: Planar64Wide2) -> Planar64Wide3 { + left.as_::()*right.as_::() +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn it_works() { + let result = add(2.into(), 2.into()); + assert_eq!(result, 4); + } + + #[test] + pub fn main(){ + let a=6f128; + let max=i32::MAX as i64; + println!("{} {}",max*max,i64::MAX); + } +} From 276602e5f392145080efbee46bb5eca8843893e0 Mon Sep 17 00:00:00 2001 From: Quaternions Date: Fri, 23 Aug 2024 13:42:44 -0700 Subject: [PATCH 002/227] WideMul trait --- Cargo.lock | 1 + fixed_wide/Cargo.lock | 1 + fixed_wide/Cargo.toml | 1 + fixed_wide/src/wide.rs | 30 ++++++++++++++++++++++++++++-- 4 files changed, 31 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index b0d4fcb..3ce3b79 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -58,6 +58,7 @@ version = "0.1.0" dependencies = [ "bnum", "fixed", + "typenum", ] [[package]] diff --git a/fixed_wide/Cargo.lock b/fixed_wide/Cargo.lock index 6e5c37e..54c950e 100644 --- a/fixed_wide/Cargo.lock +++ b/fixed_wide/Cargo.lock @@ -50,6 +50,7 @@ version = "0.1.0" dependencies = [ "bnum", "fixed", + "typenum", ] [[package]] diff --git a/fixed_wide/Cargo.toml b/fixed_wide/Cargo.toml index 89be919..54644ec 100644 --- a/fixed_wide/Cargo.toml +++ b/fixed_wide/Cargo.toml @@ -6,3 +6,4 @@ edition = "2021" [dependencies] bnum = "0.11.0" fixed = "1.28.0" +typenum = "1.17.0" diff --git a/fixed_wide/src/wide.rs b/fixed_wide/src/wide.rs index 98ab750..a57d255 100644 --- a/fixed_wide/src/wide.rs +++ b/fixed_wide/src/wide.rs @@ -1,4 +1,30 @@ -pub struct Fixed{ - bits:I, +use bnum::types::{I256,I512}; +use fixed::{FixedI64,FixedI128}; +use typenum::{Sum, Unsigned}; +use typenum::consts::{U32,U64,U96,U128,U160,U192,U224,U256}; + +pub trait WideMul{ + type Output; + fn wide_mul(self,rhs:Rhs)->Self::Output; +} + +pub struct Fixed{ + bits:Int, phantom:std::marker::PhantomData, } +pub type FixedI256=Fixed; +pub type FixedI512=Fixed; + +impl WideMul> for FixedI128 + where + A:std::ops::Add, + B:Unsigned, +{ + type Output=FixedI256>; + fn wide_mul(self,rhs:FixedI128)->Self::Output{ + FixedI256{ + bits:I256::from(self.to_bits())*I256::from(rhs.to_bits()), + phantom:std::marker::PhantomData, + } + } +} From 5f8104d53100fd815de3a2742a0d76fc2e2550bb Mon Sep 17 00:00:00 2001 From: Quaternions Date: Fri, 23 Aug 2024 14:17:48 -0700 Subject: [PATCH 003/227] wild --- fixed_wide/src/lib.rs | 1 + fixed_wide/src/types.rs | 2 ++ fixed_wide/src/wide.rs | 66 +++++++++++++++++++++++++++++++++++++---- src/lib.rs | 30 +++++++------------ 4 files changed, 75 insertions(+), 24 deletions(-) create mode 100644 fixed_wide/src/types.rs diff --git a/fixed_wide/src/lib.rs b/fixed_wide/src/lib.rs index 4472d7e..8bdda41 100644 --- a/fixed_wide/src/lib.rs +++ b/fixed_wide/src/lib.rs @@ -1 +1,2 @@ pub mod wide; +pub mod types; diff --git a/fixed_wide/src/types.rs b/fixed_wide/src/types.rs new file mode 100644 index 0000000..37ba47f --- /dev/null +++ b/fixed_wide/src/types.rs @@ -0,0 +1,2 @@ +pub type I256F128=crate::wide::FixedI256; +pub type I512F256=crate::wide::FixedI512; diff --git a/fixed_wide/src/wide.rs b/fixed_wide/src/wide.rs index a57d255..7376ac0 100644 --- a/fixed_wide/src/wide.rs +++ b/fixed_wide/src/wide.rs @@ -1,13 +1,10 @@ +use bnum::cast::As; use bnum::types::{I256,I512}; use fixed::{FixedI64,FixedI128}; use typenum::{Sum, Unsigned}; use typenum::consts::{U32,U64,U96,U128,U160,U192,U224,U256}; -pub trait WideMul{ - type Output; - fn wide_mul(self,rhs:Rhs)->Self::Output; -} - +#[derive(Clone,Copy,Debug)] pub struct Fixed{ bits:Int, phantom:std::marker::PhantomData, @@ -15,6 +12,28 @@ pub struct Fixed{ pub type FixedI256=Fixed; pub type FixedI512=Fixed; +impl+std::ops::Shl,FracDst:Unsigned> From for Fixed{ + fn from(value:i128)->Self{ + Self{ + bits:Int::from(value)< PartialEq for Fixed{ + fn eq(&self,other:&Self)->bool{ + self.bits==other.bits + } +} +impl Eq for Fixed{} + +pub trait WideMul{ + type Output; + fn wide_mul(self,rhs:Rhs)->Self::Output; +} + +//going wide from foreign fixed type impl WideMul> for FixedI128 where A:std::ops::Add, @@ -28,3 +47,40 @@ impl WideMul> for FixedI128 } } } +//going wider native +impl WideMul> for FixedI256 + where + A:std::ops::Add, + B:Unsigned, +{ + type Output=FixedI512>; + fn wide_mul(self,rhs:FixedI256)->Self::Output{ + FixedI512{ + bits:self.bits.as_::()*rhs.bits.as_::(), + phantom:std::marker::PhantomData, + } + } +} + +pub enum Narrower{ + Fits(T), + Max, + Min, +} + +fn tat(){ + let a:i8=match 257i64.try_into() { + Ok(it) => it, + Err(err) => panic!(), + }; +} + +//i16 -> i8 +// 257i16.try_narrow::() -> Narrower::Max +// 128i16.try_narrow::() -> Narrower::Fits(128i8) +// -257i16.try_narrow::() -> Narrower::Min + +pub trait TryNarrow{ + type Output; + fn wide_mul(self,rhs:Rhs)->Self::Output; +} diff --git a/src/lib.rs b/src/lib.rs index d1507fe..9e67f80 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,22 +1,9 @@ -use bnum::cast::As; +use fixed_wide::wide::WideMul; type Planar64=fixed::types::I32F32; type Planar64Wide1=fixed::types::I64F64; -type Planar64Wide2=bnum::types::I256; -type Planar64Wide3=bnum::types::I512; -//wouldn't that be nice -//type Planar64Wide2=fixed::FixedI256; -//type Planar64Wide3=fixed::FixedI512; - -pub fn wide_mul(left: Planar64, right: Planar64) -> Planar64Wide1 { - left.wide_mul(right) -} -pub fn wide_mul_2(left: Planar64Wide1, right: Planar64Wide1) -> Planar64Wide2 { - Planar64Wide2::from(left.to_bits())*Planar64Wide2::from(right.to_bits()) -} -pub fn wide_mul_3(left: Planar64Wide2, right: Planar64Wide2) -> Planar64Wide3 { - left.as_::()*right.as_::() -} +type Planar64Wide2=fixed_wide::types::I256F128; +type Planar64Wide3=fixed_wide::types::I512F256; #[cfg(test)] mod tests { @@ -24,13 +11,18 @@ mod tests { #[test] fn it_works() { - let result = add(2.into(), 2.into()); - assert_eq!(result, 4); + let a=Planar64::from(2); + let b=Planar64::from(3); + + let w1=a.wide_mul(b); + let w2=w1.wide_mul(w1); + let w3=w2.wide_mul(w2); + + assert_eq!(w3,Planar64Wide3::from(1296)); } #[test] pub fn main(){ - let a=6f128; let max=i32::MAX as i64; println!("{} {}",max*max,i64::MAX); } From 47f6e75de96cdb5d46261654adfb9f9056f12f17 Mon Sep 17 00:00:00 2001 From: Quaternions Date: Fri, 23 Aug 2024 14:50:23 -0700 Subject: [PATCH 004/227] narrow concept --- fixed_wide/src/lib.rs | 1 + fixed_wide/src/narrow.rs | 37 +++++++++++++++++++++++++++++++++++++ fixed_wide/src/wide.rs | 23 ----------------------- 3 files changed, 38 insertions(+), 23 deletions(-) create mode 100644 fixed_wide/src/narrow.rs diff --git a/fixed_wide/src/lib.rs b/fixed_wide/src/lib.rs index 8bdda41..655a298 100644 --- a/fixed_wide/src/lib.rs +++ b/fixed_wide/src/lib.rs @@ -1,2 +1,3 @@ pub mod wide; pub mod types; +pub mod narrow; diff --git a/fixed_wide/src/narrow.rs b/fixed_wide/src/narrow.rs new file mode 100644 index 0000000..ee18418 --- /dev/null +++ b/fixed_wide/src/narrow.rs @@ -0,0 +1,37 @@ +pub trait Narrow{ + type Output; + fn narrow(self)->Self::Output; +} +#[derive(Debug)] +pub enum NarrowError{ + Overflow, + Underflow, +} +pub trait TryNarrow{ + type Output; + fn try_narrow(self)->Result; +} +#[cfg(test)] +mod tests { + use super::*; + + impl TryNarrow for i16{ + type Output=i8; + fn try_narrow(self)->Result{ + if self WideMul> for FixedI256 } } } - -pub enum Narrower{ - Fits(T), - Max, - Min, -} - -fn tat(){ - let a:i8=match 257i64.try_into() { - Ok(it) => it, - Err(err) => panic!(), - }; -} - -//i16 -> i8 -// 257i16.try_narrow::() -> Narrower::Max -// 128i16.try_narrow::() -> Narrower::Fits(128i8) -// -257i16.try_narrow::() -> Narrower::Min - -pub trait TryNarrow{ - type Output; - fn wide_mul(self,rhs:Rhs)->Self::Output; -} From 73e8afbc77c1ff8455f9d202e058f74084ea9d4f Mon Sep 17 00:00:00 2001 From: Quaternions Date: Fri, 23 Aug 2024 14:59:49 -0700 Subject: [PATCH 005/227] infallible narrow tosses fractional bits and has the same or greater integer bits --- fixed_wide/src/narrow.rs | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/fixed_wide/src/narrow.rs b/fixed_wide/src/narrow.rs index ee18418..4ba82a9 100644 --- a/fixed_wide/src/narrow.rs +++ b/fixed_wide/src/narrow.rs @@ -34,4 +34,17 @@ mod tests { assert!(matches!(64i16.try_narrow(),Ok(64i8))); assert!(matches!((-257i16).try_narrow(),Err(NarrowError::Underflow))); } + + impl Narrow for fixed::FixedI16{ + type Output=i8; + fn narrow(self)->Self::Output{ + (self.to_bits()>>8) as i8 + } + } + + #[test] + fn test_fixed_i16_i8(){ + let a=fixed::FixedI16::::from(5)/2; + assert_eq!(a.narrow(),2); + } } From 3b7fbe4038b1125cf1d47feafec8ee9e2a5247f1 Mon Sep 17 00:00:00 2001 From: Quaternions Date: Fri, 23 Aug 2024 15:23:40 -0700 Subject: [PATCH 006/227] fixed crate does it like this --- fixed_wide/src/types.rs | 4 ++-- src/lib.rs | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/fixed_wide/src/types.rs b/fixed_wide/src/types.rs index 37ba47f..ef49abb 100644 --- a/fixed_wide/src/types.rs +++ b/fixed_wide/src/types.rs @@ -1,2 +1,2 @@ -pub type I256F128=crate::wide::FixedI256; -pub type I512F256=crate::wide::FixedI512; +pub type I128F128=crate::wide::FixedI256; +pub type I256F256=crate::wide::FixedI512; diff --git a/src/lib.rs b/src/lib.rs index 9e67f80..1d4be86 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -2,8 +2,8 @@ use fixed_wide::wide::WideMul; type Planar64=fixed::types::I32F32; type Planar64Wide1=fixed::types::I64F64; -type Planar64Wide2=fixed_wide::types::I256F128; -type Planar64Wide3=fixed_wide::types::I512F256; +type Planar64Wide2=fixed_wide::types::I128F128; +type Planar64Wide3=fixed_wide::types::I256F256; #[cfg(test)] mod tests { From c4462cf3403a72886fa1ec029a6c7c628aba1bdd Mon Sep 17 00:00:00 2001 From: Quaternions Date: Fri, 23 Aug 2024 15:25:12 -0700 Subject: [PATCH 007/227] rename crate --- Cargo.lock | 16 ++++++++-------- Cargo.toml | 2 +- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 3ce3b79..a67d524 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -44,14 +44,6 @@ dependencies = [ "typenum", ] -[[package]] -name = "fixed_linear_algebra" -version = "0.1.0" -dependencies = [ - "fixed", - "fixed_wide", -] - [[package]] name = "fixed_wide" version = "0.1.0" @@ -61,6 +53,14 @@ dependencies = [ "typenum", ] +[[package]] +name = "fixed_wide_vectors" +version = "0.1.0" +dependencies = [ + "fixed", + "fixed_wide", +] + [[package]] name = "half" version = "2.4.1" diff --git a/Cargo.toml b/Cargo.toml index b9efe84..c1bca07 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,5 +1,5 @@ [package] -name = "fixed_linear_algebra" +name = "fixed_wide_vectors" version = "0.1.0" edition = "2021" From 24c88e2b5bc6977fc1eb1c6e87b4af6971d76a5c Mon Sep 17 00:00:00 2001 From: Quaternions Date: Fri, 23 Aug 2024 17:23:03 -0700 Subject: [PATCH 008/227] move tests into its own folder --- src/lib.rs | 28 +--------------------------- src/tests/mod.rs | 24 ++++++++++++++++++++++++ 2 files changed, 25 insertions(+), 27 deletions(-) create mode 100644 src/tests/mod.rs diff --git a/src/lib.rs b/src/lib.rs index 1d4be86..727e5c2 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,29 +1,3 @@ -use fixed_wide::wide::WideMul; - -type Planar64=fixed::types::I32F32; -type Planar64Wide1=fixed::types::I64F64; -type Planar64Wide2=fixed_wide::types::I128F128; -type Planar64Wide3=fixed_wide::types::I256F256; #[cfg(test)] -mod tests { - use super::*; - - #[test] - fn it_works() { - let a=Planar64::from(2); - let b=Planar64::from(3); - - let w1=a.wide_mul(b); - let w2=w1.wide_mul(w1); - let w3=w2.wide_mul(w2); - - assert_eq!(w3,Planar64Wide3::from(1296)); - } - - #[test] - pub fn main(){ - let max=i32::MAX as i64; - println!("{} {}",max*max,i64::MAX); - } -} +mod tests; diff --git a/src/tests/mod.rs b/src/tests/mod.rs new file mode 100644 index 0000000..c91a008 --- /dev/null +++ b/src/tests/mod.rs @@ -0,0 +1,24 @@ +use fixed_wide::wide::WideMul; + +type Planar64=fixed::types::I32F32; +//type Planar64Wide1=fixed::types::I64F64; +//type Planar64Wide2=fixed_wide::types::I128F128; +type Planar64Wide3=fixed_wide::types::I256F256; + +#[test] +fn it_works() { + let a=Planar64::from(2); + let b=Planar64::from(3); + + let w1=a.wide_mul(b); + let w2=w1.wide_mul(w1); + let w3=w2.wide_mul(w2); + + assert_eq!(w3,Planar64Wide3::from(1296)); +} + +#[test] +pub fn main(){ + let max=i32::MAX as i64; + println!("{} {}",max*max,i64::MAX); +} From 17a6671ead63dd152d67da23c0aedb6998be1d9e Mon Sep 17 00:00:00 2001 From: Quaternions Date: Fri, 23 Aug 2024 15:42:48 -0700 Subject: [PATCH 009/227] steal code --- src/lib.rs | 2 + src/macros/mod.rs | 241 ++++++++++++++++++++++++++++++++++++++++++++++ src/vector.rs | 68 +++++++++++++ 3 files changed, 311 insertions(+) create mode 100644 src/macros/mod.rs create mode 100644 src/vector.rs diff --git a/src/lib.rs b/src/lib.rs index 727e5c2..ed7a919 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,3 +1,5 @@ +mod macros; +pub mod vector; #[cfg(test)] mod tests; diff --git a/src/macros/mod.rs b/src/macros/mod.rs new file mode 100644 index 0000000..c7be6b0 --- /dev/null +++ b/src/macros/mod.rs @@ -0,0 +1,241 @@ +// Stolen from https://github.com/c1m50c/fixed-vectors (MIT license) + +#[doc(hidden)] +#[macro_export(local_inner_macros)] +macro_rules! impl_vector { + ( $struct: ident { $($field: ident), + }, ( $($generic: ident), + ), $size: expr ) => { + impl $struct { + /// Constructs a new vector with the specified values for each field. + /// + /// # Example + /// + /// ``` + /// use fixed_vectors::Vector2; + /// + /// let vec2 = Vector2::new(0, 0); + /// + /// assert_eq!(vec2.x, 0); + /// assert_eq!(vec2.y, 0); + /// ``` + #[inline(always)] + pub const fn new( $($field: T), + ) -> Self { + Self { + $( $field ), + + } + } + + /// Consumes the vector and returns its values as an array. + /// + /// # Example + /// + /// ``` + /// use fixed_vectors::Vector2; + /// + /// let vec2 = Vector2::new(0, 0); + /// let array = vec2.to_array(); + /// + /// assert_eq!(array, [0, 0]); + /// ``` + #[inline(always)] + pub fn to_array(self) -> [T; $size] { + [ $(self.$field), + ] + } + + /// Consumes the vector and returns its values as a tuple. + /// + /// # Example + /// + /// ``` + /// use fixed_vectors::Vector2; + /// + /// let vec2 = Vector2::new(0, 0); + /// let tuple = vec2.to_tuple(); + /// + /// assert_eq!(tuple, (0, 0)); + /// ``` + #[inline(always)] + pub fn to_tuple(self) -> ( $($generic), + ) { + ( $(self.$field), + ) + } + + /// Consumes the vector and returns a new vector with the given function applied on each field. + /// + /// # Example + /// + /// ``` + /// use fixed_vectors::Vector2; + /// + /// let vec2 = Vector2::new(1, 2) + /// .map(|i| i * 2); + /// + /// assert_eq!(vec2, Vector2::new(2, 4)); + /// ``` + #[inline] + pub fn map(self, f: F) -> $struct + where + F: Fn(T) -> U + { + $struct { + $( $field: f(self.$field) ), + + } + } + } + + impl $struct { + /// Constructs a vector using the given `value` as the value for all of its fields. + /// + /// # Example + /// + /// ``` + /// use fixed_vectors::Vector2; + /// + /// let vec2 = Vector2::from_value(0); + /// + /// assert_eq!(vec2, Vector2::new(0, 0)); + /// ``` + #[inline(always)] + pub const fn from_value(value: T) -> Self { + Self { + $( $field: value ), + + } + } + } + + impl From<[T; $size]> for $struct { + fn from(from: [T; $size]) -> Self { + let mut iterator = from.into_iter(); + + Self { + // SAFETY: We know the size of `from` so `iterator.next()` is always `Some(..)` + $( $field: unsafe { iterator.next().unwrap_unchecked() } ), + + } + } + } + + impl From<($($generic), +)> for $struct { + fn from(from: ($($generic), +)) -> Self { + let ( $($field), + ) = from; + + Self { + $( $field ), + + } + } + } + + impl core::fmt::Debug for $struct { + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { + let identifier = core::stringify!($struct); + + f.debug_struct(identifier) + $( .field( core::stringify!($field), &self.$field ) ) + + .finish() + } + } + + impl PartialEq for $struct { + fn eq(&self, other: &Self) -> bool { + $( self.$field == other.$field ) && + + } + } + + impl Eq for $struct { } + + impl core::hash::Hash for $struct { + fn hash(&self, state: &mut H) { + $( self.$field.hash(state); ) + + } + } + + impl Clone for $struct { + fn clone(&self) -> Self { + Self { + $( $field: self.$field.clone() ), + + } + } + } + + impl Copy for $struct { } + + impl Default for $struct { + fn default() -> Self { + Self { + $( $field: T::default() ), + + } + } + } + + impl> core::ops::Neg for $struct { + type Output = Self; + + fn neg(self) -> Self::Output { + Self { + $( $field: -self.$field ), + + } + } + } + + // Impl arithmetic pperators + $crate::impl_operator!( $struct { $($field), + }, AddAssign, add_assign ); + $crate::impl_operator!( $struct { $($field), + }, Add, add, Self ); + $crate::impl_operator!( $struct { $($field), + }, SubAssign, sub_assign ); + $crate::impl_operator!( $struct { $($field), + }, Sub, sub, Self ); + $crate::impl_operator!( $struct { $($field), + }, MulAssign, mul_assign ); + $crate::impl_operator!( $struct { $($field), + }, Mul, mul, Self ); + $crate::impl_operator!( $struct { $($field), + }, DivAssign, div_assign ); + $crate::impl_operator!( $struct { $($field), + }, Div, div, Self ); + $crate::impl_operator!( $struct { $($field), + }, RemAssign, rem_assign ); + $crate::impl_operator!( $struct { $($field), + }, Rem, rem, Self ); + + // Impl bitwise operators + $crate::impl_operator!( $struct { $($field), + }, BitAndAssign, bitand_assign ); + $crate::impl_operator!( $struct { $($field), + }, BitAnd, bitand, Self ); + $crate::impl_operator!( $struct { $($field), + }, BitOrAssign, bitor_assign ); + $crate::impl_operator!( $struct { $($field), + }, BitOr, bitor, Self ); + $crate::impl_operator!( $struct { $($field), + }, BitXorAssign, bitxor_assign ); + $crate::impl_operator!( $struct { $($field), + }, BitXor, bitxor, Self ); + + // Impl floating-point based methods + //$crate::impl_floating_point_operations!( $struct { $($field), + }, $size ); + }; +} + + +#[doc(hidden)] +#[macro_export(local_inner_macros)] +macro_rules! impl_operator { + ( $struct: ident { $($field: ident), + }, $trait: ident, $method: ident, $output: ty ) => { + impl> core::ops::$trait for $struct { + type Output = $output; + + fn $method(self, other: Self) -> Self::Output { + Self { + $( $field: self.$field.$method(other.$field) ), + + } + } + } + + impl + Copy> core::ops::$trait for $struct { + type Output = $output; + + fn $method(self, other: T) -> Self::Output { + Self { + $( $field: self.$field.$method(other) ), + + } + } + } + }; + + ( $struct: ident { $($field: ident), + }, $trait: ident, $method: ident ) => { + impl core::ops::$trait for $struct { + fn $method(&mut self, other: Self) { + $( self.$field.$method(other.$field) ); + + } + } + + impl core::ops::$trait for $struct { + fn $method(&mut self, other: T) { + $( self.$field.$method(other) ); + + } + } + }; +} diff --git a/src/vector.rs b/src/vector.rs new file mode 100644 index 0000000..067237f --- /dev/null +++ b/src/vector.rs @@ -0,0 +1,68 @@ +// Stolen from https://github.com/c1m50c/fixed-vectors (MIT license) + +/// Vector for holding two-dimensional values. +/// +/// # Example +/// +/// ``` +/// use fixed_vectors::Vector2; +/// +/// let mut vec2 = Vector2::new(1, 2); +/// vec2 += Vector2::new(1, 2); +/// +/// assert_eq!(vec2.x, 2); +/// assert_eq!(vec2.y, 4); +/// ``` +pub struct Vector2 { + pub x: T, + pub y: T, +} + + +/// Vector for holding three-dimensional values. +/// +/// # Example +/// +/// ``` +/// use fixed_vectors::Vector3; +/// +/// let mut vec3 = Vector3::new(1, 2, 3); +/// vec3 += Vector3::new(1, 2, 3); +/// +/// assert_eq!(vec3.x, 2); +/// assert_eq!(vec3.y, 4); +/// assert_eq!(vec3.z, 6); +/// ``` +pub struct Vector3 { + pub x: T, + pub y: T, + pub z: T, +} + + +/// Vector for holding four-dimensional values. +/// +/// # Example +/// +/// ``` +/// use fixed_vectors::Vector4; +/// +/// let mut vec4 = Vector4::new(1, 2, 3, 4); +/// vec4 += Vector4::new(1, 2, 3, 4); +/// +/// assert_eq!(vec4.x, 2); +/// assert_eq!(vec4.y, 4); +/// assert_eq!(vec4.z, 6); +/// assert_eq!(vec4.w, 8); +/// ``` +pub struct Vector4 { + pub x: T, + pub y: T, + pub z: T, + pub w: T, +} + + +crate::impl_vector!(Vector2 { x, y }, (T, T), 2); +crate::impl_vector!(Vector3 { x, y, z }, (T, T, T), 3); +crate::impl_vector!(Vector4 { x, y, z, w }, (T, T, T, T), 4); From 8b4608bda32d0ad6df468d06df6e31708849b732 Mon Sep 17 00:00:00 2001 From: Quaternions Date: Fri, 23 Aug 2024 15:45:01 -0700 Subject: [PATCH 010/227] unused --- fixed_wide/src/wide.rs | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/fixed_wide/src/wide.rs b/fixed_wide/src/wide.rs index fed145e..ff46c6b 100644 --- a/fixed_wide/src/wide.rs +++ b/fixed_wide/src/wide.rs @@ -1,8 +1,7 @@ use bnum::cast::As; use bnum::types::{I256,I512}; -use fixed::{FixedI64,FixedI128}; -use typenum::{Sum, Unsigned}; -use typenum::consts::{U32,U64,U96,U128,U160,U192,U224,U256}; +use fixed::FixedI128; +use typenum::{Sum,Unsigned}; #[derive(Clone,Copy,Debug)] pub struct Fixed{ From 3d3ffbf79aecca630f742a9a488404c6294e3d67 Mon Sep 17 00:00:00 2001 From: Quaternions Date: Fri, 23 Aug 2024 15:57:12 -0700 Subject: [PATCH 011/227] steal --- src/macros/mod.rs | 1 + src/macros/wide.rs | 315 +++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 316 insertions(+) create mode 100644 src/macros/wide.rs diff --git a/src/macros/mod.rs b/src/macros/mod.rs index c7be6b0..4e65a86 100644 --- a/src/macros/mod.rs +++ b/src/macros/mod.rs @@ -1,4 +1,5 @@ // Stolen from https://github.com/c1m50c/fixed-vectors (MIT license) +mod wide; #[doc(hidden)] #[macro_export(local_inner_macros)] diff --git a/src/macros/wide.rs b/src/macros/wide.rs new file mode 100644 index 0000000..23b4527 --- /dev/null +++ b/src/macros/wide.rs @@ -0,0 +1,315 @@ +#[doc(hidden)] +#[macro_export(local_inner_macros)] +macro_rules! impl_floating_point_operations { + ( $struct: ident { $($field: ident), + }, $size: expr ) => { + impl $struct { + /// Returns the dot product of two vectors. + /// + /// # Example + /// + /// ``` + /// use fixed_vectors::Vector2; + /// + /// let a = Vector2::new(1.0, 2.0); + /// let b = Vector2::new(2.0, 4.0); + /// let dot = a.dot(&b); + /// + /// assert_eq!(dot, 10.0); + /// ``` + #[inline] + pub fn dot(&self, other: &Self) -> T { + $crate::sum_repeating!( + $( + (self.$field * other.$field) ) + + ) + } + + /// Returns the squared magnitude of vector. + /// + /// # Example + /// + /// ``` + /// use fixed_vectors::Vector3; + /// + /// let vec3 = Vector3::new(3.33, 2.04, 1.337); + /// let lsq = vec3.length_squared(); + /// + /// assert!(lsq >= 17.0); + /// ``` + pub fn length_squared(&self) -> T { + let squared = Self { + $( $field: self.$field * self.$field ), + + }; + + $crate::sum_repeating!( + $( + squared.$field ) + + ) + } + + /// Applies [`floor`](num_traits::float::FloatCore::floor) on all fields within the vector, + /// converting each field to the largest integer less than or equal to its value. + /// + /// # Example + /// + /// ``` + /// use fixed_vectors::Vector2; + /// + /// let vec2 = Vector2::new(1.6, 2.3).floor(); + /// + /// assert_eq!(vec2, Vector2::new(1.0, 2.0)); + /// ``` + #[inline] + pub fn floor(self) -> Self { + self.map(T::floor) + } + + /// Applies [`ceil`](num_traits::float::FloatCore::ceil) on all fields within the vector, + /// converting each field to the largest integer greater than or equal to its value. + /// + /// # Example + /// + /// ``` + /// use fixed_vectors::Vector2; + /// + /// let vec2 = Vector2::new(1.6, 2.3).ceil(); + /// + /// assert_eq!(vec2, Vector2::new(2.0, 3.0)); + /// ``` + #[inline] + pub fn ceil(self) -> Self { + self.map(T::ceil) + } + + /// Applies [`round`](num_traits::float::FloatCore::round) on all fields within the vector, + /// converting each field's value to its nearest integer. + /// + /// # Example + /// + /// ``` + /// use fixed_vectors::Vector2; + /// + /// let vec2 = Vector2::new(1.6, 2.3).round(); + /// + /// assert_eq!(vec2, Vector2::new(2.0, 2.0)); + /// ``` + #[inline] + pub fn round(self) -> Self { + self.map(T::round) + } + + /// Applies [`abs`](num_traits::float::FloatCore::abs) on all fields within the vector, + /// converting each field to their absolute value. + /// + /// # Example + /// + /// ``` + /// use fixed_vectors::Vector2; + /// + /// let vec2 = Vector2::new(-2.6, 2.3).abs(); + /// + /// assert_eq!(vec2, Vector2::new(2.6, 2.3)); + /// ``` + #[inline] + pub fn abs(self) -> Self { + self.map(T::abs) + } + + /// Applies [`trunc`](num_traits::float::FloatCore::trunc) on all fields within the vector, + /// converting each field's value to their integer parts. + /// + /// # Example + /// + /// ``` + /// use fixed_vectors::Vector2; + /// + /// let vec2 = Vector2::new(-2.6, 2.3).trunc(); + /// + /// assert_eq!(vec2, Vector2::new(-2.0, 2.0)); + /// ``` + #[inline] + pub fn trunc(self) -> Self { + self.map(T::trunc) + } + + /// Applies [`fract`](num_traits::float::FloatCore::fract) on all fields within the vector, + /// converting each field's value to their fractional parts. + /// + /// # Example + /// + /// ``` + /// use fixed_vectors::Vector2; + /// + /// let vec2 = Vector2::new(-2.5, 2.25).fract(); + /// + /// assert_eq!(vec2, Vector2::new(-0.5, 0.25)); + /// ``` + #[inline] + pub fn fract(self) -> Self { + self.map(T::fract) + } + + /// Applies [`powi`](num_traits::float::FloatCore::powi) on all fields within the vector, + /// raising each field's value to an integer power. + /// + /// # Example + /// + /// ``` + /// use fixed_vectors::Vector2; + /// + /// let vec2 = Vector2::new(2.0, 4.0).powi(2); + /// + /// assert_eq!(vec2, Vector2::new(4.0, 16.0)); + /// ``` + #[inline] + pub fn powi(self, n: i32) -> Self { + self.map(|f| f.powi(n)) + } + + /// Linearly interpolates between two Vectors by a normalized `weight`. + /// + /// # Example + /// + /// ``` + /// use fixed_vectors::Vector2; + /// + /// let vec2 = Vector2::new(1.0, 2.0).lerp( + /// Vector2::new(2.0, 3.0), 1.0 + /// ); + /// + /// assert_eq!(vec2, Vector2::new(2.0, 3.0)); + /// ``` + #[inline(always)] + pub fn lerp(self, to: Self, weight: T) -> Self { + Self { + $( $field: self.$field + (weight * (to.$field - self.$field)) ), + + } + } + } + + impl $struct + where + T: $crate::macros::floating::_FloatingPoint + + num_traits::float::FloatCore + { + /// Consumes the vector and returns it with all of its fields converted to their square-root. + /// + /// # Example + /// + /// ``` + /// use fixed_vectors::Vector2; + /// + /// let vec2 = Vector2::new(64.0, 25.0).sqrt(); + /// + /// assert_eq!(vec2, Vector2::new(8.0, 5.0)); + /// ``` + #[inline] + pub fn sqrt(self) -> Self { + self.map(T::sqrt) + } + + /// Returns the magnitude of the vector. + /// + /// # Example + /// + /// ``` + /// use fixed_vectors::Vector3; + /// + /// let vec3 = Vector3::new(1.5, 2.0, 3.33); + /// let length = vec3.length(); + /// + /// assert!(length < 4.2); + /// ``` + #[inline] + pub fn length(&self) -> T { + self.length_squared().sqrt() + } + + /// Consumes the vector and returns it as normalized vector. + /// + /// # Example + /// + /// ``` + /// use fixed_vectors::Vector2; + /// + /// let vec2 = Vector2::new(14.3, 7.9).normalized(); + /// + /// assert!(vec2.x < 1.0); + /// assert!(vec2.y < 1.0); + /// ``` + pub fn normalized(self) -> Self { + let length_squared = self.length_squared(); + + if length_squared == T::zero() { + return Self { $( $field: T::zero() ), + }; + } + + let length = length_squared.sqrt(); + + Self { + $( $field: self.$field / length ), + + } + } + + /// Normalizes the vector through mutation. + /// + /// # Example + /// + /// ``` + /// use fixed_vectors::Vector2; + /// + /// let mut vec2 = Vector2::new(14.3, 7.9); + /// vec2.normalize(); + /// + /// assert!(vec2.x < 1.0); + /// assert!(vec2.y < 1.0); + /// ``` + pub fn normalize(&mut self) { + let length_squared = self.length_squared(); + + if length_squared == T::zero() { + *self = Self { $( $field: T::zero() ), + }; + return; + } + + let length = length_squared.sqrt(); + + *self = Self { + $( $field: self.$field / length ), + + } + } + } + }; +} + + +// HACK: Allows us to sum repeating tokens in macros. +// See: https://stackoverflow.com/a/60187870/17452730 +#[doc(hidden)] +#[macro_export(local_inner_macros)] +macro_rules! sum_repeating { + ( + $($item: tt) * ) => { + $($item) * + }; +} + + +// Required trait for `sqrt` impls +#[doc(hidden)] +pub trait _FloatingPoint { + fn sqrt(self) -> Self; +} + + +impl _FloatingPoint for f32 { + #[inline(always)] + fn sqrt(self) -> Self { + libm::sqrtf(self) + } +} + + +impl _FloatingPoint for f64 { + #[inline(always)] + fn sqrt(self) -> Self { + libm::sqrt(self) + } +} From 78bc7aa8a15139cc0186068fd726355311373e8f Mon Sep 17 00:00:00 2001 From: Quaternions Date: Fri, 23 Aug 2024 16:26:19 -0700 Subject: [PATCH 012/227] work --- fixed_wide/src/wide.rs | 12 +- src/macros/mod.rs | 4 +- src/macros/wide.rs | 302 ++--------------------------------------- src/tests/mod.rs | 6 +- 4 files changed, 31 insertions(+), 293 deletions(-) diff --git a/fixed_wide/src/wide.rs b/fixed_wide/src/wide.rs index ff46c6b..192bead 100644 --- a/fixed_wide/src/wide.rs +++ b/fixed_wide/src/wide.rs @@ -1,6 +1,6 @@ use bnum::cast::As; use bnum::types::{I256,I512}; -use fixed::FixedI128; +use fixed::{FixedI64,FixedI128}; use typenum::{Sum,Unsigned}; #[derive(Clone,Copy,Debug)] @@ -33,6 +33,16 @@ pub trait WideMul{ } //going wide from foreign fixed type +impl WideMul> for FixedI64 + where + A:std::ops::Add, + B:Unsigned, +{ + type Output=FixedI128>; + fn wide_mul(self,rhs:FixedI64)->Self::Output{ + self.wide_mul(rhs) + } +} impl WideMul> for FixedI128 where A:std::ops::Add, diff --git a/src/macros/mod.rs b/src/macros/mod.rs index 4e65a86..912565a 100644 --- a/src/macros/mod.rs +++ b/src/macros/mod.rs @@ -1,5 +1,5 @@ // Stolen from https://github.com/c1m50c/fixed-vectors (MIT license) -mod wide; +pub mod wide; #[doc(hidden)] #[macro_export(local_inner_macros)] @@ -196,7 +196,7 @@ macro_rules! impl_vector { $crate::impl_operator!( $struct { $($field), + }, BitXor, bitxor, Self ); // Impl floating-point based methods - //$crate::impl_floating_point_operations!( $struct { $($field), + }, $size ); + $crate::impl_wide_operations!( $struct { $($field), + }, $size ); }; } diff --git a/src/macros/wide.rs b/src/macros/wide.rs index 23b4527..3b348a2 100644 --- a/src/macros/wide.rs +++ b/src/macros/wide.rs @@ -1,281 +1,32 @@ #[doc(hidden)] #[macro_export(local_inner_macros)] -macro_rules! impl_floating_point_operations { +macro_rules! impl_wide_operations { ( $struct: ident { $($field: ident), + }, $size: expr ) => { - impl $struct { - /// Returns the dot product of two vectors. - /// - /// # Example - /// - /// ``` - /// use fixed_vectors::Vector2; - /// - /// let a = Vector2::new(1.0, 2.0); - /// let b = Vector2::new(2.0, 4.0); - /// let dot = a.dot(&b); - /// - /// assert_eq!(dot, 10.0); - /// ``` + impl> fixed_wide::wide::WideMul for $struct { + type Output=$struct; #[inline] - pub fn dot(&self, other: &Self) -> T { + fn wide_mul(self, rhs: Self) -> Self::Output { + $struct{ + $( $field: self.$field.wide_mul(rhs.$field) ), + + } + } + } + impl+std::ops::Add> $struct { + #[inline] + pub fn wide_dot(&self, other: &Self) -> ::Output { $crate::sum_repeating!( - $( + (self.$field * other.$field) ) + + $( + (self.$field.wide_mul(other.$field)) ) + ) } - - /// Returns the squared magnitude of vector. - /// - /// # Example - /// - /// ``` - /// use fixed_vectors::Vector3; - /// - /// let vec3 = Vector3::new(3.33, 2.04, 1.337); - /// let lsq = vec3.length_squared(); - /// - /// assert!(lsq >= 17.0); - /// ``` - pub fn length_squared(&self) -> T { + pub fn length_squared(&self) -> ::Output { let squared = Self { - $( $field: self.$field * self.$field ), + + $( $field: self.$field.wide_mul(self.$field) ), + }; $crate::sum_repeating!( $( + squared.$field ) + ) } - - /// Applies [`floor`](num_traits::float::FloatCore::floor) on all fields within the vector, - /// converting each field to the largest integer less than or equal to its value. - /// - /// # Example - /// - /// ``` - /// use fixed_vectors::Vector2; - /// - /// let vec2 = Vector2::new(1.6, 2.3).floor(); - /// - /// assert_eq!(vec2, Vector2::new(1.0, 2.0)); - /// ``` - #[inline] - pub fn floor(self) -> Self { - self.map(T::floor) - } - - /// Applies [`ceil`](num_traits::float::FloatCore::ceil) on all fields within the vector, - /// converting each field to the largest integer greater than or equal to its value. - /// - /// # Example - /// - /// ``` - /// use fixed_vectors::Vector2; - /// - /// let vec2 = Vector2::new(1.6, 2.3).ceil(); - /// - /// assert_eq!(vec2, Vector2::new(2.0, 3.0)); - /// ``` - #[inline] - pub fn ceil(self) -> Self { - self.map(T::ceil) - } - - /// Applies [`round`](num_traits::float::FloatCore::round) on all fields within the vector, - /// converting each field's value to its nearest integer. - /// - /// # Example - /// - /// ``` - /// use fixed_vectors::Vector2; - /// - /// let vec2 = Vector2::new(1.6, 2.3).round(); - /// - /// assert_eq!(vec2, Vector2::new(2.0, 2.0)); - /// ``` - #[inline] - pub fn round(self) -> Self { - self.map(T::round) - } - - /// Applies [`abs`](num_traits::float::FloatCore::abs) on all fields within the vector, - /// converting each field to their absolute value. - /// - /// # Example - /// - /// ``` - /// use fixed_vectors::Vector2; - /// - /// let vec2 = Vector2::new(-2.6, 2.3).abs(); - /// - /// assert_eq!(vec2, Vector2::new(2.6, 2.3)); - /// ``` - #[inline] - pub fn abs(self) -> Self { - self.map(T::abs) - } - - /// Applies [`trunc`](num_traits::float::FloatCore::trunc) on all fields within the vector, - /// converting each field's value to their integer parts. - /// - /// # Example - /// - /// ``` - /// use fixed_vectors::Vector2; - /// - /// let vec2 = Vector2::new(-2.6, 2.3).trunc(); - /// - /// assert_eq!(vec2, Vector2::new(-2.0, 2.0)); - /// ``` - #[inline] - pub fn trunc(self) -> Self { - self.map(T::trunc) - } - - /// Applies [`fract`](num_traits::float::FloatCore::fract) on all fields within the vector, - /// converting each field's value to their fractional parts. - /// - /// # Example - /// - /// ``` - /// use fixed_vectors::Vector2; - /// - /// let vec2 = Vector2::new(-2.5, 2.25).fract(); - /// - /// assert_eq!(vec2, Vector2::new(-0.5, 0.25)); - /// ``` - #[inline] - pub fn fract(self) -> Self { - self.map(T::fract) - } - - /// Applies [`powi`](num_traits::float::FloatCore::powi) on all fields within the vector, - /// raising each field's value to an integer power. - /// - /// # Example - /// - /// ``` - /// use fixed_vectors::Vector2; - /// - /// let vec2 = Vector2::new(2.0, 4.0).powi(2); - /// - /// assert_eq!(vec2, Vector2::new(4.0, 16.0)); - /// ``` - #[inline] - pub fn powi(self, n: i32) -> Self { - self.map(|f| f.powi(n)) - } - - /// Linearly interpolates between two Vectors by a normalized `weight`. - /// - /// # Example - /// - /// ``` - /// use fixed_vectors::Vector2; - /// - /// let vec2 = Vector2::new(1.0, 2.0).lerp( - /// Vector2::new(2.0, 3.0), 1.0 - /// ); - /// - /// assert_eq!(vec2, Vector2::new(2.0, 3.0)); - /// ``` - #[inline(always)] - pub fn lerp(self, to: Self, weight: T) -> Self { - Self { - $( $field: self.$field + (weight * (to.$field - self.$field)) ), + - } - } - } - - impl $struct - where - T: $crate::macros::floating::_FloatingPoint - + num_traits::float::FloatCore - { - /// Consumes the vector and returns it with all of its fields converted to their square-root. - /// - /// # Example - /// - /// ``` - /// use fixed_vectors::Vector2; - /// - /// let vec2 = Vector2::new(64.0, 25.0).sqrt(); - /// - /// assert_eq!(vec2, Vector2::new(8.0, 5.0)); - /// ``` - #[inline] - pub fn sqrt(self) -> Self { - self.map(T::sqrt) - } - - /// Returns the magnitude of the vector. - /// - /// # Example - /// - /// ``` - /// use fixed_vectors::Vector3; - /// - /// let vec3 = Vector3::new(1.5, 2.0, 3.33); - /// let length = vec3.length(); - /// - /// assert!(length < 4.2); - /// ``` - #[inline] - pub fn length(&self) -> T { - self.length_squared().sqrt() - } - - /// Consumes the vector and returns it as normalized vector. - /// - /// # Example - /// - /// ``` - /// use fixed_vectors::Vector2; - /// - /// let vec2 = Vector2::new(14.3, 7.9).normalized(); - /// - /// assert!(vec2.x < 1.0); - /// assert!(vec2.y < 1.0); - /// ``` - pub fn normalized(self) -> Self { - let length_squared = self.length_squared(); - - if length_squared == T::zero() { - return Self { $( $field: T::zero() ), + }; - } - - let length = length_squared.sqrt(); - - Self { - $( $field: self.$field / length ), + - } - } - - /// Normalizes the vector through mutation. - /// - /// # Example - /// - /// ``` - /// use fixed_vectors::Vector2; - /// - /// let mut vec2 = Vector2::new(14.3, 7.9); - /// vec2.normalize(); - /// - /// assert!(vec2.x < 1.0); - /// assert!(vec2.y < 1.0); - /// ``` - pub fn normalize(&mut self) { - let length_squared = self.length_squared(); - - if length_squared == T::zero() { - *self = Self { $( $field: T::zero() ), + }; - return; - } - - let length = length_squared.sqrt(); - - *self = Self { - $( $field: self.$field / length ), + - } - } } }; } @@ -290,26 +41,3 @@ macro_rules! sum_repeating { $($item) * }; } - - -// Required trait for `sqrt` impls -#[doc(hidden)] -pub trait _FloatingPoint { - fn sqrt(self) -> Self; -} - - -impl _FloatingPoint for f32 { - #[inline(always)] - fn sqrt(self) -> Self { - libm::sqrtf(self) - } -} - - -impl _FloatingPoint for f64 { - #[inline(always)] - fn sqrt(self) -> Self { - libm::sqrt(self) - } -} diff --git a/src/tests/mod.rs b/src/tests/mod.rs index c91a008..c0767c7 100644 --- a/src/tests/mod.rs +++ b/src/tests/mod.rs @@ -18,7 +18,7 @@ fn it_works() { } #[test] -pub fn main(){ - let max=i32::MAX as i64; - println!("{} {}",max*max,i64::MAX); +pub fn wide_vec3(){ + let v=crate::vector::Vector3::from_value(Planar64::from(1)); + let v1=v.wide_mul(v); } From 01de555888de3d8471bcba36f04cc880a49e582e Mon Sep 17 00:00:00 2001 From: Quaternions Date: Fri, 23 Aug 2024 16:30:01 -0700 Subject: [PATCH 013/227] THE DOCS ARE TESTS WHAT --- src/macros/mod.rs | 10 +++++----- src/vector.rs | 6 +++--- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/macros/mod.rs b/src/macros/mod.rs index 912565a..5215000 100644 --- a/src/macros/mod.rs +++ b/src/macros/mod.rs @@ -11,7 +11,7 @@ macro_rules! impl_vector { /// # Example /// /// ``` - /// use fixed_vectors::Vector2; + /// use fixed_wide_vectors::vector::Vector2; /// /// let vec2 = Vector2::new(0, 0); /// @@ -30,7 +30,7 @@ macro_rules! impl_vector { /// # Example /// /// ``` - /// use fixed_vectors::Vector2; + /// use fixed_wide_vectors::vector::Vector2; /// /// let vec2 = Vector2::new(0, 0); /// let array = vec2.to_array(); @@ -47,7 +47,7 @@ macro_rules! impl_vector { /// # Example /// /// ``` - /// use fixed_vectors::Vector2; + /// use fixed_wide_vectors::vector::Vector2; /// /// let vec2 = Vector2::new(0, 0); /// let tuple = vec2.to_tuple(); @@ -64,7 +64,7 @@ macro_rules! impl_vector { /// # Example /// /// ``` - /// use fixed_vectors::Vector2; + /// use fixed_wide_vectors::vector::Vector2; /// /// let vec2 = Vector2::new(1, 2) /// .map(|i| i * 2); @@ -88,7 +88,7 @@ macro_rules! impl_vector { /// # Example /// /// ``` - /// use fixed_vectors::Vector2; + /// use fixed_wide_vectors::vector::Vector2; /// /// let vec2 = Vector2::from_value(0); /// diff --git a/src/vector.rs b/src/vector.rs index 067237f..8d28105 100644 --- a/src/vector.rs +++ b/src/vector.rs @@ -5,7 +5,7 @@ /// # Example /// /// ``` -/// use fixed_vectors::Vector2; +/// use fixed_wide_vectors::vector::Vector2; /// /// let mut vec2 = Vector2::new(1, 2); /// vec2 += Vector2::new(1, 2); @@ -24,7 +24,7 @@ pub struct Vector2 { /// # Example /// /// ``` -/// use fixed_vectors::Vector3; +/// use fixed_wide_vectors::vector::Vector3; /// /// let mut vec3 = Vector3::new(1, 2, 3); /// vec3 += Vector3::new(1, 2, 3); @@ -45,7 +45,7 @@ pub struct Vector3 { /// # Example /// /// ``` -/// use fixed_vectors::Vector4; +/// use fixed_wide_vectors::vector::Vector4; /// /// let mut vec4 = Vector4::new(1, 2, 3, 4); /// vec4 += Vector4::new(1, 2, 3, 4); From 75ca27f23242fc6768575a359c296bb3e7ce69ea Mon Sep 17 00:00:00 2001 From: Quaternions Date: Fri, 23 Aug 2024 16:31:25 -0700 Subject: [PATCH 014/227] do it like this --- src/lib.rs | 6 +++++- src/macros/mod.rs | 10 +++++----- src/vector.rs | 6 +++--- 3 files changed, 13 insertions(+), 9 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index ed7a919..775c4e6 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,5 +1,9 @@ mod macros; -pub mod vector; +mod vector; + +pub use vector::Vector2; +pub use vector::Vector3; +pub use vector::Vector4; #[cfg(test)] mod tests; diff --git a/src/macros/mod.rs b/src/macros/mod.rs index 5215000..ffac9aa 100644 --- a/src/macros/mod.rs +++ b/src/macros/mod.rs @@ -11,7 +11,7 @@ macro_rules! impl_vector { /// # Example /// /// ``` - /// use fixed_wide_vectors::vector::Vector2; + /// use fixed_wide_vectors::Vector2; /// /// let vec2 = Vector2::new(0, 0); /// @@ -30,7 +30,7 @@ macro_rules! impl_vector { /// # Example /// /// ``` - /// use fixed_wide_vectors::vector::Vector2; + /// use fixed_wide_vectors::Vector2; /// /// let vec2 = Vector2::new(0, 0); /// let array = vec2.to_array(); @@ -47,7 +47,7 @@ macro_rules! impl_vector { /// # Example /// /// ``` - /// use fixed_wide_vectors::vector::Vector2; + /// use fixed_wide_vectors::Vector2; /// /// let vec2 = Vector2::new(0, 0); /// let tuple = vec2.to_tuple(); @@ -64,7 +64,7 @@ macro_rules! impl_vector { /// # Example /// /// ``` - /// use fixed_wide_vectors::vector::Vector2; + /// use fixed_wide_vectors::Vector2; /// /// let vec2 = Vector2::new(1, 2) /// .map(|i| i * 2); @@ -88,7 +88,7 @@ macro_rules! impl_vector { /// # Example /// /// ``` - /// use fixed_wide_vectors::vector::Vector2; + /// use fixed_wide_vectors::Vector2; /// /// let vec2 = Vector2::from_value(0); /// diff --git a/src/vector.rs b/src/vector.rs index 8d28105..2767ad8 100644 --- a/src/vector.rs +++ b/src/vector.rs @@ -5,7 +5,7 @@ /// # Example /// /// ``` -/// use fixed_wide_vectors::vector::Vector2; +/// use fixed_wide_vectors::Vector2; /// /// let mut vec2 = Vector2::new(1, 2); /// vec2 += Vector2::new(1, 2); @@ -24,7 +24,7 @@ pub struct Vector2 { /// # Example /// /// ``` -/// use fixed_wide_vectors::vector::Vector3; +/// use fixed_wide_vectors::Vector3; /// /// let mut vec3 = Vector3::new(1, 2, 3); /// vec3 += Vector3::new(1, 2, 3); @@ -45,7 +45,7 @@ pub struct Vector3 { /// # Example /// /// ``` -/// use fixed_wide_vectors::vector::Vector4; +/// use fixed_wide_vectors::Vector4; /// /// let mut vec4 = Vector4::new(1, 2, 3, 4); /// vec4 += Vector4::new(1, 2, 3, 4); From e7eac03f040edbd6df13d7925ada25371466ca12 Mon Sep 17 00:00:00 2001 From: Quaternions Date: Fri, 23 Aug 2024 16:35:22 -0700 Subject: [PATCH 015/227] BUAHAHAHAHA --- src/tests/mod.rs | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/tests/mod.rs b/src/tests/mod.rs index c0767c7..541217c 100644 --- a/src/tests/mod.rs +++ b/src/tests/mod.rs @@ -1,5 +1,7 @@ use fixed_wide::wide::WideMul; +use crate::Vector3; + type Planar64=fixed::types::I32F32; //type Planar64Wide1=fixed::types::I64F64; //type Planar64Wide2=fixed_wide::types::I128F128; @@ -14,11 +16,15 @@ fn it_works() { let w2=w1.wide_mul(w1); let w3=w2.wide_mul(w2); - assert_eq!(w3,Planar64Wide3::from(1296)); + assert_eq!(w3,Planar64Wide3::from((3i128*2).pow(4))); } #[test] pub fn wide_vec3(){ - let v=crate::vector::Vector3::from_value(Planar64::from(1)); + let v=Vector3::from_value(Planar64::from(3)); let v1=v.wide_mul(v); + let v2=v1.wide_mul(v1); + let v3=v2.wide_mul(v2); + + assert_eq!(v3,Vector3::from_value(Planar64Wide3::from(3i128.pow(8)))); } From 114b2725eade3b6394089509a0ab43bae0a8bb91 Mon Sep 17 00:00:00 2001 From: Quaternions Date: Fri, 23 Aug 2024 16:37:31 -0700 Subject: [PATCH 016/227] tweaks --- src/tests/mod.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/tests/mod.rs b/src/tests/mod.rs index 541217c..478c945 100644 --- a/src/tests/mod.rs +++ b/src/tests/mod.rs @@ -8,7 +8,7 @@ type Planar64=fixed::types::I32F32; type Planar64Wide3=fixed_wide::types::I256F256; #[test] -fn it_works() { +fn wide_int64() { let a=Planar64::from(2); let b=Planar64::from(3); @@ -20,7 +20,7 @@ fn it_works() { } #[test] -pub fn wide_vec3(){ +fn wide_vec3(){ let v=Vector3::from_value(Planar64::from(3)); let v1=v.wide_mul(v); let v2=v1.wide_mul(v1); From d38d103399106845a016b39b3e852f9188ac23a7 Mon Sep 17 00:00:00 2001 From: Quaternions Date: Fri, 23 Aug 2024 16:48:24 -0700 Subject: [PATCH 017/227] you can add --- fixed_wide/src/wide.rs | 10 ++++++++++ src/tests/mod.rs | 6 ++++++ 2 files changed, 16 insertions(+) diff --git a/fixed_wide/src/wide.rs b/fixed_wide/src/wide.rs index 192bead..bf4c96f 100644 --- a/fixed_wide/src/wide.rs +++ b/fixed_wide/src/wide.rs @@ -27,6 +27,16 @@ impl PartialEq for Fixed{ } impl Eq for Fixed{} +impl,Frac> std::ops::Add for Fixed{ + type Output=Self; + fn add(self,rhs:Self)->Self::Output{ + Self{ + bits:self.bits+rhs.bits, + phantom:std::marker::PhantomData, + } + } +} + pub trait WideMul{ type Output; fn wide_mul(self,rhs:Rhs)->Self::Output; diff --git a/src/tests/mod.rs b/src/tests/mod.rs index 478c945..945b406 100644 --- a/src/tests/mod.rs +++ b/src/tests/mod.rs @@ -19,6 +19,12 @@ fn wide_int64() { assert_eq!(w3,Planar64Wide3::from((3i128*2).pow(4))); } +#[test] +fn you_can_add_numbers(){ + let a=Planar64Wide3::from((3i128*2).pow(4)); + assert_eq!(a+a,Planar64Wide3::from((3i128*2).pow(4)*2)) +} + #[test] fn wide_vec3(){ let v=Vector3::from_value(Planar64::from(3)); From 3ccc19f768c3a8858eacc34b4467826d02ee1669 Mon Sep 17 00:00:00 2001 From: Quaternions Date: Fri, 23 Aug 2024 16:49:05 -0700 Subject: [PATCH 018/227] fix wide_dot and wide_length_squared --- src/macros/wide.rs | 8 ++++---- src/tests/mod.rs | 20 ++++++++++++++++++++ 2 files changed, 24 insertions(+), 4 deletions(-) diff --git a/src/macros/wide.rs b/src/macros/wide.rs index 3b348a2..7e12358 100644 --- a/src/macros/wide.rs +++ b/src/macros/wide.rs @@ -11,15 +11,15 @@ macro_rules! impl_wide_operations { } } } - impl+std::ops::Add> $struct { + impl,T:Copy+fixed_wide::wide::WideMul> $struct { #[inline] - pub fn wide_dot(&self, other: &Self) -> ::Output { + pub fn wide_dot(self, other: Self) -> U { $crate::sum_repeating!( $( + (self.$field.wide_mul(other.$field)) ) + ) } - pub fn length_squared(&self) -> ::Output { - let squared = Self { + pub fn wide_length_squared(&self) -> U { + let squared = $struct { $( $field: self.$field.wide_mul(self.$field) ), + }; diff --git a/src/tests/mod.rs b/src/tests/mod.rs index 945b406..24a8b66 100644 --- a/src/tests/mod.rs +++ b/src/tests/mod.rs @@ -34,3 +34,23 @@ fn wide_vec3(){ assert_eq!(v3,Vector3::from_value(Planar64Wide3::from(3i128.pow(8)))); } + +#[test] +fn wide_vec3_dot(){ + let v=Vector3::from_value(Planar64::from(3)); + let v1=v.wide_mul(v); + let v2=v1.wide_mul(v1); + let v3=v2.wide_dot(v2); + + assert_eq!(v3,Planar64Wide3::from(3i128.pow(8)*3)); +} + +#[test] +fn wide_vec3_length_squared(){ + let v=Vector3::from_value(Planar64::from(3)); + let v1=v.wide_mul(v); + let v2=v1.wide_mul(v1); + let v3=v2.wide_length_squared(); + + assert_eq!(v3,Planar64Wide3::from(3i128.pow(8)*3)); +} From b836bc2a11864922e25c0d8caf993fa39c0852a2 Mon Sep 17 00:00:00 2001 From: Quaternions Date: Fri, 23 Aug 2024 16:53:54 -0700 Subject: [PATCH 019/227] style --- fixed_wide/src/wide.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fixed_wide/src/wide.rs b/fixed_wide/src/wide.rs index bf4c96f..9d050ce 100644 --- a/fixed_wide/src/wide.rs +++ b/fixed_wide/src/wide.rs @@ -22,7 +22,7 @@ impl+std::ops::Shl,FracDst:Unsigned> From f impl PartialEq for Fixed{ fn eq(&self,other:&Self)->bool{ - self.bits==other.bits + self.bits.eq(&other.bits) } } impl Eq for Fixed{} From c6cc1da4bef047245e998047966a00fb2ccf3926 Mon Sep 17 00:00:00 2001 From: Quaternions Date: Fri, 23 Aug 2024 17:07:11 -0700 Subject: [PATCH 020/227] reorganize repo as monorepo of two crates --- .gitignore => fixed_wide/.gitignore | 0 fixed_wide_vectors/.gitignore | 1 + Cargo.lock => fixed_wide_vectors/Cargo.lock | 0 Cargo.toml => fixed_wide_vectors/Cargo.toml | 0 {src => fixed_wide_vectors/src}/lib.rs | 0 {src => fixed_wide_vectors/src}/macros/mod.rs | 0 {src => fixed_wide_vectors/src}/macros/wide.rs | 0 {src => fixed_wide_vectors/src}/tests/mod.rs | 0 {src => fixed_wide_vectors/src}/vector.rs | 0 9 files changed, 1 insertion(+) rename .gitignore => fixed_wide/.gitignore (100%) create mode 100644 fixed_wide_vectors/.gitignore rename Cargo.lock => fixed_wide_vectors/Cargo.lock (100%) rename Cargo.toml => fixed_wide_vectors/Cargo.toml (100%) rename {src => fixed_wide_vectors/src}/lib.rs (100%) rename {src => fixed_wide_vectors/src}/macros/mod.rs (100%) rename {src => fixed_wide_vectors/src}/macros/wide.rs (100%) rename {src => fixed_wide_vectors/src}/tests/mod.rs (100%) rename {src => fixed_wide_vectors/src}/vector.rs (100%) diff --git a/.gitignore b/fixed_wide/.gitignore similarity index 100% rename from .gitignore rename to fixed_wide/.gitignore diff --git a/fixed_wide_vectors/.gitignore b/fixed_wide_vectors/.gitignore new file mode 100644 index 0000000..ea8c4bf --- /dev/null +++ b/fixed_wide_vectors/.gitignore @@ -0,0 +1 @@ +/target diff --git a/Cargo.lock b/fixed_wide_vectors/Cargo.lock similarity index 100% rename from Cargo.lock rename to fixed_wide_vectors/Cargo.lock diff --git a/Cargo.toml b/fixed_wide_vectors/Cargo.toml similarity index 100% rename from Cargo.toml rename to fixed_wide_vectors/Cargo.toml diff --git a/src/lib.rs b/fixed_wide_vectors/src/lib.rs similarity index 100% rename from src/lib.rs rename to fixed_wide_vectors/src/lib.rs diff --git a/src/macros/mod.rs b/fixed_wide_vectors/src/macros/mod.rs similarity index 100% rename from src/macros/mod.rs rename to fixed_wide_vectors/src/macros/mod.rs diff --git a/src/macros/wide.rs b/fixed_wide_vectors/src/macros/wide.rs similarity index 100% rename from src/macros/wide.rs rename to fixed_wide_vectors/src/macros/wide.rs diff --git a/src/tests/mod.rs b/fixed_wide_vectors/src/tests/mod.rs similarity index 100% rename from src/tests/mod.rs rename to fixed_wide_vectors/src/tests/mod.rs diff --git a/src/vector.rs b/fixed_wide_vectors/src/vector.rs similarity index 100% rename from src/vector.rs rename to fixed_wide_vectors/src/vector.rs From 62e0d8e2b611dbcbcb0eb1ab670107d67da01f8f Mon Sep 17 00:00:00 2001 From: Quaternions Date: Fri, 23 Aug 2024 17:14:59 -0700 Subject: [PATCH 021/227] add license and README --- LICENSE-APACHE | 176 +++++++++++++++++++++++++++++++++++++++++++++++++ LICENSE-MIT | 23 +++++++ README.md | 19 ++++++ 3 files changed, 218 insertions(+) create mode 100644 LICENSE-APACHE create mode 100644 LICENSE-MIT create mode 100644 README.md diff --git a/LICENSE-APACHE b/LICENSE-APACHE new file mode 100644 index 0000000..a7e77cb --- /dev/null +++ b/LICENSE-APACHE @@ -0,0 +1,176 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + +TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + +1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + +2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + +3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + +4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + +5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + +6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + +7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + +8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + +9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + +END OF TERMS AND CONDITIONS \ No newline at end of file diff --git a/LICENSE-MIT b/LICENSE-MIT new file mode 100644 index 0000000..468cd79 --- /dev/null +++ b/LICENSE-MIT @@ -0,0 +1,23 @@ +Permission is hereby granted, free of charge, to any +person obtaining a copy of this software and associated +documentation files (the "Software"), to deal in the +Software without restriction, including without +limitation the rights to use, copy, modify, merge, +publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software +is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice +shall be included in all copies or substantial portions +of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF +ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED +TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT +SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR +IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. \ No newline at end of file diff --git a/README.md b/README.md new file mode 100644 index 0000000..c73506e --- /dev/null +++ b/README.md @@ -0,0 +1,19 @@ +Fixed Size, Fixed Point, and Wide Vectors +========================================= + +## These exist separately in the Rust ecosystem, but not together. + +#### License + + +Licensed under either of Apache License, Version +2.0 or MIT license at your option. + + +
+ + +Unless you explicitly state otherwise, any contribution intentionally submitted +for inclusion in this crate by you, as defined in the Apache-2.0 license, shall +be dual licensed as above, without any additional terms or conditions. + From aec20424b82fa909a08ec15f2e7b188e9ee1a0da Mon Sep 17 00:00:00 2001 From: Quaternions Date: Fri, 23 Aug 2024 17:18:03 -0700 Subject: [PATCH 022/227] bad essay opening --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index c73506e..51cbf8c 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,5 @@ -Fixed Size, Fixed Point, and Wide Vectors -========================================= +Vectors: Fixed Size, Fixed Point, Wide +====================================== ## These exist separately in the Rust ecosystem, but not together. From 43b81901480af76b3e0bbc9d1292634357e62f73 Mon Sep 17 00:00:00 2001 From: Quaternions Date: Fri, 23 Aug 2024 17:50:02 -0700 Subject: [PATCH 023/227] fix path --- fixed_wide_vectors/Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fixed_wide_vectors/Cargo.toml b/fixed_wide_vectors/Cargo.toml index c1bca07..520b5b5 100644 --- a/fixed_wide_vectors/Cargo.toml +++ b/fixed_wide_vectors/Cargo.toml @@ -5,4 +5,4 @@ edition = "2021" [dependencies] fixed = "1.28.0" -fixed_wide = { version = "0.1.0", path = "fixed_wide" } +fixed_wide = { version = "0.1.0", path = "../fixed_wide" } From 98349915ec0041eb6df238cb6fa67d1c67754fb9 Mon Sep 17 00:00:00 2001 From: Quaternions Date: Fri, 23 Aug 2024 17:55:14 -0700 Subject: [PATCH 024/227] todo --- fixed_wide/src/narrow.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/fixed_wide/src/narrow.rs b/fixed_wide/src/narrow.rs index 4ba82a9..f48483b 100644 --- a/fixed_wide/src/narrow.rs +++ b/fixed_wide/src/narrow.rs @@ -15,6 +15,7 @@ pub trait TryNarrow{ mod tests { use super::*; + //TODO: use num_traits to do a blanket implementation (selfResult{ From 5175a2ea182cb5a457139332df37b35838dfb31a Mon Sep 17 00:00:00 2001 From: Quaternions Date: Mon, 26 Aug 2024 14:58:19 -0700 Subject: [PATCH 025/227] wip --- fixed_wide/src/wide.rs | 88 ++++++++++++++++++++++++++++++------------ 1 file changed, 64 insertions(+), 24 deletions(-) diff --git a/fixed_wide/src/wide.rs b/fixed_wide/src/wide.rs index 9d050ce..114c673 100644 --- a/fixed_wide/src/wide.rs +++ b/fixed_wide/src/wide.rs @@ -1,38 +1,41 @@ use bnum::cast::As; use bnum::types::{I256,I512}; +use bnum::BInt; use fixed::{FixedI64,FixedI128}; use typenum::{Sum,Unsigned}; +use std::marker::PhantomData; #[derive(Clone,Copy,Debug)] -pub struct Fixed{ - bits:Int, - phantom:std::marker::PhantomData, +pub struct Fixed{ + bits:BInt<{CHUNKS}>, + frac:PhantomData, } -pub type FixedI256=Fixed; -pub type FixedI512=Fixed; +pub type FixedI192=Fixed<3,Frac>; +pub type FixedI256=Fixed<4,Frac>; +pub type FixedI512=Fixed<8,Frac>; -impl+std::ops::Shl,FracDst:Unsigned> From for Fixed{ +impl From for Fixed{ fn from(value:i128)->Self{ Self{ - bits:Int::from(value)<::from(value)< PartialEq for Fixed{ +impl PartialEq for Fixed{ fn eq(&self,other:&Self)->bool{ self.bits.eq(&other.bits) } } -impl Eq for Fixed{} +impl Eq for Fixed{} -impl,Frac> std::ops::Add for Fixed{ +impl std::ops::Add for Fixed{ type Output=Self; fn add(self,rhs:Self)->Self::Output{ Self{ bits:self.bits+rhs.bits, - phantom:std::marker::PhantomData, + frac:PhantomData, } } } @@ -53,6 +56,32 @@ impl WideMul> for FixedI64 self.wide_mul(rhs) } } +impl WideMul> for FixedI128 + where + A:std::ops::Add, + B:Unsigned, +{ + type Output=FixedI192>; + fn wide_mul(self,rhs:FixedI64)->Self::Output{ + FixedI192{ + bits:BInt::<3>::from(self.to_bits())*BInt::<3>::from(rhs.to_bits()), + frac:PhantomData, + } + } +} +impl WideMul> for FixedI64 + where + A:std::ops::Add, + B:Unsigned, +{ + type Output=FixedI192>; + fn wide_mul(self,rhs:FixedI128)->Self::Output{ + FixedI192{ + bits:BInt::<3>::from(self.to_bits())*BInt::<3>::from(rhs.to_bits()), + frac:PhantomData, + } + } +} impl WideMul> for FixedI128 where A:std::ops::Add, @@ -62,21 +91,32 @@ impl WideMul> for FixedI128 fn wide_mul(self,rhs:FixedI128)->Self::Output{ FixedI256{ bits:I256::from(self.to_bits())*I256::from(rhs.to_bits()), - phantom:std::marker::PhantomData, + frac:PhantomData, } } } + //going wider native -impl WideMul> for FixedI256 - where - A:std::ops::Add, - B:Unsigned, -{ - type Output=FixedI512>; - fn wide_mul(self,rhs:FixedI256)->Self::Output{ - FixedI512{ - bits:self.bits.as_::()*rhs.bits.as_::(), - phantom:std::marker::PhantomData, +macro_rules! impl_wide_mul { + ($lhs: expr,$rhs: expr) => { + impl WideMul> for Fixed<$lhs,A> + where + A:std::ops::Add, + B:Unsigned, + { + type Output=Fixed<{$lhs+$rhs},Sum>; + fn wide_mul(self,rhs:Fixed<$rhs,B>)->Self::Output{ + Fixed{ + bits:self.bits.as_::>()*rhs.bits.as_::>(), + frac:PhantomData, + } + } } - } + }; } +impl_wide_mul!(3,3);impl_wide_mul!(4,3);impl_wide_mul!(5,3);impl_wide_mul!(6,3);impl_wide_mul!(7,3);impl_wide_mul!(8,3); +impl_wide_mul!(3,4);impl_wide_mul!(4,4);impl_wide_mul!(5,4);impl_wide_mul!(6,4);impl_wide_mul!(7,4);impl_wide_mul!(8,4); +impl_wide_mul!(3,5);impl_wide_mul!(4,5);impl_wide_mul!(5,5);impl_wide_mul!(6,5);impl_wide_mul!(7,5);impl_wide_mul!(8,5); +impl_wide_mul!(3,6);impl_wide_mul!(4,6);impl_wide_mul!(5,6);impl_wide_mul!(6,6);impl_wide_mul!(7,6);impl_wide_mul!(8,6); +impl_wide_mul!(3,7);impl_wide_mul!(4,7);impl_wide_mul!(5,7);impl_wide_mul!(6,7);impl_wide_mul!(7,7);impl_wide_mul!(8,7); +impl_wide_mul!(3,8);impl_wide_mul!(4,8);impl_wide_mul!(5,8);impl_wide_mul!(6,8);impl_wide_mul!(7,8);impl_wide_mul!(8,8); From f32bd4a667367e9bf105a6501ce47cc0e20d8a52 Mon Sep 17 00:00:00 2001 From: Quaternions Date: Mon, 26 Aug 2024 15:40:27 -0700 Subject: [PATCH 026/227] bad operator impl --- fixed_wide/src/wide.rs | 134 +++++++++++++++++++---------------------- 1 file changed, 62 insertions(+), 72 deletions(-) diff --git a/fixed_wide/src/wide.rs b/fixed_wide/src/wide.rs index 114c673..09cb448 100644 --- a/fixed_wide/src/wide.rs +++ b/fixed_wide/src/wide.rs @@ -1,7 +1,5 @@ use bnum::cast::As; -use bnum::types::{I256,I512}; use bnum::BInt; -use fixed::{FixedI64,FixedI128}; use typenum::{Sum,Unsigned}; use std::marker::PhantomData; @@ -10,12 +8,12 @@ pub struct Fixed{ bits:BInt<{CHUNKS}>, frac:PhantomData, } -pub type FixedI192=Fixed<3,Frac>; -pub type FixedI256=Fixed<4,Frac>; -pub type FixedI512=Fixed<8,Frac>; -impl From for Fixed{ - fn from(value:i128)->Self{ +impl From for Fixed + where + BInt:From +{ + fn from(value:T)->Self{ Self{ bits:BInt::<{CHUNKS}>::from(value)< PartialEq for Fixed{ } impl Eq for Fixed{} -impl std::ops::Add for Fixed{ - type Output=Self; - fn add(self,rhs:Self)->Self::Output{ - Self{ - bits:self.bits+rhs.bits, - frac:PhantomData, - } - } +macro_rules! impl_operator { + ( $struct: ident, $trait: ident, $method: ident, $output: ty ) => { + impl core::ops::$trait for $struct + where + $struct:From + { + type Output = $output; + + fn $method(self, other: T) -> Self::Output { + Self { + bits:self.bits.$method($struct::::from(other).bits), + frac:PhantomData, + } + } + } + }; } +macro_rules! impl_assign_operator { + ( $struct: ident, $trait: ident, $method: ident ) => { + impl core::ops::$trait for $struct + where + $struct:From + { + fn $method(&mut self, other: T) { + self.bits.$method($struct::::from(other).bits); + } + } + }; +} + +// Impl arithmetic pperators +impl_assign_operator!( Fixed, AddAssign, add_assign ); +impl_operator!( Fixed, Add, add, Self ); +impl_assign_operator!( Fixed, SubAssign, sub_assign ); +impl_operator!( Fixed, Sub, sub, Self ); +impl_assign_operator!( Fixed, MulAssign, mul_assign ); +impl_operator!( Fixed, Mul, mul, Self ); +impl_assign_operator!( Fixed, DivAssign, div_assign ); +impl_operator!( Fixed, Div, div, Self ); +impl_assign_operator!( Fixed, RemAssign, rem_assign ); +impl_operator!( Fixed, Rem, rem, Self ); + +// Impl bitwise operators +impl_assign_operator!( Fixed, BitAndAssign, bitand_assign ); +impl_operator!( Fixed, BitAnd, bitand, Self ); +impl_assign_operator!( Fixed, BitOrAssign, bitor_assign ); +impl_operator!( Fixed, BitOr, bitor, Self ); +impl_assign_operator!( Fixed, BitXorAssign, bitxor_assign ); +impl_operator!( Fixed, BitXor, bitxor, Self ); pub trait WideMul{ type Output; fn wide_mul(self,rhs:Rhs)->Self::Output; } -//going wide from foreign fixed type -impl WideMul> for FixedI64 - where - A:std::ops::Add, - B:Unsigned, -{ - type Output=FixedI128>; - fn wide_mul(self,rhs:FixedI64)->Self::Output{ - self.wide_mul(rhs) - } -} -impl WideMul> for FixedI128 - where - A:std::ops::Add, - B:Unsigned, -{ - type Output=FixedI192>; - fn wide_mul(self,rhs:FixedI64)->Self::Output{ - FixedI192{ - bits:BInt::<3>::from(self.to_bits())*BInt::<3>::from(rhs.to_bits()), - frac:PhantomData, - } - } -} -impl WideMul> for FixedI64 - where - A:std::ops::Add, - B:Unsigned, -{ - type Output=FixedI192>; - fn wide_mul(self,rhs:FixedI128)->Self::Output{ - FixedI192{ - bits:BInt::<3>::from(self.to_bits())*BInt::<3>::from(rhs.to_bits()), - frac:PhantomData, - } - } -} -impl WideMul> for FixedI128 - where - A:std::ops::Add, - B:Unsigned, -{ - type Output=FixedI256>; - fn wide_mul(self,rhs:FixedI128)->Self::Output{ - FixedI256{ - bits:I256::from(self.to_bits())*I256::from(rhs.to_bits()), - frac:PhantomData, - } - } -} - //going wider native macro_rules! impl_wide_mul { ($lhs: expr,$rhs: expr) => { @@ -114,9 +101,12 @@ macro_rules! impl_wide_mul { } }; } -impl_wide_mul!(3,3);impl_wide_mul!(4,3);impl_wide_mul!(5,3);impl_wide_mul!(6,3);impl_wide_mul!(7,3);impl_wide_mul!(8,3); -impl_wide_mul!(3,4);impl_wide_mul!(4,4);impl_wide_mul!(5,4);impl_wide_mul!(6,4);impl_wide_mul!(7,4);impl_wide_mul!(8,4); -impl_wide_mul!(3,5);impl_wide_mul!(4,5);impl_wide_mul!(5,5);impl_wide_mul!(6,5);impl_wide_mul!(7,5);impl_wide_mul!(8,5); -impl_wide_mul!(3,6);impl_wide_mul!(4,6);impl_wide_mul!(5,6);impl_wide_mul!(6,6);impl_wide_mul!(7,6);impl_wide_mul!(8,6); -impl_wide_mul!(3,7);impl_wide_mul!(4,7);impl_wide_mul!(5,7);impl_wide_mul!(6,7);impl_wide_mul!(7,7);impl_wide_mul!(8,7); -impl_wide_mul!(3,8);impl_wide_mul!(4,8);impl_wide_mul!(5,8);impl_wide_mul!(6,8);impl_wide_mul!(7,8);impl_wide_mul!(8,8); +//const generics sidestepped wahoo +impl_wide_mul!(1,1);impl_wide_mul!(2,1);impl_wide_mul!(3,1);impl_wide_mul!(4,1);impl_wide_mul!(5,1);impl_wide_mul!(6,1);impl_wide_mul!(7,1);impl_wide_mul!(8,1); +impl_wide_mul!(1,2);impl_wide_mul!(2,2);impl_wide_mul!(3,2);impl_wide_mul!(4,2);impl_wide_mul!(5,2);impl_wide_mul!(6,2);impl_wide_mul!(7,2);impl_wide_mul!(8,2); +impl_wide_mul!(1,3);impl_wide_mul!(2,3);impl_wide_mul!(3,3);impl_wide_mul!(4,3);impl_wide_mul!(5,3);impl_wide_mul!(6,3);impl_wide_mul!(7,3);impl_wide_mul!(8,3); +impl_wide_mul!(1,4);impl_wide_mul!(2,4);impl_wide_mul!(3,4);impl_wide_mul!(4,4);impl_wide_mul!(5,4);impl_wide_mul!(6,4);impl_wide_mul!(7,4);impl_wide_mul!(8,4); +impl_wide_mul!(1,5);impl_wide_mul!(2,5);impl_wide_mul!(3,5);impl_wide_mul!(4,5);impl_wide_mul!(5,5);impl_wide_mul!(6,5);impl_wide_mul!(7,5);impl_wide_mul!(8,5); +impl_wide_mul!(1,6);impl_wide_mul!(2,6);impl_wide_mul!(3,6);impl_wide_mul!(4,6);impl_wide_mul!(5,6);impl_wide_mul!(6,6);impl_wide_mul!(7,6);impl_wide_mul!(8,6); +impl_wide_mul!(1,7);impl_wide_mul!(2,7);impl_wide_mul!(3,7);impl_wide_mul!(4,7);impl_wide_mul!(5,7);impl_wide_mul!(6,7);impl_wide_mul!(7,7);impl_wide_mul!(8,7); +impl_wide_mul!(1,8);impl_wide_mul!(2,8);impl_wide_mul!(3,8);impl_wide_mul!(4,8);impl_wide_mul!(5,8);impl_wide_mul!(6,8);impl_wide_mul!(7,8);impl_wide_mul!(8,8); From 8206e1695210e7435ab38e2ffadc9f2f53253d70 Mon Sep 17 00:00:00 2001 From: Quaternions Date: Mon, 26 Aug 2024 15:40:37 -0700 Subject: [PATCH 027/227] drop fixed dep --- fixed_wide/Cargo.lock | 47 ---------------------------- fixed_wide/Cargo.toml | 1 - fixed_wide/src/types.rs | 6 ++-- fixed_wide_vectors/Cargo.lock | 48 ----------------------------- fixed_wide_vectors/Cargo.toml | 1 - fixed_wide_vectors/src/tests/mod.rs | 2 +- 6 files changed, 5 insertions(+), 100 deletions(-) diff --git a/fixed_wide/Cargo.lock b/fixed_wide/Cargo.lock index 54c950e..b4a8917 100644 --- a/fixed_wide/Cargo.lock +++ b/fixed_wide/Cargo.lock @@ -2,67 +2,20 @@ # It is not intended for manual editing. version = 3 -[[package]] -name = "az" -version = "1.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7b7e4c2464d97fe331d41de9d5db0def0a96f4d823b8b32a2efd503578988973" - [[package]] name = "bnum" version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3e31ea183f6ee62ac8b8a8cf7feddd766317adfb13ff469de57ce033efd6a790" -[[package]] -name = "bytemuck" -version = "1.17.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6fd4c6dcc3b0aea2f5c0b4b82c2b15fe39ddbc76041a310848f4706edf76bb31" - -[[package]] -name = "cfg-if" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" - -[[package]] -name = "crunchy" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a81dae078cea95a014a339291cec439d2f232ebe854a9d672b796c6afafa9b7" - -[[package]] -name = "fixed" -version = "1.28.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "85c6e0b89bf864acd20590dbdbad56f69aeb898abfc9443008fd7bd48b2cc85a" -dependencies = [ - "az", - "bytemuck", - "half", - "typenum", -] - [[package]] name = "fixed_wide" version = "0.1.0" dependencies = [ "bnum", - "fixed", "typenum", ] -[[package]] -name = "half" -version = "2.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6dd08c532ae367adf81c312a4580bc67f1d0fe8bc9c460520283f4c0ff277888" -dependencies = [ - "cfg-if", - "crunchy", -] - [[package]] name = "typenum" version = "1.17.0" diff --git a/fixed_wide/Cargo.toml b/fixed_wide/Cargo.toml index 54644ec..3ce0e48 100644 --- a/fixed_wide/Cargo.toml +++ b/fixed_wide/Cargo.toml @@ -5,5 +5,4 @@ edition = "2021" [dependencies] bnum = "0.11.0" -fixed = "1.28.0" typenum = "1.17.0" diff --git a/fixed_wide/src/types.rs b/fixed_wide/src/types.rs index ef49abb..9e0ba24 100644 --- a/fixed_wide/src/types.rs +++ b/fixed_wide/src/types.rs @@ -1,2 +1,4 @@ -pub type I128F128=crate::wide::FixedI256; -pub type I256F256=crate::wide::FixedI512; +pub type I32F32=crate::wide::Fixed<1,typenum::consts::U32>; +pub type I64F64=crate::wide::Fixed<2,typenum::consts::U64>; +pub type I128F128=crate::wide::Fixed<4,typenum::consts::U128>; +pub type I256F256=crate::wide::Fixed<8,typenum::consts::U256>; diff --git a/fixed_wide_vectors/Cargo.lock b/fixed_wide_vectors/Cargo.lock index a67d524..79830bd 100644 --- a/fixed_wide_vectors/Cargo.lock +++ b/fixed_wide_vectors/Cargo.lock @@ -2,54 +2,17 @@ # It is not intended for manual editing. version = 3 -[[package]] -name = "az" -version = "1.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7b7e4c2464d97fe331d41de9d5db0def0a96f4d823b8b32a2efd503578988973" - [[package]] name = "bnum" version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3e31ea183f6ee62ac8b8a8cf7feddd766317adfb13ff469de57ce033efd6a790" -[[package]] -name = "bytemuck" -version = "1.17.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6fd4c6dcc3b0aea2f5c0b4b82c2b15fe39ddbc76041a310848f4706edf76bb31" - -[[package]] -name = "cfg-if" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" - -[[package]] -name = "crunchy" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a81dae078cea95a014a339291cec439d2f232ebe854a9d672b796c6afafa9b7" - -[[package]] -name = "fixed" -version = "1.28.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "85c6e0b89bf864acd20590dbdbad56f69aeb898abfc9443008fd7bd48b2cc85a" -dependencies = [ - "az", - "bytemuck", - "half", - "typenum", -] - [[package]] name = "fixed_wide" version = "0.1.0" dependencies = [ "bnum", - "fixed", "typenum", ] @@ -57,20 +20,9 @@ dependencies = [ name = "fixed_wide_vectors" version = "0.1.0" dependencies = [ - "fixed", "fixed_wide", ] -[[package]] -name = "half" -version = "2.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6dd08c532ae367adf81c312a4580bc67f1d0fe8bc9c460520283f4c0ff277888" -dependencies = [ - "cfg-if", - "crunchy", -] - [[package]] name = "typenum" version = "1.17.0" diff --git a/fixed_wide_vectors/Cargo.toml b/fixed_wide_vectors/Cargo.toml index 520b5b5..b46e6a5 100644 --- a/fixed_wide_vectors/Cargo.toml +++ b/fixed_wide_vectors/Cargo.toml @@ -4,5 +4,4 @@ version = "0.1.0" edition = "2021" [dependencies] -fixed = "1.28.0" fixed_wide = { version = "0.1.0", path = "../fixed_wide" } diff --git a/fixed_wide_vectors/src/tests/mod.rs b/fixed_wide_vectors/src/tests/mod.rs index 24a8b66..c15e56d 100644 --- a/fixed_wide_vectors/src/tests/mod.rs +++ b/fixed_wide_vectors/src/tests/mod.rs @@ -2,7 +2,7 @@ use fixed_wide::wide::WideMul; use crate::Vector3; -type Planar64=fixed::types::I32F32; +type Planar64=fixed_wide::types::I32F32; //type Planar64Wide1=fixed::types::I64F64; //type Planar64Wide2=fixed_wide::types::I128F128; type Planar64Wide3=fixed_wide::types::I256F256; From da5decb2f70dbbe7e92babea110be23c80dfc835 Mon Sep 17 00:00:00 2001 From: Quaternions Date: Mon, 26 Aug 2024 15:57:02 -0700 Subject: [PATCH 028/227] faster with less convenience --- fixed_wide/src/wide.rs | 20 +++++++------------- 1 file changed, 7 insertions(+), 13 deletions(-) diff --git a/fixed_wide/src/wide.rs b/fixed_wide/src/wide.rs index 09cb448..7944395 100644 --- a/fixed_wide/src/wide.rs +++ b/fixed_wide/src/wide.rs @@ -29,16 +29,13 @@ impl PartialEq for Fixed{ impl Eq for Fixed{} macro_rules! impl_operator { - ( $struct: ident, $trait: ident, $method: ident, $output: ty ) => { - impl core::ops::$trait for $struct - where - $struct:From - { + ( $struct: ident, $trait: ident, $method: ident, $output: ty ) => { + impl core::ops::$trait<$struct> for $struct{ type Output = $output; - fn $method(self, other: T) -> Self::Output { + fn $method(self, other: Self) -> Self::Output { Self { - bits:self.bits.$method($struct::::from(other).bits), + bits:self.bits.$method(other.bits), frac:PhantomData, } } @@ -47,12 +44,9 @@ macro_rules! impl_operator { } macro_rules! impl_assign_operator { ( $struct: ident, $trait: ident, $method: ident ) => { - impl core::ops::$trait for $struct - where - $struct:From - { - fn $method(&mut self, other: T) { - self.bits.$method($struct::::from(other).bits); + impl core::ops::$trait<$struct> for $struct{ + fn $method(&mut self, other: Self) { + self.bits.$method(other.bits); } } }; From f12ab4a3c3b93fb0ec9446af07a77b6db88d37fc Mon Sep 17 00:00:00 2001 From: Quaternions Date: Mon, 26 Aug 2024 16:03:02 -0700 Subject: [PATCH 029/227] whats missing --- fixed_wide/src/wide.rs | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/fixed_wide/src/wide.rs b/fixed_wide/src/wide.rs index 7944395..7b2db63 100644 --- a/fixed_wide/src/wide.rs +++ b/fixed_wide/src/wide.rs @@ -3,7 +3,7 @@ use bnum::BInt; use typenum::{Sum,Unsigned}; use std::marker::PhantomData; -#[derive(Clone,Copy,Debug)] +#[derive(Clone,Copy,Debug,Hash)] pub struct Fixed{ bits:BInt<{CHUNKS}>, frac:PhantomData, @@ -28,6 +28,16 @@ impl PartialEq for Fixed{ } impl Eq for Fixed{} +impl std::ops::Neg for Fixed{ + type Output=Self; + fn neg(self)->Self{ + Self{ + bits:self.bits.neg(), + frac:PhantomData, + } + } +} + macro_rules! impl_operator { ( $struct: ident, $trait: ident, $method: ident, $output: ty ) => { impl core::ops::$trait<$struct> for $struct{ From dda8ebefc4212b6efef38a8527528baf003f19ab Mon Sep 17 00:00:00 2001 From: Quaternions Date: Mon, 26 Aug 2024 17:04:41 -0700 Subject: [PATCH 030/227] create wide_traits crate --- fixed_wide/Cargo.lock | 5 ++ fixed_wide/Cargo.toml | 1 + fixed_wide/src/lib.rs | 1 - fixed_wide/src/wide.rs | 6 +-- fixed_wide_vectors/Cargo.lock | 6 +++ fixed_wide_vectors/Cargo.toml | 1 + fixed_wide_vectors/src/macros/wide.rs | 4 +- fixed_wide_vectors/src/tests/mod.rs | 2 +- wide_traits/.gitignore | 1 + wide_traits/Cargo.lock | 63 +++++++++++++++++++++++ wide_traits/Cargo.toml | 10 ++++ wide_traits/src/lib.rs | 2 + {fixed_wide => wide_traits}/src/narrow.rs | 20 ++++--- wide_traits/src/wide.rs | 4 ++ 14 files changed, 110 insertions(+), 16 deletions(-) create mode 100644 wide_traits/.gitignore create mode 100644 wide_traits/Cargo.lock create mode 100644 wide_traits/Cargo.toml create mode 100644 wide_traits/src/lib.rs rename {fixed_wide => wide_traits}/src/narrow.rs (61%) create mode 100644 wide_traits/src/wide.rs diff --git a/fixed_wide/Cargo.lock b/fixed_wide/Cargo.lock index b4a8917..b181692 100644 --- a/fixed_wide/Cargo.lock +++ b/fixed_wide/Cargo.lock @@ -14,6 +14,7 @@ version = "0.1.0" dependencies = [ "bnum", "typenum", + "wide_traits", ] [[package]] @@ -21,3 +22,7 @@ name = "typenum" version = "1.17.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825" + +[[package]] +name = "wide_traits" +version = "0.1.0" diff --git a/fixed_wide/Cargo.toml b/fixed_wide/Cargo.toml index 3ce0e48..86f99f6 100644 --- a/fixed_wide/Cargo.toml +++ b/fixed_wide/Cargo.toml @@ -6,3 +6,4 @@ edition = "2021" [dependencies] bnum = "0.11.0" typenum = "1.17.0" +wide_traits = { version = "0.1.0", path = "../wide_traits" } diff --git a/fixed_wide/src/lib.rs b/fixed_wide/src/lib.rs index 655a298..8bdda41 100644 --- a/fixed_wide/src/lib.rs +++ b/fixed_wide/src/lib.rs @@ -1,3 +1,2 @@ pub mod wide; pub mod types; -pub mod narrow; diff --git a/fixed_wide/src/wide.rs b/fixed_wide/src/wide.rs index 7b2db63..0a5140a 100644 --- a/fixed_wide/src/wide.rs +++ b/fixed_wide/src/wide.rs @@ -1,5 +1,6 @@ use bnum::cast::As; use bnum::BInt; +use wide_traits::wide::WideMul; use typenum::{Sum,Unsigned}; use std::marker::PhantomData; @@ -82,11 +83,6 @@ impl_operator!( Fixed, BitOr, bitor, Self ); impl_assign_operator!( Fixed, BitXorAssign, bitxor_assign ); impl_operator!( Fixed, BitXor, bitxor, Self ); -pub trait WideMul{ - type Output; - fn wide_mul(self,rhs:Rhs)->Self::Output; -} - //going wider native macro_rules! impl_wide_mul { ($lhs: expr,$rhs: expr) => { diff --git a/fixed_wide_vectors/Cargo.lock b/fixed_wide_vectors/Cargo.lock index 79830bd..5c9399b 100644 --- a/fixed_wide_vectors/Cargo.lock +++ b/fixed_wide_vectors/Cargo.lock @@ -14,6 +14,7 @@ version = "0.1.0" dependencies = [ "bnum", "typenum", + "wide_traits", ] [[package]] @@ -21,6 +22,7 @@ name = "fixed_wide_vectors" version = "0.1.0" dependencies = [ "fixed_wide", + "wide_traits", ] [[package]] @@ -28,3 +30,7 @@ name = "typenum" version = "1.17.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825" + +[[package]] +name = "wide_traits" +version = "0.1.0" diff --git a/fixed_wide_vectors/Cargo.toml b/fixed_wide_vectors/Cargo.toml index b46e6a5..b96d9c1 100644 --- a/fixed_wide_vectors/Cargo.toml +++ b/fixed_wide_vectors/Cargo.toml @@ -5,3 +5,4 @@ edition = "2021" [dependencies] fixed_wide = { version = "0.1.0", path = "../fixed_wide" } +wide_traits = { version = "0.1.0", path = "../wide_traits" } diff --git a/fixed_wide_vectors/src/macros/wide.rs b/fixed_wide_vectors/src/macros/wide.rs index 7e12358..434d383 100644 --- a/fixed_wide_vectors/src/macros/wide.rs +++ b/fixed_wide_vectors/src/macros/wide.rs @@ -2,7 +2,7 @@ #[macro_export(local_inner_macros)] macro_rules! impl_wide_operations { ( $struct: ident { $($field: ident), + }, $size: expr ) => { - impl> fixed_wide::wide::WideMul for $struct { + impl> wide_traits::wide::WideMul for $struct { type Output=$struct; #[inline] fn wide_mul(self, rhs: Self) -> Self::Output { @@ -11,7 +11,7 @@ macro_rules! impl_wide_operations { } } } - impl,T:Copy+fixed_wide::wide::WideMul> $struct { + impl,T:Copy+wide_traits::wide::WideMul> $struct { #[inline] pub fn wide_dot(self, other: Self) -> U { $crate::sum_repeating!( diff --git a/fixed_wide_vectors/src/tests/mod.rs b/fixed_wide_vectors/src/tests/mod.rs index c15e56d..b48a11c 100644 --- a/fixed_wide_vectors/src/tests/mod.rs +++ b/fixed_wide_vectors/src/tests/mod.rs @@ -1,4 +1,4 @@ -use fixed_wide::wide::WideMul; +use wide_traits::wide::WideMul; use crate::Vector3; diff --git a/wide_traits/.gitignore b/wide_traits/.gitignore new file mode 100644 index 0000000..ea8c4bf --- /dev/null +++ b/wide_traits/.gitignore @@ -0,0 +1 @@ +/target diff --git a/wide_traits/Cargo.lock b/wide_traits/Cargo.lock new file mode 100644 index 0000000..a3a18a8 --- /dev/null +++ b/wide_traits/Cargo.lock @@ -0,0 +1,63 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "az" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7b7e4c2464d97fe331d41de9d5db0def0a96f4d823b8b32a2efd503578988973" + +[[package]] +name = "bytemuck" +version = "1.17.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6fd4c6dcc3b0aea2f5c0b4b82c2b15fe39ddbc76041a310848f4706edf76bb31" + +[[package]] +name = "cfg-if" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" + +[[package]] +name = "crunchy" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a81dae078cea95a014a339291cec439d2f232ebe854a9d672b796c6afafa9b7" + +[[package]] +name = "fixed" +version = "1.28.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85c6e0b89bf864acd20590dbdbad56f69aeb898abfc9443008fd7bd48b2cc85a" +dependencies = [ + "az", + "bytemuck", + "half", + "typenum", +] + +[[package]] +name = "half" +version = "2.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6dd08c532ae367adf81c312a4580bc67f1d0fe8bc9c460520283f4c0ff277888" +dependencies = [ + "cfg-if", + "crunchy", +] + +[[package]] +name = "typenum" +version = "1.17.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825" + +[[package]] +name = "wide_traits" +version = "0.1.0" +dependencies = [ + "fixed", + "typenum", +] diff --git a/wide_traits/Cargo.toml b/wide_traits/Cargo.toml new file mode 100644 index 0000000..806fb3e --- /dev/null +++ b/wide_traits/Cargo.toml @@ -0,0 +1,10 @@ +[package] +name = "wide_traits" +version = "0.1.0" +edition = "2021" + +[dependencies] + +[dev-dependencies] +fixed = "1.28.0" +typenum = "1.17.0" diff --git a/wide_traits/src/lib.rs b/wide_traits/src/lib.rs new file mode 100644 index 0000000..21c9224 --- /dev/null +++ b/wide_traits/src/lib.rs @@ -0,0 +1,2 @@ +pub mod wide; +pub mod narrow; diff --git a/fixed_wide/src/narrow.rs b/wide_traits/src/narrow.rs similarity index 61% rename from fixed_wide/src/narrow.rs rename to wide_traits/src/narrow.rs index f48483b..698eacc 100644 --- a/fixed_wide/src/narrow.rs +++ b/wide_traits/src/narrow.rs @@ -3,13 +3,19 @@ pub trait Narrow{ fn narrow(self)->Self::Output; } #[derive(Debug)] -pub enum NarrowError{ +pub enum Error{ Overflow, Underflow, } +impl std::fmt::Display for Error{ + fn fmt(&self,f:&mut std::fmt::Formatter<'_>)->std::fmt::Result{ + write!(f,"{self:?}") + } +} +impl std::error::Error for Error{} pub trait TryNarrow{ type Output; - fn try_narrow(self)->Result; + fn try_narrow(self)->Result; } #[cfg(test)] mod tests { @@ -18,12 +24,12 @@ mod tests { //TODO: use num_traits to do a blanket implementation (selfResult{ + fn try_narrow(self)->Result{ if self{ diff --git a/wide_traits/src/wide.rs b/wide_traits/src/wide.rs new file mode 100644 index 0000000..341aea9 --- /dev/null +++ b/wide_traits/src/wide.rs @@ -0,0 +1,4 @@ +pub trait WideMul{ + type Output; + fn wide_mul(self,rhs:Rhs)->Self::Output; +} From ac5ef8f9be74160ff5c72e1e3733e67bb9026f27 Mon Sep 17 00:00:00 2001 From: Quaternions Date: Mon, 26 Aug 2024 17:07:29 -0700 Subject: [PATCH 031/227] rename fixed_wide::wide to fixed_wide::fixed --- fixed_wide/src/{wide.rs => fixed.rs} | 0 fixed_wide/src/lib.rs | 2 +- fixed_wide/src/types.rs | 8 ++++---- 3 files changed, 5 insertions(+), 5 deletions(-) rename fixed_wide/src/{wide.rs => fixed.rs} (100%) diff --git a/fixed_wide/src/wide.rs b/fixed_wide/src/fixed.rs similarity index 100% rename from fixed_wide/src/wide.rs rename to fixed_wide/src/fixed.rs diff --git a/fixed_wide/src/lib.rs b/fixed_wide/src/lib.rs index 8bdda41..3f00234 100644 --- a/fixed_wide/src/lib.rs +++ b/fixed_wide/src/lib.rs @@ -1,2 +1,2 @@ -pub mod wide; +pub mod fixed; pub mod types; diff --git a/fixed_wide/src/types.rs b/fixed_wide/src/types.rs index 9e0ba24..98cec10 100644 --- a/fixed_wide/src/types.rs +++ b/fixed_wide/src/types.rs @@ -1,4 +1,4 @@ -pub type I32F32=crate::wide::Fixed<1,typenum::consts::U32>; -pub type I64F64=crate::wide::Fixed<2,typenum::consts::U64>; -pub type I128F128=crate::wide::Fixed<4,typenum::consts::U128>; -pub type I256F256=crate::wide::Fixed<8,typenum::consts::U256>; +pub type I32F32=crate::fixed::Fixed<1,typenum::consts::U32>; +pub type I64F64=crate::fixed::Fixed<2,typenum::consts::U64>; +pub type I128F128=crate::fixed::Fixed<4,typenum::consts::U128>; +pub type I256F256=crate::fixed::Fixed<8,typenum::consts::U256>; From fa2b9ca515b49c5504ecd499e918a3293b5b0800 Mon Sep 17 00:00:00 2001 From: Quaternions Date: Mon, 26 Aug 2024 17:28:33 -0700 Subject: [PATCH 032/227] hide wide_traits behind a feature flag --- fixed_wide/Cargo.toml | 6 +++- fixed_wide/src/fixed.rs | 36 ++--------------------- fixed_wide/src/lib.rs | 3 ++ fixed_wide/src/wide_traits.rs | 44 ++++++++++++++++++++++++++++ fixed_wide_vectors/Cargo.toml | 6 +++- fixed_wide_vectors/src/macros/mod.rs | 3 +- 6 files changed, 62 insertions(+), 36 deletions(-) create mode 100644 fixed_wide/src/wide_traits.rs diff --git a/fixed_wide/Cargo.toml b/fixed_wide/Cargo.toml index 86f99f6..dd50704 100644 --- a/fixed_wide/Cargo.toml +++ b/fixed_wide/Cargo.toml @@ -3,7 +3,11 @@ name = "fixed_wide" version = "0.1.0" edition = "2021" +[features] +default=["wide_traits"] +wide_traits=["dep:wide_traits"] + [dependencies] bnum = "0.11.0" typenum = "1.17.0" -wide_traits = { version = "0.1.0", path = "../wide_traits" } +wide_traits = { version = "0.1.0", path = "../wide_traits", optional = true } diff --git a/fixed_wide/src/fixed.rs b/fixed_wide/src/fixed.rs index 0a5140a..8b16620 100644 --- a/fixed_wide/src/fixed.rs +++ b/fixed_wide/src/fixed.rs @@ -1,13 +1,11 @@ -use bnum::cast::As; use bnum::BInt; -use wide_traits::wide::WideMul; -use typenum::{Sum,Unsigned}; +use typenum::Unsigned; use std::marker::PhantomData; #[derive(Clone,Copy,Debug,Hash)] pub struct Fixed{ - bits:BInt<{CHUNKS}>, - frac:PhantomData, + pub(crate)bits:BInt<{CHUNKS}>, + pub(crate)frac:PhantomData, } impl From for Fixed @@ -82,31 +80,3 @@ impl_assign_operator!( Fixed, BitOrAssign, bitor_assign ); impl_operator!( Fixed, BitOr, bitor, Self ); impl_assign_operator!( Fixed, BitXorAssign, bitxor_assign ); impl_operator!( Fixed, BitXor, bitxor, Self ); - -//going wider native -macro_rules! impl_wide_mul { - ($lhs: expr,$rhs: expr) => { - impl WideMul> for Fixed<$lhs,A> - where - A:std::ops::Add, - B:Unsigned, - { - type Output=Fixed<{$lhs+$rhs},Sum>; - fn wide_mul(self,rhs:Fixed<$rhs,B>)->Self::Output{ - Fixed{ - bits:self.bits.as_::>()*rhs.bits.as_::>(), - frac:PhantomData, - } - } - } - }; -} -//const generics sidestepped wahoo -impl_wide_mul!(1,1);impl_wide_mul!(2,1);impl_wide_mul!(3,1);impl_wide_mul!(4,1);impl_wide_mul!(5,1);impl_wide_mul!(6,1);impl_wide_mul!(7,1);impl_wide_mul!(8,1); -impl_wide_mul!(1,2);impl_wide_mul!(2,2);impl_wide_mul!(3,2);impl_wide_mul!(4,2);impl_wide_mul!(5,2);impl_wide_mul!(6,2);impl_wide_mul!(7,2);impl_wide_mul!(8,2); -impl_wide_mul!(1,3);impl_wide_mul!(2,3);impl_wide_mul!(3,3);impl_wide_mul!(4,3);impl_wide_mul!(5,3);impl_wide_mul!(6,3);impl_wide_mul!(7,3);impl_wide_mul!(8,3); -impl_wide_mul!(1,4);impl_wide_mul!(2,4);impl_wide_mul!(3,4);impl_wide_mul!(4,4);impl_wide_mul!(5,4);impl_wide_mul!(6,4);impl_wide_mul!(7,4);impl_wide_mul!(8,4); -impl_wide_mul!(1,5);impl_wide_mul!(2,5);impl_wide_mul!(3,5);impl_wide_mul!(4,5);impl_wide_mul!(5,5);impl_wide_mul!(6,5);impl_wide_mul!(7,5);impl_wide_mul!(8,5); -impl_wide_mul!(1,6);impl_wide_mul!(2,6);impl_wide_mul!(3,6);impl_wide_mul!(4,6);impl_wide_mul!(5,6);impl_wide_mul!(6,6);impl_wide_mul!(7,6);impl_wide_mul!(8,6); -impl_wide_mul!(1,7);impl_wide_mul!(2,7);impl_wide_mul!(3,7);impl_wide_mul!(4,7);impl_wide_mul!(5,7);impl_wide_mul!(6,7);impl_wide_mul!(7,7);impl_wide_mul!(8,7); -impl_wide_mul!(1,8);impl_wide_mul!(2,8);impl_wide_mul!(3,8);impl_wide_mul!(4,8);impl_wide_mul!(5,8);impl_wide_mul!(6,8);impl_wide_mul!(7,8);impl_wide_mul!(8,8); diff --git a/fixed_wide/src/lib.rs b/fixed_wide/src/lib.rs index 3f00234..02c82a7 100644 --- a/fixed_wide/src/lib.rs +++ b/fixed_wide/src/lib.rs @@ -1,2 +1,5 @@ pub mod fixed; pub mod types; + +#[cfg(feature="wide_traits")] +mod wide_traits; diff --git a/fixed_wide/src/wide_traits.rs b/fixed_wide/src/wide_traits.rs new file mode 100644 index 0000000..86bbae4 --- /dev/null +++ b/fixed_wide/src/wide_traits.rs @@ -0,0 +1,44 @@ +use bnum::BInt; +use bnum::cast::As; +use typenum::{Sum,Unsigned}; +use crate::fixed::Fixed; +use wide_traits::wide::WideMul; +use std::marker::PhantomData; + +macro_rules! impl_wide_mul { + ($lhs: expr,$rhs: expr) => { + impl WideMul> for Fixed<$lhs,A> + where + A:std::ops::Add, + B:Unsigned, + { + type Output=Fixed<{$lhs+$rhs},Sum>; + fn wide_mul(self,rhs:Fixed<$rhs,B>)->Self::Output{ + Fixed{ + bits:self.bits.as_::>()*rhs.bits.as_::>(), + frac:PhantomData, + } + } + } + }; +} + +macro_rules! impl_wide_mul_all { + ($(($x:expr, $y:expr)),*) => { + $( + impl_wide_mul!($x, $y); + )* + }; +} + +//const generics sidestepped wahoo +impl_wide_mul_all!( + (1,1),(2,1),(3,1),(4,1),(5,1),(6,1),(7,1),(8,1), + (1,2),(2,2),(3,2),(4,2),(5,2),(6,2),(7,2),(8,2), + (1,3),(2,3),(3,3),(4,3),(5,3),(6,3),(7,3),(8,3), + (1,4),(2,4),(3,4),(4,4),(5,4),(6,4),(7,4),(8,4), + (1,5),(2,5),(3,5),(4,5),(5,5),(6,5),(7,5),(8,5), + (1,6),(2,6),(3,6),(4,6),(5,6),(6,6),(7,6),(8,6), + (1,7),(2,7),(3,7),(4,7),(5,7),(6,7),(7,7),(8,7), + (1,8),(2,8),(3,8),(4,8),(5,8),(6,8),(7,8),(8,8) +); diff --git a/fixed_wide_vectors/Cargo.toml b/fixed_wide_vectors/Cargo.toml index b96d9c1..0241f59 100644 --- a/fixed_wide_vectors/Cargo.toml +++ b/fixed_wide_vectors/Cargo.toml @@ -3,6 +3,10 @@ name = "fixed_wide_vectors" version = "0.1.0" edition = "2021" +[features] +default=["wide_traits"] +wide_traits=["dep:wide_traits"] + [dependencies] fixed_wide = { version = "0.1.0", path = "../fixed_wide" } -wide_traits = { version = "0.1.0", path = "../wide_traits" } +wide_traits = { version = "0.1.0", path = "../wide_traits", optional = true } diff --git a/fixed_wide_vectors/src/macros/mod.rs b/fixed_wide_vectors/src/macros/mod.rs index ffac9aa..314de3c 100644 --- a/fixed_wide_vectors/src/macros/mod.rs +++ b/fixed_wide_vectors/src/macros/mod.rs @@ -1,6 +1,7 @@ -// Stolen from https://github.com/c1m50c/fixed-vectors (MIT license) +#[cfg(feature="wide_traits")] pub mod wide; +// Stolen from https://github.com/c1m50c/fixed-vectors (MIT license) #[doc(hidden)] #[macro_export(local_inner_macros)] macro_rules! impl_vector { From ef13fbe5f0f134b3282464d383614a5d53e44216 Mon Sep 17 00:00:00 2001 From: Quaternions Date: Mon, 26 Aug 2024 17:44:11 -0700 Subject: [PATCH 033/227] fixed_wide is a dev dep --- fixed_wide_vectors/Cargo.toml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/fixed_wide_vectors/Cargo.toml b/fixed_wide_vectors/Cargo.toml index 0241f59..1b76fa9 100644 --- a/fixed_wide_vectors/Cargo.toml +++ b/fixed_wide_vectors/Cargo.toml @@ -8,5 +8,7 @@ default=["wide_traits"] wide_traits=["dep:wide_traits"] [dependencies] -fixed_wide = { version = "0.1.0", path = "../fixed_wide" } wide_traits = { version = "0.1.0", path = "../wide_traits", optional = true } + +[dev-dependencies] +fixed_wide = { version = "0.1.0", path = "../fixed_wide" } From a96cae9e8001ee3cb6d3b27fb735d99381f34375 Mon Sep 17 00:00:00 2001 From: Quaternions Date: Mon, 26 Aug 2024 17:44:49 -0700 Subject: [PATCH 034/227] re-export wide_traits::wide --- fixed_wide/src/lib.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/fixed_wide/src/lib.rs b/fixed_wide/src/lib.rs index 02c82a7..7519abb 100644 --- a/fixed_wide/src/lib.rs +++ b/fixed_wide/src/lib.rs @@ -3,3 +3,5 @@ pub mod types; #[cfg(feature="wide_traits")] mod wide_traits; +#[cfg(feature="wide_traits")] +pub use ::wide_traits::wide; From d48b03889d3ec006a70af5977dfafe25f8d0bdaf Mon Sep 17 00:00:00 2001 From: Quaternions Date: Tue, 27 Aug 2024 12:07:19 -0700 Subject: [PATCH 035/227] rename wide_traits to fixed_wide_traits --- fixed_wide/Cargo.lock | 10 +++++----- fixed_wide/Cargo.toml | 6 +++--- .../src/{wide_traits.rs => fixed_wide_traits.rs} | 2 +- fixed_wide/src/lib.rs | 8 ++++---- {wide_traits => fixed_wide_traits}/.gitignore | 0 {wide_traits => fixed_wide_traits}/Cargo.lock | 16 ++++++++-------- {wide_traits => fixed_wide_traits}/Cargo.toml | 2 +- {wide_traits => fixed_wide_traits}/src/lib.rs | 0 {wide_traits => fixed_wide_traits}/src/narrow.rs | 0 {wide_traits => fixed_wide_traits}/src/wide.rs | 0 fixed_wide_vectors/Cargo.lock | 12 ++++++------ fixed_wide_vectors/Cargo.toml | 6 +++--- fixed_wide_vectors/src/macros/mod.rs | 2 +- fixed_wide_vectors/src/macros/wide.rs | 4 ++-- fixed_wide_vectors/src/tests/mod.rs | 2 +- 15 files changed, 35 insertions(+), 35 deletions(-) rename fixed_wide/src/{wide_traits.rs => fixed_wide_traits.rs} (96%) rename {wide_traits => fixed_wide_traits}/.gitignore (100%) rename {wide_traits => fixed_wide_traits}/Cargo.lock (98%) rename {wide_traits => fixed_wide_traits}/Cargo.toml (81%) rename {wide_traits => fixed_wide_traits}/src/lib.rs (100%) rename {wide_traits => fixed_wide_traits}/src/narrow.rs (100%) rename {wide_traits => fixed_wide_traits}/src/wide.rs (100%) diff --git a/fixed_wide/Cargo.lock b/fixed_wide/Cargo.lock index b181692..c65cd17 100644 --- a/fixed_wide/Cargo.lock +++ b/fixed_wide/Cargo.lock @@ -13,16 +13,16 @@ name = "fixed_wide" version = "0.1.0" dependencies = [ "bnum", + "fixed_wide_traits", "typenum", - "wide_traits", ] +[[package]] +name = "fixed_wide_traits" +version = "0.1.0" + [[package]] name = "typenum" version = "1.17.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825" - -[[package]] -name = "wide_traits" -version = "0.1.0" diff --git a/fixed_wide/Cargo.toml b/fixed_wide/Cargo.toml index dd50704..84206fd 100644 --- a/fixed_wide/Cargo.toml +++ b/fixed_wide/Cargo.toml @@ -4,10 +4,10 @@ version = "0.1.0" edition = "2021" [features] -default=["wide_traits"] -wide_traits=["dep:wide_traits"] +default=["fixed_wide_traits"] +fixed_wide_traits=["dep:fixed_wide_traits"] [dependencies] bnum = "0.11.0" typenum = "1.17.0" -wide_traits = { version = "0.1.0", path = "../wide_traits", optional = true } +fixed_wide_traits = { version = "0.1.0", path = "../fixed_wide_traits", optional = true } diff --git a/fixed_wide/src/wide_traits.rs b/fixed_wide/src/fixed_wide_traits.rs similarity index 96% rename from fixed_wide/src/wide_traits.rs rename to fixed_wide/src/fixed_wide_traits.rs index 86bbae4..efc655e 100644 --- a/fixed_wide/src/wide_traits.rs +++ b/fixed_wide/src/fixed_wide_traits.rs @@ -2,7 +2,7 @@ use bnum::BInt; use bnum::cast::As; use typenum::{Sum,Unsigned}; use crate::fixed::Fixed; -use wide_traits::wide::WideMul; +use fixed_wide_traits::wide::WideMul; use std::marker::PhantomData; macro_rules! impl_wide_mul { diff --git a/fixed_wide/src/lib.rs b/fixed_wide/src/lib.rs index 7519abb..7f8c922 100644 --- a/fixed_wide/src/lib.rs +++ b/fixed_wide/src/lib.rs @@ -1,7 +1,7 @@ pub mod fixed; pub mod types; -#[cfg(feature="wide_traits")] -mod wide_traits; -#[cfg(feature="wide_traits")] -pub use ::wide_traits::wide; +#[cfg(feature="fixed_wide_traits")] +mod fixed_wide_traits; +#[cfg(feature="fixed_wide_traits")] +pub use ::fixed_wide_traits::wide; diff --git a/wide_traits/.gitignore b/fixed_wide_traits/.gitignore similarity index 100% rename from wide_traits/.gitignore rename to fixed_wide_traits/.gitignore diff --git a/wide_traits/Cargo.lock b/fixed_wide_traits/Cargo.lock similarity index 98% rename from wide_traits/Cargo.lock rename to fixed_wide_traits/Cargo.lock index a3a18a8..8ece885 100644 --- a/wide_traits/Cargo.lock +++ b/fixed_wide_traits/Cargo.lock @@ -38,6 +38,14 @@ dependencies = [ "typenum", ] +[[package]] +name = "fixed_wide_traits" +version = "0.1.0" +dependencies = [ + "fixed", + "typenum", +] + [[package]] name = "half" version = "2.4.1" @@ -53,11 +61,3 @@ name = "typenum" version = "1.17.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825" - -[[package]] -name = "wide_traits" -version = "0.1.0" -dependencies = [ - "fixed", - "typenum", -] diff --git a/wide_traits/Cargo.toml b/fixed_wide_traits/Cargo.toml similarity index 81% rename from wide_traits/Cargo.toml rename to fixed_wide_traits/Cargo.toml index 806fb3e..b761c99 100644 --- a/wide_traits/Cargo.toml +++ b/fixed_wide_traits/Cargo.toml @@ -1,5 +1,5 @@ [package] -name = "wide_traits" +name = "fixed_wide_traits" version = "0.1.0" edition = "2021" diff --git a/wide_traits/src/lib.rs b/fixed_wide_traits/src/lib.rs similarity index 100% rename from wide_traits/src/lib.rs rename to fixed_wide_traits/src/lib.rs diff --git a/wide_traits/src/narrow.rs b/fixed_wide_traits/src/narrow.rs similarity index 100% rename from wide_traits/src/narrow.rs rename to fixed_wide_traits/src/narrow.rs diff --git a/wide_traits/src/wide.rs b/fixed_wide_traits/src/wide.rs similarity index 100% rename from wide_traits/src/wide.rs rename to fixed_wide_traits/src/wide.rs diff --git a/fixed_wide_vectors/Cargo.lock b/fixed_wide_vectors/Cargo.lock index 5c9399b..a0a650c 100644 --- a/fixed_wide_vectors/Cargo.lock +++ b/fixed_wide_vectors/Cargo.lock @@ -13,16 +13,20 @@ name = "fixed_wide" version = "0.1.0" dependencies = [ "bnum", + "fixed_wide_traits", "typenum", - "wide_traits", ] +[[package]] +name = "fixed_wide_traits" +version = "0.1.0" + [[package]] name = "fixed_wide_vectors" version = "0.1.0" dependencies = [ "fixed_wide", - "wide_traits", + "fixed_wide_traits", ] [[package]] @@ -30,7 +34,3 @@ name = "typenum" version = "1.17.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825" - -[[package]] -name = "wide_traits" -version = "0.1.0" diff --git a/fixed_wide_vectors/Cargo.toml b/fixed_wide_vectors/Cargo.toml index 1b76fa9..55d64c0 100644 --- a/fixed_wide_vectors/Cargo.toml +++ b/fixed_wide_vectors/Cargo.toml @@ -4,11 +4,11 @@ version = "0.1.0" edition = "2021" [features] -default=["wide_traits"] -wide_traits=["dep:wide_traits"] +default=["fixed_wide_traits"] +fixed_wide_traits=["dep:fixed_wide_traits"] [dependencies] -wide_traits = { version = "0.1.0", path = "../wide_traits", optional = true } +fixed_wide_traits = { version = "0.1.0", path = "../fixed_wide_traits", optional = true } [dev-dependencies] fixed_wide = { version = "0.1.0", path = "../fixed_wide" } diff --git a/fixed_wide_vectors/src/macros/mod.rs b/fixed_wide_vectors/src/macros/mod.rs index 314de3c..0d899e2 100644 --- a/fixed_wide_vectors/src/macros/mod.rs +++ b/fixed_wide_vectors/src/macros/mod.rs @@ -1,4 +1,4 @@ -#[cfg(feature="wide_traits")] +#[cfg(feature="fixed_wide_traits")] pub mod wide; // Stolen from https://github.com/c1m50c/fixed-vectors (MIT license) diff --git a/fixed_wide_vectors/src/macros/wide.rs b/fixed_wide_vectors/src/macros/wide.rs index 434d383..c2c9c59 100644 --- a/fixed_wide_vectors/src/macros/wide.rs +++ b/fixed_wide_vectors/src/macros/wide.rs @@ -2,7 +2,7 @@ #[macro_export(local_inner_macros)] macro_rules! impl_wide_operations { ( $struct: ident { $($field: ident), + }, $size: expr ) => { - impl> wide_traits::wide::WideMul for $struct { + impl> fixed_wide_traits::wide::WideMul for $struct { type Output=$struct; #[inline] fn wide_mul(self, rhs: Self) -> Self::Output { @@ -11,7 +11,7 @@ macro_rules! impl_wide_operations { } } } - impl,T:Copy+wide_traits::wide::WideMul> $struct { + impl,T:Copy+fixed_wide_traits::wide::WideMul> $struct { #[inline] pub fn wide_dot(self, other: Self) -> U { $crate::sum_repeating!( diff --git a/fixed_wide_vectors/src/tests/mod.rs b/fixed_wide_vectors/src/tests/mod.rs index b48a11c..24bf782 100644 --- a/fixed_wide_vectors/src/tests/mod.rs +++ b/fixed_wide_vectors/src/tests/mod.rs @@ -1,4 +1,4 @@ -use wide_traits::wide::WideMul; +use fixed_wide_traits::wide::WideMul; use crate::Vector3; From a097e3945f06ab891b71058555bcc9d076678d82 Mon Sep 17 00:00:00 2001 From: Quaternions Date: Tue, 27 Aug 2024 13:28:45 -0700 Subject: [PATCH 036/227] more traits --- fixed_wide_traits/src/wide.rs | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/fixed_wide_traits/src/wide.rs b/fixed_wide_traits/src/wide.rs index 341aea9..dfb7b15 100644 --- a/fixed_wide_traits/src/wide.rs +++ b/fixed_wide_traits/src/wide.rs @@ -2,3 +2,15 @@ pub trait WideMul{ type Output; fn wide_mul(self,rhs:Rhs)->Self::Output; } +pub trait WideDiv{ + type Output; + fn wide_div(self,rhs:Rhs)->Self::Output; +} +pub trait WideDot{ + type Output; + fn wide_dot(self,rhs:Rhs)->Self::Output; +} +pub trait WideCross{ + type Output; + fn wide_cross(self,rhs:Rhs)->Self::Output; +} From 047451d247dd8d2615326064e17bbc050402cddf Mon Sep 17 00:00:00 2001 From: Quaternions Date: Tue, 27 Aug 2024 14:23:20 -0700 Subject: [PATCH 037/227] affine --- fixed_wide_vectors/src/affine.rs | 17 +++++++++++++++++ fixed_wide_vectors/src/lib.rs | 3 +++ 2 files changed, 20 insertions(+) create mode 100644 fixed_wide_vectors/src/affine.rs diff --git a/fixed_wide_vectors/src/affine.rs b/fixed_wide_vectors/src/affine.rs new file mode 100644 index 0000000..74ba207 --- /dev/null +++ b/fixed_wide_vectors/src/affine.rs @@ -0,0 +1,17 @@ +use std::ops::Add; +use fixed_wide_traits::wide::WideDot; + +pub struct Affine{ + pub matrix:M, + pub offset:T, +} + +impl Affine{ + pub fn wide_transform(&self,input:X)-><>::Output as Add>::Output + where + M:WideDot, + >::Output:Add, + { + self.matrix.wide_dot(input)+self.offset + } +} diff --git a/fixed_wide_vectors/src/lib.rs b/fixed_wide_vectors/src/lib.rs index 775c4e6..2dc585f 100644 --- a/fixed_wide_vectors/src/lib.rs +++ b/fixed_wide_vectors/src/lib.rs @@ -1,6 +1,9 @@ mod macros; mod vector; +#[cfg(feature="fixed_wide_traits")] +pub mod affine; + pub use vector::Vector2; pub use vector::Vector3; pub use vector::Vector4; From 4ce5c045a805d46ad0430ac6551020684bd31084 Mon Sep 17 00:00:00 2001 From: Quaternions Date: Tue, 27 Aug 2024 14:23:38 -0700 Subject: [PATCH 038/227] fixed: PartialOrd, Ord --- fixed_wide/src/fixed.rs | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/fixed_wide/src/fixed.rs b/fixed_wide/src/fixed.rs index 8b16620..fdda80a 100644 --- a/fixed_wide/src/fixed.rs +++ b/fixed_wide/src/fixed.rs @@ -27,6 +27,17 @@ impl PartialEq for Fixed{ } impl Eq for Fixed{} +impl PartialOrd for Fixed{ + fn partial_cmp(&self,other:&Self)->Option{ + self.bits.partial_cmp(&other.bits) + } +} +impl Ord for Fixed{ + fn cmp(&self,other:&Self)->std::cmp::Ordering{ + self.bits.cmp(&other.bits) + } +} + impl std::ops::Neg for Fixed{ type Output=Self; fn neg(self)->Self{ From 2d87e4b5cca34d078100201e8b720666ec928e06 Mon Sep 17 00:00:00 2001 From: Quaternions Date: Tue, 27 Aug 2024 14:23:53 -0700 Subject: [PATCH 039/227] vectors: min, max --- fixed_wide_vectors/src/macros/mod.rs | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/fixed_wide_vectors/src/macros/mod.rs b/fixed_wide_vectors/src/macros/mod.rs index 0d899e2..caedc19 100644 --- a/fixed_wide_vectors/src/macros/mod.rs +++ b/fixed_wide_vectors/src/macros/mod.rs @@ -166,6 +166,19 @@ macro_rules! impl_vector { } } + impl $struct { + pub fn min(self, rhs: Self) -> $struct { + $struct{ + $( $field: self.$field.min(rhs.$field) ), + + } + } + pub fn max(self, rhs: Self) -> $struct { + $struct{ + $( $field: self.$field.max(rhs.$field) ), + + } + } + } + impl> core::ops::Neg for $struct { type Output = Self; From 009aa0c296d6d23d0085fe4a0adc371b88543a81 Mon Sep 17 00:00:00 2001 From: Quaternions Date: Tue, 27 Aug 2024 13:28:53 -0700 Subject: [PATCH 040/227] ratio crate --- deferred_division/.gitignore | 1 + deferred_division/Cargo.lock | 14 ++++++++++ deferred_division/Cargo.toml | 11 ++++++++ deferred_division/src/lib.rs | 8 ++++++ deferred_division/src/ratio.rs | 10 +++++++ deferred_division/src/wide.rs | 51 ++++++++++++++++++++++++++++++++++ 6 files changed, 95 insertions(+) create mode 100644 deferred_division/.gitignore create mode 100644 deferred_division/Cargo.lock create mode 100644 deferred_division/Cargo.toml create mode 100644 deferred_division/src/lib.rs create mode 100644 deferred_division/src/ratio.rs create mode 100644 deferred_division/src/wide.rs diff --git a/deferred_division/.gitignore b/deferred_division/.gitignore new file mode 100644 index 0000000..ea8c4bf --- /dev/null +++ b/deferred_division/.gitignore @@ -0,0 +1 @@ +/target diff --git a/deferred_division/Cargo.lock b/deferred_division/Cargo.lock new file mode 100644 index 0000000..973fcc1 --- /dev/null +++ b/deferred_division/Cargo.lock @@ -0,0 +1,14 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "deferred_division" +version = "0.1.0" +dependencies = [ + "fixed_wide_traits", +] + +[[package]] +name = "fixed_wide_traits" +version = "0.1.0" diff --git a/deferred_division/Cargo.toml b/deferred_division/Cargo.toml new file mode 100644 index 0000000..73eafc4 --- /dev/null +++ b/deferred_division/Cargo.toml @@ -0,0 +1,11 @@ +[package] +name = "deferred_division" +version = "0.1.0" +edition = "2021" + +[features] +default=["fixed_wide_traits"] +fixed_wide_traits=["dep:fixed_wide_traits"] + +[dependencies] +fixed_wide_traits = { version = "0.1.0", path = "../fixed_wide_traits", optional = true } diff --git a/deferred_division/src/lib.rs b/deferred_division/src/lib.rs new file mode 100644 index 0000000..86c9a9d --- /dev/null +++ b/deferred_division/src/lib.rs @@ -0,0 +1,8 @@ +pub mod ratio; + + +#[cfg(feature="fixed_wide_traits")] +mod wide; + +#[cfg(test)] +mod tests; diff --git a/deferred_division/src/ratio.rs b/deferred_division/src/ratio.rs new file mode 100644 index 0000000..a6bd02d --- /dev/null +++ b/deferred_division/src/ratio.rs @@ -0,0 +1,10 @@ +#[derive(Clone,Copy,Debug,Hash)] +pub struct Ratio{ + pub(crate)num:Num, + pub(crate)den:Den, +} +//this trait is like a constructor for Ratio +pub trait DeferredDiv{ + type Output; + fn deferred_div(self,rhs:Rhs)->Self::Output; +} diff --git a/deferred_division/src/wide.rs b/deferred_division/src/wide.rs new file mode 100644 index 0000000..df7dcae --- /dev/null +++ b/deferred_division/src/wide.rs @@ -0,0 +1,51 @@ +use std::ops::{Add,Mul}; +use crate::ratio::Ratio; +use fixed_wide_traits::wide::{WideMul,WideDiv}; + +impl Ratio +{ + pub fn rational_add(self,rhs:T)->Ratio<>::Output>>::Output,Den> + where + Den:Mul, + Num:Add<>::Output>, + { + Ratio{ + num:self.num+self.den.mul(rhs), + den:self.den, + } + } + pub fn wide_rational_add(self,rhs:T)->Ratio<>::Output>>::Output,Den> + where + Den:WideMul, + Num:Add<>::Output>, + { + Ratio{ + num:self.num+self.den.wide_mul(rhs), + den:self.den, + } + } +} +impl WideMul for Ratio + where + Num:WideMul, +{ + type Output=Ratio<>::Output,Den>; + fn wide_mul(self,rhs:T)->Ratio<>::Output,Den>{ + Ratio{ + num:self.num.wide_mul(rhs), + den:self.den, + } + } +} +impl WideDiv for Ratio + where + Den:WideMul, +{ + type Output=Ratio>::Output>; + fn wide_div(self,rhs:T)->Ratio>::Output>{ + Ratio{ + num:self.num, + den:self.den.wide_mul(rhs), + } + } +} From 7a5406e769f4c3a5f7a75f37964b1bc6cc22accc Mon Sep 17 00:00:00 2001 From: Quaternions Date: Tue, 27 Aug 2024 14:58:20 -0700 Subject: [PATCH 041/227] fixed: fixup operator impls - this is implicitly Self --- fixed_wide/src/fixed.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/fixed_wide/src/fixed.rs b/fixed_wide/src/fixed.rs index fdda80a..1efe378 100644 --- a/fixed_wide/src/fixed.rs +++ b/fixed_wide/src/fixed.rs @@ -50,7 +50,7 @@ impl std::ops::Neg for Fixed{ macro_rules! impl_operator { ( $struct: ident, $trait: ident, $method: ident, $output: ty ) => { - impl core::ops::$trait<$struct> for $struct{ + impl core::ops::$trait for $struct{ type Output = $output; fn $method(self, other: Self) -> Self::Output { @@ -64,7 +64,7 @@ macro_rules! impl_operator { } macro_rules! impl_assign_operator { ( $struct: ident, $trait: ident, $method: ident ) => { - impl core::ops::$trait<$struct> for $struct{ + impl core::ops::$trait for $struct{ fn $method(&mut self, other: Self) { self.bits.$method(other.bits); } From 79ab26f1189615fae69d22c816d458fe4a17bca0 Mon Sep 17 00:00:00 2001 From: Quaternions Date: Tue, 27 Aug 2024 14:58:32 -0700 Subject: [PATCH 042/227] fixed: implement shift operators --- fixed_wide/src/fixed.rs | 28 ++++++++++++++++++++++++++++ fixed_wide_vectors/src/tests/mod.rs | 6 ++++++ 2 files changed, 34 insertions(+) diff --git a/fixed_wide/src/fixed.rs b/fixed_wide/src/fixed.rs index 1efe378..5f72a47 100644 --- a/fixed_wide/src/fixed.rs +++ b/fixed_wide/src/fixed.rs @@ -91,3 +91,31 @@ impl_assign_operator!( Fixed, BitOrAssign, bitor_assign ); impl_operator!( Fixed, BitOr, bitor, Self ); impl_assign_operator!( Fixed, BitXorAssign, bitxor_assign ); impl_operator!( Fixed, BitXor, bitxor, Self ); + +macro_rules! impl_shift_operator { + ( $struct: ident, $trait: ident, $method: ident, $output: ty ) => { + impl core::ops::$trait for $struct{ + type Output = $output; + + fn $method(self, other: u32) -> Self::Output { + Self { + bits:self.bits.$method(other), + frac:PhantomData, + } + } + } + }; +} +macro_rules! impl_shift_assign_operator { + ( $struct: ident, $trait: ident, $method: ident ) => { + impl core::ops::$trait for $struct{ + fn $method(&mut self, other: u32) { + self.bits.$method(other); + } + } + }; +} +impl_shift_assign_operator!( Fixed, ShlAssign, shl_assign ); +impl_shift_operator!( Fixed, Shl, shl, Self ); +impl_shift_assign_operator!( Fixed, ShrAssign, shr_assign ); +impl_shift_operator!( Fixed, Shr, shr, Self ); diff --git a/fixed_wide_vectors/src/tests/mod.rs b/fixed_wide_vectors/src/tests/mod.rs index 24bf782..426d018 100644 --- a/fixed_wide_vectors/src/tests/mod.rs +++ b/fixed_wide_vectors/src/tests/mod.rs @@ -25,6 +25,12 @@ fn you_can_add_numbers(){ assert_eq!(a+a,Planar64Wide3::from((3i128*2).pow(4)*2)) } +#[test] +fn you_can_shr_numbers(){ + let a=Planar64::from(4); + assert_eq!(a>>1,Planar64::from(2)) +} + #[test] fn wide_vec3(){ let v=Vector3::from_value(Planar64::from(3)); From 60753490c67ab97868761095e1e41765c4d7e559 Mon Sep 17 00:00:00 2001 From: Quaternions Date: Tue, 27 Aug 2024 14:59:29 -0700 Subject: [PATCH 043/227] vectors: implement Ord stuff as vectors of boolean --- fixed_wide_vectors/src/macros/mod.rs | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/fixed_wide_vectors/src/macros/mod.rs b/fixed_wide_vectors/src/macros/mod.rs index caedc19..0d9be65 100644 --- a/fixed_wide_vectors/src/macros/mod.rs +++ b/fixed_wide_vectors/src/macros/mod.rs @@ -177,6 +177,31 @@ macro_rules! impl_vector { $( $field: self.$field.max(rhs.$field) ), + } } + pub fn cmp(self, rhs: Self) -> $struct { + $struct{ + $( $field: self.$field.cmp(&rhs.$field) ), + + } + } + pub fn lt(self, rhs: Self) -> $struct { + $struct{ + $( $field: self.$field.lt(&rhs.$field) ), + + } + } + pub fn gt(self, rhs: Self) -> $struct { + $struct{ + $( $field: self.$field.gt(&rhs.$field) ), + + } + } + pub fn ge(self, rhs: Self) -> $struct { + $struct{ + $( $field: self.$field.ge(&rhs.$field) ), + + } + } + pub fn le(self, rhs: Self) -> $struct { + $struct{ + $( $field: self.$field.le(&rhs.$field) ), + + } + } } impl> core::ops::Neg for $struct { From 20a317612ed8c80eb315bcfd3579bcfc2f13e99d Mon Sep 17 00:00:00 2001 From: Quaternions Date: Tue, 27 Aug 2024 16:49:49 -0700 Subject: [PATCH 044/227] fixed: constants --- fixed_wide/src/fixed.rs | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/fixed_wide/src/fixed.rs b/fixed_wide/src/fixed.rs index 5f72a47..ab18621 100644 --- a/fixed_wide/src/fixed.rs +++ b/fixed_wide/src/fixed.rs @@ -8,6 +8,12 @@ pub struct Fixed{ pub(crate)frac:PhantomData, } +impl Fixed{ + pub const ZERO:Self=Self{bits:BInt::::ZERO,frac:PhantomData}; + pub const ONE:Self=Self{bits:BInt::::ONE.shl(Frac::U32),frac:PhantomData}; + pub const NEG_ONE:Self=Self{bits:BInt::::NEG_ONE.shl(Frac::U32),frac:PhantomData}; +} + impl From for Fixed where BInt:From From c43fab2f18643e16530d2ea2d2bc0bdbf4e91949 Mon Sep 17 00:00:00 2001 From: Quaternions Date: Tue, 27 Aug 2024 16:50:24 -0700 Subject: [PATCH 045/227] reexport typenum for convenience --- fixed_wide/src/lib.rs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/fixed_wide/src/lib.rs b/fixed_wide/src/lib.rs index 7f8c922..4d35f29 100644 --- a/fixed_wide/src/lib.rs +++ b/fixed_wide/src/lib.rs @@ -1,6 +1,10 @@ pub mod fixed; pub mod types; +pub mod typenum{ + pub use typenum::Unsigned; +} + #[cfg(feature="fixed_wide_traits")] mod fixed_wide_traits; #[cfg(feature="fixed_wide_traits")] From 4ae391e9fd9c581cc2982cf747107a292a571bae Mon Sep 17 00:00:00 2001 From: Quaternions Date: Wed, 28 Aug 2024 09:06:16 -0700 Subject: [PATCH 046/227] trait constructor doesn't work because trait bounds (and is also bad) --- deferred_division/src/ratio.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/deferred_division/src/ratio.rs b/deferred_division/src/ratio.rs index a6bd02d..6ae0ad2 100644 --- a/deferred_division/src/ratio.rs +++ b/deferred_division/src/ratio.rs @@ -3,8 +3,8 @@ pub struct Ratio{ pub(crate)num:Num, pub(crate)den:Den, } -//this trait is like a constructor for Ratio -pub trait DeferredDiv{ - type Output; - fn deferred_div(self,rhs:Rhs)->Self::Output; +impl Ratio{ + pub const fn new(num:Num,den:Den)->Self{ + Self{num,den} + } } From e1368962c1589cf7fad19bbdd6a32ac1b03cf350 Mon Sep 17 00:00:00 2001 From: Quaternions Date: Wed, 28 Aug 2024 10:04:58 -0700 Subject: [PATCH 047/227] holy wide dot batman --- fixed_wide_vectors/src/macros/wide.rs | 14 +++++++++----- fixed_wide_vectors/src/tests/mod.rs | 1 + 2 files changed, 10 insertions(+), 5 deletions(-) diff --git a/fixed_wide_vectors/src/macros/wide.rs b/fixed_wide_vectors/src/macros/wide.rs index c2c9c59..ea5f6c3 100644 --- a/fixed_wide_vectors/src/macros/wide.rs +++ b/fixed_wide_vectors/src/macros/wide.rs @@ -11,13 +11,17 @@ macro_rules! impl_wide_operations { } } } + impl,U,T:fixed_wide_traits::wide::WideMul> fixed_wide_traits::wide::WideDot<$struct> for $struct { + type Output=V; + #[inline] + fn wide_dot(self, rhs: $struct) -> Self::Output { + $crate::sum_repeating!( + $( + (self.$field.wide_mul(rhs.$field)) ) + + ) + } + } impl,T:Copy+fixed_wide_traits::wide::WideMul> $struct { #[inline] - pub fn wide_dot(self, other: Self) -> U { - $crate::sum_repeating!( - $( + (self.$field.wide_mul(other.$field)) ) + - ) - } pub fn wide_length_squared(&self) -> U { let squared = $struct { $( $field: self.$field.wide_mul(self.$field) ), + diff --git a/fixed_wide_vectors/src/tests/mod.rs b/fixed_wide_vectors/src/tests/mod.rs index 426d018..7a5deb2 100644 --- a/fixed_wide_vectors/src/tests/mod.rs +++ b/fixed_wide_vectors/src/tests/mod.rs @@ -1,4 +1,5 @@ use fixed_wide_traits::wide::WideMul; +use fixed_wide_traits::wide::WideDot; use crate::Vector3; From 002d3d9eac022a1e01074e79a2b1d1e65f839a83 Mon Sep 17 00:00:00 2001 From: Quaternions Date: Wed, 28 Aug 2024 10:05:08 -0700 Subject: [PATCH 048/227] why intermediate --- fixed_wide_vectors/src/macros/wide.rs | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/fixed_wide_vectors/src/macros/wide.rs b/fixed_wide_vectors/src/macros/wide.rs index ea5f6c3..01da30b 100644 --- a/fixed_wide_vectors/src/macros/wide.rs +++ b/fixed_wide_vectors/src/macros/wide.rs @@ -23,12 +23,8 @@ macro_rules! impl_wide_operations { impl,T:Copy+fixed_wide_traits::wide::WideMul> $struct { #[inline] pub fn wide_length_squared(&self) -> U { - let squared = $struct { - $( $field: self.$field.wide_mul(self.$field) ), + - }; - $crate::sum_repeating!( - $( + squared.$field ) + + $( + self.$field.wide_mul(self.$field) ) + ) } } From 67ac4cf7ff165557bd34e5256e9cf30fa4304910 Mon Sep 17 00:00:00 2001 From: Quaternions Date: Wed, 28 Aug 2024 10:14:49 -0700 Subject: [PATCH 049/227] todo: drop affine --- fixed_wide_vectors/src/affine.rs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/fixed_wide_vectors/src/affine.rs b/fixed_wide_vectors/src/affine.rs index 74ba207..f1d3fc3 100644 --- a/fixed_wide_vectors/src/affine.rs +++ b/fixed_wide_vectors/src/affine.rs @@ -1,6 +1,9 @@ use std::ops::Add; use fixed_wide_traits::wide::WideDot; +//TODO: replace this with 4x3 matrix +// mat4x3.wide_dot(vec3.extend(1)) + pub struct Affine{ pub matrix:M, pub offset:T, From f4ab9403a4c27e9b8a4f8f2ca238b25e819a5571 Mon Sep 17 00:00:00 2001 From: Quaternions Date: Wed, 28 Aug 2024 10:47:30 -0700 Subject: [PATCH 050/227] oh my god use tabs --- fixed_wide_vectors/src/affine.rs | 4 +- fixed_wide_vectors/src/macros/mod.rs | 480 +++++++++++++------------- fixed_wide_vectors/src/macros/wide.rs | 44 +-- fixed_wide_vectors/src/vector.rs | 18 +- 4 files changed, 273 insertions(+), 273 deletions(-) diff --git a/fixed_wide_vectors/src/affine.rs b/fixed_wide_vectors/src/affine.rs index f1d3fc3..d4bcc00 100644 --- a/fixed_wide_vectors/src/affine.rs +++ b/fixed_wide_vectors/src/affine.rs @@ -5,8 +5,8 @@ use fixed_wide_traits::wide::WideDot; // mat4x3.wide_dot(vec3.extend(1)) pub struct Affine{ - pub matrix:M, - pub offset:T, + pub matrix:M, + pub offset:T, } impl Affine{ diff --git a/fixed_wide_vectors/src/macros/mod.rs b/fixed_wide_vectors/src/macros/mod.rs index 0d9be65..4cf9651 100644 --- a/fixed_wide_vectors/src/macros/mod.rs +++ b/fixed_wide_vectors/src/macros/mod.rs @@ -5,277 +5,277 @@ pub mod wide; #[doc(hidden)] #[macro_export(local_inner_macros)] macro_rules! impl_vector { - ( $struct: ident { $($field: ident), + }, ( $($generic: ident), + ), $size: expr ) => { - impl $struct { - /// Constructs a new vector with the specified values for each field. - /// - /// # Example - /// - /// ``` - /// use fixed_wide_vectors::Vector2; - /// - /// let vec2 = Vector2::new(0, 0); - /// - /// assert_eq!(vec2.x, 0); - /// assert_eq!(vec2.y, 0); - /// ``` - #[inline(always)] - pub const fn new( $($field: T), + ) -> Self { - Self { - $( $field ), + - } - } + ( $struct: ident { $($field: ident), + }, ( $($generic: ident), + ), $size: expr ) => { + impl $struct { + /// Constructs a new vector with the specified values for each field. + /// + /// # Example + /// + /// ``` + /// use fixed_wide_vectors::Vector2; + /// + /// let vec2 = Vector2::new(0, 0); + /// + /// assert_eq!(vec2.x, 0); + /// assert_eq!(vec2.y, 0); + /// ``` + #[inline(always)] + pub const fn new( $($field: T), + ) -> Self { + Self { + $( $field ), + + } + } - /// Consumes the vector and returns its values as an array. - /// - /// # Example - /// - /// ``` - /// use fixed_wide_vectors::Vector2; - /// - /// let vec2 = Vector2::new(0, 0); - /// let array = vec2.to_array(); - /// - /// assert_eq!(array, [0, 0]); - /// ``` - #[inline(always)] - pub fn to_array(self) -> [T; $size] { - [ $(self.$field), + ] - } + /// Consumes the vector and returns its values as an array. + /// + /// # Example + /// + /// ``` + /// use fixed_wide_vectors::Vector2; + /// + /// let vec2 = Vector2::new(0, 0); + /// let array = vec2.to_array(); + /// + /// assert_eq!(array, [0, 0]); + /// ``` + #[inline(always)] + pub fn to_array(self) -> [T; $size] { + [ $(self.$field), + ] + } - /// Consumes the vector and returns its values as a tuple. - /// - /// # Example - /// - /// ``` - /// use fixed_wide_vectors::Vector2; - /// - /// let vec2 = Vector2::new(0, 0); - /// let tuple = vec2.to_tuple(); - /// - /// assert_eq!(tuple, (0, 0)); - /// ``` - #[inline(always)] - pub fn to_tuple(self) -> ( $($generic), + ) { - ( $(self.$field), + ) - } + /// Consumes the vector and returns its values as a tuple. + /// + /// # Example + /// + /// ``` + /// use fixed_wide_vectors::Vector2; + /// + /// let vec2 = Vector2::new(0, 0); + /// let tuple = vec2.to_tuple(); + /// + /// assert_eq!(tuple, (0, 0)); + /// ``` + #[inline(always)] + pub fn to_tuple(self) -> ( $($generic), + ) { + ( $(self.$field), + ) + } - /// Consumes the vector and returns a new vector with the given function applied on each field. - /// - /// # Example - /// - /// ``` - /// use fixed_wide_vectors::Vector2; - /// - /// let vec2 = Vector2::new(1, 2) - /// .map(|i| i * 2); - /// - /// assert_eq!(vec2, Vector2::new(2, 4)); - /// ``` - #[inline] - pub fn map(self, f: F) -> $struct - where - F: Fn(T) -> U - { - $struct { - $( $field: f(self.$field) ), + - } - } - } + /// Consumes the vector and returns a new vector with the given function applied on each field. + /// + /// # Example + /// + /// ``` + /// use fixed_wide_vectors::Vector2; + /// + /// let vec2 = Vector2::new(1, 2) + /// .map(|i| i * 2); + /// + /// assert_eq!(vec2, Vector2::new(2, 4)); + /// ``` + #[inline] + pub fn map(self, f: F) -> $struct + where + F: Fn(T) -> U + { + $struct { + $( $field: f(self.$field) ), + + } + } + } - impl $struct { - /// Constructs a vector using the given `value` as the value for all of its fields. - /// - /// # Example - /// - /// ``` - /// use fixed_wide_vectors::Vector2; - /// - /// let vec2 = Vector2::from_value(0); - /// - /// assert_eq!(vec2, Vector2::new(0, 0)); - /// ``` - #[inline(always)] - pub const fn from_value(value: T) -> Self { - Self { - $( $field: value ), + - } - } - } + impl $struct { + /// Constructs a vector using the given `value` as the value for all of its fields. + /// + /// # Example + /// + /// ``` + /// use fixed_wide_vectors::Vector2; + /// + /// let vec2 = Vector2::from_value(0); + /// + /// assert_eq!(vec2, Vector2::new(0, 0)); + /// ``` + #[inline(always)] + pub const fn from_value(value: T) -> Self { + Self { + $( $field: value ), + + } + } + } - impl From<[T; $size]> for $struct { - fn from(from: [T; $size]) -> Self { - let mut iterator = from.into_iter(); + impl From<[T; $size]> for $struct { + fn from(from: [T; $size]) -> Self { + let mut iterator = from.into_iter(); - Self { - // SAFETY: We know the size of `from` so `iterator.next()` is always `Some(..)` - $( $field: unsafe { iterator.next().unwrap_unchecked() } ), + - } - } - } + Self { + // SAFETY: We know the size of `from` so `iterator.next()` is always `Some(..)` + $( $field: unsafe { iterator.next().unwrap_unchecked() } ), + + } + } + } - impl From<($($generic), +)> for $struct { - fn from(from: ($($generic), +)) -> Self { - let ( $($field), + ) = from; + impl From<($($generic), +)> for $struct { + fn from(from: ($($generic), +)) -> Self { + let ( $($field), + ) = from; - Self { - $( $field ), + - } - } - } + Self { + $( $field ), + + } + } + } - impl core::fmt::Debug for $struct { - fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { - let identifier = core::stringify!($struct); + impl core::fmt::Debug for $struct { + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { + let identifier = core::stringify!($struct); - f.debug_struct(identifier) - $( .field( core::stringify!($field), &self.$field ) ) + - .finish() - } - } + f.debug_struct(identifier) + $( .field( core::stringify!($field), &self.$field ) ) + + .finish() + } + } - impl PartialEq for $struct { - fn eq(&self, other: &Self) -> bool { - $( self.$field == other.$field ) && + - } - } + impl PartialEq for $struct { + fn eq(&self, other: &Self) -> bool { + $( self.$field == other.$field ) && + + } + } - impl Eq for $struct { } + impl Eq for $struct { } - impl core::hash::Hash for $struct { - fn hash(&self, state: &mut H) { - $( self.$field.hash(state); ) + - } - } + impl core::hash::Hash for $struct { + fn hash(&self, state: &mut H) { + $( self.$field.hash(state); ) + + } + } - impl Clone for $struct { - fn clone(&self) -> Self { - Self { - $( $field: self.$field.clone() ), + - } - } - } + impl Clone for $struct { + fn clone(&self) -> Self { + Self { + $( $field: self.$field.clone() ), + + } + } + } - impl Copy for $struct { } + impl Copy for $struct { } - impl Default for $struct { - fn default() -> Self { - Self { - $( $field: T::default() ), + - } - } - } + impl Default for $struct { + fn default() -> Self { + Self { + $( $field: T::default() ), + + } + } + } - impl $struct { - pub fn min(self, rhs: Self) -> $struct { - $struct{ - $( $field: self.$field.min(rhs.$field) ), + - } - } - pub fn max(self, rhs: Self) -> $struct { - $struct{ - $( $field: self.$field.max(rhs.$field) ), + - } - } - pub fn cmp(self, rhs: Self) -> $struct { - $struct{ - $( $field: self.$field.cmp(&rhs.$field) ), + - } - } - pub fn lt(self, rhs: Self) -> $struct { - $struct{ - $( $field: self.$field.lt(&rhs.$field) ), + - } - } - pub fn gt(self, rhs: Self) -> $struct { - $struct{ - $( $field: self.$field.gt(&rhs.$field) ), + - } - } - pub fn ge(self, rhs: Self) -> $struct { - $struct{ - $( $field: self.$field.ge(&rhs.$field) ), + - } - } - pub fn le(self, rhs: Self) -> $struct { - $struct{ - $( $field: self.$field.le(&rhs.$field) ), + - } - } - } + impl $struct { + pub fn min(self, rhs: Self) -> $struct { + $struct{ + $( $field: self.$field.min(rhs.$field) ), + + } + } + pub fn max(self, rhs: Self) -> $struct { + $struct{ + $( $field: self.$field.max(rhs.$field) ), + + } + } + pub fn cmp(self, rhs: Self) -> $struct { + $struct{ + $( $field: self.$field.cmp(&rhs.$field) ), + + } + } + pub fn lt(self, rhs: Self) -> $struct { + $struct{ + $( $field: self.$field.lt(&rhs.$field) ), + + } + } + pub fn gt(self, rhs: Self) -> $struct { + $struct{ + $( $field: self.$field.gt(&rhs.$field) ), + + } + } + pub fn ge(self, rhs: Self) -> $struct { + $struct{ + $( $field: self.$field.ge(&rhs.$field) ), + + } + } + pub fn le(self, rhs: Self) -> $struct { + $struct{ + $( $field: self.$field.le(&rhs.$field) ), + + } + } + } - impl> core::ops::Neg for $struct { - type Output = Self; + impl> core::ops::Neg for $struct { + type Output = Self; - fn neg(self) -> Self::Output { - Self { - $( $field: -self.$field ), + - } - } - } + fn neg(self) -> Self::Output { + Self { + $( $field: -self.$field ), + + } + } + } - // Impl arithmetic pperators - $crate::impl_operator!( $struct { $($field), + }, AddAssign, add_assign ); - $crate::impl_operator!( $struct { $($field), + }, Add, add, Self ); - $crate::impl_operator!( $struct { $($field), + }, SubAssign, sub_assign ); - $crate::impl_operator!( $struct { $($field), + }, Sub, sub, Self ); - $crate::impl_operator!( $struct { $($field), + }, MulAssign, mul_assign ); - $crate::impl_operator!( $struct { $($field), + }, Mul, mul, Self ); - $crate::impl_operator!( $struct { $($field), + }, DivAssign, div_assign ); - $crate::impl_operator!( $struct { $($field), + }, Div, div, Self ); - $crate::impl_operator!( $struct { $($field), + }, RemAssign, rem_assign ); - $crate::impl_operator!( $struct { $($field), + }, Rem, rem, Self ); + // Impl arithmetic pperators + $crate::impl_operator!( $struct { $($field), + }, AddAssign, add_assign ); + $crate::impl_operator!( $struct { $($field), + }, Add, add, Self ); + $crate::impl_operator!( $struct { $($field), + }, SubAssign, sub_assign ); + $crate::impl_operator!( $struct { $($field), + }, Sub, sub, Self ); + $crate::impl_operator!( $struct { $($field), + }, MulAssign, mul_assign ); + $crate::impl_operator!( $struct { $($field), + }, Mul, mul, Self ); + $crate::impl_operator!( $struct { $($field), + }, DivAssign, div_assign ); + $crate::impl_operator!( $struct { $($field), + }, Div, div, Self ); + $crate::impl_operator!( $struct { $($field), + }, RemAssign, rem_assign ); + $crate::impl_operator!( $struct { $($field), + }, Rem, rem, Self ); - // Impl bitwise operators - $crate::impl_operator!( $struct { $($field), + }, BitAndAssign, bitand_assign ); - $crate::impl_operator!( $struct { $($field), + }, BitAnd, bitand, Self ); - $crate::impl_operator!( $struct { $($field), + }, BitOrAssign, bitor_assign ); - $crate::impl_operator!( $struct { $($field), + }, BitOr, bitor, Self ); - $crate::impl_operator!( $struct { $($field), + }, BitXorAssign, bitxor_assign ); - $crate::impl_operator!( $struct { $($field), + }, BitXor, bitxor, Self ); + // Impl bitwise operators + $crate::impl_operator!( $struct { $($field), + }, BitAndAssign, bitand_assign ); + $crate::impl_operator!( $struct { $($field), + }, BitAnd, bitand, Self ); + $crate::impl_operator!( $struct { $($field), + }, BitOrAssign, bitor_assign ); + $crate::impl_operator!( $struct { $($field), + }, BitOr, bitor, Self ); + $crate::impl_operator!( $struct { $($field), + }, BitXorAssign, bitxor_assign ); + $crate::impl_operator!( $struct { $($field), + }, BitXor, bitxor, Self ); - // Impl floating-point based methods - $crate::impl_wide_operations!( $struct { $($field), + }, $size ); - }; + // Impl floating-point based methods + $crate::impl_wide_operations!( $struct { $($field), + }, $size ); + }; } #[doc(hidden)] #[macro_export(local_inner_macros)] macro_rules! impl_operator { - ( $struct: ident { $($field: ident), + }, $trait: ident, $method: ident, $output: ty ) => { - impl> core::ops::$trait for $struct { - type Output = $output; + ( $struct: ident { $($field: ident), + }, $trait: ident, $method: ident, $output: ty ) => { + impl> core::ops::$trait for $struct { + type Output = $output; - fn $method(self, other: Self) -> Self::Output { - Self { - $( $field: self.$field.$method(other.$field) ), + - } - } - } + fn $method(self, other: Self) -> Self::Output { + Self { + $( $field: self.$field.$method(other.$field) ), + + } + } + } - impl + Copy> core::ops::$trait for $struct { - type Output = $output; + impl + Copy> core::ops::$trait for $struct { + type Output = $output; - fn $method(self, other: T) -> Self::Output { - Self { - $( $field: self.$field.$method(other) ), + - } - } - } - }; + fn $method(self, other: T) -> Self::Output { + Self { + $( $field: self.$field.$method(other) ), + + } + } + } + }; - ( $struct: ident { $($field: ident), + }, $trait: ident, $method: ident ) => { - impl core::ops::$trait for $struct { - fn $method(&mut self, other: Self) { - $( self.$field.$method(other.$field) ); + - } - } + ( $struct: ident { $($field: ident), + }, $trait: ident, $method: ident ) => { + impl core::ops::$trait for $struct { + fn $method(&mut self, other: Self) { + $( self.$field.$method(other.$field) ); + + } + } - impl core::ops::$trait for $struct { - fn $method(&mut self, other: T) { - $( self.$field.$method(other) ); + - } - } - }; + impl core::ops::$trait for $struct { + fn $method(&mut self, other: T) { + $( self.$field.$method(other) ); + + } + } + }; } diff --git a/fixed_wide_vectors/src/macros/wide.rs b/fixed_wide_vectors/src/macros/wide.rs index 01da30b..dc73596 100644 --- a/fixed_wide_vectors/src/macros/wide.rs +++ b/fixed_wide_vectors/src/macros/wide.rs @@ -1,34 +1,34 @@ #[doc(hidden)] #[macro_export(local_inner_macros)] macro_rules! impl_wide_operations { - ( $struct: ident { $($field: ident), + }, $size: expr ) => { - impl> fixed_wide_traits::wide::WideMul for $struct { + ( $struct: ident { $($field: ident), + }, $size: expr ) => { + impl> fixed_wide_traits::wide::WideMul for $struct { type Output=$struct; - #[inline] - fn wide_mul(self, rhs: Self) -> Self::Output { - $struct{ - $( $field: self.$field.wide_mul(rhs.$field) ), + - } - } + #[inline] + fn wide_mul(self, rhs: Self) -> Self::Output { + $struct{ + $( $field: self.$field.wide_mul(rhs.$field) ), + + } + } } impl,U,T:fixed_wide_traits::wide::WideMul> fixed_wide_traits::wide::WideDot<$struct> for $struct { type Output=V; #[inline] fn wide_dot(self, rhs: $struct) -> Self::Output { $crate::sum_repeating!( - $( + (self.$field.wide_mul(rhs.$field)) ) + - ) + $( + (self.$field.wide_mul(rhs.$field)) ) + + ) } } - impl,T:Copy+fixed_wide_traits::wide::WideMul> $struct { - #[inline] - pub fn wide_length_squared(&self) -> U { - $crate::sum_repeating!( - $( + self.$field.wide_mul(self.$field) ) + - ) - } - } - }; + impl,T:Copy+fixed_wide_traits::wide::WideMul> $struct { + #[inline] + pub fn wide_length_squared(&self) -> U { + $crate::sum_repeating!( + $( + self.$field.wide_mul(self.$field) ) + + ) + } + } + }; } @@ -37,7 +37,7 @@ macro_rules! impl_wide_operations { #[doc(hidden)] #[macro_export(local_inner_macros)] macro_rules! sum_repeating { - ( + $($item: tt) * ) => { - $($item) * - }; + ( + $($item: tt) * ) => { + $($item) * + }; } diff --git a/fixed_wide_vectors/src/vector.rs b/fixed_wide_vectors/src/vector.rs index 2767ad8..6e7dae6 100644 --- a/fixed_wide_vectors/src/vector.rs +++ b/fixed_wide_vectors/src/vector.rs @@ -14,8 +14,8 @@ /// assert_eq!(vec2.y, 4); /// ``` pub struct Vector2 { - pub x: T, - pub y: T, + pub x: T, + pub y: T, } @@ -34,9 +34,9 @@ pub struct Vector2 { /// assert_eq!(vec3.z, 6); /// ``` pub struct Vector3 { - pub x: T, - pub y: T, - pub z: T, + pub x: T, + pub y: T, + pub z: T, } @@ -56,10 +56,10 @@ pub struct Vector3 { /// assert_eq!(vec4.w, 8); /// ``` pub struct Vector4 { - pub x: T, - pub y: T, - pub z: T, - pub w: T, + pub x: T, + pub y: T, + pub z: T, + pub w: T, } From 0be0dd5c6f51fa7bdd0497b4408a0385f3bf47dd Mon Sep 17 00:00:00 2001 From: Quaternions Date: Wed, 28 Aug 2024 11:47:40 -0700 Subject: [PATCH 051/227] fixed: more constants --- fixed_wide/src/fixed.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/fixed_wide/src/fixed.rs b/fixed_wide/src/fixed.rs index ab18621..52284d9 100644 --- a/fixed_wide/src/fixed.rs +++ b/fixed_wide/src/fixed.rs @@ -12,6 +12,8 @@ impl Fixed{ pub const ZERO:Self=Self{bits:BInt::::ZERO,frac:PhantomData}; pub const ONE:Self=Self{bits:BInt::::ONE.shl(Frac::U32),frac:PhantomData}; pub const NEG_ONE:Self=Self{bits:BInt::::NEG_ONE.shl(Frac::U32),frac:PhantomData}; + pub const MAX:Self=Self{bits:BInt::::MAX,frac:PhantomData}; + pub const MIN:Self=Self{bits:BInt::::MIN,frac:PhantomData}; } impl From for Fixed From 8aa7da6be79d6d1979f4a54f7c824babadce676e Mon Sep 17 00:00:00 2001 From: Quaternions Date: Wed, 28 Aug 2024 12:17:00 -0700 Subject: [PATCH 052/227] add tests --- fixed_wide/src/lib.rs | 3 +++ fixed_wide/src/tests.rs | 14 ++++++++++++++ 2 files changed, 17 insertions(+) create mode 100644 fixed_wide/src/tests.rs diff --git a/fixed_wide/src/lib.rs b/fixed_wide/src/lib.rs index 4d35f29..b593a63 100644 --- a/fixed_wide/src/lib.rs +++ b/fixed_wide/src/lib.rs @@ -9,3 +9,6 @@ pub mod typenum{ mod fixed_wide_traits; #[cfg(feature="fixed_wide_traits")] pub use ::fixed_wide_traits::wide; + +#[cfg(test)] +mod tests; diff --git a/fixed_wide/src/tests.rs b/fixed_wide/src/tests.rs new file mode 100644 index 0000000..0029267 --- /dev/null +++ b/fixed_wide/src/tests.rs @@ -0,0 +1,14 @@ +use fixed_wide_traits::wide::WideMul; + +#[test] +fn test_wide_mul(){ + let a=crate::types::I32F32::ONE; + let aa=a.wide_mul(a); + assert_eq!(aa,crate::types::I64F64::ONE); +} + +#[test] +fn test_bint(){ + let a=crate::types::I32F32::ONE; + assert_eq!(a*2,crate::types::I32F32::from(2)); +} From 68d1c23cfa85c45ef62fd47cfc5f7e2739925b9e Mon Sep 17 00:00:00 2001 From: Quaternions Date: Wed, 28 Aug 2024 12:17:25 -0700 Subject: [PATCH 053/227] allow simple ops (why did this not work before?) --- fixed_wide/src/fixed.rs | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/fixed_wide/src/fixed.rs b/fixed_wide/src/fixed.rs index 52284d9..47ae1a9 100644 --- a/fixed_wide/src/fixed.rs +++ b/fixed_wide/src/fixed.rs @@ -68,6 +68,19 @@ macro_rules! impl_operator { } } } + impl core::ops::$trait for $struct + where + BInt:::From, + { + type Output = $output; + + fn $method(self, other: U) -> Self::Output { + Self { + bits:self.bits.$method(BInt::::from(other)< core::ops::$trait for $struct + where + BInt:::From, + { + fn $method(&mut self, other: U) { + self.bits.$method(BInt::::from(other)< Date: Wed, 28 Aug 2024 12:23:13 -0700 Subject: [PATCH 054/227] consistency --- fixed_wide/src/fixed.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/fixed_wide/src/fixed.rs b/fixed_wide/src/fixed.rs index 47ae1a9..fd49ace 100644 --- a/fixed_wide/src/fixed.rs +++ b/fixed_wide/src/fixed.rs @@ -16,13 +16,13 @@ impl Fixed{ pub const MIN:Self=Self{bits:BInt::::MIN,frac:PhantomData}; } -impl From for Fixed +impl From for Fixed where BInt:From { fn from(value:T)->Self{ Self{ - bits:BInt::<{CHUNKS}>::from(value)<::from(value)< Date: Wed, 28 Aug 2024 12:54:38 -0700 Subject: [PATCH 055/227] cant do it man --- fixed_wide_vectors/src/macros/mod.rs | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/fixed_wide_vectors/src/macros/mod.rs b/fixed_wide_vectors/src/macros/mod.rs index 4cf9651..abd22ee 100644 --- a/fixed_wide_vectors/src/macros/mod.rs +++ b/fixed_wide_vectors/src/macros/mod.rs @@ -244,7 +244,7 @@ macro_rules! impl_vector { #[macro_export(local_inner_macros)] macro_rules! impl_operator { ( $struct: ident { $($field: ident), + }, $trait: ident, $method: ident, $output: ty ) => { - impl> core::ops::$trait for $struct { + impl> core::ops::$trait for $struct { type Output = $output; fn $method(self, other: Self) -> Self::Output { @@ -253,12 +253,11 @@ macro_rules! impl_operator { } } } - - impl + Copy> core::ops::$trait for $struct { + impl+Copy> core::ops::$trait for $struct{ type Output = $output; fn $method(self, other: T) -> Self::Output { - Self { + $struct { $( $field: self.$field.$method(other) ), + } } From 1f6594468d157c11063cd0bc08609837cc11a654 Mon Sep 17 00:00:00 2001 From: Quaternions Date: Wed, 28 Aug 2024 13:29:29 -0700 Subject: [PATCH 056/227] bvec --- fixed_wide_vectors/src/macros/mod.rs | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/fixed_wide_vectors/src/macros/mod.rs b/fixed_wide_vectors/src/macros/mod.rs index abd22ee..fadc426 100644 --- a/fixed_wide_vectors/src/macros/mod.rs +++ b/fixed_wide_vectors/src/macros/mod.rs @@ -204,6 +204,16 @@ macro_rules! impl_vector { } } + impl $struct{ + pub fn all(&self)->bool{ + const ALL:[bool;$size]=[true;$size]; + core::matches!(self.to_array(),ALL) + } + pub fn any(&self)->bool{ + $( self.$field )|| + + } + } + impl> core::ops::Neg for $struct { type Output = Self; From 9f9e8c793b921b368028effe3aa6e708701a205d Mon Sep 17 00:00:00 2001 From: Quaternions Date: Wed, 28 Aug 2024 13:33:45 -0700 Subject: [PATCH 057/227] probably need this to make compiling with no wide work --- fixed_wide_vectors/src/macros/mod.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/fixed_wide_vectors/src/macros/mod.rs b/fixed_wide_vectors/src/macros/mod.rs index fadc426..7faa7dd 100644 --- a/fixed_wide_vectors/src/macros/mod.rs +++ b/fixed_wide_vectors/src/macros/mod.rs @@ -245,6 +245,7 @@ macro_rules! impl_vector { $crate::impl_operator!( $struct { $($field), + }, BitXor, bitxor, Self ); // Impl floating-point based methods + #[cfg(feature="fixed_wide_traits")] $crate::impl_wide_operations!( $struct { $($field), + }, $size ); }; } From 617952c1e380652d46e0ac8da9c6e4fca5f3f05f Mon Sep 17 00:00:00 2001 From: Quaternions Date: Wed, 28 Aug 2024 13:36:17 -0700 Subject: [PATCH 058/227] split tests --- .../src/tests/fixed_wide_traits.rs | 51 +++++++++++++++ fixed_wide_vectors/src/tests/mod.rs | 64 +------------------ fixed_wide_vectors/src/tests/tests.rs | 16 +++++ 3 files changed, 70 insertions(+), 61 deletions(-) create mode 100644 fixed_wide_vectors/src/tests/fixed_wide_traits.rs create mode 100644 fixed_wide_vectors/src/tests/tests.rs diff --git a/fixed_wide_vectors/src/tests/fixed_wide_traits.rs b/fixed_wide_vectors/src/tests/fixed_wide_traits.rs new file mode 100644 index 0000000..04925e6 --- /dev/null +++ b/fixed_wide_vectors/src/tests/fixed_wide_traits.rs @@ -0,0 +1,51 @@ +use fixed_wide_traits::wide::WideMul; +use fixed_wide_traits::wide::WideDot; + +use crate::Vector3; + +type Planar64=fixed_wide::types::I32F32; +//type Planar64Wide1=fixed::types::I64F64; +//type Planar64Wide2=fixed_wide::types::I128F128; +type Planar64Wide3=fixed_wide::types::I256F256; + +#[test] +fn wide_int64() { + let a=Planar64::from(2); + let b=Planar64::from(3); + + let w1=a.wide_mul(b); + let w2=w1.wide_mul(w1); + let w3=w2.wide_mul(w2); + + assert_eq!(w3,Planar64Wide3::from((3i128*2).pow(4))); +} + +#[test] +fn wide_vec3(){ + let v=Vector3::from_value(Planar64::from(3)); + let v1=v.wide_mul(v); + let v2=v1.wide_mul(v1); + let v3=v2.wide_mul(v2); + + assert_eq!(v3,Vector3::from_value(Planar64Wide3::from(3i128.pow(8)))); +} + +#[test] +fn wide_vec3_dot(){ + let v=Vector3::from_value(Planar64::from(3)); + let v1=v.wide_mul(v); + let v2=v1.wide_mul(v1); + let v3=v2.wide_dot(v2); + + assert_eq!(v3,Planar64Wide3::from(3i128.pow(8)*3)); +} + +#[test] +fn wide_vec3_length_squared(){ + let v=Vector3::from_value(Planar64::from(3)); + let v1=v.wide_mul(v); + let v2=v1.wide_mul(v1); + let v3=v2.wide_length_squared(); + + assert_eq!(v3,Planar64Wide3::from(3i128.pow(8)*3)); +} diff --git a/fixed_wide_vectors/src/tests/mod.rs b/fixed_wide_vectors/src/tests/mod.rs index 7a5deb2..36de35f 100644 --- a/fixed_wide_vectors/src/tests/mod.rs +++ b/fixed_wide_vectors/src/tests/mod.rs @@ -1,63 +1,5 @@ -use fixed_wide_traits::wide::WideMul; -use fixed_wide_traits::wide::WideDot; +mod tests; -use crate::Vector3; -type Planar64=fixed_wide::types::I32F32; -//type Planar64Wide1=fixed::types::I64F64; -//type Planar64Wide2=fixed_wide::types::I128F128; -type Planar64Wide3=fixed_wide::types::I256F256; - -#[test] -fn wide_int64() { - let a=Planar64::from(2); - let b=Planar64::from(3); - - let w1=a.wide_mul(b); - let w2=w1.wide_mul(w1); - let w3=w2.wide_mul(w2); - - assert_eq!(w3,Planar64Wide3::from((3i128*2).pow(4))); -} - -#[test] -fn you_can_add_numbers(){ - let a=Planar64Wide3::from((3i128*2).pow(4)); - assert_eq!(a+a,Planar64Wide3::from((3i128*2).pow(4)*2)) -} - -#[test] -fn you_can_shr_numbers(){ - let a=Planar64::from(4); - assert_eq!(a>>1,Planar64::from(2)) -} - -#[test] -fn wide_vec3(){ - let v=Vector3::from_value(Planar64::from(3)); - let v1=v.wide_mul(v); - let v2=v1.wide_mul(v1); - let v3=v2.wide_mul(v2); - - assert_eq!(v3,Vector3::from_value(Planar64Wide3::from(3i128.pow(8)))); -} - -#[test] -fn wide_vec3_dot(){ - let v=Vector3::from_value(Planar64::from(3)); - let v1=v.wide_mul(v); - let v2=v1.wide_mul(v1); - let v3=v2.wide_dot(v2); - - assert_eq!(v3,Planar64Wide3::from(3i128.pow(8)*3)); -} - -#[test] -fn wide_vec3_length_squared(){ - let v=Vector3::from_value(Planar64::from(3)); - let v1=v.wide_mul(v); - let v2=v1.wide_mul(v1); - let v3=v2.wide_length_squared(); - - assert_eq!(v3,Planar64Wide3::from(3i128.pow(8)*3)); -} +#[cfg(feature="fixed_wide_traits")] +mod fixed_wide_traits; diff --git a/fixed_wide_vectors/src/tests/tests.rs b/fixed_wide_vectors/src/tests/tests.rs new file mode 100644 index 0000000..25982f7 --- /dev/null +++ b/fixed_wide_vectors/src/tests/tests.rs @@ -0,0 +1,16 @@ +type Planar64=fixed_wide::types::I32F32; +//type Planar64Wide1=fixed::types::I64F64; +//type Planar64Wide2=fixed_wide::types::I128F128; +type Planar64Wide3=fixed_wide::types::I256F256; + +#[test] +fn you_can_add_numbers(){ + let a=Planar64Wide3::from((3i128*2).pow(4)); + assert_eq!(a+a,Planar64Wide3::from((3i128*2).pow(4)*2)) +} + +#[test] +fn you_can_shr_numbers(){ + let a=Planar64::from(4); + assert_eq!(a>>1,Planar64::from(2)) +} From ac250e9d8470cea8b7663e78adfc554e35fc2c33 Mon Sep 17 00:00:00 2001 From: Quaternions Date: Wed, 28 Aug 2024 15:21:36 -0700 Subject: [PATCH 059/227] ratio operators --- deferred_division/src/ratio.rs | 147 +++++++++++++++++++++++++++++++++ 1 file changed, 147 insertions(+) diff --git a/deferred_division/src/ratio.rs b/deferred_division/src/ratio.rs index 6ae0ad2..c5abad4 100644 --- a/deferred_division/src/ratio.rs +++ b/deferred_division/src/ratio.rs @@ -1,3 +1,5 @@ +use std::ops::Mul; + #[derive(Clone,Copy,Debug,Hash)] pub struct Ratio{ pub(crate)num:Num, @@ -8,3 +10,148 @@ impl Ratio{ Self{num,den} } } + +impl PartialEq for Ratio + where + Den:Copy, + Rhs:Mul+Copy, + Num:PartialEq<>::Output> +{ + fn eq(&self,rhs:&Rhs)->bool{ + self.num.eq(&rhs.mul(self.den)) + } +} +/* +//You can't do Ratio==Ratio I guess +impl Eq for Ratio +where + Num:Mul, + >::Output:PartialEq +{} +*/ + +// num/den == rhs +// num == rhs * den + +impl PartialOrd for Ratio + where + Den:Copy, + Rhs:Mul+Copy, + Num:PartialOrd<>::Output> +{ + fn partial_cmp(&self,rhs:&Rhs)->Option{ + self.num.partial_cmp(&rhs.mul(self.den)) + } +} +/* +impl Ord for Ratio<>::Output,Den> +where + Rhs:Mul, + Rhs:Ord, + >::Output:Ord, +{ + fn cmp(&self,other:&Rhs)->std::cmp::Ordering{ + self.num.cmp(&other.mul(self.den)) + } +} +*/ + +impl,Den> std::ops::Neg for Ratio{ + type Output=Ratio; + fn neg(self)->Self::Output{ + Ratio{ + num:self.num.neg(), + den:self.den, + } + } +} + +// num/den + rhs == new_num/den +// new_num = num + rhs * den + +macro_rules! impl_operator { + ($struct:ident,$trait:ident,$method:ident)=>{ + impl core::ops::$trait for $struct + where + Den:Copy, + Rhs:Mul, + Num:core::ops::$trait<>::Output>, + { + type Output=$struct<>::Output>>::Output,Den>; + + fn $method(self,rhs:Rhs)->Self::Output{ + $struct{ + num:self.num.$method(rhs.mul(self.den)), + den:self.den, + } + } + } + }; +} +macro_rules! impl_assign_operator{ + ($struct:ident,$trait:ident,$method:ident)=>{ + impl core::ops::$trait for $struct + where + Den:Copy, + Rhs:Mul, + Num:core::ops::$trait<>::Output>, + { + fn $method(&mut self,rhs:Rhs){ + self.num.$method(rhs.mul(self.den)); + } + } + }; +} + +// Impl arithmetic operators +impl_assign_operator!(Ratio,AddAssign,add_assign); +impl_operator!(Ratio,Add,add); +impl_assign_operator!(Ratio,SubAssign,sub_assign); +impl_operator!(Ratio,Sub,sub); +// num/den % rhs == new_num/den +// new_num = num % (rhs * den) +impl_assign_operator!(Ratio,RemAssign,rem_assign); +impl_operator!(Ratio,Rem,rem); + +//mul and div is special +impl Mul for Ratio + where + Num:Mul, +{ + type Output=Ratio<>::Output,Den>; + fn mul(self,rhs:Rhs)->Self::Output{ + Ratio{ + num:self.num.mul(rhs), + den:self.den, + } + } +} +impl core::ops::MulAssign for Ratio + where + Num:core::ops::MulAssign, +{ + fn mul_assign(&mut self,rhs:Rhs){ + self.num.mul_assign(rhs); + } +} + +impl core::ops::Div for Ratio + where + Den:Mul, +{ + type Output=Ratio>::Output>; + fn div(self,rhs:Rhs)->Self::Output{ + Ratio{ + num:self.num, + den:self.den.mul(rhs), + } + } +} +impl core::ops::DivAssign for Ratio + where + Den:core::ops::MulAssign, +{ + fn div_assign(&mut self,rhs:Rhs){ + self.den.mul_assign(rhs); + } +} From e604ce83e92807e4c8c928ce108a67ee72f5dcc1 Mon Sep 17 00:00:00 2001 From: Quaternions Date: Wed, 28 Aug 2024 15:32:33 -0700 Subject: [PATCH 060/227] macro up wide traits --- deferred_division/src/wide.rs | 27 +++++++++++++++++---------- 1 file changed, 17 insertions(+), 10 deletions(-) diff --git a/deferred_division/src/wide.rs b/deferred_division/src/wide.rs index df7dcae..c2e1205 100644 --- a/deferred_division/src/wide.rs +++ b/deferred_division/src/wide.rs @@ -1,6 +1,6 @@ use std::ops::{Add,Mul}; use crate::ratio::Ratio; -use fixed_wide_traits::wide::{WideMul,WideDiv}; +use fixed_wide_traits::wide::{WideMul,WideDiv,WideDot,WideCross}; impl Ratio { @@ -25,18 +25,25 @@ impl Ratio } } } -impl WideMul for Ratio - where - Num:WideMul, -{ - type Output=Ratio<>::Output,Den>; - fn wide_mul(self,rhs:T)->Ratio<>::Output,Den>{ - Ratio{ - num:self.num.wide_mul(rhs), - den:self.den, +macro_rules! impl_mul_operator { + ($struct:ident,$trait:ident,$method:ident)=>{ + impl $trait for $struct + where + Num:$trait, + { + type Output=$struct<>::Output,Den>; + fn $method(self,rhs:Rhs)->Self::Output{ + $struct{ + num:self.num.$method(rhs), + den:self.den, + } + } } } } +impl_mul_operator!(Ratio,WideMul,wide_mul); +impl_mul_operator!(Ratio,WideDot,wide_dot); +impl_mul_operator!(Ratio,WideCross,wide_cross); impl WideDiv for Ratio where Den:WideMul, From d47eaa423e4e21fccd29c5e6b882317195cd04f6 Mon Sep 17 00:00:00 2001 From: Quaternions Date: Wed, 28 Aug 2024 15:46:49 -0700 Subject: [PATCH 061/227] write some ratio tests --- deferred_division/Cargo.lock | 22 ++++++++++++++++++++++ deferred_division/Cargo.toml | 3 +++ deferred_division/src/tests/mod.rs | 4 ++++ deferred_division/src/tests/tests.rs | 15 +++++++++++++++ deferred_division/src/tests/wide.rs | 15 +++++++++++++++ 5 files changed, 59 insertions(+) create mode 100644 deferred_division/src/tests/mod.rs create mode 100644 deferred_division/src/tests/tests.rs create mode 100644 deferred_division/src/tests/wide.rs diff --git a/deferred_division/Cargo.lock b/deferred_division/Cargo.lock index 973fcc1..512511f 100644 --- a/deferred_division/Cargo.lock +++ b/deferred_division/Cargo.lock @@ -2,13 +2,35 @@ # It is not intended for manual editing. version = 3 +[[package]] +name = "bnum" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3e31ea183f6ee62ac8b8a8cf7feddd766317adfb13ff469de57ce033efd6a790" + [[package]] name = "deferred_division" version = "0.1.0" dependencies = [ + "fixed_wide", "fixed_wide_traits", ] +[[package]] +name = "fixed_wide" +version = "0.1.0" +dependencies = [ + "bnum", + "fixed_wide_traits", + "typenum", +] + [[package]] name = "fixed_wide_traits" version = "0.1.0" + +[[package]] +name = "typenum" +version = "1.17.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825" diff --git a/deferred_division/Cargo.toml b/deferred_division/Cargo.toml index 73eafc4..0f2ab79 100644 --- a/deferred_division/Cargo.toml +++ b/deferred_division/Cargo.toml @@ -9,3 +9,6 @@ fixed_wide_traits=["dep:fixed_wide_traits"] [dependencies] fixed_wide_traits = { version = "0.1.0", path = "../fixed_wide_traits", optional = true } + +[dev-dependencies] +fixed_wide = { version = "0.1.0", path = "../fixed_wide" } diff --git a/deferred_division/src/tests/mod.rs b/deferred_division/src/tests/mod.rs new file mode 100644 index 0000000..a74aed6 --- /dev/null +++ b/deferred_division/src/tests/mod.rs @@ -0,0 +1,4 @@ +mod tests; + +#[cfg(feature="fixed_wide_traits")] +mod wide; diff --git a/deferred_division/src/tests/tests.rs b/deferred_division/src/tests/tests.rs new file mode 100644 index 0000000..e98e832 --- /dev/null +++ b/deferred_division/src/tests/tests.rs @@ -0,0 +1,15 @@ +use crate::ratio::Ratio; + +#[test] +fn ratio(){ + let r=Ratio::new(5,3); + let a=r%1; + assert_eq!(a.num,2); + assert_eq!(a.den,3); + let b=r*2; + assert_eq!(b.num,10); + assert_eq!(b.den,3); + let c=r/2; + assert_eq!(c.num,5); + assert_eq!(c.den,6); +} diff --git a/deferred_division/src/tests/wide.rs b/deferred_division/src/tests/wide.rs new file mode 100644 index 0000000..4246565 --- /dev/null +++ b/deferred_division/src/tests/wide.rs @@ -0,0 +1,15 @@ +use crate::ratio::Ratio; +use fixed_wide_traits::wide::{WideMul,WideDiv}; +use fixed_wide::types::I32F32; +use fixed_wide::types::I64F64; + +#[test] +fn ratio(){ + let r=Ratio::new(I32F32::from(5),I32F32::from(3)); + let a=r.wide_mul(I32F32::from(7)>>2); + assert_eq!(a.num,I64F64::from(7*5)>>2); + assert_eq!(a.den,I32F32::from(3)); + let a=r.wide_div(I32F32::from(7)>>2); + assert_eq!(a.num,I32F32::from(5)); + assert_eq!(a.den,I64F64::from(3*7)>>2); +} From 446de71c30801383c02d900f44516694c78a82ca Mon Sep 17 00:00:00 2001 From: Quaternions Date: Wed, 28 Aug 2024 16:15:54 -0700 Subject: [PATCH 062/227] uh oh --- deferred_division/src/tests/tests.rs | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/deferred_division/src/tests/tests.rs b/deferred_division/src/tests/tests.rs index e98e832..d004719 100644 --- a/deferred_division/src/tests/tests.rs +++ b/deferred_division/src/tests/tests.rs @@ -13,3 +13,10 @@ fn ratio(){ assert_eq!(c.num,5); assert_eq!(c.den,6); } + +#[test] +fn add_ratio_cmp(){ + let a=Ratio::new(5,3); + let b=Ratio::new(1,3); + assert_eq!(a+b,2); +} From 9f6dffafdad0f00254a06d673c4c5053a9571ab2 Mon Sep 17 00:00:00 2001 From: Quaternions Date: Thu, 29 Aug 2024 10:12:08 -0700 Subject: [PATCH 063/227] cordic sqrt --- fixed_wide/src/fixed.rs | 57 ++++++++++++++++++++++++++++++++++++++--- fixed_wide/src/tests.rs | 6 +++++ 2 files changed, 60 insertions(+), 3 deletions(-) diff --git a/fixed_wide/src/fixed.rs b/fixed_wide/src/fixed.rs index fd49ace..1c1ca49 100644 --- a/fixed_wide/src/fixed.rs +++ b/fixed_wide/src/fixed.rs @@ -9,11 +9,15 @@ pub struct Fixed{ } impl Fixed{ - pub const ZERO:Self=Self{bits:BInt::::ZERO,frac:PhantomData}; - pub const ONE:Self=Self{bits:BInt::::ONE.shl(Frac::U32),frac:PhantomData}; - pub const NEG_ONE:Self=Self{bits:BInt::::NEG_ONE.shl(Frac::U32),frac:PhantomData}; pub const MAX:Self=Self{bits:BInt::::MAX,frac:PhantomData}; pub const MIN:Self=Self{bits:BInt::::MIN,frac:PhantomData}; + pub const ZERO:Self=Self{bits:BInt::::ZERO,frac:PhantomData}; + pub const ONE:Self=Self{bits:BInt::::ONE.shl(Frac::U32),frac:PhantomData}; + pub const TWO:Self=Self{bits:BInt::::TWO.shl(Frac::U32),frac:PhantomData}; + pub const HALF:Self=Self{bits:BInt::::ONE.shl(Frac::U32-1),frac:PhantomData}; + pub const NEG_ONE:Self=Self{bits:BInt::::NEG_ONE.shl(Frac::U32),frac:PhantomData}; + pub const NEG_TWO:Self=Self{bits:BInt::::NEG_TWO.shl(Frac::U32),frac:PhantomData}; + pub const NEG_HALF:Self=Self{bits:BInt::::NEG_ONE.shl(Frac::U32-1),frac:PhantomData}; } impl From for Fixed @@ -148,3 +152,50 @@ impl_shift_assign_operator!( Fixed, ShlAssign, shl_assign ); impl_shift_operator!( Fixed, Shl, shl, Self ); impl_shift_assign_operator!( Fixed, ShrAssign, shr_assign ); impl_shift_operator!( Fixed, Shr, shr, Self ); + +impl Fixed{ + pub fn sqrt_unchecked(self)->Self{ + let mut pow2=if self==Self::ZERO{ + return Self::ZERO; + }else if self>=1; + } + pow2 + }else if self==Self::ONE{ + return Self::ONE; + }else{ + //find pow2 more powerful than self + let mut pow2=Self::ONE; + while pow2<=self{ + pow2<<=1; + } + pow2 + }; + let mut result=pow2; + while pow2!=Self::ZERO{ + pow2>>=1; + let new_result=result+pow2; + if new_result*new_result<=self{ + result=new_result; + } + } + result + } + pub fn sqrt(self)->Self{ + if selfOption{ + if self Date: Thu, 29 Aug 2024 10:42:11 -0700 Subject: [PATCH 064/227] use tabs --- fixed_wide/src/fixed.rs | 108 ++++++++++++++++++++-------------------- 1 file changed, 54 insertions(+), 54 deletions(-) diff --git a/fixed_wide/src/fixed.rs b/fixed_wide/src/fixed.rs index 1c1ca49..9ed0f1a 100644 --- a/fixed_wide/src/fixed.rs +++ b/fixed_wide/src/fixed.rs @@ -62,47 +62,47 @@ impl std::ops::Neg for Fixed{ macro_rules! impl_operator { ( $struct: ident, $trait: ident, $method: ident, $output: ty ) => { - impl core::ops::$trait for $struct{ - type Output = $output; + impl core::ops::$trait for $struct{ + type Output = $output; - fn $method(self, other: Self) -> Self::Output { - Self { - bits:self.bits.$method(other.bits), - frac:PhantomData, - } - } - } - impl core::ops::$trait for $struct - where - BInt:::From, - { - type Output = $output; + fn $method(self, other: Self) -> Self::Output { + Self { + bits:self.bits.$method(other.bits), + frac:PhantomData, + } + } + } + impl core::ops::$trait for $struct + where + BInt:::From, + { + type Output = $output; - fn $method(self, other: U) -> Self::Output { - Self { - bits:self.bits.$method(BInt::::from(other)< Self::Output { + Self { + bits:self.bits.$method(BInt::::from(other)< { - impl core::ops::$trait for $struct{ - fn $method(&mut self, other: Self) { - self.bits.$method(other.bits); - } - } - impl core::ops::$trait for $struct - where - BInt:::From, - { - fn $method(&mut self, other: U) { - self.bits.$method(BInt::::from(other)< { + impl core::ops::$trait for $struct{ + fn $method(&mut self, other: Self) { + self.bits.$method(other.bits); + } + } + impl core::ops::$trait for $struct + where + BInt:::From, + { + fn $method(&mut self, other: U) { + self.bits.$method(BInt::::from(other)< { - impl core::ops::$trait for $struct{ - type Output = $output; + impl core::ops::$trait for $struct{ + type Output = $output; - fn $method(self, other: u32) -> Self::Output { - Self { - bits:self.bits.$method(other), - frac:PhantomData, - } - } - } - }; + fn $method(self, other: u32) -> Self::Output { + Self { + bits:self.bits.$method(other), + frac:PhantomData, + } + } + } + }; } macro_rules! impl_shift_assign_operator { - ( $struct: ident, $trait: ident, $method: ident ) => { - impl core::ops::$trait for $struct{ - fn $method(&mut self, other: u32) { - self.bits.$method(other); - } - } - }; + ( $struct: ident, $trait: ident, $method: ident ) => { + impl core::ops::$trait for $struct{ + fn $method(&mut self, other: u32) { + self.bits.$method(other); + } + } + }; } impl_shift_assign_operator!( Fixed, ShlAssign, shl_assign ); impl_shift_operator!( Fixed, Shl, shl, Self ); From 491de52f17586c53abbb9014660bea4d980be3ea Mon Sep 17 00:00:00 2001 From: Quaternions Date: Thu, 29 Aug 2024 10:42:50 -0700 Subject: [PATCH 065/227] improve failure mode --- fixed_wide/src/fixed.rs | 25 ++++++++++++------------- 1 file changed, 12 insertions(+), 13 deletions(-) diff --git a/fixed_wide/src/fixed.rs b/fixed_wide/src/fixed.rs index 9ed0f1a..7abb1fc 100644 --- a/fixed_wide/src/fixed.rs +++ b/fixed_wide/src/fixed.rs @@ -155,24 +155,23 @@ impl_shift_operator!( Fixed, Shr, shr, Self ); impl Fixed{ pub fn sqrt_unchecked(self)->Self{ - let mut pow2=if self==Self::ZERO{ - return Self::ZERO; - }else if self>=1; } pow2 - }else if self==Self::ONE{ - return Self::ONE; - }else{ - //find pow2 more powerful than self - let mut pow2=Self::ONE; - while pow2<=self{ - pow2<<=1; - } - pow2 + }else{//either 0==self or self is negative + return Self::ZERO; }; let mut result=pow2; while pow2!=Self::ZERO{ From 3d3eb966a48120799dad65da8e0d4de1ac0e49d1 Mon Sep 17 00:00:00 2001 From: Quaternions Date: Thu, 29 Aug 2024 11:16:38 -0700 Subject: [PATCH 066/227] multiply and divide was straight up wrong, and bruh this needs const generics so bad --- fixed_wide/src/fixed.rs | 174 +++++++++++++++++++++++++++++++++++----- 1 file changed, 154 insertions(+), 20 deletions(-) diff --git a/fixed_wide/src/fixed.rs b/fixed_wide/src/fixed.rs index 7abb1fc..83125b3 100644 --- a/fixed_wide/src/fixed.rs +++ b/fixed_wide/src/fixed.rs @@ -1,4 +1,4 @@ -use bnum::BInt; +use bnum::{BInt,cast::As}; use typenum::Unsigned; use std::marker::PhantomData; @@ -60,7 +60,7 @@ impl std::ops::Neg for Fixed{ } } -macro_rules! impl_operator { +macro_rules! impl_additive_operator { ( $struct: ident, $trait: ident, $method: ident, $output: ty ) => { impl core::ops::$trait for $struct{ type Output = $output; @@ -87,7 +87,7 @@ macro_rules! impl_operator { } }; } -macro_rules! impl_assign_operator { +macro_rules! impl_additive_assign_operator { ( $struct: ident, $trait: ident, $method: ident ) => { impl core::ops::$trait for $struct{ fn $method(&mut self, other: Self) { @@ -106,24 +106,155 @@ macro_rules! impl_assign_operator { } // Impl arithmetic pperators -impl_assign_operator!( Fixed, AddAssign, add_assign ); -impl_operator!( Fixed, Add, add, Self ); -impl_assign_operator!( Fixed, SubAssign, sub_assign ); -impl_operator!( Fixed, Sub, sub, Self ); -impl_assign_operator!( Fixed, MulAssign, mul_assign ); -impl_operator!( Fixed, Mul, mul, Self ); -impl_assign_operator!( Fixed, DivAssign, div_assign ); -impl_operator!( Fixed, Div, div, Self ); -impl_assign_operator!( Fixed, RemAssign, rem_assign ); -impl_operator!( Fixed, Rem, rem, Self ); +impl_additive_assign_operator!( Fixed, AddAssign, add_assign ); +impl_additive_operator!( Fixed, Add, add, Self ); +impl_additive_assign_operator!( Fixed, SubAssign, sub_assign ); +impl_additive_operator!( Fixed, Sub, sub, Self ); +impl_additive_assign_operator!( Fixed, RemAssign, rem_assign ); +impl_additive_operator!( Fixed, Rem, rem, Self ); // Impl bitwise operators -impl_assign_operator!( Fixed, BitAndAssign, bitand_assign ); -impl_operator!( Fixed, BitAnd, bitand, Self ); -impl_assign_operator!( Fixed, BitOrAssign, bitor_assign ); -impl_operator!( Fixed, BitOr, bitor, Self ); -impl_assign_operator!( Fixed, BitXorAssign, bitxor_assign ); -impl_operator!( Fixed, BitXor, bitxor, Self ); +impl_additive_assign_operator!( Fixed, BitAndAssign, bitand_assign ); +impl_additive_operator!( Fixed, BitAnd, bitand, Self ); +impl_additive_assign_operator!( Fixed, BitOrAssign, bitor_assign ); +impl_additive_operator!( Fixed, BitOr, bitor, Self ); +impl_additive_assign_operator!( Fixed, BitXorAssign, bitxor_assign ); +impl_additive_operator!( Fixed, BitXor, bitxor, Self ); + +macro_rules! impl_multiply_operator_const { + ( $width:expr, $struct: ident, $trait: ident, $method: ident, $output: ty ) => { + impl core::ops::$trait for $struct<$width,Frac>{ + type Output = $output; + + fn $method(self, other: Self) -> Self::Output { + //this can be done better but that is a job for later + let lhs=self.bits.as_::>(); + let rhs=other.bits.as_::>(); + Self { + bits:lhs.mul(rhs).shr(Frac::U32).as_(), + frac:PhantomData, + } + } + } + }; +} +macro_rules! impl_multiply_assign_operator_const { + ( $width:expr, $struct: ident, $trait: ident, $method: ident ) => { + impl core::ops::$trait for $struct<$width,Frac>{ + fn $method(&mut self, other: Self) { + self.bits.$method(other.bits); + } + } + }; +} + +macro_rules! impl_divide_operator_const { + ( $width:expr, $struct: ident, $trait: ident, $method: ident, $output: ty ) => { + impl core::ops::$trait for $struct<$width,Frac>{ + type Output = $output; + + fn $method(self, other: Self) -> Self::Output { + //this can be done better but that is a job for later + //this only needs to be $width+Frac::U32/64+1 but MUH CONST GENERICS!!!!! + let lhs=self.bits.as_::>().shl(Frac::U32); + let rhs=other.bits.as_::>(); + Self { + bits:lhs.div(rhs).as_(), + frac:PhantomData, + } + } + } + }; +} +macro_rules! impl_divide_assign_operator_const { + ( $width:expr, $struct: ident, $trait: ident, $method: ident ) => { + impl core::ops::$trait for $struct<$width,Frac>{ + fn $method(&mut self, other: Self) { + self.bits.$method(other.bits); + } + } + }; +} + +macro_rules! impl_multiplicatave_operator { + ( $struct: ident, $trait: ident, $method: ident, $output: ty ) => { + impl core::ops::$trait for $struct + where + BInt:::From+core::ops::$trait, + { + type Output = $output; + + fn $method(self, other: U) -> Self::Output { + Self { + bits:self.bits.$method(BInt::::from(other)), + frac:PhantomData, + } + } + } + }; +} +macro_rules! impl_multiplicatave_assign_operator { + ( $struct: ident, $trait: ident, $method: ident ) => { + impl core::ops::$trait for $struct + where + BInt:::From+core::ops::$trait, + { + fn $method(&mut self, other: U) { + self.bits.$method(BInt::::from(other)); + } + } + }; +} + +macro_rules! impl_operator_16 { + ( $macro: ident, $struct: ident, $trait: ident, $method: ident, $output: ty ) => { + $macro!(1,$struct,$trait,$method,$output); + $macro!(2,$struct,$trait,$method,$output); + $macro!(3,$struct,$trait,$method,$output); + $macro!(4,$struct,$trait,$method,$output); + $macro!(5,$struct,$trait,$method,$output); + $macro!(6,$struct,$trait,$method,$output); + $macro!(7,$struct,$trait,$method,$output); + $macro!(8,$struct,$trait,$method,$output); + $macro!(9,$struct,$trait,$method,$output); + $macro!(10,$struct,$trait,$method,$output); + $macro!(11,$struct,$trait,$method,$output); + $macro!(12,$struct,$trait,$method,$output); + $macro!(13,$struct,$trait,$method,$output); + $macro!(14,$struct,$trait,$method,$output); + $macro!(15,$struct,$trait,$method,$output); + $macro!(16,$struct,$trait,$method,$output); + } +} +macro_rules! impl_assign_operator_16 { + ( $macro: ident, $struct: ident, $trait: ident, $method: ident ) => { + $macro!(1,$struct,$trait,$method); + $macro!(2,$struct,$trait,$method); + $macro!(3,$struct,$trait,$method); + $macro!(4,$struct,$trait,$method); + $macro!(5,$struct,$trait,$method); + $macro!(6,$struct,$trait,$method); + $macro!(7,$struct,$trait,$method); + $macro!(8,$struct,$trait,$method); + $macro!(9,$struct,$trait,$method); + $macro!(10,$struct,$trait,$method); + $macro!(11,$struct,$trait,$method); + $macro!(12,$struct,$trait,$method); + $macro!(13,$struct,$trait,$method); + $macro!(14,$struct,$trait,$method); + $macro!(15,$struct,$trait,$method); + $macro!(16,$struct,$trait,$method); + } +} + +impl_assign_operator_16!( impl_multiply_assign_operator_const, Fixed, MulAssign, mul_assign ); +impl_operator_16!( impl_multiply_operator_const, Fixed, Mul, mul, Self ); +impl_assign_operator_16!( impl_divide_assign_operator_const, Fixed, DivAssign, div_assign ); +impl_operator_16!( impl_divide_operator_const, Fixed, Div, div, Self ); +impl_multiplicatave_assign_operator!( Fixed, MulAssign, mul_assign ); +impl_multiplicatave_operator!( Fixed, Mul, mul, Self ); +impl_multiplicatave_assign_operator!( Fixed, DivAssign, div_assign ); +impl_multiplicatave_operator!( Fixed, Div, div, Self ); macro_rules! impl_shift_operator { ( $struct: ident, $trait: ident, $method: ident, $output: ty ) => { @@ -153,7 +284,10 @@ impl_shift_operator!( Fixed, Shl, shl, Self ); impl_shift_assign_operator!( Fixed, ShrAssign, shr_assign ); impl_shift_operator!( Fixed, Shr, shr, Self ); -impl Fixed{ +impl Fixed + where + Fixed:::std::ops::Mul,Output=Fixed>, +{ pub fn sqrt_unchecked(self)->Self{ //find pow2 more powerful than self let mut pow2=if Self::ONE Date: Thu, 29 Aug 2024 12:12:14 -0700 Subject: [PATCH 067/227] smarter sqrt --- fixed_wide/src/fixed.rs | 28 ++++++++++------------------ 1 file changed, 10 insertions(+), 18 deletions(-) diff --git a/fixed_wide/src/fixed.rs b/fixed_wide/src/fixed.rs index 83125b3..0030361 100644 --- a/fixed_wide/src/fixed.rs +++ b/fixed_wide/src/fixed.rs @@ -289,25 +289,17 @@ impl Fixed Fixed:::std::ops::Mul,Output=Fixed>, { pub fn sqrt_unchecked(self)->Self{ - //find pow2 more powerful than self - let mut pow2=if Self::ONE>=1; - } - pow2 - }else{//either 0==self or self is negative - return Self::ZERO; + //pow2 must be the minimum power of two which when squared is greater than self + //0001.0000 Fixed + //sqrt + //0110.0000 + //pow2 = 0100.0000 + let mut pow2=Self{ + bits:BInt::::ONE.shl((((CHUNKS as i32*64-Frac::I32-(self.bits.leading_zeros() as i32)+1)>>1)+Frac::I32) as u32), + frac:PhantomData, }; - let mut result=pow2; + let mut result=pow2>>1; + while pow2!=Self::ZERO{ pow2>>=1; let new_result=result+pow2; From e684fb421e3ca3bd0597749ed0f68fa4d67734e1 Mon Sep 17 00:00:00 2001 From: Quaternions Date: Thu, 29 Aug 2024 12:13:42 -0700 Subject: [PATCH 068/227] tests --- fixed_wide/src/tests.rs | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/fixed_wide/src/tests.rs b/fixed_wide/src/tests.rs index 447545a..811714c 100644 --- a/fixed_wide/src/tests.rs +++ b/fixed_wide/src/tests.rs @@ -18,3 +18,9 @@ fn test_sqrt(){ let a=crate::types::I32F32::ONE*4; assert_eq!(a.sqrt(),crate::types::I32F32::from(2)); } +#[test] +fn test_sqrt_low(){ + let a=crate::types::I32F32::HALF; + let b=a*a; + assert_eq!(b.sqrt(),a); +} From 6ea9eff84461637b63c3f84af9f63a4d83247d82 Mon Sep 17 00:00:00 2001 From: Quaternions Date: Thu, 29 Aug 2024 13:15:17 -0700 Subject: [PATCH 069/227] further sqrt improvements --- fixed_wide/src/fixed.rs | 31 +++++++++++++++++++++++++++---- 1 file changed, 27 insertions(+), 4 deletions(-) diff --git a/fixed_wide/src/fixed.rs b/fixed_wide/src/fixed.rs index 0030361..4fa36fa 100644 --- a/fixed_wide/src/fixed.rs +++ b/fixed_wide/src/fixed.rs @@ -18,6 +18,15 @@ impl Fixed{ pub const NEG_ONE:Self=Self{bits:BInt::::NEG_ONE.shl(Frac::U32),frac:PhantomData}; pub const NEG_TWO:Self=Self{bits:BInt::::NEG_TWO.shl(Frac::U32),frac:PhantomData}; pub const NEG_HALF:Self=Self{bits:BInt::::NEG_ONE.shl(Frac::U32-1),frac:PhantomData}; + pub const fn from_bits(bits:BInt::)->Self{ + Self{ + bits, + frac:PhantomData, + } + } + pub const fn to_bits(self)->BInt{ + self.bits + } } impl From for Fixed @@ -290,6 +299,13 @@ impl Fixed { pub fn sqrt_unchecked(self)->Self{ //pow2 must be the minimum power of two which when squared is greater than self + //the algorithm: + //1. count "used" bits to the left of the decimal + //2. add one + //This is the power of two which is greater than self. + //3. divide by 2 via >>1 + //4. add on fractional offset + //Voila //0001.0000 Fixed //sqrt //0110.0000 @@ -300,14 +316,21 @@ impl Fixed }; let mut result=pow2>>1; - while pow2!=Self::ZERO{ + loop{ pow2>>=1; + if pow2==Self::ZERO{ + break result; + } + //TODO: flip a single bit instead of adding a power of 2 let new_result=result+pow2; - if new_result*new_result<=self{ - result=new_result; + //note that the implicit truncation in the multiply + //means that the algorithm can return a result which squares to a number greater than the input. + match self.cmp(&(new_result*new_result)){ + core::cmp::Ordering::Less=>continue, + core::cmp::Ordering::Equal=>break new_result, + core::cmp::Ordering::Greater=>result=new_result, } } - result } pub fn sqrt(self)->Self{ if self Date: Thu, 29 Aug 2024 13:16:02 -0700 Subject: [PATCH 070/227] use import --- fixed_wide/src/tests.rs | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/fixed_wide/src/tests.rs b/fixed_wide/src/tests.rs index 811714c..3b40d7f 100644 --- a/fixed_wide/src/tests.rs +++ b/fixed_wide/src/tests.rs @@ -1,26 +1,27 @@ use fixed_wide_traits::wide::WideMul; +use crate::types::I32F32; #[test] fn test_wide_mul(){ - let a=crate::types::I32F32::ONE; + let a=I32F32::ONE; let aa=a.wide_mul(a); assert_eq!(aa,crate::types::I64F64::ONE); } #[test] fn test_bint(){ - let a=crate::types::I32F32::ONE; - assert_eq!(a*2,crate::types::I32F32::from(2)); + let a=I32F32::ONE; + assert_eq!(a*2,I32F32::from(2)); } #[test] fn test_sqrt(){ - let a=crate::types::I32F32::ONE*4; - assert_eq!(a.sqrt(),crate::types::I32F32::from(2)); + let a=I32F32::ONE*4; + assert_eq!(a.sqrt(),I32F32::from(2)); } #[test] fn test_sqrt_low(){ - let a=crate::types::I32F32::HALF; + let a=I32F32::HALF; let b=a*a; assert_eq!(b.sqrt(),a); } From b45d93a7dc65c50cefc9299e6c2daf9cfe07e838 Mon Sep 17 00:00:00 2001 From: Quaternions Date: Thu, 29 Aug 2024 13:16:09 -0700 Subject: [PATCH 071/227] more sqrt tests --- fixed_wide/src/tests.rs | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/fixed_wide/src/tests.rs b/fixed_wide/src/tests.rs index 3b40d7f..05c911a 100644 --- a/fixed_wide/src/tests.rs +++ b/fixed_wide/src/tests.rs @@ -25,3 +25,22 @@ fn test_sqrt_low(){ let b=a*a; assert_eq!(b.sqrt(),a); } +fn find_equiv_sqrt_via_f64(n:I32F32)->I32F32{ + //GIMME THEM BITS BOY + let &[bits]=n.to_bits().to_bits().digits(); + let ibits=bits as i64; + let f=(ibits as f64)/((1u64<<32) as f64); + let f_ans=f.sqrt(); + let mut i=(f_ans*((1u64<<32) as f64)) as i64; + let s=(i as i128)*(i as i128); + if s<((ibits as i128)<<32){ + i+=1; + } + I32F32::from_bits(bnum::BInt::<1>::from(i)) +} +#[test] +fn test_sqrt_exact(){ + let a=I32F32::ONE*2; + let b=find_equiv_sqrt_via_f64(a); + assert_eq!(a.sqrt(),b); +} From ac7d9f5c3b04d938fb25a750497b3e9d32541734 Mon Sep 17 00:00:00 2001 From: Quaternions Date: Thu, 29 Aug 2024 13:30:48 -0700 Subject: [PATCH 072/227] test more --- fixed_wide/src/fixed.rs | 2 ++ fixed_wide/src/tests.rs | 26 ++++++++++++++++++-------- 2 files changed, 20 insertions(+), 8 deletions(-) diff --git a/fixed_wide/src/fixed.rs b/fixed_wide/src/fixed.rs index 4fa36fa..c39e31d 100644 --- a/fixed_wide/src/fixed.rs +++ b/fixed_wide/src/fixed.rs @@ -12,6 +12,8 @@ impl Fixed{ pub const MAX:Self=Self{bits:BInt::::MAX,frac:PhantomData}; pub const MIN:Self=Self{bits:BInt::::MIN,frac:PhantomData}; pub const ZERO:Self=Self{bits:BInt::::ZERO,frac:PhantomData}; + pub const EPSILON:Self=Self{bits:BInt::::ONE,frac:PhantomData}; + pub const NEG_EPSILON:Self=Self{bits:BInt::::NEG_ONE,frac:PhantomData}; pub const ONE:Self=Self{bits:BInt::::ONE.shl(Frac::U32),frac:PhantomData}; pub const TWO:Self=Self{bits:BInt::::TWO.shl(Frac::U32),frac:PhantomData}; pub const HALF:Self=Self{bits:BInt::::ONE.shl(Frac::U32-1),frac:PhantomData}; diff --git a/fixed_wide/src/tests.rs b/fixed_wide/src/tests.rs index 05c911a..a46ef87 100644 --- a/fixed_wide/src/tests.rs +++ b/fixed_wide/src/tests.rs @@ -31,16 +31,26 @@ fn find_equiv_sqrt_via_f64(n:I32F32)->I32F32{ let ibits=bits as i64; let f=(ibits as f64)/((1u64<<32) as f64); let f_ans=f.sqrt(); - let mut i=(f_ans*((1u64<<32) as f64)) as i64; - let s=(i as i128)*(i as i128); - if s<((ibits as i128)<<32){ - i+=1; + let i=(f_ans*((1u64<<32) as f64)) as i64; + let r=I32F32::from_bits(bnum::BInt::<1>::from(i)); + //mimic the behaviour of the algorithm, + //return the result if it truncates to the exact answer + if (r+I32F32::EPSILON)*(r+I32F32::EPSILON)==n{ + return r+I32F32::EPSILON; } - I32F32::from_bits(bnum::BInt::<1>::from(i)) + if (r-I32F32::EPSILON)*(r-I32F32::EPSILON)==n{ + return r-I32F32::EPSILON; + } + return r; +} +fn test_exact(n:I32F32){ + assert_eq!(n.sqrt(),find_equiv_sqrt_via_f64(n)); } #[test] fn test_sqrt_exact(){ - let a=I32F32::ONE*2; - let b=find_equiv_sqrt_via_f64(a); - assert_eq!(a.sqrt(),b); + //43 + for i in 0..((i64::MAX as f32).ln() as u32){ + let n=I32F32::from_bits(bnum::BInt::<1>::from((i as f32).exp() as i64)); + test_exact(n); + } } From 91b378aa433d7e41d16f1c5e451a532957f1ba7c Mon Sep 17 00:00:00 2001 From: Quaternions Date: Thu, 29 Aug 2024 14:28:40 -0700 Subject: [PATCH 073/227] use tabs --- fixed_wide/src/fixed_wide_traits.rs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/fixed_wide/src/fixed_wide_traits.rs b/fixed_wide/src/fixed_wide_traits.rs index efc655e..84f6634 100644 --- a/fixed_wide/src/fixed_wide_traits.rs +++ b/fixed_wide/src/fixed_wide_traits.rs @@ -24,11 +24,11 @@ macro_rules! impl_wide_mul { } macro_rules! impl_wide_mul_all { - ($(($x:expr, $y:expr)),*) => { - $( - impl_wide_mul!($x, $y); - )* - }; + ($(($x:expr, $y:expr)),*) => { + $( + impl_wide_mul!($x, $y); + )* + }; } //const generics sidestepped wahoo From 95651d7091427fe65709af0268a20c47754fb918 Mon Sep 17 00:00:00 2001 From: Quaternions Date: Thu, 29 Aug 2024 14:41:08 -0700 Subject: [PATCH 074/227] use wide_mul for more precise sqrt --- fixed_wide/src/fixed.rs | 55 ------------------------ fixed_wide/src/fixed_wide_traits.rs | 66 +++++++++++++++++++++++++++++ fixed_wide/src/tests.rs | 4 +- 3 files changed, 68 insertions(+), 57 deletions(-) diff --git a/fixed_wide/src/fixed.rs b/fixed_wide/src/fixed.rs index c39e31d..b6956b2 100644 --- a/fixed_wide/src/fixed.rs +++ b/fixed_wide/src/fixed.rs @@ -294,58 +294,3 @@ impl_shift_assign_operator!( Fixed, ShlAssign, shl_assign ); impl_shift_operator!( Fixed, Shl, shl, Self ); impl_shift_assign_operator!( Fixed, ShrAssign, shr_assign ); impl_shift_operator!( Fixed, Shr, shr, Self ); - -impl Fixed - where - Fixed:::std::ops::Mul,Output=Fixed>, -{ - pub fn sqrt_unchecked(self)->Self{ - //pow2 must be the minimum power of two which when squared is greater than self - //the algorithm: - //1. count "used" bits to the left of the decimal - //2. add one - //This is the power of two which is greater than self. - //3. divide by 2 via >>1 - //4. add on fractional offset - //Voila - //0001.0000 Fixed - //sqrt - //0110.0000 - //pow2 = 0100.0000 - let mut pow2=Self{ - bits:BInt::::ONE.shl((((CHUNKS as i32*64-Frac::I32-(self.bits.leading_zeros() as i32)+1)>>1)+Frac::I32) as u32), - frac:PhantomData, - }; - let mut result=pow2>>1; - - loop{ - pow2>>=1; - if pow2==Self::ZERO{ - break result; - } - //TODO: flip a single bit instead of adding a power of 2 - let new_result=result+pow2; - //note that the implicit truncation in the multiply - //means that the algorithm can return a result which squares to a number greater than the input. - match self.cmp(&(new_result*new_result)){ - core::cmp::Ordering::Less=>continue, - core::cmp::Ordering::Equal=>break new_result, - core::cmp::Ordering::Greater=>result=new_result, - } - } - } - pub fn sqrt(self)->Self{ - if selfOption{ - if self Fixed{ + pub fn widen(self)->Fixed{ + Fixed{ + bits:self.bits.as_::>(), + frac:PhantomData, + } + } +} + +impl Fixed + where + Fixed:::WideMul, + as WideMul>::Output:Ord, +{ + pub fn sqrt_unchecked(self)->Self{ + //pow2 must be the minimum power of two which when squared is greater than self + //the algorithm: + //1. count "used" bits to the left of the decimal + //2. add one + //This is the power of two which is greater than self. + //3. divide by 2 via >>1 + //4. add on fractional offset + //Voila + //0001.0000 Fixed + //sqrt + //0110.0000 + //pow2 = 0100.0000 + let mut pow2=Self{ + bits:BInt::::ONE.shl((((CHUNKS as i32*64-Frac::I32-(self.bits.leading_zeros() as i32)+1)>>1)+Frac::I32) as u32), + frac:PhantomData, + }; + let mut result=pow2>>1; + + //cheat to make the types match + let wide_self=self.wide_mul(Fixed::::ONE); + loop{ + pow2>>=1; + if pow2==Self::ZERO{ + break result; + } + //TODO: flip a single bit instead of adding a power of 2 + let new_result=result+pow2; + //note that the implicit truncation in the multiply + //means that the algorithm can return a result which squares to a number greater than the input. + match wide_self.cmp(&new_result.wide_mul(new_result)){ + core::cmp::Ordering::Less=>continue, + core::cmp::Ordering::Equal=>break new_result, + core::cmp::Ordering::Greater=>result=new_result, + } + } + } + pub fn sqrt(self)->Self{ + if selfOption{ + if selfI32F32{ let r=I32F32::from_bits(bnum::BInt::<1>::from(i)); //mimic the behaviour of the algorithm, //return the result if it truncates to the exact answer - if (r+I32F32::EPSILON)*(r+I32F32::EPSILON)==n{ + if (r+I32F32::EPSILON).wide_mul(r+I32F32::EPSILON)==n.wide_mul(I32F32::ONE){ return r+I32F32::EPSILON; } - if (r-I32F32::EPSILON)*(r-I32F32::EPSILON)==n{ + if (r-I32F32::EPSILON).wide_mul(r-I32F32::EPSILON)==n.wide_mul(I32F32::ONE){ return r-I32F32::EPSILON; } return r; From 67c30b85358e9e3817a82670926a147492d5fa1c Mon Sep 17 00:00:00 2001 From: Quaternions Date: Thu, 29 Aug 2024 15:21:10 -0700 Subject: [PATCH 075/227] save one shr operation --- fixed_wide/src/fixed_wide_traits.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/fixed_wide/src/fixed_wide_traits.rs b/fixed_wide/src/fixed_wide_traits.rs index f8b0d5c..566d396 100644 --- a/fixed_wide/src/fixed_wide_traits.rs +++ b/fixed_wide/src/fixed_wide_traits.rs @@ -70,15 +70,14 @@ impl Fixed //0110.0000 //pow2 = 0100.0000 let mut pow2=Self{ - bits:BInt::::ONE.shl((((CHUNKS as i32*64-Frac::I32-(self.bits.leading_zeros() as i32)+1)>>1)+Frac::I32) as u32), + bits:BInt::::ONE.shl(((((CHUNKS as i32*64-Frac::I32-(self.bits.leading_zeros() as i32)+1)>>1)+Frac::I32) as u32).saturating_sub(1)), frac:PhantomData, }; - let mut result=pow2>>1; + let mut result=pow2; //cheat to make the types match let wide_self=self.wide_mul(Fixed::::ONE); loop{ - pow2>>=1; if pow2==Self::ZERO{ break result; } @@ -87,10 +86,11 @@ impl Fixed //note that the implicit truncation in the multiply //means that the algorithm can return a result which squares to a number greater than the input. match wide_self.cmp(&new_result.wide_mul(new_result)){ - core::cmp::Ordering::Less=>continue, + core::cmp::Ordering::Less=>(), core::cmp::Ordering::Equal=>break new_result, core::cmp::Ordering::Greater=>result=new_result, } + pow2>>=1; } } pub fn sqrt(self)->Self{ From 8d5fc1ae48a80ec9ae4621dad60eb340b697888b Mon Sep 17 00:00:00 2001 From: Quaternions Date: Thu, 29 Aug 2024 15:27:48 -0700 Subject: [PATCH 076/227] test max --- fixed_wide/src/tests.rs | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/fixed_wide/src/tests.rs b/fixed_wide/src/tests.rs index 3234541..26ec4f3 100644 --- a/fixed_wide/src/tests.rs +++ b/fixed_wide/src/tests.rs @@ -54,3 +54,8 @@ fn test_sqrt_exact(){ test_exact(n); } } +#[test] +fn test_sqrt_max(){ + let a=I32F32::MAX; + test_exact(a); +} From 6335b1da47ff3ef0ec1472bc442c9b48681eed72 Mon Sep 17 00:00:00 2001 From: Quaternions Date: Thu, 29 Aug 2024 15:35:33 -0700 Subject: [PATCH 077/227] todo --- fixed_wide/src/fixed_wide_traits.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/fixed_wide/src/fixed_wide_traits.rs b/fixed_wide/src/fixed_wide_traits.rs index 566d396..24459f5 100644 --- a/fixed_wide/src/fixed_wide_traits.rs +++ b/fixed_wide/src/fixed_wide_traits.rs @@ -78,6 +78,7 @@ impl Fixed //cheat to make the types match let wide_self=self.wide_mul(Fixed::::ONE); loop{ + //TODO: closed loop over bit shift exponent rather than pow2 if pow2==Self::ZERO{ break result; } From 9266edbf92f0e0d1f8b5cf430ca3c86c1999f4c7 Mon Sep 17 00:00:00 2001 From: Quaternions Date: Thu, 29 Aug 2024 16:20:10 -0700 Subject: [PATCH 078/227] forgot to test zero... --- fixed_wide/src/tests.rs | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/fixed_wide/src/tests.rs b/fixed_wide/src/tests.rs index 26ec4f3..61e6b96 100644 --- a/fixed_wide/src/tests.rs +++ b/fixed_wide/src/tests.rs @@ -20,6 +20,11 @@ fn test_sqrt(){ assert_eq!(a.sqrt(),I32F32::from(2)); } #[test] +fn test_sqrt_zero(){ + let a=I32F32::ZERO; + assert_eq!(a.sqrt(),I32F32::ZERO); +} +#[test] fn test_sqrt_low(){ let a=I32F32::HALF; let b=a*a; From b656371142a5bc18917b723ffdf07627b2ed0b72 Mon Sep 17 00:00:00 2001 From: Quaternions Date: Thu, 29 Aug 2024 17:03:25 -0700 Subject: [PATCH 079/227] pass zero test --- fixed_wide/src/fixed_wide_traits.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fixed_wide/src/fixed_wide_traits.rs b/fixed_wide/src/fixed_wide_traits.rs index 24459f5..d34419c 100644 --- a/fixed_wide/src/fixed_wide_traits.rs +++ b/fixed_wide/src/fixed_wide_traits.rs @@ -73,7 +73,7 @@ impl Fixed bits:BInt::::ONE.shl(((((CHUNKS as i32*64-Frac::I32-(self.bits.leading_zeros() as i32)+1)>>1)+Frac::I32) as u32).saturating_sub(1)), frac:PhantomData, }; - let mut result=pow2; + let mut result=Self::ZERO; //cheat to make the types match let wide_self=self.wide_mul(Fixed::::ONE); From cd1aa26293770df0a8d00a56022abf7efbe8bfa7 Mon Sep 17 00:00:00 2001 From: Quaternions Date: Thu, 29 Aug 2024 17:22:45 -0700 Subject: [PATCH 080/227] prevent 50 headaches --- fixed_wide/src/fixed.rs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/fixed_wide/src/fixed.rs b/fixed_wide/src/fixed.rs index b6956b2..23a8774 100644 --- a/fixed_wide/src/fixed.rs +++ b/fixed_wide/src/fixed.rs @@ -29,6 +29,9 @@ impl Fixed{ pub const fn to_bits(self)->BInt{ self.bits } + pub const fn raw(value:i64)->Self{ + Self::from_bits(BInt::from_bits(bnum::BUint::from_digit(value as u64))) + } } impl From for Fixed From 61aad93f8dea749f327372839fbd53c3f02f392d Mon Sep 17 00:00:00 2001 From: Quaternions Date: Thu, 29 Aug 2024 18:29:04 -0700 Subject: [PATCH 081/227] sqrt: closed loop over bit shift --- fixed_wide/src/fixed_wide_traits.rs | 24 ++++++------------------ 1 file changed, 6 insertions(+), 18 deletions(-) diff --git a/fixed_wide/src/fixed_wide_traits.rs b/fixed_wide/src/fixed_wide_traits.rs index d34419c..0c8e9d8 100644 --- a/fixed_wide/src/fixed_wide_traits.rs +++ b/fixed_wide/src/fixed_wide_traits.rs @@ -69,30 +69,18 @@ impl Fixed //sqrt //0110.0000 //pow2 = 0100.0000 - let mut pow2=Self{ - bits:BInt::::ONE.shl(((((CHUNKS as i32*64-Frac::I32-(self.bits.leading_zeros() as i32)+1)>>1)+Frac::I32) as u32).saturating_sub(1)), - frac:PhantomData, - }; + let max_shift=((((CHUNKS as i32*64-Frac::I32-(self.bits.leading_zeros() as i32)+1)>>1)+Frac::I32) as u32).saturating_sub(1); let mut result=Self::ZERO; //cheat to make the types match let wide_self=self.wide_mul(Fixed::::ONE); - loop{ - //TODO: closed loop over bit shift exponent rather than pow2 - if pow2==Self::ZERO{ - break result; + for shift in (0..=max_shift).rev(){ + let new_result=result|(Fixed::::EPSILON<(), - core::cmp::Ordering::Equal=>break new_result, - core::cmp::Ordering::Greater=>result=new_result, - } - pow2>>=1; } + result } pub fn sqrt(self)->Self{ if self Date: Thu, 29 Aug 2024 18:38:23 -0700 Subject: [PATCH 082/227] fast --- fixed_wide/src/fixed_wide_traits.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fixed_wide/src/fixed_wide_traits.rs b/fixed_wide/src/fixed_wide_traits.rs index 0c8e9d8..9d6ab27 100644 --- a/fixed_wide/src/fixed_wide_traits.rs +++ b/fixed_wide/src/fixed_wide_traits.rs @@ -75,7 +75,7 @@ impl Fixed //cheat to make the types match let wide_self=self.wide_mul(Fixed::::ONE); for shift in (0..=max_shift).rev(){ - let new_result=result|(Fixed::::EPSILON<::from_bits(BInt::from_bits(bnum::BUint::power_of_two(shift))); if new_result.wide_mul(new_result)<=wide_self{ result=new_result; } From 70a79a8d252bd5ce03baa5e6ea938e4c077ce135 Mon Sep 17 00:00:00 2001 From: Quaternions Date: Thu, 29 Aug 2024 18:54:43 -0700 Subject: [PATCH 083/227] remove old kludge --- fixed_wide/src/fixed_wide_traits.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/fixed_wide/src/fixed_wide_traits.rs b/fixed_wide/src/fixed_wide_traits.rs index 9d6ab27..bd9ac24 100644 --- a/fixed_wide/src/fixed_wide_traits.rs +++ b/fixed_wide/src/fixed_wide_traits.rs @@ -69,7 +69,8 @@ impl Fixed //sqrt //0110.0000 //pow2 = 0100.0000 - let max_shift=((((CHUNKS as i32*64-Frac::I32-(self.bits.leading_zeros() as i32)+1)>>1)+Frac::I32) as u32).saturating_sub(1); + let used_bits=CHUNKS as i32*64-1-Frac::I32-self.bits.leading_zeros() as i32; + let max_shift=((used_bits>>1)+Frac::I32) as u32; let mut result=Self::ZERO; //cheat to make the types match From 3c5f01da89995983442c893565fc553178d9b431 Mon Sep 17 00:00:00 2001 From: Quaternions Date: Thu, 29 Aug 2024 18:38:18 -0700 Subject: [PATCH 084/227] describe algorithm --- fixed_wide/src/fixed_wide_traits.rs | 19 +++++++------------ 1 file changed, 7 insertions(+), 12 deletions(-) diff --git a/fixed_wide/src/fixed_wide_traits.rs b/fixed_wide/src/fixed_wide_traits.rs index bd9ac24..b2b41de 100644 --- a/fixed_wide/src/fixed_wide_traits.rs +++ b/fixed_wide/src/fixed_wide_traits.rs @@ -57,24 +57,19 @@ impl Fixed as WideMul>::Output:Ord, { pub fn sqrt_unchecked(self)->Self{ - //pow2 must be the minimum power of two which when squared is greater than self - //the algorithm: - //1. count "used" bits to the left of the decimal - //2. add one - //This is the power of two which is greater than self. - //3. divide by 2 via >>1 - //4. add on fractional offset + //1<>1 (sqrt-ish) + //3. add on fractional offset //Voila - //0001.0000 Fixed - //sqrt - //0110.0000 - //pow2 = 0100.0000 let used_bits=CHUNKS as i32*64-1-Frac::I32-self.bits.leading_zeros() as i32; let max_shift=((used_bits>>1)+Frac::I32) as u32; let mut result=Self::ZERO; - //cheat to make the types match + //multiply by one to make the types match (hack) let wide_self=self.wide_mul(Fixed::::ONE); + //descend down the bits and check if flipping each bit would push the square over the input value for shift in (0..=max_shift).rev(){ let new_result=result|Fixed::::from_bits(BInt::from_bits(bnum::BUint::power_of_two(shift))); if new_result.wide_mul(new_result)<=wide_self{ From 540749e4f10e54e35188b36ab558048e4d2cd146 Mon Sep 17 00:00:00 2001 From: Quaternions Date: Thu, 29 Aug 2024 19:52:00 -0700 Subject: [PATCH 085/227] there is a poorly named function for this --- fixed_wide/src/fixed_wide_traits.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fixed_wide/src/fixed_wide_traits.rs b/fixed_wide/src/fixed_wide_traits.rs index b2b41de..185ec95 100644 --- a/fixed_wide/src/fixed_wide_traits.rs +++ b/fixed_wide/src/fixed_wide_traits.rs @@ -63,7 +63,7 @@ impl Fixed //2. divide by 2 via >>1 (sqrt-ish) //3. add on fractional offset //Voila - let used_bits=CHUNKS as i32*64-1-Frac::I32-self.bits.leading_zeros() as i32; + let used_bits=self.bits.bits() as i32-1-Frac::I32; let max_shift=((used_bits>>1)+Frac::I32) as u32; let mut result=Self::ZERO; From 46d89619bd746ddf0dc225ad668a15f7ac4d9904 Mon Sep 17 00:00:00 2001 From: Quaternions Date: Thu, 29 Aug 2024 20:03:56 -0700 Subject: [PATCH 086/227] use from_bits function for consts --- fixed_wide/src/fixed.rs | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/fixed_wide/src/fixed.rs b/fixed_wide/src/fixed.rs index 23a8774..b26a4ed 100644 --- a/fixed_wide/src/fixed.rs +++ b/fixed_wide/src/fixed.rs @@ -9,17 +9,17 @@ pub struct Fixed{ } impl Fixed{ - pub const MAX:Self=Self{bits:BInt::::MAX,frac:PhantomData}; - pub const MIN:Self=Self{bits:BInt::::MIN,frac:PhantomData}; - pub const ZERO:Self=Self{bits:BInt::::ZERO,frac:PhantomData}; - pub const EPSILON:Self=Self{bits:BInt::::ONE,frac:PhantomData}; - pub const NEG_EPSILON:Self=Self{bits:BInt::::NEG_ONE,frac:PhantomData}; - pub const ONE:Self=Self{bits:BInt::::ONE.shl(Frac::U32),frac:PhantomData}; - pub const TWO:Self=Self{bits:BInt::::TWO.shl(Frac::U32),frac:PhantomData}; - pub const HALF:Self=Self{bits:BInt::::ONE.shl(Frac::U32-1),frac:PhantomData}; - pub const NEG_ONE:Self=Self{bits:BInt::::NEG_ONE.shl(Frac::U32),frac:PhantomData}; - pub const NEG_TWO:Self=Self{bits:BInt::::NEG_TWO.shl(Frac::U32),frac:PhantomData}; - pub const NEG_HALF:Self=Self{bits:BInt::::NEG_ONE.shl(Frac::U32-1),frac:PhantomData}; + pub const MAX:Self=Self::from_bits(BInt::::MAX); + pub const MIN:Self=Self::from_bits(BInt::::MIN); + pub const ZERO:Self=Self::from_bits(BInt::::ZERO); + pub const EPSILON:Self=Self::from_bits(BInt::::ONE); + pub const NEG_EPSILON:Self=Self::from_bits(BInt::::NEG_ONE); + pub const ONE:Self=Self::from_bits(BInt::::ONE.shl(Frac::U32)); + pub const TWO:Self=Self::from_bits(BInt::::TWO.shl(Frac::U32)); + pub const HALF:Self=Self::from_bits(BInt::::ONE.shl(Frac::U32-1)); + pub const NEG_ONE:Self=Self::from_bits(BInt::::NEG_ONE.shl(Frac::U32)); + pub const NEG_TWO:Self=Self::from_bits(BInt::::NEG_TWO.shl(Frac::U32)); + pub const NEG_HALF:Self=Self::from_bits(BInt::::NEG_ONE.shl(Frac::U32-1)); pub const fn from_bits(bits:BInt::)->Self{ Self{ bits, From 0924518922548e68d68119824ac7c08ef99cc494 Mon Sep 17 00:00:00 2001 From: Quaternions Date: Thu, 29 Aug 2024 20:07:18 -0700 Subject: [PATCH 087/227] eviscerate PhantomData --- fixed_wide/src/fixed.rs | 47 ++++++++--------------------- fixed_wide/src/fixed_wide_traits.rs | 11 ++----- 2 files changed, 14 insertions(+), 44 deletions(-) diff --git a/fixed_wide/src/fixed.rs b/fixed_wide/src/fixed.rs index b26a4ed..71b56e3 100644 --- a/fixed_wide/src/fixed.rs +++ b/fixed_wide/src/fixed.rs @@ -1,11 +1,10 @@ use bnum::{BInt,cast::As}; use typenum::Unsigned; -use std::marker::PhantomData; #[derive(Clone,Copy,Debug,Hash)] pub struct Fixed{ pub(crate)bits:BInt<{CHUNKS}>, - pub(crate)frac:PhantomData, + pub(crate)frac:std::marker::PhantomData, } impl Fixed{ @@ -20,10 +19,12 @@ impl Fixed{ pub const NEG_ONE:Self=Self::from_bits(BInt::::NEG_ONE.shl(Frac::U32)); pub const NEG_TWO:Self=Self::from_bits(BInt::::NEG_TWO.shl(Frac::U32)); pub const NEG_HALF:Self=Self::from_bits(BInt::::NEG_ONE.shl(Frac::U32-1)); +} +impl Fixed{ pub const fn from_bits(bits:BInt::)->Self{ Self{ bits, - frac:PhantomData, + frac:std::marker::PhantomData, } } pub const fn to_bits(self)->BInt{ @@ -39,10 +40,7 @@ impl From for Fixed BInt:From { fn from(value:T)->Self{ - Self{ - bits:BInt::<{CHUNKS}>::from(value)<::from(value)< Ord for Fixed{ impl std::ops::Neg for Fixed{ type Output=Self; fn neg(self)->Self{ - Self{ - bits:self.bits.neg(), - frac:PhantomData, - } + Self::from_bits(self.bits.neg()) } } @@ -80,10 +75,7 @@ macro_rules! impl_additive_operator { type Output = $output; fn $method(self, other: Self) -> Self::Output { - Self { - bits:self.bits.$method(other.bits), - frac:PhantomData, - } + Self::from_bits(self.bits.$method(other.bits)) } } impl core::ops::$trait for $struct @@ -93,10 +85,7 @@ macro_rules! impl_additive_operator { type Output = $output; fn $method(self, other: U) -> Self::Output { - Self { - bits:self.bits.$method(BInt::::from(other)<::from(other)<>(); let rhs=other.bits.as_::>(); - Self { - bits:lhs.mul(rhs).shr(Frac::U32).as_(), - frac:PhantomData, - } + Self::from_bits(lhs.mul(rhs).shr(Frac::U32).as_()) } } }; @@ -172,10 +158,7 @@ macro_rules! impl_divide_operator_const { //this only needs to be $width+Frac::U32/64+1 but MUH CONST GENERICS!!!!! let lhs=self.bits.as_::>().shl(Frac::U32); let rhs=other.bits.as_::>(); - Self { - bits:lhs.div(rhs).as_(), - frac:PhantomData, - } + Self::from_bits(lhs.div(rhs).as_()) } } }; @@ -199,10 +182,7 @@ macro_rules! impl_multiplicatave_operator { type Output = $output; fn $method(self, other: U) -> Self::Output { - Self { - bits:self.bits.$method(BInt::::from(other)), - frac:PhantomData, - } + Self::from_bits(self.bits.$method(BInt::::from(other))) } } }; @@ -276,10 +256,7 @@ macro_rules! impl_shift_operator { type Output = $output; fn $method(self, other: u32) -> Self::Output { - Self { - bits:self.bits.$method(other), - frac:PhantomData, - } + Self::from_bits(self.bits.$method(other)) } } }; diff --git a/fixed_wide/src/fixed_wide_traits.rs b/fixed_wide/src/fixed_wide_traits.rs index 185ec95..c48ce71 100644 --- a/fixed_wide/src/fixed_wide_traits.rs +++ b/fixed_wide/src/fixed_wide_traits.rs @@ -3,7 +3,6 @@ use bnum::cast::As; use typenum::{Sum,Unsigned}; use crate::fixed::Fixed; use fixed_wide_traits::wide::WideMul; -use std::marker::PhantomData; macro_rules! impl_wide_mul { ($lhs: expr,$rhs: expr) => { @@ -14,10 +13,7 @@ macro_rules! impl_wide_mul { { type Output=Fixed<{$lhs+$rhs},Sum>; fn wide_mul(self,rhs:Fixed<$rhs,B>)->Self::Output{ - Fixed{ - bits:self.bits.as_::>()*rhs.bits.as_::>(), - frac:PhantomData, - } + Fixed::from_bits(self.bits.as_::>()*rhs.bits.as_::>()) } } }; @@ -44,10 +40,7 @@ impl_wide_mul_all!( ); impl Fixed{ pub fn widen(self)->Fixed{ - Fixed{ - bits:self.bits.as_::>(), - frac:PhantomData, - } + Fixed::from_bits(self.bits.as_::>()) } } From 78f860c6726c0da84624d570bffe7a2720709864 Mon Sep 17 00:00:00 2001 From: Quaternions Date: Thu, 29 Aug 2024 20:11:07 -0700 Subject: [PATCH 088/227] inline const functions --- fixed_wide/src/fixed.rs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/fixed_wide/src/fixed.rs b/fixed_wide/src/fixed.rs index 71b56e3..663be09 100644 --- a/fixed_wide/src/fixed.rs +++ b/fixed_wide/src/fixed.rs @@ -21,15 +21,18 @@ impl Fixed{ pub const NEG_HALF:Self=Self::from_bits(BInt::::NEG_ONE.shl(Frac::U32-1)); } impl Fixed{ + #[inline] pub const fn from_bits(bits:BInt::)->Self{ Self{ bits, frac:std::marker::PhantomData, } } + #[inline] pub const fn to_bits(self)->BInt{ self.bits } + #[inline] pub const fn raw(value:i64)->Self{ Self::from_bits(BInt::from_bits(bnum::BUint::from_digit(value as u64))) } From f531e8d8eed9446dc15a6d2d8b04bcae057371d2 Mon Sep 17 00:00:00 2001 From: Quaternions Date: Fri, 30 Aug 2024 12:05:52 -0700 Subject: [PATCH 089/227] move vector2 macro code --- fixed_wide_vectors/src/macros/mod.rs | 289 +----------------------- fixed_wide_vectors/src/macros/vector.rs | 288 +++++++++++++++++++++++ fixed_wide_vectors/src/macros/wide.rs | 2 +- 3 files changed, 290 insertions(+), 289 deletions(-) create mode 100644 fixed_wide_vectors/src/macros/vector.rs diff --git a/fixed_wide_vectors/src/macros/mod.rs b/fixed_wide_vectors/src/macros/mod.rs index 7faa7dd..3c74505 100644 --- a/fixed_wide_vectors/src/macros/mod.rs +++ b/fixed_wide_vectors/src/macros/mod.rs @@ -1,291 +1,4 @@ #[cfg(feature="fixed_wide_traits")] pub mod wide; -// Stolen from https://github.com/c1m50c/fixed-vectors (MIT license) -#[doc(hidden)] -#[macro_export(local_inner_macros)] -macro_rules! impl_vector { - ( $struct: ident { $($field: ident), + }, ( $($generic: ident), + ), $size: expr ) => { - impl $struct { - /// Constructs a new vector with the specified values for each field. - /// - /// # Example - /// - /// ``` - /// use fixed_wide_vectors::Vector2; - /// - /// let vec2 = Vector2::new(0, 0); - /// - /// assert_eq!(vec2.x, 0); - /// assert_eq!(vec2.y, 0); - /// ``` - #[inline(always)] - pub const fn new( $($field: T), + ) -> Self { - Self { - $( $field ), + - } - } - - /// Consumes the vector and returns its values as an array. - /// - /// # Example - /// - /// ``` - /// use fixed_wide_vectors::Vector2; - /// - /// let vec2 = Vector2::new(0, 0); - /// let array = vec2.to_array(); - /// - /// assert_eq!(array, [0, 0]); - /// ``` - #[inline(always)] - pub fn to_array(self) -> [T; $size] { - [ $(self.$field), + ] - } - - /// Consumes the vector and returns its values as a tuple. - /// - /// # Example - /// - /// ``` - /// use fixed_wide_vectors::Vector2; - /// - /// let vec2 = Vector2::new(0, 0); - /// let tuple = vec2.to_tuple(); - /// - /// assert_eq!(tuple, (0, 0)); - /// ``` - #[inline(always)] - pub fn to_tuple(self) -> ( $($generic), + ) { - ( $(self.$field), + ) - } - - /// Consumes the vector and returns a new vector with the given function applied on each field. - /// - /// # Example - /// - /// ``` - /// use fixed_wide_vectors::Vector2; - /// - /// let vec2 = Vector2::new(1, 2) - /// .map(|i| i * 2); - /// - /// assert_eq!(vec2, Vector2::new(2, 4)); - /// ``` - #[inline] - pub fn map(self, f: F) -> $struct - where - F: Fn(T) -> U - { - $struct { - $( $field: f(self.$field) ), + - } - } - } - - impl $struct { - /// Constructs a vector using the given `value` as the value for all of its fields. - /// - /// # Example - /// - /// ``` - /// use fixed_wide_vectors::Vector2; - /// - /// let vec2 = Vector2::from_value(0); - /// - /// assert_eq!(vec2, Vector2::new(0, 0)); - /// ``` - #[inline(always)] - pub const fn from_value(value: T) -> Self { - Self { - $( $field: value ), + - } - } - } - - impl From<[T; $size]> for $struct { - fn from(from: [T; $size]) -> Self { - let mut iterator = from.into_iter(); - - Self { - // SAFETY: We know the size of `from` so `iterator.next()` is always `Some(..)` - $( $field: unsafe { iterator.next().unwrap_unchecked() } ), + - } - } - } - - impl From<($($generic), +)> for $struct { - fn from(from: ($($generic), +)) -> Self { - let ( $($field), + ) = from; - - Self { - $( $field ), + - } - } - } - - impl core::fmt::Debug for $struct { - fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { - let identifier = core::stringify!($struct); - - f.debug_struct(identifier) - $( .field( core::stringify!($field), &self.$field ) ) + - .finish() - } - } - - impl PartialEq for $struct { - fn eq(&self, other: &Self) -> bool { - $( self.$field == other.$field ) && + - } - } - - impl Eq for $struct { } - - impl core::hash::Hash for $struct { - fn hash(&self, state: &mut H) { - $( self.$field.hash(state); ) + - } - } - - impl Clone for $struct { - fn clone(&self) -> Self { - Self { - $( $field: self.$field.clone() ), + - } - } - } - - impl Copy for $struct { } - - impl Default for $struct { - fn default() -> Self { - Self { - $( $field: T::default() ), + - } - } - } - - impl $struct { - pub fn min(self, rhs: Self) -> $struct { - $struct{ - $( $field: self.$field.min(rhs.$field) ), + - } - } - pub fn max(self, rhs: Self) -> $struct { - $struct{ - $( $field: self.$field.max(rhs.$field) ), + - } - } - pub fn cmp(self, rhs: Self) -> $struct { - $struct{ - $( $field: self.$field.cmp(&rhs.$field) ), + - } - } - pub fn lt(self, rhs: Self) -> $struct { - $struct{ - $( $field: self.$field.lt(&rhs.$field) ), + - } - } - pub fn gt(self, rhs: Self) -> $struct { - $struct{ - $( $field: self.$field.gt(&rhs.$field) ), + - } - } - pub fn ge(self, rhs: Self) -> $struct { - $struct{ - $( $field: self.$field.ge(&rhs.$field) ), + - } - } - pub fn le(self, rhs: Self) -> $struct { - $struct{ - $( $field: self.$field.le(&rhs.$field) ), + - } - } - } - - impl $struct{ - pub fn all(&self)->bool{ - const ALL:[bool;$size]=[true;$size]; - core::matches!(self.to_array(),ALL) - } - pub fn any(&self)->bool{ - $( self.$field )|| + - } - } - - impl> core::ops::Neg for $struct { - type Output = Self; - - fn neg(self) -> Self::Output { - Self { - $( $field: -self.$field ), + - } - } - } - - // Impl arithmetic pperators - $crate::impl_operator!( $struct { $($field), + }, AddAssign, add_assign ); - $crate::impl_operator!( $struct { $($field), + }, Add, add, Self ); - $crate::impl_operator!( $struct { $($field), + }, SubAssign, sub_assign ); - $crate::impl_operator!( $struct { $($field), + }, Sub, sub, Self ); - $crate::impl_operator!( $struct { $($field), + }, MulAssign, mul_assign ); - $crate::impl_operator!( $struct { $($field), + }, Mul, mul, Self ); - $crate::impl_operator!( $struct { $($field), + }, DivAssign, div_assign ); - $crate::impl_operator!( $struct { $($field), + }, Div, div, Self ); - $crate::impl_operator!( $struct { $($field), + }, RemAssign, rem_assign ); - $crate::impl_operator!( $struct { $($field), + }, Rem, rem, Self ); - - // Impl bitwise operators - $crate::impl_operator!( $struct { $($field), + }, BitAndAssign, bitand_assign ); - $crate::impl_operator!( $struct { $($field), + }, BitAnd, bitand, Self ); - $crate::impl_operator!( $struct { $($field), + }, BitOrAssign, bitor_assign ); - $crate::impl_operator!( $struct { $($field), + }, BitOr, bitor, Self ); - $crate::impl_operator!( $struct { $($field), + }, BitXorAssign, bitxor_assign ); - $crate::impl_operator!( $struct { $($field), + }, BitXor, bitxor, Self ); - - // Impl floating-point based methods - #[cfg(feature="fixed_wide_traits")] - $crate::impl_wide_operations!( $struct { $($field), + }, $size ); - }; -} - - -#[doc(hidden)] -#[macro_export(local_inner_macros)] -macro_rules! impl_operator { - ( $struct: ident { $($field: ident), + }, $trait: ident, $method: ident, $output: ty ) => { - impl> core::ops::$trait for $struct { - type Output = $output; - - fn $method(self, other: Self) -> Self::Output { - Self { - $( $field: self.$field.$method(other.$field) ), + - } - } - } - impl+Copy> core::ops::$trait for $struct{ - type Output = $output; - - fn $method(self, other: T) -> Self::Output { - $struct { - $( $field: self.$field.$method(other) ), + - } - } - } - }; - - ( $struct: ident { $($field: ident), + }, $trait: ident, $method: ident ) => { - impl core::ops::$trait for $struct { - fn $method(&mut self, other: Self) { - $( self.$field.$method(other.$field) ); + - } - } - - impl core::ops::$trait for $struct { - fn $method(&mut self, other: T) { - $( self.$field.$method(other) ); + - } - } - }; -} +pub mod vector; diff --git a/fixed_wide_vectors/src/macros/vector.rs b/fixed_wide_vectors/src/macros/vector.rs new file mode 100644 index 0000000..064ff11 --- /dev/null +++ b/fixed_wide_vectors/src/macros/vector.rs @@ -0,0 +1,288 @@ +// Stolen from https://github.com/c1m50c/fixed-vectors (MIT license) +#[doc(hidden)] +#[macro_export(local_inner_macros)] +macro_rules! impl_vector { + ( $struct: ident { $($field: ident), + }, ( $($generic: ident), + ), $size: expr ) => { + impl $struct { + /// Constructs a new vector with the specified values for each field. + /// + /// # Example + /// + /// ``` + /// use fixed_wide_vectors::Vector2; + /// + /// let vec2 = Vector2::new(0, 0); + /// + /// assert_eq!(vec2.x, 0); + /// assert_eq!(vec2.y, 0); + /// ``` + #[inline(always)] + pub const fn new( $($field: T), + ) -> Self { + Self { + $( $field ), + + } + } + + /// Consumes the vector and returns its values as an array. + /// + /// # Example + /// + /// ``` + /// use fixed_wide_vectors::Vector2; + /// + /// let vec2 = Vector2::new(0, 0); + /// let array = vec2.to_array(); + /// + /// assert_eq!(array, [0, 0]); + /// ``` + #[inline(always)] + pub fn to_array(self) -> [T; $size] { + [ $(self.$field), + ] + } + + /// Consumes the vector and returns its values as a tuple. + /// + /// # Example + /// + /// ``` + /// use fixed_wide_vectors::Vector2; + /// + /// let vec2 = Vector2::new(0, 0); + /// let tuple = vec2.to_tuple(); + /// + /// assert_eq!(tuple, (0, 0)); + /// ``` + #[inline(always)] + pub fn to_tuple(self) -> ( $($generic), + ) { + ( $(self.$field), + ) + } + + /// Consumes the vector and returns a new vector with the given function applied on each field. + /// + /// # Example + /// + /// ``` + /// use fixed_wide_vectors::Vector2; + /// + /// let vec2 = Vector2::new(1, 2) + /// .map(|i| i * 2); + /// + /// assert_eq!(vec2, Vector2::new(2, 4)); + /// ``` + #[inline] + pub fn map(self, f: F) -> $struct + where + F: Fn(T) -> U + { + $struct { + $( $field: f(self.$field) ), + + } + } + } + + impl $struct { + /// Constructs a vector using the given `value` as the value for all of its fields. + /// + /// # Example + /// + /// ``` + /// use fixed_wide_vectors::Vector2; + /// + /// let vec2 = Vector2::from_value(0); + /// + /// assert_eq!(vec2, Vector2::new(0, 0)); + /// ``` + #[inline(always)] + pub const fn from_value(value: T) -> Self { + Self { + $( $field: value ), + + } + } + } + + impl From<[T; $size]> for $struct { + fn from(from: [T; $size]) -> Self { + let mut iterator = from.into_iter(); + + Self { + // SAFETY: We know the size of `from` so `iterator.next()` is always `Some(..)` + $( $field: unsafe { iterator.next().unwrap_unchecked() } ), + + } + } + } + + impl From<($($generic), +)> for $struct { + fn from(from: ($($generic), +)) -> Self { + let ( $($field), + ) = from; + + Self { + $( $field ), + + } + } + } + + impl core::fmt::Debug for $struct { + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { + let identifier = core::stringify!($struct); + + f.debug_struct(identifier) + $( .field( core::stringify!($field), &self.$field ) ) + + .finish() + } + } + + impl PartialEq for $struct { + fn eq(&self, other: &Self) -> bool { + $( self.$field == other.$field ) && + + } + } + + impl Eq for $struct { } + + impl core::hash::Hash for $struct { + fn hash(&self, state: &mut H) { + $( self.$field.hash(state); ) + + } + } + + impl Clone for $struct { + fn clone(&self) -> Self { + Self { + $( $field: self.$field.clone() ), + + } + } + } + + impl Copy for $struct { } + + impl Default for $struct { + fn default() -> Self { + Self { + $( $field: T::default() ), + + } + } + } + + impl $struct { + pub fn min(self, rhs: Self) -> $struct { + $struct{ + $( $field: self.$field.min(rhs.$field) ), + + } + } + pub fn max(self, rhs: Self) -> $struct { + $struct{ + $( $field: self.$field.max(rhs.$field) ), + + } + } + pub fn cmp(self, rhs: Self) -> $struct { + $struct{ + $( $field: self.$field.cmp(&rhs.$field) ), + + } + } + pub fn lt(self, rhs: Self) -> $struct { + $struct{ + $( $field: self.$field.lt(&rhs.$field) ), + + } + } + pub fn gt(self, rhs: Self) -> $struct { + $struct{ + $( $field: self.$field.gt(&rhs.$field) ), + + } + } + pub fn ge(self, rhs: Self) -> $struct { + $struct{ + $( $field: self.$field.ge(&rhs.$field) ), + + } + } + pub fn le(self, rhs: Self) -> $struct { + $struct{ + $( $field: self.$field.le(&rhs.$field) ), + + } + } + } + + impl $struct{ + pub fn all(&self)->bool{ + const ALL:[bool;$size]=[true;$size]; + core::matches!(self.to_array(),ALL) + } + pub fn any(&self)->bool{ + $( self.$field )|| + + } + } + + impl> core::ops::Neg for $struct { + type Output = Self; + + fn neg(self) -> Self::Output { + Self { + $( $field: -self.$field ), + + } + } + } + + // Impl arithmetic pperators + $crate::impl_vector_operator!( $struct { $($field), + }, AddAssign, add_assign ); + $crate::impl_vector_operator!( $struct { $($field), + }, Add, add, Self ); + $crate::impl_vector_operator!( $struct { $($field), + }, SubAssign, sub_assign ); + $crate::impl_vector_operator!( $struct { $($field), + }, Sub, sub, Self ); + $crate::impl_vector_operator!( $struct { $($field), + }, MulAssign, mul_assign ); + $crate::impl_vector_operator!( $struct { $($field), + }, Mul, mul, Self ); + $crate::impl_vector_operator!( $struct { $($field), + }, DivAssign, div_assign ); + $crate::impl_vector_operator!( $struct { $($field), + }, Div, div, Self ); + $crate::impl_vector_operator!( $struct { $($field), + }, RemAssign, rem_assign ); + $crate::impl_vector_operator!( $struct { $($field), + }, Rem, rem, Self ); + + // Impl bitwise operators + $crate::impl_vector_operator!( $struct { $($field), + }, BitAndAssign, bitand_assign ); + $crate::impl_vector_operator!( $struct { $($field), + }, BitAnd, bitand, Self ); + $crate::impl_vector_operator!( $struct { $($field), + }, BitOrAssign, bitor_assign ); + $crate::impl_vector_operator!( $struct { $($field), + }, BitOr, bitor, Self ); + $crate::impl_vector_operator!( $struct { $($field), + }, BitXorAssign, bitxor_assign ); + $crate::impl_vector_operator!( $struct { $($field), + }, BitXor, bitxor, Self ); + + // Impl floating-point based methods + #[cfg(feature="fixed_wide_traits")] + $crate::impl_wide_vector_operations!( $struct { $($field), + }, $size ); + }; +} + + +#[doc(hidden)] +#[macro_export(local_inner_macros)] +macro_rules! impl_vector_operator { + ( $struct: ident { $($field: ident), + }, $trait: ident, $method: ident, $output: ty ) => { + impl> core::ops::$trait for $struct { + type Output = $output; + + fn $method(self, other: Self) -> Self::Output { + Self { + $( $field: self.$field.$method(other.$field) ), + + } + } + } + impl+Copy> core::ops::$trait for $struct{ + type Output = $output; + + fn $method(self, other: T) -> Self::Output { + $struct { + $( $field: self.$field.$method(other) ), + + } + } + } + }; + + ( $struct: ident { $($field: ident), + }, $trait: ident, $method: ident ) => { + impl core::ops::$trait for $struct { + fn $method(&mut self, other: Self) { + $( self.$field.$method(other.$field) ); + + } + } + + impl core::ops::$trait for $struct { + fn $method(&mut self, other: T) { + $( self.$field.$method(other) ); + + } + } + }; +} diff --git a/fixed_wide_vectors/src/macros/wide.rs b/fixed_wide_vectors/src/macros/wide.rs index dc73596..d6a9eec 100644 --- a/fixed_wide_vectors/src/macros/wide.rs +++ b/fixed_wide_vectors/src/macros/wide.rs @@ -1,6 +1,6 @@ #[doc(hidden)] #[macro_export(local_inner_macros)] -macro_rules! impl_wide_operations { +macro_rules! impl_wide_vector_operations { ( $struct: ident { $($field: ident), + }, $size: expr ) => { impl> fixed_wide_traits::wide::WideMul for $struct { type Output=$struct; From 8e1807b4b75082ea503c63d0811efde4867bbc3e Mon Sep 17 00:00:00 2001 From: Quaternions Date: Fri, 30 Aug 2024 12:06:33 -0700 Subject: [PATCH 090/227] VECTOR IS MATRIX --- fixed_wide_vectors/src/macros/matrix.rs | 171 ++++++++++++++++++++++++ fixed_wide_vectors/src/macros/mod.rs | 1 + fixed_wide_vectors/src/vector.rs | 10 ++ 3 files changed, 182 insertions(+) create mode 100644 fixed_wide_vectors/src/macros/matrix.rs diff --git a/fixed_wide_vectors/src/macros/matrix.rs b/fixed_wide_vectors/src/macros/matrix.rs new file mode 100644 index 0000000..eaa507c --- /dev/null +++ b/fixed_wide_vectors/src/macros/matrix.rs @@ -0,0 +1,171 @@ +// Stolen from https://github.com/c1m50c/fixed-vectors (MIT license) +#[doc(hidden)] +#[macro_export(local_inner_macros)] +macro_rules! impl_matrix { + ( + ($struct_outer: ident { $($field_outer: ident), + }, ( $($generic_outer: tt), + ), $size_outer: expr), + ($struct_inner: ident, $size_inner: expr), $fields_inner:tt + ) => { + impl $struct_outer<$struct_inner> { + /// Consumes the matrix and returns its values as an array. + /// + /// # Example + /// + /// ``` + /// use fixed_wide_vectors::Vector2; + /// + /// let mat2 = Vector2::new( + /// Vector2::new(0, 0), + /// Vector2::new(0, 0) + /// ); + /// let array = mat2.to_array_2d(); + /// + /// assert_eq!(array, [[0, 0], [0, 0]]); + /// ``` + #[inline(always)] + pub fn to_array_2d(self) -> [[T; $size_inner]; $size_outer] { + [ $(self.$field_outer.to_array()), + ] + } + + /// Consumes the matrix and returns its values as a tuple. + /// + /// # Example + /// + /// ``` + /// use fixed_wide_vectors::Vector2; + /// + /// let mat2 = Vector2::new( + /// Vector2::new(0, 0), + /// Vector2::new(0, 0) + /// ); + /// let tuple = mat2.to_tuple_2d(); + /// + /// assert_eq!(tuple, ((0, 0), (0, 0))); + /// ``` + #[inline(always)] + pub fn to_tuple_2d(self) -> ( $($generic_outer), + ) { + ( $(self.$field_outer.to_tuple()), + ) + } + + /// Consumes the matrix and returns a new matrix with the given function applied on each field. + /// + /// # Example + /// + /// ``` + /// use fixed_wide_vectors::Vector2; + /// + /// let mat2 = Vector2::new( + /// Vector2::new(1, 2), + /// Vector2::new(3, 4) + /// ) + /// .map_2d(|i| i * 2); + /// + /// assert_eq!(mat2, Vector2::new(Vector2::new(2, 4), Vector2::new(6, 8))); + /// ``` + #[inline] + pub fn map_2d(self, f: F) -> $struct_outer<$struct_inner> + where + F: Fn(T) -> U + { + $struct_outer { + $( + $field_outer: $crate::matrix_map2d_inner!{f,self,$field_outer,$fields_inner} + ), + + } + } + } + + impl $struct_outer<$struct_inner> { + /// Constructs a matrix using the given `value` as the value for all of its fields. + /// + /// # Example + /// + /// ``` + /// use fixed_wide_vectors::Vector2; + /// + /// let mat2 = Vector2::>::from_value_2d(0); + /// + /// assert_eq!(mat2, Vector2::new(Vector2::new(0, 0), Vector2::new(0, 0))); + /// ``` + #[inline(always)] + pub const fn from_value_2d(value: T) -> Self { + Self { + $( $field_outer: $struct_inner::from_value(value) ), + + } + } + //TODO: diagonal + } + + // Impl floating-point based methods + //#[cfg(feature="fixed_wide_traits")] + //$crate::impl_wide_matrix_operations!( ($struct_outer { $($field_outer), + }, $size_outer), ($struct_inner, $size_inner), $fields_inner ); + }; +} + + +#[doc(hidden)] +#[macro_export(local_inner_macros)] +macro_rules! matrix_map2d_inner { + ( $f:ident, $value:ident, $field_outer:ident, ($struct_inner: ident { $($field_inner: ident), + }) ) => { + $struct_inner { + $( + $field_inner: $f($value.$field_outer.$field_inner) + ), + + } + } +} + +/* +macro_rules! nested { + (($($f:ident),*) $args:tt) => { + $(nested!(@call $f $args);)* + }; + (@call $f:ident ($($arg:expr),*)) => { + $f($($arg),*); + }; +} + +nested! { + (show1, show2) + (a, b, c) +} +*/ + +#[doc(hidden)] +#[macro_export(local_inner_macros)] +macro_rules! impl_matrix_operator { + ( $struct: ident { $($field: ident), + }, $trait: ident, $method: ident, $output: ty ) => { + impl> core::ops::$trait for $struct { + type Output = $output; + + fn $method(self, other: Self) -> Self::Output { + Self { + $( $field: self.$field.$method(other.$field) ), + + } + } + } + impl+Copy> core::ops::$trait for $struct{ + type Output = $output; + + fn $method(self, other: T) -> Self::Output { + $struct { + $( $field: self.$field.$method(other) ), + + } + } + } + }; + + ( $struct: ident { $($field: ident), + }, $trait: ident, $method: ident ) => { + impl core::ops::$trait for $struct { + fn $method(&mut self, other: Self) { + $( self.$field.$method(other.$field) ); + + } + } + + impl core::ops::$trait for $struct { + fn $method(&mut self, other: T) { + $( self.$field.$method(other) ); + + } + } + }; +} diff --git a/fixed_wide_vectors/src/macros/mod.rs b/fixed_wide_vectors/src/macros/mod.rs index 3c74505..dff0bf0 100644 --- a/fixed_wide_vectors/src/macros/mod.rs +++ b/fixed_wide_vectors/src/macros/mod.rs @@ -2,3 +2,4 @@ pub mod wide; pub mod vector; +pub mod matrix; diff --git a/fixed_wide_vectors/src/vector.rs b/fixed_wide_vectors/src/vector.rs index 6e7dae6..6d39e49 100644 --- a/fixed_wide_vectors/src/vector.rs +++ b/fixed_wide_vectors/src/vector.rs @@ -66,3 +66,13 @@ pub struct Vector4 { crate::impl_vector!(Vector2 { x, y }, (T, T), 2); crate::impl_vector!(Vector3 { x, y, z }, (T, T, T), 3); crate::impl_vector!(Vector4 { x, y, z, w }, (T, T, T, T), 4); + +crate::impl_matrix!((Vector2 { x, y }, ((T, T), (T, T)), 2), (Vector2, 2), (Vector2 { x, y }) ); +crate::impl_matrix!((Vector2 { x, y }, ((T, T, T), (T, T, T)), 2), (Vector3, 3), (Vector3 { x, y, z }) ); +crate::impl_matrix!((Vector2 { x, y }, ((T, T, T, T), (T, T, T, T)), 2), (Vector4, 4), (Vector4 { x, y, z, w }) ); +crate::impl_matrix!((Vector3 { x, y, z }, ((T, T), (T, T), (T, T)), 3), (Vector2, 2), (Vector2 { x, y }) ); +crate::impl_matrix!((Vector3 { x, y, z }, ((T, T, T), (T, T, T), (T, T, T)), 3), (Vector3, 3), (Vector3 { x, y, z }) ); +crate::impl_matrix!((Vector3 { x, y, z }, ((T, T, T, T), (T, T, T, T), (T, T, T, T)), 3), (Vector4, 4), (Vector4 { x, y, z, w }) ); +crate::impl_matrix!((Vector4 { x, y, z, w }, ((T, T), (T, T), (T, T), (T, T)), 4), (Vector2, 2), (Vector2 { x, y }) ); +crate::impl_matrix!((Vector4 { x, y, z, w }, ((T, T, T), (T, T, T), (T, T, T), (T, T, T)), 4), (Vector3, 3), (Vector3 { x, y, z }) ); +crate::impl_matrix!((Vector4 { x, y, z, w }, ((T, T, T, T), (T, T, T, T), (T, T, T, T), (T, T, T, T)), 4), (Vector4, 4), (Vector4 { x, y, z, w }) ); From f103c247b818ab9a9a81b34a5a72687024e26102 Mon Sep 17 00:00:00 2001 From: Quaternions Date: Fri, 30 Aug 2024 12:20:54 -0700 Subject: [PATCH 091/227] transpose too easy --- fixed_wide_vectors/src/macros/matrix.rs | 46 +++++++++++++++++++++++++ 1 file changed, 46 insertions(+) diff --git a/fixed_wide_vectors/src/macros/matrix.rs b/fixed_wide_vectors/src/macros/matrix.rs index eaa507c..f3ebce4 100644 --- a/fixed_wide_vectors/src/macros/matrix.rs +++ b/fixed_wide_vectors/src/macros/matrix.rs @@ -73,6 +73,26 @@ macro_rules! impl_matrix { ), + } } + + /// Consumes the matrix and returns a new matrix with the given function applied on each field. + /// + /// # Example + /// + /// ``` + /// use fixed_wide_vectors::Vector2; + /// + /// let mat2 = Vector2::new( + /// Vector2::new(1, 2), + /// Vector2::new(3, 4) + /// ) + /// .transpose(); + /// + /// assert_eq!(mat2, Vector2::new(Vector2::new(1, 3), Vector2::new(2, 4))); + /// ``` + #[inline] + pub fn transpose(self) -> $struct_inner<$struct_outer>{ + $crate::matrix_transpose_outer!{self,$fields_inner,($struct_outer { $($field_outer), + })} + } } impl $struct_outer<$struct_inner> { @@ -114,6 +134,32 @@ macro_rules! matrix_map2d_inner { } } } +#[doc(hidden)] +#[macro_export(local_inner_macros)] +macro_rules! matrix_transpose_outer { + ( + $value:ident, + ($struct_outer: ident { $($field_outer: ident), + }), + $fields_inner:tt + ) => { + $struct_outer { + $( + $field_outer: $crate::matrix_transpose_inner!{$value,$field_outer,$fields_inner} + ), + + } + } +} +#[doc(hidden)] +#[macro_export(local_inner_macros)] +macro_rules! matrix_transpose_inner { + ( $value:ident, $field_outer:ident, ($struct_inner: ident { $($field_inner: ident), + }) ) => { + $struct_inner { + $( + $field_inner: $value.$field_inner.$field_outer + ), + + } + } +} /* macro_rules! nested { From 20285f0f98226f5e72c3f181a4365686e2db86d8 Mon Sep 17 00:00:00 2001 From: Quaternions Date: Fri, 30 Aug 2024 12:31:20 -0700 Subject: [PATCH 092/227] delete affine --- fixed_wide_vectors/src/affine.rs | 20 -------------------- fixed_wide_vectors/src/lib.rs | 3 --- 2 files changed, 23 deletions(-) delete mode 100644 fixed_wide_vectors/src/affine.rs diff --git a/fixed_wide_vectors/src/affine.rs b/fixed_wide_vectors/src/affine.rs deleted file mode 100644 index d4bcc00..0000000 --- a/fixed_wide_vectors/src/affine.rs +++ /dev/null @@ -1,20 +0,0 @@ -use std::ops::Add; -use fixed_wide_traits::wide::WideDot; - -//TODO: replace this with 4x3 matrix -// mat4x3.wide_dot(vec3.extend(1)) - -pub struct Affine{ - pub matrix:M, - pub offset:T, -} - -impl Affine{ - pub fn wide_transform(&self,input:X)-><>::Output as Add>::Output - where - M:WideDot, - >::Output:Add, - { - self.matrix.wide_dot(input)+self.offset - } -} diff --git a/fixed_wide_vectors/src/lib.rs b/fixed_wide_vectors/src/lib.rs index 2dc585f..775c4e6 100644 --- a/fixed_wide_vectors/src/lib.rs +++ b/fixed_wide_vectors/src/lib.rs @@ -1,9 +1,6 @@ mod macros; mod vector; -#[cfg(feature="fixed_wide_traits")] -pub mod affine; - pub use vector::Vector2; pub use vector::Vector3; pub use vector::Vector4; From d713b96ad39bf3c0f504027e3a045207853dda01 Mon Sep 17 00:00:00 2001 From: Quaternions Date: Fri, 30 Aug 2024 12:41:25 -0700 Subject: [PATCH 093/227] vectors: extend --- fixed_wide_vectors/src/macros/vector.rs | 16 ++++++++++++++++ fixed_wide_vectors/src/vector.rs | 3 +++ 2 files changed, 19 insertions(+) diff --git a/fixed_wide_vectors/src/macros/vector.rs b/fixed_wide_vectors/src/macros/vector.rs index 064ff11..8ba5e62 100644 --- a/fixed_wide_vectors/src/macros/vector.rs +++ b/fixed_wide_vectors/src/macros/vector.rs @@ -248,6 +248,22 @@ macro_rules! impl_vector { } +#[doc(hidden)] +#[macro_export(local_inner_macros)] +macro_rules! impl_vector_extend { + ( ($struct: ident { $($field: ident), + }), ($struct_extended: ident, $field_extended: ident) ) => { + impl $struct { + #[inline(always)] + pub fn extend(self,value:T) -> $struct_extended { + $struct_extended { + $( $field:self.$field, ) + + $field_extended:value + } + } + } + }; +} + #[doc(hidden)] #[macro_export(local_inner_macros)] macro_rules! impl_vector_operator { diff --git a/fixed_wide_vectors/src/vector.rs b/fixed_wide_vectors/src/vector.rs index 6d39e49..9f34410 100644 --- a/fixed_wide_vectors/src/vector.rs +++ b/fixed_wide_vectors/src/vector.rs @@ -67,6 +67,9 @@ crate::impl_vector!(Vector2 { x, y }, (T, T), 2); crate::impl_vector!(Vector3 { x, y, z }, (T, T, T), 3); crate::impl_vector!(Vector4 { x, y, z, w }, (T, T, T, T), 4); +crate::impl_vector_extend!((Vector2 { x, y }), (Vector3, z)); +crate::impl_vector_extend!((Vector3 { x, y, z }), (Vector4, w)); + crate::impl_matrix!((Vector2 { x, y }, ((T, T), (T, T)), 2), (Vector2, 2), (Vector2 { x, y }) ); crate::impl_matrix!((Vector2 { x, y }, ((T, T, T), (T, T, T)), 2), (Vector3, 3), (Vector3 { x, y, z }) ); crate::impl_matrix!((Vector2 { x, y }, ((T, T, T, T), (T, T, T, T)), 2), (Vector4, 4), (Vector4 { x, y, z, w }) ); From 263f0d35d4a86aee23a475c73a16b759be285d24 Mon Sep 17 00:00:00 2001 From: Quaternions Date: Fri, 30 Aug 2024 12:52:54 -0700 Subject: [PATCH 094/227] test reason why matrix needs its own type --- .../src/tests/fixed_wide_traits.rs | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/fixed_wide_vectors/src/tests/fixed_wide_traits.rs b/fixed_wide_vectors/src/tests/fixed_wide_traits.rs index 04925e6..a409d5e 100644 --- a/fixed_wide_vectors/src/tests/fixed_wide_traits.rs +++ b/fixed_wide_vectors/src/tests/fixed_wide_traits.rs @@ -4,7 +4,7 @@ use fixed_wide_traits::wide::WideDot; use crate::Vector3; type Planar64=fixed_wide::types::I32F32; -//type Planar64Wide1=fixed::types::I64F64; +type Planar64Wide1=fixed_wide::types::I64F64; //type Planar64Wide2=fixed_wide::types::I128F128; type Planar64Wide3=fixed_wide::types::I256F256; @@ -49,3 +49,17 @@ fn wide_vec3_length_squared(){ assert_eq!(v3,Planar64Wide3::from(3i128.pow(8)*3)); } + +#[test] +fn wide_matrix_dot_vs_vec_of_vec_dot(){ + let vv=Vector3::>::from_value_2d(Planar64::from(3)); + // do the dot product of the inner vectors multiplied component wise + // this lowers the rank of the data structure and is kind of a weird operation lol + let vv_dot=vv.wide_dot(vv); + assert_eq!(vv_dot,crate::Vector2::from_value(Planar64Wide1::from(3i128.pow(3)))); + + //let m=Matrix3::>::from_value_2d(Planar64::from(3)); + //normal matrix product + //let m_dot=m.wide_dot(m); + //assert_eq!(m_dot,Vector3::from_value(Planar64Wide1::from(3i128.pow(3)))); +} From 0f0d7f7a9a434b9dcd73df1771bf3bd0c5c40b9c Mon Sep 17 00:00:00 2001 From: Quaternions Date: Fri, 30 Aug 2024 13:02:48 -0700 Subject: [PATCH 095/227] initial matrix type --- fixed_wide_vectors/src/lib.rs | 5 +++++ fixed_wide_vectors/src/matrix.rs | 27 +++++++++++++++++++++++++++ 2 files changed, 32 insertions(+) create mode 100644 fixed_wide_vectors/src/matrix.rs diff --git a/fixed_wide_vectors/src/lib.rs b/fixed_wide_vectors/src/lib.rs index 775c4e6..a9c0b41 100644 --- a/fixed_wide_vectors/src/lib.rs +++ b/fixed_wide_vectors/src/lib.rs @@ -1,9 +1,14 @@ mod macros; mod vector; +mod matrix; pub use vector::Vector2; pub use vector::Vector3; pub use vector::Vector4; +pub use matrix::Matrix2; +pub use matrix::Matrix3; +pub use matrix::Matrix4; + #[cfg(test)] mod tests; diff --git a/fixed_wide_vectors/src/matrix.rs b/fixed_wide_vectors/src/matrix.rs new file mode 100644 index 0000000..f95a0ee --- /dev/null +++ b/fixed_wide_vectors/src/matrix.rs @@ -0,0 +1,27 @@ +use crate::{Vector2,Vector3,Vector4}; + +pub struct Matrix2 { + pub x_axis: T, + pub y_axis: T, +} +pub struct Matrix3 { + pub x_axis: T, + pub y_axis: T, + pub z_axis: T, +} +pub struct Matrix4 { + pub x_axis: T, + pub y_axis: T, + pub z_axis: T, + pub w_axis: T, +} + +crate::impl_matrix!((Matrix2 { x_axis, y_axis }, ((T, T), (T, T)), 2), (Vector2, 2), (Vector2 { x, y }) ); +crate::impl_matrix!((Matrix2 { x_axis, y_axis }, ((T, T, T), (T, T, T)), 2), (Vector3, 3), (Vector3 { x, y, z }) ); +crate::impl_matrix!((Matrix2 { x_axis, y_axis }, ((T, T, T, T), (T, T, T, T)), 2), (Vector4, 4), (Vector4 { x, y, z, w }) ); +crate::impl_matrix!((Matrix3 { x_axis, y_axis, z_axis }, ((T, T), (T, T), (T, T)), 3), (Vector2, 2), (Vector2 { x, y }) ); +crate::impl_matrix!((Matrix3 { x_axis, y_axis, z_axis }, ((T, T, T), (T, T, T), (T, T, T)), 3), (Vector3, 3), (Vector3 { x, y, z }) ); +crate::impl_matrix!((Matrix3 { x_axis, y_axis, z_axis }, ((T, T, T, T), (T, T, T, T), (T, T, T, T)), 3), (Vector4, 4), (Vector4 { x, y, z, w }) ); +crate::impl_matrix!((Matrix4 { x_axis, y_axis, z_axis, w_axis }, ((T, T), (T, T), (T, T), (T, T)), 4), (Vector2, 2), (Vector2 { x, y }) ); +crate::impl_matrix!((Matrix4 { x_axis, y_axis, z_axis, w_axis }, ((T, T, T), (T, T, T), (T, T, T), (T, T, T)), 4), (Vector3, 3), (Vector3 { x, y, z }) ); +crate::impl_matrix!((Matrix4 { x_axis, y_axis, z_axis, w_axis }, ((T, T, T, T), (T, T, T, T), (T, T, T, T), (T, T, T, T)), 4), (Vector4, 4), (Vector4 { x, y, z, w }) ); From 88acec565905b685213837df15809448d56bbb00 Mon Sep 17 00:00:00 2001 From: Quaternions Date: Fri, 30 Aug 2024 13:07:56 -0700 Subject: [PATCH 096/227] matrix test to pass --- .../src/tests/fixed_wide_traits.rs | 20 ++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/fixed_wide_vectors/src/tests/fixed_wide_traits.rs b/fixed_wide_vectors/src/tests/fixed_wide_traits.rs index a409d5e..d5389c2 100644 --- a/fixed_wide_vectors/src/tests/fixed_wide_traits.rs +++ b/fixed_wide_vectors/src/tests/fixed_wide_traits.rs @@ -1,7 +1,7 @@ use fixed_wide_traits::wide::WideMul; use fixed_wide_traits::wide::WideDot; -use crate::Vector3; +use crate::{Vector2,Vector3,Matrix3}; type Planar64=fixed_wide::types::I32F32; type Planar64Wide1=fixed_wide::types::I64F64; @@ -51,15 +51,17 @@ fn wide_vec3_length_squared(){ } #[test] -fn wide_matrix_dot_vs_vec_of_vec_dot(){ - let vv=Vector3::>::from_value_2d(Planar64::from(3)); +fn wide_vec_of_vec_dot(){ + let vv=Vector3::>::from_value_2d(Planar64::from(3)); // do the dot product of the inner vectors multiplied component wise // this lowers the rank of the data structure and is kind of a weird operation lol let vv_dot=vv.wide_dot(vv); - assert_eq!(vv_dot,crate::Vector2::from_value(Planar64Wide1::from(3i128.pow(3)))); - - //let m=Matrix3::>::from_value_2d(Planar64::from(3)); - //normal matrix product - //let m_dot=m.wide_dot(m); - //assert_eq!(m_dot,Vector3::from_value(Planar64Wide1::from(3i128.pow(3)))); + assert_eq!(vv_dot,Vector2::from_value(Planar64Wide1::from(3i128.pow(3)))); +} +#[test] +fn wide_matrix_dot(){ + let m=Matrix3::>::from_value_2d(Planar64::from(3)); + //normal matrix product + let m_dot=m.wide_dot(m); + assert_eq!(m_dot,Matrix3::>::from_value_2d(Planar64Wide1::from(3i128.pow(2)))); } From e6a28fbb701f9b8e3de6fd553e6d2bf6a7be15fb Mon Sep 17 00:00:00 2001 From: Quaternions Date: Fri, 30 Aug 2024 13:25:27 -0700 Subject: [PATCH 097/227] test doesn't compile yet --- fixed_wide_vectors/src/tests/fixed_wide_traits.rs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/fixed_wide_vectors/src/tests/fixed_wide_traits.rs b/fixed_wide_vectors/src/tests/fixed_wide_traits.rs index d5389c2..bbc1df1 100644 --- a/fixed_wide_vectors/src/tests/fixed_wide_traits.rs +++ b/fixed_wide_vectors/src/tests/fixed_wide_traits.rs @@ -62,6 +62,7 @@ fn wide_vec_of_vec_dot(){ fn wide_matrix_dot(){ let m=Matrix3::>::from_value_2d(Planar64::from(3)); //normal matrix product - let m_dot=m.wide_dot(m); - assert_eq!(m_dot,Matrix3::>::from_value_2d(Planar64Wide1::from(3i128.pow(2)))); + todo!() + //let m_dot=m.wide_dot(m); + //assert_eq!(m_dot,Matrix3::>::from_value_2d(Planar64Wide1::from(3i128.pow(2)))); } From e413409f9fed4a169304ab01f02bdd42dea3f515 Mon Sep 17 00:00:00 2001 From: Quaternions Date: Fri, 30 Aug 2024 13:25:50 -0700 Subject: [PATCH 098/227] remove parentheses from macro --- fixed_wide_vectors/src/macros/vector.rs | 2 +- fixed_wide_vectors/src/vector.rs | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/fixed_wide_vectors/src/macros/vector.rs b/fixed_wide_vectors/src/macros/vector.rs index 8ba5e62..e8da06b 100644 --- a/fixed_wide_vectors/src/macros/vector.rs +++ b/fixed_wide_vectors/src/macros/vector.rs @@ -251,7 +251,7 @@ macro_rules! impl_vector { #[doc(hidden)] #[macro_export(local_inner_macros)] macro_rules! impl_vector_extend { - ( ($struct: ident { $($field: ident), + }), ($struct_extended: ident, $field_extended: ident) ) => { + ( $struct: ident { $($field: ident), + }, $struct_extended: ident, $field_extended: ident ) => { impl $struct { #[inline(always)] pub fn extend(self,value:T) -> $struct_extended { diff --git a/fixed_wide_vectors/src/vector.rs b/fixed_wide_vectors/src/vector.rs index 9f34410..6f95a15 100644 --- a/fixed_wide_vectors/src/vector.rs +++ b/fixed_wide_vectors/src/vector.rs @@ -67,8 +67,8 @@ crate::impl_vector!(Vector2 { x, y }, (T, T), 2); crate::impl_vector!(Vector3 { x, y, z }, (T, T, T), 3); crate::impl_vector!(Vector4 { x, y, z, w }, (T, T, T, T), 4); -crate::impl_vector_extend!((Vector2 { x, y }), (Vector3, z)); -crate::impl_vector_extend!((Vector3 { x, y, z }), (Vector4, w)); +crate::impl_vector_extend!(Vector2 { x, y }, Vector3, z); +crate::impl_vector_extend!(Vector3 { x, y, z }, Vector4, w); crate::impl_matrix!((Vector2 { x, y }, ((T, T), (T, T)), 2), (Vector2, 2), (Vector2 { x, y }) ); crate::impl_matrix!((Vector2 { x, y }, ((T, T, T), (T, T, T)), 2), (Vector3, 3), (Vector3 { x, y, z }) ); From 9aba811cd0d12fb50671e4462aef63eb7d615024 Mon Sep 17 00:00:00 2001 From: Quaternions Date: Fri, 30 Aug 2024 13:27:26 -0700 Subject: [PATCH 099/227] delete spam doc tests --- fixed_wide_vectors/src/macros/matrix.rs | 71 ------------------------- 1 file changed, 71 deletions(-) diff --git a/fixed_wide_vectors/src/macros/matrix.rs b/fixed_wide_vectors/src/macros/matrix.rs index f3ebce4..23755f3 100644 --- a/fixed_wide_vectors/src/macros/matrix.rs +++ b/fixed_wide_vectors/src/macros/matrix.rs @@ -7,61 +7,16 @@ macro_rules! impl_matrix { ($struct_inner: ident, $size_inner: expr), $fields_inner:tt ) => { impl $struct_outer<$struct_inner> { - /// Consumes the matrix and returns its values as an array. - /// - /// # Example - /// - /// ``` - /// use fixed_wide_vectors::Vector2; - /// - /// let mat2 = Vector2::new( - /// Vector2::new(0, 0), - /// Vector2::new(0, 0) - /// ); - /// let array = mat2.to_array_2d(); - /// - /// assert_eq!(array, [[0, 0], [0, 0]]); - /// ``` #[inline(always)] pub fn to_array_2d(self) -> [[T; $size_inner]; $size_outer] { [ $(self.$field_outer.to_array()), + ] } - /// Consumes the matrix and returns its values as a tuple. - /// - /// # Example - /// - /// ``` - /// use fixed_wide_vectors::Vector2; - /// - /// let mat2 = Vector2::new( - /// Vector2::new(0, 0), - /// Vector2::new(0, 0) - /// ); - /// let tuple = mat2.to_tuple_2d(); - /// - /// assert_eq!(tuple, ((0, 0), (0, 0))); - /// ``` #[inline(always)] pub fn to_tuple_2d(self) -> ( $($generic_outer), + ) { ( $(self.$field_outer.to_tuple()), + ) } - /// Consumes the matrix and returns a new matrix with the given function applied on each field. - /// - /// # Example - /// - /// ``` - /// use fixed_wide_vectors::Vector2; - /// - /// let mat2 = Vector2::new( - /// Vector2::new(1, 2), - /// Vector2::new(3, 4) - /// ) - /// .map_2d(|i| i * 2); - /// - /// assert_eq!(mat2, Vector2::new(Vector2::new(2, 4), Vector2::new(6, 8))); - /// ``` #[inline] pub fn map_2d(self, f: F) -> $struct_outer<$struct_inner> where @@ -74,21 +29,6 @@ macro_rules! impl_matrix { } } - /// Consumes the matrix and returns a new matrix with the given function applied on each field. - /// - /// # Example - /// - /// ``` - /// use fixed_wide_vectors::Vector2; - /// - /// let mat2 = Vector2::new( - /// Vector2::new(1, 2), - /// Vector2::new(3, 4) - /// ) - /// .transpose(); - /// - /// assert_eq!(mat2, Vector2::new(Vector2::new(1, 3), Vector2::new(2, 4))); - /// ``` #[inline] pub fn transpose(self) -> $struct_inner<$struct_outer>{ $crate::matrix_transpose_outer!{self,$fields_inner,($struct_outer { $($field_outer), + })} @@ -96,17 +36,6 @@ macro_rules! impl_matrix { } impl $struct_outer<$struct_inner> { - /// Constructs a matrix using the given `value` as the value for all of its fields. - /// - /// # Example - /// - /// ``` - /// use fixed_wide_vectors::Vector2; - /// - /// let mat2 = Vector2::>::from_value_2d(0); - /// - /// assert_eq!(mat2, Vector2::new(Vector2::new(0, 0), Vector2::new(0, 0))); - /// ``` #[inline(always)] pub const fn from_value_2d(value: T) -> Self { Self { From 83a39468d514881defa3ea349ef8ce62f38820e6 Mon Sep 17 00:00:00 2001 From: Quaternions Date: Fri, 30 Aug 2024 13:49:23 -0700 Subject: [PATCH 100/227] matrix extend --- fixed_wide_vectors/src/macros/vector.rs | 2 +- fixed_wide_vectors/src/matrix.rs | 3 +++ fixed_wide_vectors/src/vector.rs | 4 ++-- 3 files changed, 6 insertions(+), 3 deletions(-) diff --git a/fixed_wide_vectors/src/macros/vector.rs b/fixed_wide_vectors/src/macros/vector.rs index e8da06b..3af837a 100644 --- a/fixed_wide_vectors/src/macros/vector.rs +++ b/fixed_wide_vectors/src/macros/vector.rs @@ -250,7 +250,7 @@ macro_rules! impl_vector { #[doc(hidden)] #[macro_export(local_inner_macros)] -macro_rules! impl_vector_extend { +macro_rules! impl_extend { ( $struct: ident { $($field: ident), + }, $struct_extended: ident, $field_extended: ident ) => { impl $struct { #[inline(always)] diff --git a/fixed_wide_vectors/src/matrix.rs b/fixed_wide_vectors/src/matrix.rs index f95a0ee..9a658b8 100644 --- a/fixed_wide_vectors/src/matrix.rs +++ b/fixed_wide_vectors/src/matrix.rs @@ -16,6 +16,9 @@ pub struct Matrix4 { pub w_axis: T, } +crate::impl_extend!(Matrix2 { x_axis, y_axis }, Matrix3, z_axis); +crate::impl_extend!(Matrix3 { x_axis, y_axis, z_axis }, Matrix4, w_axis); + crate::impl_matrix!((Matrix2 { x_axis, y_axis }, ((T, T), (T, T)), 2), (Vector2, 2), (Vector2 { x, y }) ); crate::impl_matrix!((Matrix2 { x_axis, y_axis }, ((T, T, T), (T, T, T)), 2), (Vector3, 3), (Vector3 { x, y, z }) ); crate::impl_matrix!((Matrix2 { x_axis, y_axis }, ((T, T, T, T), (T, T, T, T)), 2), (Vector4, 4), (Vector4 { x, y, z, w }) ); diff --git a/fixed_wide_vectors/src/vector.rs b/fixed_wide_vectors/src/vector.rs index 6f95a15..b9df27c 100644 --- a/fixed_wide_vectors/src/vector.rs +++ b/fixed_wide_vectors/src/vector.rs @@ -67,8 +67,8 @@ crate::impl_vector!(Vector2 { x, y }, (T, T), 2); crate::impl_vector!(Vector3 { x, y, z }, (T, T, T), 3); crate::impl_vector!(Vector4 { x, y, z, w }, (T, T, T, T), 4); -crate::impl_vector_extend!(Vector2 { x, y }, Vector3, z); -crate::impl_vector_extend!(Vector3 { x, y, z }, Vector4, w); +crate::impl_extend!(Vector2 { x, y }, Vector3, z); +crate::impl_extend!(Vector3 { x, y, z }, Vector4, w); crate::impl_matrix!((Vector2 { x, y }, ((T, T), (T, T)), 2), (Vector2, 2), (Vector2 { x, y }) ); crate::impl_matrix!((Vector2 { x, y }, ((T, T, T), (T, T, T)), 2), (Vector3, 3), (Vector3 { x, y, z }) ); From 63cf94499bdb7a95c951a5623f7c99f5a91b5212 Mon Sep 17 00:00:00 2001 From: Quaternions Date: Fri, 30 Aug 2024 14:49:15 -0700 Subject: [PATCH 101/227] rewrite transpose --- fixed_wide_vectors/src/macros/matrix.rs | 42 +++++++++++++++++-------- fixed_wide_vectors/src/matrix.rs | 18 +++++------ fixed_wide_vectors/src/vector.rs | 18 +++++------ 3 files changed, 47 insertions(+), 31 deletions(-) diff --git a/fixed_wide_vectors/src/macros/matrix.rs b/fixed_wide_vectors/src/macros/matrix.rs index 23755f3..f9375e7 100644 --- a/fixed_wide_vectors/src/macros/matrix.rs +++ b/fixed_wide_vectors/src/macros/matrix.rs @@ -3,8 +3,9 @@ #[macro_export(local_inner_macros)] macro_rules! impl_matrix { ( - ($struct_outer: ident { $($field_outer: ident), + }, ( $($generic_outer: tt), + ), $size_outer: expr), - ($struct_inner: ident, $size_inner: expr), $fields_inner:tt + ($struct_outer: ident { $($field_outer: ident), + }, $vector_outer: ident { $($vector_field_outer: ident), + }, $size_outer: expr), + ($struct_inner: ident { $($field_inner: ident), + }, $matrix_inner: ident { $($matrix_field_inner: ident), + }, $size_inner: expr), + ( $($generic_outer: tt), + ) ) => { impl $struct_outer<$struct_inner> { #[inline(always)] @@ -22,16 +23,15 @@ macro_rules! impl_matrix { where F: Fn(T) -> U { - $struct_outer { - $( - $field_outer: $crate::matrix_map2d_inner!{f,self,$field_outer,$fields_inner} - ), + - } + $crate::matrix_map2d_outer!{f,self,($struct_outer { $($field_outer), + }),($struct_inner { $($field_inner), + })} } #[inline] - pub fn transpose(self) -> $struct_inner<$struct_outer>{ - $crate::matrix_transpose_outer!{self,$fields_inner,($struct_outer { $($field_outer), + })} + pub fn transpose(self) -> $matrix_inner<$vector_outer>{ + $crate::matrix_transpose_outer!{self, + ($matrix_inner { $($matrix_field_inner), + }),($struct_inner { $($field_inner), + }), + ($vector_outer { $($vector_field_outer), + }),($struct_outer { $($field_outer), + }) + } } } @@ -52,6 +52,17 @@ macro_rules! impl_matrix { } +#[doc(hidden)] +#[macro_export(local_inner_macros)] +macro_rules! matrix_map2d_outer { + ( $f:ident, $value:ident, ($struct_outer: ident { $($field_outer: ident), + }), $unparsed_inner:tt ) => { + $struct_outer { + $( + $field_outer: $crate::matrix_map2d_inner!{$f,$value,$field_outer,$unparsed_inner} + ), + + } + } +} #[doc(hidden)] #[macro_export(local_inner_macros)] macro_rules! matrix_map2d_inner { @@ -69,11 +80,13 @@ macro_rules! matrix_transpose_outer { ( $value:ident, ($struct_outer: ident { $($field_outer: ident), + }), - $fields_inner:tt + ($old_outer: ident { $($old_field_outer: ident), + }), + $fields_inner:tt, + $old_fields_inner:tt ) => { $struct_outer { $( - $field_outer: $crate::matrix_transpose_inner!{$value,$field_outer,$fields_inner} + $field_outer: $crate::matrix_transpose_inner!{$value,$old_field_outer,$fields_inner,$old_fields_inner} ), + } } @@ -81,10 +94,13 @@ macro_rules! matrix_transpose_outer { #[doc(hidden)] #[macro_export(local_inner_macros)] macro_rules! matrix_transpose_inner { - ( $value:ident, $field_outer:ident, ($struct_inner: ident { $($field_inner: ident), + }) ) => { + ( $value:ident, $field_outer:ident, + ($struct_inner: ident { $($field_inner: ident), + }), + ($old_struct_inner: ident { $($old_field_inner: ident), + }) + ) => { $struct_inner { $( - $field_inner: $value.$field_inner.$field_outer + $field_inner: $value.$old_field_inner.$field_outer ), + } } diff --git a/fixed_wide_vectors/src/matrix.rs b/fixed_wide_vectors/src/matrix.rs index 9a658b8..a1e6943 100644 --- a/fixed_wide_vectors/src/matrix.rs +++ b/fixed_wide_vectors/src/matrix.rs @@ -19,12 +19,12 @@ pub struct Matrix4 { crate::impl_extend!(Matrix2 { x_axis, y_axis }, Matrix3, z_axis); crate::impl_extend!(Matrix3 { x_axis, y_axis, z_axis }, Matrix4, w_axis); -crate::impl_matrix!((Matrix2 { x_axis, y_axis }, ((T, T), (T, T)), 2), (Vector2, 2), (Vector2 { x, y }) ); -crate::impl_matrix!((Matrix2 { x_axis, y_axis }, ((T, T, T), (T, T, T)), 2), (Vector3, 3), (Vector3 { x, y, z }) ); -crate::impl_matrix!((Matrix2 { x_axis, y_axis }, ((T, T, T, T), (T, T, T, T)), 2), (Vector4, 4), (Vector4 { x, y, z, w }) ); -crate::impl_matrix!((Matrix3 { x_axis, y_axis, z_axis }, ((T, T), (T, T), (T, T)), 3), (Vector2, 2), (Vector2 { x, y }) ); -crate::impl_matrix!((Matrix3 { x_axis, y_axis, z_axis }, ((T, T, T), (T, T, T), (T, T, T)), 3), (Vector3, 3), (Vector3 { x, y, z }) ); -crate::impl_matrix!((Matrix3 { x_axis, y_axis, z_axis }, ((T, T, T, T), (T, T, T, T), (T, T, T, T)), 3), (Vector4, 4), (Vector4 { x, y, z, w }) ); -crate::impl_matrix!((Matrix4 { x_axis, y_axis, z_axis, w_axis }, ((T, T), (T, T), (T, T), (T, T)), 4), (Vector2, 2), (Vector2 { x, y }) ); -crate::impl_matrix!((Matrix4 { x_axis, y_axis, z_axis, w_axis }, ((T, T, T), (T, T, T), (T, T, T), (T, T, T)), 4), (Vector3, 3), (Vector3 { x, y, z }) ); -crate::impl_matrix!((Matrix4 { x_axis, y_axis, z_axis, w_axis }, ((T, T, T, T), (T, T, T, T), (T, T, T, T), (T, T, T, T)), 4), (Vector4, 4), (Vector4 { x, y, z, w }) ); +crate::impl_matrix!((Matrix2 { x_axis, y_axis }, Vector2 { x, y }, 2), (Vector2 { x, y }, Matrix2 { x_axis, y_axis }, 2), ((T, T), (T, T)) ); +crate::impl_matrix!((Matrix2 { x_axis, y_axis }, Vector2 { x, y }, 2), (Vector3 { x, y, z }, Matrix3 { x_axis, y_axis, z_axis }, 3), ((T, T, T), (T, T, T)) ); +crate::impl_matrix!((Matrix2 { x_axis, y_axis }, Vector2 { x, y }, 2), (Vector4 { x, y, z, w }, Matrix4 { x_axis, y_axis, z_axis, w_axis }, 4), ((T, T, T, T), (T, T, T, T)) ); +crate::impl_matrix!((Matrix3 { x_axis, y_axis, z_axis }, Vector3 { x, y, z }, 3), (Vector2 { x, y }, Matrix2 { x_axis, y_axis }, 2), ((T, T), (T, T), (T, T)) ); +crate::impl_matrix!((Matrix3 { x_axis, y_axis, z_axis }, Vector3 { x, y, z }, 3), (Vector3 { x, y, z }, Matrix3 { x_axis, y_axis, z_axis }, 3), ((T, T, T), (T, T, T), (T, T, T)) ); +crate::impl_matrix!((Matrix3 { x_axis, y_axis, z_axis }, Vector3 { x, y, z }, 3), (Vector4 { x, y, z, w }, Matrix4 { x_axis, y_axis, z_axis, w_axis }, 4), ((T, T, T, T), (T, T, T, T), (T, T, T, T)) ); +crate::impl_matrix!((Matrix4 { x_axis, y_axis, z_axis, w_axis }, Vector4 { x, y, z, w }, 4), (Vector2 { x, y }, Matrix2 { x_axis, y_axis }, 2), ((T, T), (T, T), (T, T), (T, T)) ); +crate::impl_matrix!((Matrix4 { x_axis, y_axis, z_axis, w_axis }, Vector4 { x, y, z, w }, 4), (Vector3 { x, y, z }, Matrix3 { x_axis, y_axis, z_axis }, 3), ((T, T, T), (T, T, T), (T, T, T), (T, T, T)) ); +crate::impl_matrix!((Matrix4 { x_axis, y_axis, z_axis, w_axis }, Vector4 { x, y, z, w }, 4), (Vector4 { x, y, z, w }, Matrix4 { x_axis, y_axis, z_axis, w_axis }, 4), ((T, T, T, T), (T, T, T, T), (T, T, T, T), (T, T, T, T)) ); diff --git a/fixed_wide_vectors/src/vector.rs b/fixed_wide_vectors/src/vector.rs index b9df27c..c528b5c 100644 --- a/fixed_wide_vectors/src/vector.rs +++ b/fixed_wide_vectors/src/vector.rs @@ -70,12 +70,12 @@ crate::impl_vector!(Vector4 { x, y, z, w }, (T, T, T, T), 4); crate::impl_extend!(Vector2 { x, y }, Vector3, z); crate::impl_extend!(Vector3 { x, y, z }, Vector4, w); -crate::impl_matrix!((Vector2 { x, y }, ((T, T), (T, T)), 2), (Vector2, 2), (Vector2 { x, y }) ); -crate::impl_matrix!((Vector2 { x, y }, ((T, T, T), (T, T, T)), 2), (Vector3, 3), (Vector3 { x, y, z }) ); -crate::impl_matrix!((Vector2 { x, y }, ((T, T, T, T), (T, T, T, T)), 2), (Vector4, 4), (Vector4 { x, y, z, w }) ); -crate::impl_matrix!((Vector3 { x, y, z }, ((T, T), (T, T), (T, T)), 3), (Vector2, 2), (Vector2 { x, y }) ); -crate::impl_matrix!((Vector3 { x, y, z }, ((T, T, T), (T, T, T), (T, T, T)), 3), (Vector3, 3), (Vector3 { x, y, z }) ); -crate::impl_matrix!((Vector3 { x, y, z }, ((T, T, T, T), (T, T, T, T), (T, T, T, T)), 3), (Vector4, 4), (Vector4 { x, y, z, w }) ); -crate::impl_matrix!((Vector4 { x, y, z, w }, ((T, T), (T, T), (T, T), (T, T)), 4), (Vector2, 2), (Vector2 { x, y }) ); -crate::impl_matrix!((Vector4 { x, y, z, w }, ((T, T, T), (T, T, T), (T, T, T), (T, T, T)), 4), (Vector3, 3), (Vector3 { x, y, z }) ); -crate::impl_matrix!((Vector4 { x, y, z, w }, ((T, T, T, T), (T, T, T, T), (T, T, T, T), (T, T, T, T)), 4), (Vector4, 4), (Vector4 { x, y, z, w }) ); +crate::impl_matrix!((Vector2 { x, y }, Vector2 { x, y }, 2), (Vector2 { x, y }, Vector2 { x, y }, 2), ((T, T), (T, T)) ); +crate::impl_matrix!((Vector2 { x, y }, Vector2 { x, y }, 2), (Vector3 { x, y, z }, Vector3 { x, y, z }, 3), ((T, T, T), (T, T, T)) ); +crate::impl_matrix!((Vector2 { x, y }, Vector2 { x, y }, 2), (Vector4 { x, y, z, w }, Vector4 { x, y, z, w }, 4), ((T, T, T, T), (T, T, T, T)) ); +crate::impl_matrix!((Vector3 { x, y, z }, Vector3 { x, y, z }, 3), (Vector2 { x, y }, Vector2 { x, y }, 2), ((T, T), (T, T), (T, T)) ); +crate::impl_matrix!((Vector3 { x, y, z }, Vector3 { x, y, z }, 3), (Vector3 { x, y, z }, Vector3 { x, y, z }, 3), ((T, T, T), (T, T, T), (T, T, T)) ); +crate::impl_matrix!((Vector3 { x, y, z }, Vector3 { x, y, z }, 3), (Vector4 { x, y, z, w }, Vector4 { x, y, z, w }, 4), ((T, T, T, T), (T, T, T, T), (T, T, T, T)) ); +crate::impl_matrix!((Vector4 { x, y, z, w }, Vector4 { x, y, z, w }, 4), (Vector2 { x, y }, Vector2 { x, y }, 2), ((T, T), (T, T), (T, T), (T, T)) ); +crate::impl_matrix!((Vector4 { x, y, z, w }, Vector4 { x, y, z, w }, 4), (Vector3 { x, y, z }, Vector3 { x, y, z }, 3), ((T, T, T), (T, T, T), (T, T, T), (T, T, T)) ); +crate::impl_matrix!((Vector4 { x, y, z, w }, Vector4 { x, y, z, w }, 4), (Vector4 { x, y, z, w }, Vector4 { x, y, z, w }, 4), ((T, T, T, T), (T, T, T, T), (T, T, T, T), (T, T, T, T)) ); From 2a2e729f59da29bfcc780a01423c42c8ed8d5e72 Mon Sep 17 00:00:00 2001 From: Quaternions Date: Mon, 2 Sep 2024 16:15:17 -0700 Subject: [PATCH 102/227] wip --- deferred_division/.gitignore | 1 - deferred_division/Cargo.lock | 36 ------ deferred_division/Cargo.toml | 14 --- deferred_division/src/lib.rs | 8 -- deferred_division/src/ratio.rs | 157 --------------------------- deferred_division/src/tests/mod.rs | 4 - deferred_division/src/tests/tests.rs | 22 ---- deferred_division/src/tests/wide.rs | 15 --- deferred_division/src/wide.rs | 58 ---------- fixed_wide/Cargo.lock | 12 +- fixed_wide/Cargo.toml | 7 +- fixed_wide/src/fixed.rs | 97 ++++++++++++++++- fixed_wide/src/fixed_wide_traits.rs | 88 --------------- fixed_wide/src/lib.rs | 9 +- fixed_wide/src/ratio.rs | 10 ++ fixed_wide/src/tests.rs | 1 - fixed_wide/src/traits.rs | 8 ++ fixed_wide/src/zeroes.rs | 58 ++++++++++ fixed_wide_traits/.gitignore | 1 - fixed_wide_traits/Cargo.lock | 63 ----------- fixed_wide_traits/Cargo.toml | 10 -- fixed_wide_traits/src/lib.rs | 2 - fixed_wide_traits/src/narrow.rs | 57 ---------- fixed_wide_traits/src/wide.rs | 16 --- 24 files changed, 188 insertions(+), 566 deletions(-) delete mode 100644 deferred_division/.gitignore delete mode 100644 deferred_division/Cargo.lock delete mode 100644 deferred_division/Cargo.toml delete mode 100644 deferred_division/src/lib.rs delete mode 100644 deferred_division/src/ratio.rs delete mode 100644 deferred_division/src/tests/mod.rs delete mode 100644 deferred_division/src/tests/tests.rs delete mode 100644 deferred_division/src/tests/wide.rs delete mode 100644 deferred_division/src/wide.rs delete mode 100644 fixed_wide/src/fixed_wide_traits.rs create mode 100644 fixed_wide/src/ratio.rs create mode 100644 fixed_wide/src/traits.rs create mode 100644 fixed_wide/src/zeroes.rs delete mode 100644 fixed_wide_traits/.gitignore delete mode 100644 fixed_wide_traits/Cargo.lock delete mode 100644 fixed_wide_traits/Cargo.toml delete mode 100644 fixed_wide_traits/src/lib.rs delete mode 100644 fixed_wide_traits/src/narrow.rs delete mode 100644 fixed_wide_traits/src/wide.rs diff --git a/deferred_division/.gitignore b/deferred_division/.gitignore deleted file mode 100644 index ea8c4bf..0000000 --- a/deferred_division/.gitignore +++ /dev/null @@ -1 +0,0 @@ -/target diff --git a/deferred_division/Cargo.lock b/deferred_division/Cargo.lock deleted file mode 100644 index 512511f..0000000 --- a/deferred_division/Cargo.lock +++ /dev/null @@ -1,36 +0,0 @@ -# This file is automatically @generated by Cargo. -# It is not intended for manual editing. -version = 3 - -[[package]] -name = "bnum" -version = "0.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3e31ea183f6ee62ac8b8a8cf7feddd766317adfb13ff469de57ce033efd6a790" - -[[package]] -name = "deferred_division" -version = "0.1.0" -dependencies = [ - "fixed_wide", - "fixed_wide_traits", -] - -[[package]] -name = "fixed_wide" -version = "0.1.0" -dependencies = [ - "bnum", - "fixed_wide_traits", - "typenum", -] - -[[package]] -name = "fixed_wide_traits" -version = "0.1.0" - -[[package]] -name = "typenum" -version = "1.17.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825" diff --git a/deferred_division/Cargo.toml b/deferred_division/Cargo.toml deleted file mode 100644 index 0f2ab79..0000000 --- a/deferred_division/Cargo.toml +++ /dev/null @@ -1,14 +0,0 @@ -[package] -name = "deferred_division" -version = "0.1.0" -edition = "2021" - -[features] -default=["fixed_wide_traits"] -fixed_wide_traits=["dep:fixed_wide_traits"] - -[dependencies] -fixed_wide_traits = { version = "0.1.0", path = "../fixed_wide_traits", optional = true } - -[dev-dependencies] -fixed_wide = { version = "0.1.0", path = "../fixed_wide" } diff --git a/deferred_division/src/lib.rs b/deferred_division/src/lib.rs deleted file mode 100644 index 86c9a9d..0000000 --- a/deferred_division/src/lib.rs +++ /dev/null @@ -1,8 +0,0 @@ -pub mod ratio; - - -#[cfg(feature="fixed_wide_traits")] -mod wide; - -#[cfg(test)] -mod tests; diff --git a/deferred_division/src/ratio.rs b/deferred_division/src/ratio.rs deleted file mode 100644 index c5abad4..0000000 --- a/deferred_division/src/ratio.rs +++ /dev/null @@ -1,157 +0,0 @@ -use std::ops::Mul; - -#[derive(Clone,Copy,Debug,Hash)] -pub struct Ratio{ - pub(crate)num:Num, - pub(crate)den:Den, -} -impl Ratio{ - pub const fn new(num:Num,den:Den)->Self{ - Self{num,den} - } -} - -impl PartialEq for Ratio - where - Den:Copy, - Rhs:Mul+Copy, - Num:PartialEq<>::Output> -{ - fn eq(&self,rhs:&Rhs)->bool{ - self.num.eq(&rhs.mul(self.den)) - } -} -/* -//You can't do Ratio==Ratio I guess -impl Eq for Ratio -where - Num:Mul, - >::Output:PartialEq -{} -*/ - -// num/den == rhs -// num == rhs * den - -impl PartialOrd for Ratio - where - Den:Copy, - Rhs:Mul+Copy, - Num:PartialOrd<>::Output> -{ - fn partial_cmp(&self,rhs:&Rhs)->Option{ - self.num.partial_cmp(&rhs.mul(self.den)) - } -} -/* -impl Ord for Ratio<>::Output,Den> -where - Rhs:Mul, - Rhs:Ord, - >::Output:Ord, -{ - fn cmp(&self,other:&Rhs)->std::cmp::Ordering{ - self.num.cmp(&other.mul(self.den)) - } -} -*/ - -impl,Den> std::ops::Neg for Ratio{ - type Output=Ratio; - fn neg(self)->Self::Output{ - Ratio{ - num:self.num.neg(), - den:self.den, - } - } -} - -// num/den + rhs == new_num/den -// new_num = num + rhs * den - -macro_rules! impl_operator { - ($struct:ident,$trait:ident,$method:ident)=>{ - impl core::ops::$trait for $struct - where - Den:Copy, - Rhs:Mul, - Num:core::ops::$trait<>::Output>, - { - type Output=$struct<>::Output>>::Output,Den>; - - fn $method(self,rhs:Rhs)->Self::Output{ - $struct{ - num:self.num.$method(rhs.mul(self.den)), - den:self.den, - } - } - } - }; -} -macro_rules! impl_assign_operator{ - ($struct:ident,$trait:ident,$method:ident)=>{ - impl core::ops::$trait for $struct - where - Den:Copy, - Rhs:Mul, - Num:core::ops::$trait<>::Output>, - { - fn $method(&mut self,rhs:Rhs){ - self.num.$method(rhs.mul(self.den)); - } - } - }; -} - -// Impl arithmetic operators -impl_assign_operator!(Ratio,AddAssign,add_assign); -impl_operator!(Ratio,Add,add); -impl_assign_operator!(Ratio,SubAssign,sub_assign); -impl_operator!(Ratio,Sub,sub); -// num/den % rhs == new_num/den -// new_num = num % (rhs * den) -impl_assign_operator!(Ratio,RemAssign,rem_assign); -impl_operator!(Ratio,Rem,rem); - -//mul and div is special -impl Mul for Ratio - where - Num:Mul, -{ - type Output=Ratio<>::Output,Den>; - fn mul(self,rhs:Rhs)->Self::Output{ - Ratio{ - num:self.num.mul(rhs), - den:self.den, - } - } -} -impl core::ops::MulAssign for Ratio - where - Num:core::ops::MulAssign, -{ - fn mul_assign(&mut self,rhs:Rhs){ - self.num.mul_assign(rhs); - } -} - -impl core::ops::Div for Ratio - where - Den:Mul, -{ - type Output=Ratio>::Output>; - fn div(self,rhs:Rhs)->Self::Output{ - Ratio{ - num:self.num, - den:self.den.mul(rhs), - } - } -} -impl core::ops::DivAssign for Ratio - where - Den:core::ops::MulAssign, -{ - fn div_assign(&mut self,rhs:Rhs){ - self.den.mul_assign(rhs); - } -} diff --git a/deferred_division/src/tests/mod.rs b/deferred_division/src/tests/mod.rs deleted file mode 100644 index a74aed6..0000000 --- a/deferred_division/src/tests/mod.rs +++ /dev/null @@ -1,4 +0,0 @@ -mod tests; - -#[cfg(feature="fixed_wide_traits")] -mod wide; diff --git a/deferred_division/src/tests/tests.rs b/deferred_division/src/tests/tests.rs deleted file mode 100644 index d004719..0000000 --- a/deferred_division/src/tests/tests.rs +++ /dev/null @@ -1,22 +0,0 @@ -use crate::ratio::Ratio; - -#[test] -fn ratio(){ - let r=Ratio::new(5,3); - let a=r%1; - assert_eq!(a.num,2); - assert_eq!(a.den,3); - let b=r*2; - assert_eq!(b.num,10); - assert_eq!(b.den,3); - let c=r/2; - assert_eq!(c.num,5); - assert_eq!(c.den,6); -} - -#[test] -fn add_ratio_cmp(){ - let a=Ratio::new(5,3); - let b=Ratio::new(1,3); - assert_eq!(a+b,2); -} diff --git a/deferred_division/src/tests/wide.rs b/deferred_division/src/tests/wide.rs deleted file mode 100644 index 4246565..0000000 --- a/deferred_division/src/tests/wide.rs +++ /dev/null @@ -1,15 +0,0 @@ -use crate::ratio::Ratio; -use fixed_wide_traits::wide::{WideMul,WideDiv}; -use fixed_wide::types::I32F32; -use fixed_wide::types::I64F64; - -#[test] -fn ratio(){ - let r=Ratio::new(I32F32::from(5),I32F32::from(3)); - let a=r.wide_mul(I32F32::from(7)>>2); - assert_eq!(a.num,I64F64::from(7*5)>>2); - assert_eq!(a.den,I32F32::from(3)); - let a=r.wide_div(I32F32::from(7)>>2); - assert_eq!(a.num,I32F32::from(5)); - assert_eq!(a.den,I64F64::from(3*7)>>2); -} diff --git a/deferred_division/src/wide.rs b/deferred_division/src/wide.rs deleted file mode 100644 index c2e1205..0000000 --- a/deferred_division/src/wide.rs +++ /dev/null @@ -1,58 +0,0 @@ -use std::ops::{Add,Mul}; -use crate::ratio::Ratio; -use fixed_wide_traits::wide::{WideMul,WideDiv,WideDot,WideCross}; - -impl Ratio -{ - pub fn rational_add(self,rhs:T)->Ratio<>::Output>>::Output,Den> - where - Den:Mul, - Num:Add<>::Output>, - { - Ratio{ - num:self.num+self.den.mul(rhs), - den:self.den, - } - } - pub fn wide_rational_add(self,rhs:T)->Ratio<>::Output>>::Output,Den> - where - Den:WideMul, - Num:Add<>::Output>, - { - Ratio{ - num:self.num+self.den.wide_mul(rhs), - den:self.den, - } - } -} -macro_rules! impl_mul_operator { - ($struct:ident,$trait:ident,$method:ident)=>{ - impl $trait for $struct - where - Num:$trait, - { - type Output=$struct<>::Output,Den>; - fn $method(self,rhs:Rhs)->Self::Output{ - $struct{ - num:self.num.$method(rhs), - den:self.den, - } - } - } - } -} -impl_mul_operator!(Ratio,WideMul,wide_mul); -impl_mul_operator!(Ratio,WideDot,wide_dot); -impl_mul_operator!(Ratio,WideCross,wide_cross); -impl WideDiv for Ratio - where - Den:WideMul, -{ - type Output=Ratio>::Output>; - fn wide_div(self,rhs:T)->Ratio>::Output>{ - Ratio{ - num:self.num, - den:self.den.wide_mul(rhs), - } - } -} diff --git a/fixed_wide/Cargo.lock b/fixed_wide/Cargo.lock index c65cd17..e28b2bc 100644 --- a/fixed_wide/Cargo.lock +++ b/fixed_wide/Cargo.lock @@ -2,6 +2,12 @@ # It is not intended for manual editing. version = 3 +[[package]] +name = "arrayvec" +version = "0.7.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7c02d123df017efcdfbd739ef81735b36c5ba83ec3c59c80a9d7ecc718f92e50" + [[package]] name = "bnum" version = "0.11.0" @@ -12,15 +18,11 @@ checksum = "3e31ea183f6ee62ac8b8a8cf7feddd766317adfb13ff469de57ce033efd6a790" name = "fixed_wide" version = "0.1.0" dependencies = [ + "arrayvec", "bnum", - "fixed_wide_traits", "typenum", ] -[[package]] -name = "fixed_wide_traits" -version = "0.1.0" - [[package]] name = "typenum" version = "1.17.0" diff --git a/fixed_wide/Cargo.toml b/fixed_wide/Cargo.toml index 84206fd..8b2b4e9 100644 --- a/fixed_wide/Cargo.toml +++ b/fixed_wide/Cargo.toml @@ -4,10 +4,11 @@ version = "0.1.0" edition = "2021" [features] -default=["fixed_wide_traits"] -fixed_wide_traits=["dep:fixed_wide_traits"] +default=["zeroes"] +ratio=[] +zeroes=["ratio","dep:arrayvec"] [dependencies] bnum = "0.11.0" typenum = "1.17.0" -fixed_wide_traits = { version = "0.1.0", path = "../fixed_wide_traits", optional = true } +arrayvec = { version = "0.7.6", optional = true } diff --git a/fixed_wide/src/fixed.rs b/fixed_wide/src/fixed.rs index 663be09..4045ff1 100644 --- a/fixed_wide/src/fixed.rs +++ b/fixed_wide/src/fixed.rs @@ -1,5 +1,6 @@ use bnum::{BInt,cast::As}; -use typenum::Unsigned; +use typenum::{Sum,Unsigned}; +use crate::traits::WideMul; #[derive(Clone,Copy,Debug,Hash)] pub struct Fixed{ @@ -277,3 +278,97 @@ impl_shift_assign_operator!( Fixed, ShlAssign, shl_assign ); impl_shift_operator!( Fixed, Shl, shl, Self ); impl_shift_assign_operator!( Fixed, ShrAssign, shr_assign ); impl_shift_operator!( Fixed, Shr, shr, Self ); + +// WIDE MUL: multiply into a wider type +// let a = I32F32::ONE; +// let b:I64F64 = a.wide_mul(a); +macro_rules! impl_wide_mul{ + ($lhs:expr,$rhs:expr)=>{ + impl WideMul> for Fixed<$lhs,A> + where + A:std::ops::Add, + B:Unsigned, + { + type Output=Fixed<{$lhs+$rhs},Sum>; + fn wide_mul(self,rhs:Fixed<$rhs,B>)->Self::Output{ + Fixed::from_bits(self.bits.as_::>()*rhs.bits.as_::>()) + } + } + }; +} + +macro_rules! impl_wide_mul_all{ + ($(($x:expr, $y:expr)),*)=>{ + $( + impl_wide_mul!($x, $y); + )* + }; +} + +//const generics sidestepped wahoo +impl_wide_mul_all!( + (1,1),(2,1),(3,1),(4,1),(5,1),(6,1),(7,1),(8,1), + (1,2),(2,2),(3,2),(4,2),(5,2),(6,2),(7,2),(8,2), + (1,3),(2,3),(3,3),(4,3),(5,3),(6,3),(7,3),(8,3), + (1,4),(2,4),(3,4),(4,4),(5,4),(6,4),(7,4),(8,4), + (1,5),(2,5),(3,5),(4,5),(5,5),(6,5),(7,5),(8,5), + (1,6),(2,6),(3,6),(4,6),(5,6),(6,6),(7,6),(8,6), + (1,7),(2,7),(3,7),(4,7),(5,7),(6,7),(7,7),(8,7), + (1,8),(2,8),(3,8),(4,8),(5,8),(6,8),(7,8),(8,8) +); +impl Fixed{ + pub fn resize_into(self)->Fixed{ + Fixed::from_bits(self.bits.as_::>()) + } +} + +macro_rules! impl_const{ + ($n:expr)=>{ + impl Fixed<$n,F>{ + pub fn sqrt_unchecked(self)->Self{ + //1<>1 (sqrt-ish) + //3. add on fractional offset + //Voila + let used_bits=self.bits.bits() as i32-1-F::I32; + let max_shift=((used_bits>>1)+F::I32) as u32; + let mut result=Self::ZERO; + + //multiply by one to make the types match (hack) + let wide_self=self.wide_mul(Self::ONE); + //descend down the bits and check if flipping each bit would push the square over the input value + for shift in (0..=max_shift).rev(){ + let new_result=result|Self::from_bits(BInt::from_bits(bnum::BUint::power_of_two(shift))); + if new_result.wide_mul(new_result)<=wide_self{ + result=new_result; + } + } + result + } + pub fn sqrt(self)->Self{ + if selfOption{ + if self { - impl WideMul> for Fixed<$lhs,A> - where - A:std::ops::Add, - B:Unsigned, - { - type Output=Fixed<{$lhs+$rhs},Sum>; - fn wide_mul(self,rhs:Fixed<$rhs,B>)->Self::Output{ - Fixed::from_bits(self.bits.as_::>()*rhs.bits.as_::>()) - } - } - }; -} - -macro_rules! impl_wide_mul_all { - ($(($x:expr, $y:expr)),*) => { - $( - impl_wide_mul!($x, $y); - )* - }; -} - -//const generics sidestepped wahoo -impl_wide_mul_all!( - (1,1),(2,1),(3,1),(4,1),(5,1),(6,1),(7,1),(8,1), - (1,2),(2,2),(3,2),(4,2),(5,2),(6,2),(7,2),(8,2), - (1,3),(2,3),(3,3),(4,3),(5,3),(6,3),(7,3),(8,3), - (1,4),(2,4),(3,4),(4,4),(5,4),(6,4),(7,4),(8,4), - (1,5),(2,5),(3,5),(4,5),(5,5),(6,5),(7,5),(8,5), - (1,6),(2,6),(3,6),(4,6),(5,6),(6,6),(7,6),(8,6), - (1,7),(2,7),(3,7),(4,7),(5,7),(6,7),(7,7),(8,7), - (1,8),(2,8),(3,8),(4,8),(5,8),(6,8),(7,8),(8,8) -); -impl Fixed{ - pub fn widen(self)->Fixed{ - Fixed::from_bits(self.bits.as_::>()) - } -} - -impl Fixed - where - Fixed:::WideMul, - as WideMul>::Output:Ord, -{ - pub fn sqrt_unchecked(self)->Self{ - //1<>1 (sqrt-ish) - //3. add on fractional offset - //Voila - let used_bits=self.bits.bits() as i32-1-Frac::I32; - let max_shift=((used_bits>>1)+Frac::I32) as u32; - let mut result=Self::ZERO; - - //multiply by one to make the types match (hack) - let wide_self=self.wide_mul(Fixed::::ONE); - //descend down the bits and check if flipping each bit would push the square over the input value - for shift in (0..=max_shift).rev(){ - let new_result=result|Fixed::::from_bits(BInt::from_bits(bnum::BUint::power_of_two(shift))); - if new_result.wide_mul(new_result)<=wide_self{ - result=new_result; - } - } - result - } - pub fn sqrt(self)->Self{ - if selfOption{ - if self{ + pub(crate)num:Num, + pub(crate)den:Den, +} +impl Ratio{ + pub const fn new(num:Num,den:Den)->Self{ + Self{num,den} + } +} diff --git a/fixed_wide/src/tests.rs b/fixed_wide/src/tests.rs index 61e6b96..1e92025 100644 --- a/fixed_wide/src/tests.rs +++ b/fixed_wide/src/tests.rs @@ -1,4 +1,3 @@ -use fixed_wide_traits::wide::WideMul; use crate::types::I32F32; #[test] diff --git a/fixed_wide/src/traits.rs b/fixed_wide/src/traits.rs new file mode 100644 index 0000000..486fc49 --- /dev/null +++ b/fixed_wide/src/traits.rs @@ -0,0 +1,8 @@ +pub trait WideMul{ + type Output; + fn wide_mul(self,rhs:Rhs)->Self::Output; +} +pub trait WideDiv{ + type Output; + fn wide_div(self,rhs:Rhs)->Self::Output; +} diff --git a/fixed_wide/src/zeroes.rs b/fixed_wide/src/zeroes.rs new file mode 100644 index 0000000..60f5a47 --- /dev/null +++ b/fixed_wide/src/zeroes.rs @@ -0,0 +1,58 @@ +use crate::fixed::Fixed; +use crate::ratio::Ratio; + +use typenum::{Sum,Unsigned}; +use arrayvec::ArrayVec; +use std::cmp::Ordering; +macro_rules! impl_zeroes{ + ($n:expr)=>{ + impl Fixed<$n,F> + where + F:Unsigned+std::ops::Add, + ::Output:Unsigned, + { + #[inline] + pub fn zeroes2(a0:Self,a1:Self,a2:Self)->ArrayVec,2>{ + let a2pos=match a2.cmp(&Self::ZERO){ + Ordering::Greater=>true, + Ordering::Equal=>return ArrayVec::from_iter($crate::zeroes::zeroes1(a0,a1).into_iter()), + Ordering::Less=>true, + }; + let radicand=$crate::traits::WideMul::wide_mul(a1,a1)-$crate::traits::WideMul::wide_mul(a2,a0)*4; + match radicand.cmp(&Fixed::<{$n*2},Sum>::ZERO){ + Ordering::Greater=>{ + //start with f64 sqrt + //failure case: 2^63 < sqrt(2^127) + let planar_radicand=radicand.sqrt(); + //TODO: one or two newtons + //sort roots ascending and avoid taking the difference of large numbers + match (a2pos,Self::ZERO[Ratio::new(-a1-planar_radicand,a2*2),Ratio::new(a0*2,-a1-planar_radicand)].into(), + (true, false)=>[Ratio::new(a0*2,-a1+planar_radicand),Ratio::new(-a1+planar_radicand,a2*2)].into(), + (false,true )=>[Ratio::new(a0*2,-a1-planar_radicand),Ratio::new(-a1-planar_radicand,a2*2)].into(), + (false,false)=>[Ratio::new(-a1+planar_radicand,a2*2),Ratio::new(a0*2,-a1+planar_radicand)].into(), + } + }, + Ordering::Equal=>ArrayVec::from_iter([Ratio::new(a1,a2*-2)]), + Ordering::Less=>ArrayVec::new_const(), + } + } + #[inline] + pub fn zeroes1(a0:Self,a1:Self)->ArrayVec,1>{ + if a1==Self::ZERO{ + ArrayVec::new_const() + }else{ + ArrayVec::from_iter([Ratio::new(-a0,a1)]) + } + } + } + }; +} +impl_zeroes!(1); +impl_zeroes!(2); +impl_zeroes!(3); +impl_zeroes!(4); +impl_zeroes!(5); +impl_zeroes!(6); +impl_zeroes!(7); +impl_zeroes!(8); diff --git a/fixed_wide_traits/.gitignore b/fixed_wide_traits/.gitignore deleted file mode 100644 index ea8c4bf..0000000 --- a/fixed_wide_traits/.gitignore +++ /dev/null @@ -1 +0,0 @@ -/target diff --git a/fixed_wide_traits/Cargo.lock b/fixed_wide_traits/Cargo.lock deleted file mode 100644 index 8ece885..0000000 --- a/fixed_wide_traits/Cargo.lock +++ /dev/null @@ -1,63 +0,0 @@ -# This file is automatically @generated by Cargo. -# It is not intended for manual editing. -version = 3 - -[[package]] -name = "az" -version = "1.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7b7e4c2464d97fe331d41de9d5db0def0a96f4d823b8b32a2efd503578988973" - -[[package]] -name = "bytemuck" -version = "1.17.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6fd4c6dcc3b0aea2f5c0b4b82c2b15fe39ddbc76041a310848f4706edf76bb31" - -[[package]] -name = "cfg-if" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" - -[[package]] -name = "crunchy" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a81dae078cea95a014a339291cec439d2f232ebe854a9d672b796c6afafa9b7" - -[[package]] -name = "fixed" -version = "1.28.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "85c6e0b89bf864acd20590dbdbad56f69aeb898abfc9443008fd7bd48b2cc85a" -dependencies = [ - "az", - "bytemuck", - "half", - "typenum", -] - -[[package]] -name = "fixed_wide_traits" -version = "0.1.0" -dependencies = [ - "fixed", - "typenum", -] - -[[package]] -name = "half" -version = "2.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6dd08c532ae367adf81c312a4580bc67f1d0fe8bc9c460520283f4c0ff277888" -dependencies = [ - "cfg-if", - "crunchy", -] - -[[package]] -name = "typenum" -version = "1.17.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825" diff --git a/fixed_wide_traits/Cargo.toml b/fixed_wide_traits/Cargo.toml deleted file mode 100644 index b761c99..0000000 --- a/fixed_wide_traits/Cargo.toml +++ /dev/null @@ -1,10 +0,0 @@ -[package] -name = "fixed_wide_traits" -version = "0.1.0" -edition = "2021" - -[dependencies] - -[dev-dependencies] -fixed = "1.28.0" -typenum = "1.17.0" diff --git a/fixed_wide_traits/src/lib.rs b/fixed_wide_traits/src/lib.rs deleted file mode 100644 index 21c9224..0000000 --- a/fixed_wide_traits/src/lib.rs +++ /dev/null @@ -1,2 +0,0 @@ -pub mod wide; -pub mod narrow; diff --git a/fixed_wide_traits/src/narrow.rs b/fixed_wide_traits/src/narrow.rs deleted file mode 100644 index 698eacc..0000000 --- a/fixed_wide_traits/src/narrow.rs +++ /dev/null @@ -1,57 +0,0 @@ -pub trait Narrow{ - type Output; - fn narrow(self)->Self::Output; -} -#[derive(Debug)] -pub enum Error{ - Overflow, - Underflow, -} -impl std::fmt::Display for Error{ - fn fmt(&self,f:&mut std::fmt::Formatter<'_>)->std::fmt::Result{ - write!(f,"{self:?}") - } -} -impl std::error::Error for Error{} -pub trait TryNarrow{ - type Output; - fn try_narrow(self)->Result; -} -#[cfg(test)] -mod tests { - use super::*; - - //TODO: use num_traits to do a blanket implementation (selfResult{ - if self{ - type Output=i8; - fn narrow(self)->Self::Output{ - (self.to_bits()>>8) as i8 - } - } - - #[test] - fn test_fixed_i16_i8(){ - let a=fixed::FixedI16::::from(5)/2; - assert_eq!(a.narrow(),2); - } -} diff --git a/fixed_wide_traits/src/wide.rs b/fixed_wide_traits/src/wide.rs deleted file mode 100644 index dfb7b15..0000000 --- a/fixed_wide_traits/src/wide.rs +++ /dev/null @@ -1,16 +0,0 @@ -pub trait WideMul{ - type Output; - fn wide_mul(self,rhs:Rhs)->Self::Output; -} -pub trait WideDiv{ - type Output; - fn wide_div(self,rhs:Rhs)->Self::Output; -} -pub trait WideDot{ - type Output; - fn wide_dot(self,rhs:Rhs)->Self::Output; -} -pub trait WideCross{ - type Output; - fn wide_cross(self,rhs:Rhs)->Self::Output; -} From 4d13b4ada7f428168e7ef9eaf6eb93da76200212 Mon Sep 17 00:00:00 2001 From: Quaternions Date: Mon, 2 Sep 2024 16:35:01 -0700 Subject: [PATCH 103/227] paste (this sucks) --- fixed_wide/Cargo.lock | 7 +++++++ fixed_wide/Cargo.toml | 1 + fixed_wide/src/fixed.rs | 24 +++++++++++++----------- fixed_wide/src/lib.rs | 1 - fixed_wide/src/traits.rs | 8 -------- fixed_wide/src/zeroes.rs | 4 +++- 6 files changed, 24 insertions(+), 21 deletions(-) delete mode 100644 fixed_wide/src/traits.rs diff --git a/fixed_wide/Cargo.lock b/fixed_wide/Cargo.lock index e28b2bc..d8b81fb 100644 --- a/fixed_wide/Cargo.lock +++ b/fixed_wide/Cargo.lock @@ -20,9 +20,16 @@ version = "0.1.0" dependencies = [ "arrayvec", "bnum", + "paste", "typenum", ] +[[package]] +name = "paste" +version = "1.0.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "57c0d7b74b563b49d38dae00a0c37d4d6de9b432382b2892f0574ddcae73fd0a" + [[package]] name = "typenum" version = "1.17.0" diff --git a/fixed_wide/Cargo.toml b/fixed_wide/Cargo.toml index 8b2b4e9..6b39bd1 100644 --- a/fixed_wide/Cargo.toml +++ b/fixed_wide/Cargo.toml @@ -12,3 +12,4 @@ zeroes=["ratio","dep:arrayvec"] bnum = "0.11.0" typenum = "1.17.0" arrayvec = { version = "0.7.6", optional = true } +paste = "1.0.15" diff --git a/fixed_wide/src/fixed.rs b/fixed_wide/src/fixed.rs index 4045ff1..a57135f 100644 --- a/fixed_wide/src/fixed.rs +++ b/fixed_wide/src/fixed.rs @@ -1,6 +1,5 @@ use bnum::{BInt,cast::As}; use typenum::{Sum,Unsigned}; -use crate::traits::WideMul; #[derive(Clone,Copy,Debug,Hash)] pub struct Fixed{ @@ -284,14 +283,15 @@ impl_shift_operator!( Fixed, Shr, shr, Self ); // let b:I64F64 = a.wide_mul(a); macro_rules! impl_wide_mul{ ($lhs:expr,$rhs:expr)=>{ - impl WideMul> for Fixed<$lhs,A> - where - A:std::ops::Add, - B:Unsigned, + impl Fixed<$lhs,A> { - type Output=Fixed<{$lhs+$rhs},Sum>; - fn wide_mul(self,rhs:Fixed<$rhs,B>)->Self::Output{ - Fixed::from_bits(self.bits.as_::>()*rhs.bits.as_::>()) + paste::item!{ + pub fn [](self,rhs:Fixed<$rhs,B>)->Fixed<{$lhs+$rhs},Sum> + where + A:std::ops::Add, + B:Unsigned,{ + Fixed::from_bits(self.bits.as_::>()*rhs.bits.as_::>()) + } } } }; @@ -324,7 +324,8 @@ impl Fixed{ macro_rules! impl_const{ ($n:expr)=>{ - impl Fixed<$n,F>{ + impl Fixed<$n,F>{ + paste::item!{ pub fn sqrt_unchecked(self)->Self{ //1<](Self::ONE); //descend down the bits and check if flipping each bit would push the square over the input value for shift in (0..=max_shift).rev(){ let new_result=result|Self::from_bits(BInt::from_bits(bnum::BUint::power_of_two(shift))); - if new_result.wide_mul(new_result)<=wide_self{ + if new_result.[](new_result)<=wide_self{ result=new_result; } } result } + } pub fn sqrt(self)->Self{ if self{ - type Output; - fn wide_mul(self,rhs:Rhs)->Self::Output; -} -pub trait WideDiv{ - type Output; - fn wide_div(self,rhs:Rhs)->Self::Output; -} diff --git a/fixed_wide/src/zeroes.rs b/fixed_wide/src/zeroes.rs index 60f5a47..8668dc5 100644 --- a/fixed_wide/src/zeroes.rs +++ b/fixed_wide/src/zeroes.rs @@ -11,6 +11,7 @@ macro_rules! impl_zeroes{ F:Unsigned+std::ops::Add, ::Output:Unsigned, { + paste::item!{ #[inline] pub fn zeroes2(a0:Self,a1:Self,a2:Self)->ArrayVec,2>{ let a2pos=match a2.cmp(&Self::ZERO){ @@ -18,7 +19,7 @@ macro_rules! impl_zeroes{ Ordering::Equal=>return ArrayVec::from_iter($crate::zeroes::zeroes1(a0,a1).into_iter()), Ordering::Less=>true, }; - let radicand=$crate::traits::WideMul::wide_mul(a1,a1)-$crate::traits::WideMul::wide_mul(a2,a0)*4; + let radicand=a1.[](a1)-a2.[](a0)*4; match radicand.cmp(&Fixed::<{$n*2},Sum>::ZERO){ Ordering::Greater=>{ //start with f64 sqrt @@ -37,6 +38,7 @@ macro_rules! impl_zeroes{ Ordering::Less=>ArrayVec::new_const(), } } + } #[inline] pub fn zeroes1(a0:Self,a1:Self)->ArrayVec,1>{ if a1==Self::ZERO{ From e0dba8840e40979af9063640eedcd8a256fc1981 Mon Sep 17 00:00:00 2001 From: Quaternions Date: Mon, 2 Sep 2024 17:03:01 -0700 Subject: [PATCH 104/227] ruin everything successfully --- fixed_wide/Cargo.lock | 7 --- fixed_wide/Cargo.toml | 1 - fixed_wide/src/fixed.rs | 118 +++++++++++++++++++-------------------- fixed_wide/src/lib.rs | 4 -- fixed_wide/src/tests.rs | 6 +- fixed_wide/src/types.rs | 8 +-- fixed_wide/src/zeroes.rs | 24 ++++---- 7 files changed, 75 insertions(+), 93 deletions(-) diff --git a/fixed_wide/Cargo.lock b/fixed_wide/Cargo.lock index d8b81fb..ff09daa 100644 --- a/fixed_wide/Cargo.lock +++ b/fixed_wide/Cargo.lock @@ -21,7 +21,6 @@ dependencies = [ "arrayvec", "bnum", "paste", - "typenum", ] [[package]] @@ -29,9 +28,3 @@ name = "paste" version = "1.0.15" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "57c0d7b74b563b49d38dae00a0c37d4d6de9b432382b2892f0574ddcae73fd0a" - -[[package]] -name = "typenum" -version = "1.17.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825" diff --git a/fixed_wide/Cargo.toml b/fixed_wide/Cargo.toml index 6b39bd1..cc218bc 100644 --- a/fixed_wide/Cargo.toml +++ b/fixed_wide/Cargo.toml @@ -10,6 +10,5 @@ zeroes=["ratio","dep:arrayvec"] [dependencies] bnum = "0.11.0" -typenum = "1.17.0" arrayvec = { version = "0.7.6", optional = true } paste = "1.0.15" diff --git a/fixed_wide/src/fixed.rs b/fixed_wide/src/fixed.rs index a57135f..81494a3 100644 --- a/fixed_wide/src/fixed.rs +++ b/fixed_wide/src/fixed.rs @@ -1,35 +1,34 @@ use bnum::{BInt,cast::As}; -use typenum::{Sum,Unsigned}; #[derive(Clone,Copy,Debug,Hash)] -pub struct Fixed{ - pub(crate)bits:BInt<{CHUNKS}>, - pub(crate)frac:std::marker::PhantomData, +/// N is the number of u64s to use +/// F is the number of fractional bits (always N*32 lol) +pub struct Fixed{ + pub(crate)bits:BInt<{N}>, } -impl Fixed{ - pub const MAX:Self=Self::from_bits(BInt::::MAX); - pub const MIN:Self=Self::from_bits(BInt::::MIN); - pub const ZERO:Self=Self::from_bits(BInt::::ZERO); - pub const EPSILON:Self=Self::from_bits(BInt::::ONE); - pub const NEG_EPSILON:Self=Self::from_bits(BInt::::NEG_ONE); - pub const ONE:Self=Self::from_bits(BInt::::ONE.shl(Frac::U32)); - pub const TWO:Self=Self::from_bits(BInt::::TWO.shl(Frac::U32)); - pub const HALF:Self=Self::from_bits(BInt::::ONE.shl(Frac::U32-1)); - pub const NEG_ONE:Self=Self::from_bits(BInt::::NEG_ONE.shl(Frac::U32)); - pub const NEG_TWO:Self=Self::from_bits(BInt::::NEG_TWO.shl(Frac::U32)); - pub const NEG_HALF:Self=Self::from_bits(BInt::::NEG_ONE.shl(Frac::U32-1)); +impl Fixed{ + pub const MAX:Self=Self::from_bits(BInt::::MAX); + pub const MIN:Self=Self::from_bits(BInt::::MIN); + pub const ZERO:Self=Self::from_bits(BInt::::ZERO); + pub const EPSILON:Self=Self::from_bits(BInt::::ONE); + pub const NEG_EPSILON:Self=Self::from_bits(BInt::::NEG_ONE); + pub const ONE:Self=Self::from_bits(BInt::::ONE.shl(F as u32)); + pub const TWO:Self=Self::from_bits(BInt::::TWO.shl(F as u32)); + pub const HALF:Self=Self::from_bits(BInt::::ONE.shl(F as u32-1)); + pub const NEG_ONE:Self=Self::from_bits(BInt::::NEG_ONE.shl(F as u32)); + pub const NEG_TWO:Self=Self::from_bits(BInt::::NEG_TWO.shl(F as u32)); + pub const NEG_HALF:Self=Self::from_bits(BInt::::NEG_ONE.shl(F as u32-1)); } -impl Fixed{ +impl Fixed{ #[inline] - pub const fn from_bits(bits:BInt::)->Self{ + pub const fn from_bits(bits:BInt::)->Self{ Self{ bits, - frac:std::marker::PhantomData, } } #[inline] - pub const fn to_bits(self)->BInt{ + pub const fn to_bits(self)->BInt{ self.bits } #[inline] @@ -38,34 +37,34 @@ impl Fixed{ } } -impl From for Fixed +impl From for Fixed where - BInt:From + BInt:From { fn from(value:T)->Self{ - Self::from_bits(BInt::<{CHUNKS}>::from(value)<::from(value)< PartialEq for Fixed{ +impl PartialEq for Fixed{ fn eq(&self,other:&Self)->bool{ self.bits.eq(&other.bits) } } -impl Eq for Fixed{} +impl Eq for Fixed{} -impl PartialOrd for Fixed{ +impl PartialOrd for Fixed{ fn partial_cmp(&self,other:&Self)->Option{ self.bits.partial_cmp(&other.bits) } } -impl Ord for Fixed{ +impl Ord for Fixed{ fn cmp(&self,other:&Self)->std::cmp::Ordering{ self.bits.cmp(&other.bits) } } -impl std::ops::Neg for Fixed{ +impl std::ops::Neg for Fixed{ type Output=Self; fn neg(self)->Self{ Self::from_bits(self.bits.neg()) @@ -74,38 +73,38 @@ impl std::ops::Neg for Fixed{ macro_rules! impl_additive_operator { ( $struct: ident, $trait: ident, $method: ident, $output: ty ) => { - impl core::ops::$trait for $struct{ + impl core::ops::$trait for $struct{ type Output = $output; fn $method(self, other: Self) -> Self::Output { Self::from_bits(self.bits.$method(other.bits)) } } - impl core::ops::$trait for $struct + impl core::ops::$trait for $struct where - BInt:::From, + BInt:::From, { type Output = $output; fn $method(self, other: U) -> Self::Output { - Self::from_bits(self.bits.$method(BInt::::from(other)<::from(other).shl(F as u32))) } } }; } macro_rules! impl_additive_assign_operator { ( $struct: ident, $trait: ident, $method: ident ) => { - impl core::ops::$trait for $struct{ + impl core::ops::$trait for $struct{ fn $method(&mut self, other: Self) { self.bits.$method(other.bits); } } - impl core::ops::$trait for $struct + impl core::ops::$trait for $struct where - BInt:::From, + BInt:::From, { fn $method(&mut self, other: U) { - self.bits.$method(BInt::::from(other)<::from(other)< { - impl core::ops::$trait for $struct<$width,Frac>{ + impl core::ops::$trait for $struct<$width,F>{ type Output = $output; fn $method(self, other: Self) -> Self::Output { //this can be done better but that is a job for later let lhs=self.bits.as_::>(); let rhs=other.bits.as_::>(); - Self::from_bits(lhs.mul(rhs).shr(Frac::U32).as_()) + Self::from_bits(lhs.mul(rhs).shr(F as u32).as_()) } } }; } macro_rules! impl_multiply_assign_operator_const { ( $width:expr, $struct: ident, $trait: ident, $method: ident ) => { - impl core::ops::$trait for $struct<$width,Frac>{ + impl core::ops::$trait for $struct<$width,F>{ fn $method(&mut self, other: Self) { self.bits.$method(other.bits); } @@ -153,13 +152,13 @@ macro_rules! impl_multiply_assign_operator_const { macro_rules! impl_divide_operator_const { ( $width:expr, $struct: ident, $trait: ident, $method: ident, $output: ty ) => { - impl core::ops::$trait for $struct<$width,Frac>{ + impl core::ops::$trait for $struct<$width,F>{ type Output = $output; fn $method(self, other: Self) -> Self::Output { //this can be done better but that is a job for later - //this only needs to be $width+Frac::U32/64+1 but MUH CONST GENERICS!!!!! - let lhs=self.bits.as_::>().shl(Frac::U32); + //this only needs to be $width+F as u32/64+1 but MUH CONST GENERICS!!!!! + let lhs=self.bits.as_::>().shl(F as u32); let rhs=other.bits.as_::>(); Self::from_bits(lhs.div(rhs).as_()) } @@ -168,7 +167,7 @@ macro_rules! impl_divide_operator_const { } macro_rules! impl_divide_assign_operator_const { ( $width:expr, $struct: ident, $trait: ident, $method: ident ) => { - impl core::ops::$trait for $struct<$width,Frac>{ + impl core::ops::$trait for $struct<$width,F>{ fn $method(&mut self, other: Self) { self.bits.$method(other.bits); } @@ -178,26 +177,26 @@ macro_rules! impl_divide_assign_operator_const { macro_rules! impl_multiplicatave_operator { ( $struct: ident, $trait: ident, $method: ident, $output: ty ) => { - impl core::ops::$trait for $struct + impl core::ops::$trait for $struct where - BInt:::From+core::ops::$trait, + BInt:::From+core::ops::$trait, { type Output = $output; fn $method(self, other: U) -> Self::Output { - Self::from_bits(self.bits.$method(BInt::::from(other))) + Self::from_bits(self.bits.$method(BInt::::from(other))) } } }; } macro_rules! impl_multiplicatave_assign_operator { ( $struct: ident, $trait: ident, $method: ident ) => { - impl core::ops::$trait for $struct + impl core::ops::$trait for $struct where - BInt:::From+core::ops::$trait, + BInt:::From+core::ops::$trait, { fn $method(&mut self, other: U) { - self.bits.$method(BInt::::from(other)); + self.bits.$method(BInt::::from(other)); } } }; @@ -255,7 +254,7 @@ impl_multiplicatave_operator!( Fixed, Div, div, Self ); macro_rules! impl_shift_operator { ( $struct: ident, $trait: ident, $method: ident, $output: ty ) => { - impl core::ops::$trait for $struct{ + impl core::ops::$trait for $struct{ type Output = $output; fn $method(self, other: u32) -> Self::Output { @@ -266,7 +265,7 @@ macro_rules! impl_shift_operator { } macro_rules! impl_shift_assign_operator { ( $struct: ident, $trait: ident, $method: ident ) => { - impl core::ops::$trait for $struct{ + impl core::ops::$trait for $struct{ fn $method(&mut self, other: u32) { self.bits.$method(other); } @@ -283,13 +282,10 @@ impl_shift_operator!( Fixed, Shr, shr, Self ); // let b:I64F64 = a.wide_mul(a); macro_rules! impl_wide_mul{ ($lhs:expr,$rhs:expr)=>{ - impl Fixed<$lhs,A> + impl Fixed<$lhs,{$lhs*32}> { paste::item!{ - pub fn [](self,rhs:Fixed<$rhs,B>)->Fixed<{$lhs+$rhs},Sum> - where - A:std::ops::Add, - B:Unsigned,{ + pub fn [](self,rhs:Fixed<$rhs,{$rhs*32}>)->Fixed<{$lhs+$rhs},{($lhs+$rhs)*32}>{ Fixed::from_bits(self.bits.as_::>()*rhs.bits.as_::>()) } } @@ -316,15 +312,15 @@ impl_wide_mul_all!( (1,7),(2,7),(3,7),(4,7),(5,7),(6,7),(7,7),(8,7), (1,8),(2,8),(3,8),(4,8),(5,8),(6,8),(7,8),(8,8) ); -impl Fixed{ - pub fn resize_into(self)->Fixed{ +impl Fixed{ + pub fn resize_into(self)->Fixed{ Fixed::from_bits(self.bits.as_::>()) } } macro_rules! impl_const{ ($n:expr)=>{ - impl Fixed<$n,F>{ + impl Fixed<$n,{$n*32}>{ paste::item!{ pub fn sqrt_unchecked(self)->Self{ //1<>1 (sqrt-ish) //3. add on fractional offset //Voila - let used_bits=self.bits.bits() as i32-1-F::I32; - let max_shift=((used_bits>>1)+F::I32) as u32; + let used_bits=self.bits.bits() as i32-1-($n*32) as i32; + let max_shift=((used_bits>>1)+($n*32) as i32) as u32; let mut result=Self::ZERO; //multiply by one to make the types match (hack) diff --git a/fixed_wide/src/lib.rs b/fixed_wide/src/lib.rs index 049fd9d..eee0ec3 100644 --- a/fixed_wide/src/lib.rs +++ b/fixed_wide/src/lib.rs @@ -1,10 +1,6 @@ pub mod fixed; pub mod types; -pub mod typenum{ - pub use typenum::Unsigned; -} - #[cfg(feature="zeroes")] pub mod zeroes; #[cfg(feature="ratio")] diff --git a/fixed_wide/src/tests.rs b/fixed_wide/src/tests.rs index 1e92025..879a7fe 100644 --- a/fixed_wide/src/tests.rs +++ b/fixed_wide/src/tests.rs @@ -3,7 +3,7 @@ use crate::types::I32F32; #[test] fn test_wide_mul(){ let a=I32F32::ONE; - let aa=a.wide_mul(a); + let aa=a.wide_mul_1_1(a); assert_eq!(aa,crate::types::I64F64::ONE); } @@ -39,10 +39,10 @@ fn find_equiv_sqrt_via_f64(n:I32F32)->I32F32{ let r=I32F32::from_bits(bnum::BInt::<1>::from(i)); //mimic the behaviour of the algorithm, //return the result if it truncates to the exact answer - if (r+I32F32::EPSILON).wide_mul(r+I32F32::EPSILON)==n.wide_mul(I32F32::ONE){ + if (r+I32F32::EPSILON).wide_mul_1_1(r+I32F32::EPSILON)==n.wide_mul_1_1(I32F32::ONE){ return r+I32F32::EPSILON; } - if (r-I32F32::EPSILON).wide_mul(r-I32F32::EPSILON)==n.wide_mul(I32F32::ONE){ + if (r-I32F32::EPSILON).wide_mul_1_1(r-I32F32::EPSILON)==n.wide_mul_1_1(I32F32::ONE){ return r-I32F32::EPSILON; } return r; diff --git a/fixed_wide/src/types.rs b/fixed_wide/src/types.rs index 98cec10..8694435 100644 --- a/fixed_wide/src/types.rs +++ b/fixed_wide/src/types.rs @@ -1,4 +1,4 @@ -pub type I32F32=crate::fixed::Fixed<1,typenum::consts::U32>; -pub type I64F64=crate::fixed::Fixed<2,typenum::consts::U64>; -pub type I128F128=crate::fixed::Fixed<4,typenum::consts::U128>; -pub type I256F256=crate::fixed::Fixed<8,typenum::consts::U256>; +pub type I32F32=crate::fixed::Fixed<1,32>; +pub type I64F64=crate::fixed::Fixed<2,64>; +pub type I128F128=crate::fixed::Fixed<4,128>; +pub type I256F256=crate::fixed::Fixed<8,256>; diff --git a/fixed_wide/src/zeroes.rs b/fixed_wide/src/zeroes.rs index 8668dc5..16d211d 100644 --- a/fixed_wide/src/zeroes.rs +++ b/fixed_wide/src/zeroes.rs @@ -1,30 +1,27 @@ use crate::fixed::Fixed; use crate::ratio::Ratio; -use typenum::{Sum,Unsigned}; use arrayvec::ArrayVec; use std::cmp::Ordering; macro_rules! impl_zeroes{ ($n:expr)=>{ - impl Fixed<$n,F> - where - F:Unsigned+std::ops::Add, - ::Output:Unsigned, - { + impl Fixed<$n,{$n*32}>{ paste::item!{ #[inline] pub fn zeroes2(a0:Self,a1:Self,a2:Self)->ArrayVec,2>{ let a2pos=match a2.cmp(&Self::ZERO){ Ordering::Greater=>true, - Ordering::Equal=>return ArrayVec::from_iter($crate::zeroes::zeroes1(a0,a1).into_iter()), + Ordering::Equal=>return ArrayVec::from_iter(Self::zeroes1(a0,a1).into_iter()), Ordering::Less=>true, }; let radicand=a1.[](a1)-a2.[](a0)*4; - match radicand.cmp(&Fixed::<{$n*2},Sum>::ZERO){ + match radicand.cmp(&Fixed::<{$n*2},{$n*2*32}>::ZERO){ Ordering::Greater=>{ //start with f64 sqrt //failure case: 2^63 < sqrt(2^127) - let planar_radicand=radicand.sqrt(); + let planar_radicand_wide=radicand.sqrt(); + //lazy hack + let planar_radicand=Self::from_bits(bnum::cast::As::as_(planar_radicand_wide.bits.shr($n*32))); //TODO: one or two newtons //sort roots ascending and avoid taking the difference of large numbers match (a2pos,Self::ZERO Date: Mon, 2 Sep 2024 17:09:37 -0700 Subject: [PATCH 105/227] named function --- fixed_wide/src/fixed.rs | 5 +++++ fixed_wide/src/zeroes.rs | 4 +--- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/fixed_wide/src/fixed.rs b/fixed_wide/src/fixed.rs index 81494a3..d0aad2d 100644 --- a/fixed_wide/src/fixed.rs +++ b/fixed_wide/src/fixed.rs @@ -320,6 +320,11 @@ impl Fixed{ macro_rules! impl_const{ ($n:expr)=>{ + impl Fixed<{$n*2},{$n*2*32}>{ + pub fn halve_precision(self)->Fixed<$n,{$n*32}>{ + Fixed::from_bits(bnum::cast::As::as_(self.bits.shr($n*32))) + } + } impl Fixed<$n,{$n*32}>{ paste::item!{ pub fn sqrt_unchecked(self)->Self{ diff --git a/fixed_wide/src/zeroes.rs b/fixed_wide/src/zeroes.rs index 16d211d..97da6c9 100644 --- a/fixed_wide/src/zeroes.rs +++ b/fixed_wide/src/zeroes.rs @@ -19,9 +19,7 @@ macro_rules! impl_zeroes{ Ordering::Greater=>{ //start with f64 sqrt //failure case: 2^63 < sqrt(2^127) - let planar_radicand_wide=radicand.sqrt(); - //lazy hack - let planar_radicand=Self::from_bits(bnum::cast::As::as_(planar_radicand_wide.bits.shr($n*32))); + let planar_radicand=radicand.sqrt().halve_precision(); //TODO: one or two newtons //sort roots ascending and avoid taking the difference of large numbers match (a2pos,Self::ZERO Date: Mon, 2 Sep 2024 17:42:01 -0700 Subject: [PATCH 106/227] move tests --- fixed_wide/src/tests.rs | 25 +++++++++++++++++++ .../src/tests/fixed_wide_traits.rs | 12 --------- fixed_wide_vectors/src/tests/tests.rs | 15 ----------- 3 files changed, 25 insertions(+), 27 deletions(-) diff --git a/fixed_wide/src/tests.rs b/fixed_wide/src/tests.rs index 879a7fe..01fb9f1 100644 --- a/fixed_wide/src/tests.rs +++ b/fixed_wide/src/tests.rs @@ -1,4 +1,17 @@ use crate::types::I32F32; +use crate::types::I256F256; + +#[test] +fn you_can_add_numbers(){ + let a=I256F256::from((3i128*2).pow(4)); + assert_eq!(a+a,I256F256::from((3i128*2).pow(4)*2)) +} + +#[test] +fn you_can_shr_numbers(){ + let a=I32F32::from(4); + assert_eq!(a>>1,I32F32::from(2)) +} #[test] fn test_wide_mul(){ @@ -7,6 +20,18 @@ fn test_wide_mul(){ assert_eq!(aa,crate::types::I64F64::ONE); } +#[test] +fn test_wide_mul_repeated() { + let a=I32F32::from(2); + let b=I32F32::from(3); + + let w1=a.wide_mul_1_1(b); + let w2=w1.wide_mul_2_2(w1); + let w3=w2.wide_mul_4_4(w2); + + assert_eq!(w3,I256F256::from((3i128*2).pow(4))); +} + #[test] fn test_bint(){ let a=I32F32::ONE; diff --git a/fixed_wide_vectors/src/tests/fixed_wide_traits.rs b/fixed_wide_vectors/src/tests/fixed_wide_traits.rs index bbc1df1..73a0a1b 100644 --- a/fixed_wide_vectors/src/tests/fixed_wide_traits.rs +++ b/fixed_wide_vectors/src/tests/fixed_wide_traits.rs @@ -8,18 +8,6 @@ type Planar64Wide1=fixed_wide::types::I64F64; //type Planar64Wide2=fixed_wide::types::I128F128; type Planar64Wide3=fixed_wide::types::I256F256; -#[test] -fn wide_int64() { - let a=Planar64::from(2); - let b=Planar64::from(3); - - let w1=a.wide_mul(b); - let w2=w1.wide_mul(w1); - let w3=w2.wide_mul(w2); - - assert_eq!(w3,Planar64Wide3::from((3i128*2).pow(4))); -} - #[test] fn wide_vec3(){ let v=Vector3::from_value(Planar64::from(3)); diff --git a/fixed_wide_vectors/src/tests/tests.rs b/fixed_wide_vectors/src/tests/tests.rs index 25982f7..8b13789 100644 --- a/fixed_wide_vectors/src/tests/tests.rs +++ b/fixed_wide_vectors/src/tests/tests.rs @@ -1,16 +1 @@ -type Planar64=fixed_wide::types::I32F32; -//type Planar64Wide1=fixed::types::I64F64; -//type Planar64Wide2=fixed_wide::types::I128F128; -type Planar64Wide3=fixed_wide::types::I256F256; -#[test] -fn you_can_add_numbers(){ - let a=Planar64Wide3::from((3i128*2).pow(4)); - assert_eq!(a+a,Planar64Wide3::from((3i128*2).pow(4)*2)) -} - -#[test] -fn you_can_shr_numbers(){ - let a=Planar64::from(4); - assert_eq!(a>>1,Planar64::from(2)) -} From 5cb98ee29f21f7f78c16369625630f05fc1bebf7 Mon Sep 17 00:00:00 2001 From: Quaternions Date: Mon, 2 Sep 2024 17:41:54 -0700 Subject: [PATCH 107/227] vectors: no traits --- fixed_wide_vectors/Cargo.lock | 21 +++++++++-------- fixed_wide_vectors/Cargo.toml | 9 +++----- .../src/macros/{wide.rs => fixed_wide.rs} | 0 fixed_wide_vectors/src/macros/mod.rs | 4 ++-- fixed_wide_vectors/src/macros/vector.rs | 2 +- .../{fixed_wide_traits.rs => fixed_wide.rs} | 23 ++++++++----------- fixed_wide_vectors/src/tests/mod.rs | 4 ++-- 7 files changed, 29 insertions(+), 34 deletions(-) rename fixed_wide_vectors/src/macros/{wide.rs => fixed_wide.rs} (100%) rename fixed_wide_vectors/src/tests/{fixed_wide_traits.rs => fixed_wide.rs} (79%) diff --git a/fixed_wide_vectors/Cargo.lock b/fixed_wide_vectors/Cargo.lock index a0a650c..5bb2156 100644 --- a/fixed_wide_vectors/Cargo.lock +++ b/fixed_wide_vectors/Cargo.lock @@ -2,6 +2,12 @@ # It is not intended for manual editing. version = 3 +[[package]] +name = "arrayvec" +version = "0.7.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7c02d123df017efcdfbd739ef81735b36c5ba83ec3c59c80a9d7ecc718f92e50" + [[package]] name = "bnum" version = "0.11.0" @@ -12,25 +18,20 @@ checksum = "3e31ea183f6ee62ac8b8a8cf7feddd766317adfb13ff469de57ce033efd6a790" name = "fixed_wide" version = "0.1.0" dependencies = [ + "arrayvec", "bnum", - "fixed_wide_traits", - "typenum", + "paste", ] -[[package]] -name = "fixed_wide_traits" -version = "0.1.0" - [[package]] name = "fixed_wide_vectors" version = "0.1.0" dependencies = [ "fixed_wide", - "fixed_wide_traits", ] [[package]] -name = "typenum" -version = "1.17.0" +name = "paste" +version = "1.0.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825" +checksum = "57c0d7b74b563b49d38dae00a0c37d4d6de9b432382b2892f0574ddcae73fd0a" diff --git a/fixed_wide_vectors/Cargo.toml b/fixed_wide_vectors/Cargo.toml index 55d64c0..a3dad29 100644 --- a/fixed_wide_vectors/Cargo.toml +++ b/fixed_wide_vectors/Cargo.toml @@ -4,11 +4,8 @@ version = "0.1.0" edition = "2021" [features] -default=["fixed_wide_traits"] -fixed_wide_traits=["dep:fixed_wide_traits"] +default=["fixed_wide"] +fixed_wide=["dep:fixed_wide"] [dependencies] -fixed_wide_traits = { version = "0.1.0", path = "../fixed_wide_traits", optional = true } - -[dev-dependencies] -fixed_wide = { version = "0.1.0", path = "../fixed_wide" } +fixed_wide = { version = "0.1.0", path = "../fixed_wide", optional = true } diff --git a/fixed_wide_vectors/src/macros/wide.rs b/fixed_wide_vectors/src/macros/fixed_wide.rs similarity index 100% rename from fixed_wide_vectors/src/macros/wide.rs rename to fixed_wide_vectors/src/macros/fixed_wide.rs diff --git a/fixed_wide_vectors/src/macros/mod.rs b/fixed_wide_vectors/src/macros/mod.rs index dff0bf0..9dfc914 100644 --- a/fixed_wide_vectors/src/macros/mod.rs +++ b/fixed_wide_vectors/src/macros/mod.rs @@ -1,5 +1,5 @@ -#[cfg(feature="fixed_wide_traits")] -pub mod wide; +#[cfg(feature="fixed_wide")] +pub mod fixed_wide; pub mod vector; pub mod matrix; diff --git a/fixed_wide_vectors/src/macros/vector.rs b/fixed_wide_vectors/src/macros/vector.rs index 3af837a..a68d0d7 100644 --- a/fixed_wide_vectors/src/macros/vector.rs +++ b/fixed_wide_vectors/src/macros/vector.rs @@ -242,7 +242,7 @@ macro_rules! impl_vector { $crate::impl_vector_operator!( $struct { $($field), + }, BitXor, bitxor, Self ); // Impl floating-point based methods - #[cfg(feature="fixed_wide_traits")] + #[cfg(feature="fixed_wide")] $crate::impl_wide_vector_operations!( $struct { $($field), + }, $size ); }; } diff --git a/fixed_wide_vectors/src/tests/fixed_wide_traits.rs b/fixed_wide_vectors/src/tests/fixed_wide.rs similarity index 79% rename from fixed_wide_vectors/src/tests/fixed_wide_traits.rs rename to fixed_wide_vectors/src/tests/fixed_wide.rs index 73a0a1b..99a72d6 100644 --- a/fixed_wide_vectors/src/tests/fixed_wide_traits.rs +++ b/fixed_wide_vectors/src/tests/fixed_wide.rs @@ -1,6 +1,3 @@ -use fixed_wide_traits::wide::WideMul; -use fixed_wide_traits::wide::WideDot; - use crate::{Vector2,Vector3,Matrix3}; type Planar64=fixed_wide::types::I32F32; @@ -11,9 +8,9 @@ type Planar64Wide3=fixed_wide::types::I256F256; #[test] fn wide_vec3(){ let v=Vector3::from_value(Planar64::from(3)); - let v1=v.wide_mul(v); - let v2=v1.wide_mul(v1); - let v3=v2.wide_mul(v2); + let v1=v.wide_mul_1_1(v); + let v2=v1.wide_mul_2_2(v1); + let v3=v2.wide_mul_4_4(v2); assert_eq!(v3,Vector3::from_value(Planar64Wide3::from(3i128.pow(8)))); } @@ -21,9 +18,9 @@ fn wide_vec3(){ #[test] fn wide_vec3_dot(){ let v=Vector3::from_value(Planar64::from(3)); - let v1=v.wide_mul(v); - let v2=v1.wide_mul(v1); - let v3=v2.wide_dot(v2); + let v1=v.wide_mul_1_1(v); + let v2=v1.wide_mul_2_2(v1); + let v3=v2.wide_dot_4_4(v2); assert_eq!(v3,Planar64Wide3::from(3i128.pow(8)*3)); } @@ -31,8 +28,8 @@ fn wide_vec3_dot(){ #[test] fn wide_vec3_length_squared(){ let v=Vector3::from_value(Planar64::from(3)); - let v1=v.wide_mul(v); - let v2=v1.wide_mul(v1); + let v1=v.wide_mul_1_1(v); + let v2=v1.wide_mul_2_2(v1); let v3=v2.wide_length_squared(); assert_eq!(v3,Planar64Wide3::from(3i128.pow(8)*3)); @@ -43,7 +40,7 @@ fn wide_vec_of_vec_dot(){ let vv=Vector3::>::from_value_2d(Planar64::from(3)); // do the dot product of the inner vectors multiplied component wise // this lowers the rank of the data structure and is kind of a weird operation lol - let vv_dot=vv.wide_dot(vv); + let vv_dot=vv.wide_dot_1_1(vv); assert_eq!(vv_dot,Vector2::from_value(Planar64Wide1::from(3i128.pow(3)))); } #[test] @@ -51,6 +48,6 @@ fn wide_matrix_dot(){ let m=Matrix3::>::from_value_2d(Planar64::from(3)); //normal matrix product todo!() - //let m_dot=m.wide_dot(m); + //let m_dot=m.wide_dot_1_1(m); //assert_eq!(m_dot,Matrix3::>::from_value_2d(Planar64Wide1::from(3i128.pow(2)))); } diff --git a/fixed_wide_vectors/src/tests/mod.rs b/fixed_wide_vectors/src/tests/mod.rs index 36de35f..67fb0b3 100644 --- a/fixed_wide_vectors/src/tests/mod.rs +++ b/fixed_wide_vectors/src/tests/mod.rs @@ -1,5 +1,5 @@ mod tests; -#[cfg(feature="fixed_wide_traits")] -mod fixed_wide_traits; +#[cfg(feature="fixed_wide")] +mod fixed_wide; From c856509759ece77215489ba457e1a5efba21adc6 Mon Sep 17 00:00:00 2001 From: Quaternions Date: Mon, 2 Sep 2024 17:49:15 -0700 Subject: [PATCH 108/227] remove old comment --- fixed_wide/src/zeroes.rs | 3 --- 1 file changed, 3 deletions(-) diff --git a/fixed_wide/src/zeroes.rs b/fixed_wide/src/zeroes.rs index 97da6c9..865d7d3 100644 --- a/fixed_wide/src/zeroes.rs +++ b/fixed_wide/src/zeroes.rs @@ -17,10 +17,7 @@ macro_rules! impl_zeroes{ let radicand=a1.[](a1)-a2.[](a0)*4; match radicand.cmp(&Fixed::<{$n*2},{$n*2*32}>::ZERO){ Ordering::Greater=>{ - //start with f64 sqrt - //failure case: 2^63 < sqrt(2^127) let planar_radicand=radicand.sqrt().halve_precision(); - //TODO: one or two newtons //sort roots ascending and avoid taking the difference of large numbers match (a2pos,Self::ZERO[Ratio::new(-a1-planar_radicand,a2*2),Ratio::new(a0*2,-a1-planar_radicand)].into(), From c26ce93fc87d176b3e6a0aa2b068445a6a874a13 Mon Sep 17 00:00:00 2001 From: Quaternions Date: Mon, 2 Sep 2024 18:03:11 -0700 Subject: [PATCH 109/227] paste --- fixed_wide_vectors/Cargo.lock | 1 + fixed_wide_vectors/Cargo.toml | 1 + 2 files changed, 2 insertions(+) diff --git a/fixed_wide_vectors/Cargo.lock b/fixed_wide_vectors/Cargo.lock index 5bb2156..7c320dd 100644 --- a/fixed_wide_vectors/Cargo.lock +++ b/fixed_wide_vectors/Cargo.lock @@ -28,6 +28,7 @@ name = "fixed_wide_vectors" version = "0.1.0" dependencies = [ "fixed_wide", + "paste", ] [[package]] diff --git a/fixed_wide_vectors/Cargo.toml b/fixed_wide_vectors/Cargo.toml index a3dad29..b2f5856 100644 --- a/fixed_wide_vectors/Cargo.toml +++ b/fixed_wide_vectors/Cargo.toml @@ -9,3 +9,4 @@ fixed_wide=["dep:fixed_wide"] [dependencies] fixed_wide = { version = "0.1.0", path = "../fixed_wide", optional = true } +paste = "1.0.15" From e98744871b979ba35b8cda3e8230bdd4dd18479f Mon Sep 17 00:00:00 2001 From: Quaternions Date: Mon, 2 Sep 2024 18:05:56 -0700 Subject: [PATCH 110/227] narrow paste scope --- fixed_wide/src/zeroes.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/fixed_wide/src/zeroes.rs b/fixed_wide/src/zeroes.rs index 865d7d3..5966615 100644 --- a/fixed_wide/src/zeroes.rs +++ b/fixed_wide/src/zeroes.rs @@ -6,7 +6,6 @@ use std::cmp::Ordering; macro_rules! impl_zeroes{ ($n:expr)=>{ impl Fixed<$n,{$n*32}>{ - paste::item!{ #[inline] pub fn zeroes2(a0:Self,a1:Self,a2:Self)->ArrayVec,2>{ let a2pos=match a2.cmp(&Self::ZERO){ @@ -14,7 +13,9 @@ macro_rules! impl_zeroes{ Ordering::Equal=>return ArrayVec::from_iter(Self::zeroes1(a0,a1).into_iter()), Ordering::Less=>true, }; + paste::item!{ let radicand=a1.[](a1)-a2.[](a0)*4; + } match radicand.cmp(&Fixed::<{$n*2},{$n*2*32}>::ZERO){ Ordering::Greater=>{ let planar_radicand=radicand.sqrt().halve_precision(); @@ -30,7 +31,6 @@ macro_rules! impl_zeroes{ Ordering::Less=>ArrayVec::new_const(), } } - } #[inline] pub fn zeroes1(a0:Self,a1:Self)->ArrayVec,1>{ if a1==Self::ZERO{ From b14c84bdad5558cd67c5ae979433a0a359cec3b7 Mon Sep 17 00:00:00 2001 From: Quaternions Date: Mon, 2 Sep 2024 18:19:25 -0700 Subject: [PATCH 111/227] MACRO MACRO MACRO --- fixed_wide_vectors/src/macros/fixed_wide.rs | 56 ++++++++++++++++++--- 1 file changed, 50 insertions(+), 6 deletions(-) diff --git a/fixed_wide_vectors/src/macros/fixed_wide.rs b/fixed_wide_vectors/src/macros/fixed_wide.rs index d6a9eec..1cf0cb9 100644 --- a/fixed_wide_vectors/src/macros/fixed_wide.rs +++ b/fixed_wide_vectors/src/macros/fixed_wide.rs @@ -1,16 +1,18 @@ #[doc(hidden)] #[macro_export(local_inner_macros)] -macro_rules! impl_wide_vector_operations { - ( $struct: ident { $($field: ident), + }, $size: expr ) => { - impl> fixed_wide_traits::wide::WideMul for $struct { - type Output=$struct; +macro_rules! impl_wide_vector_operations_const { + ( $lhs:expr, $rhs:expr, ($struct: ident { $($field: ident), + }, $size: expr) ) => { + impl $struct>{ + paste::item!{ #[inline] - fn wide_mul(self, rhs: Self) -> Self::Output { + pub fn [](self,rhs:$struct>)->$struct>{ $struct{ - $( $field: self.$field.wide_mul(rhs.$field) ), + + $( $field: self.$field.[](rhs.$field) ), + } } + } } + /* impl,U,T:fixed_wide_traits::wide::WideMul> fixed_wide_traits::wide::WideDot<$struct> for $struct { type Output=V; #[inline] @@ -28,6 +30,48 @@ macro_rules! impl_wide_vector_operations { ) } } + */ + }; +} +#[doc(hidden)] +#[macro_export(local_inner_macros)] +macro_rules! do_macro_repeated{ + ( + $macro:ident, + $any:tt, + $(($x:expr, $y:expr)),* + )=>{ + $( + $crate::$macro!($x, $y, $any); + )* + }; +} + +#[doc(hidden)] +#[macro_export(local_inner_macros)] +macro_rules! do_macro_8x8{ + ( + $macro:ident, + $any:tt + )=>{ + $crate::do_macro_repeated!($macro, $any, + (1,1),(2,1),(3,1),(4,1),(5,1),(6,1),(7,1),(8,1), + (1,2),(2,2),(3,2),(4,2),(5,2),(6,2),(7,2),(8,2), + (1,3),(2,3),(3,3),(4,3),(5,3),(6,3),(7,3),(8,3), + (1,4),(2,4),(3,4),(4,4),(5,4),(6,4),(7,4),(8,4), + (1,5),(2,5),(3,5),(4,5),(5,5),(6,5),(7,5),(8,5), + (1,6),(2,6),(3,6),(4,6),(5,6),(6,6),(7,6),(8,6), + (1,7),(2,7),(3,7),(4,7),(5,7),(6,7),(7,7),(8,7), + (1,8),(2,8),(3,8),(4,8),(5,8),(6,8),(7,8),(8,8) + ); + }; +} + +#[doc(hidden)] +#[macro_export(local_inner_macros)] +macro_rules! impl_wide_vector_operations { + ( $struct: ident { $($field: ident), + }, $size: expr ) => { + $crate::do_macro_8x8!(impl_wide_vector_operations_const,($struct { $($field), + }, $size)); }; } From 83434a89c7763502c3837e7cd97c8139390d0e52 Mon Sep 17 00:00:00 2001 From: Quaternions Date: Mon, 2 Sep 2024 18:25:21 -0700 Subject: [PATCH 112/227] wide_dot --- fixed_wide_vectors/src/macros/fixed_wide.rs | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) diff --git a/fixed_wide_vectors/src/macros/fixed_wide.rs b/fixed_wide_vectors/src/macros/fixed_wide.rs index 1cf0cb9..7679939 100644 --- a/fixed_wide_vectors/src/macros/fixed_wide.rs +++ b/fixed_wide_vectors/src/macros/fixed_wide.rs @@ -10,18 +10,15 @@ macro_rules! impl_wide_vector_operations_const { $( $field: self.$field.[](rhs.$field) ), + } } + #[inline] + pub fn [](self,rhs:$struct>)->fixed_wide::fixed::Fixed<{$lhs+$rhs},{($lhs+$rhs)*32}>{ + $crate::sum_repeating!( + $( + (self.$field.[](rhs.$field)) ) + + ) + } } } /* - impl,U,T:fixed_wide_traits::wide::WideMul> fixed_wide_traits::wide::WideDot<$struct> for $struct { - type Output=V; - #[inline] - fn wide_dot(self, rhs: $struct) -> Self::Output { - $crate::sum_repeating!( - $( + (self.$field.wide_mul(rhs.$field)) ) + - ) - } - } impl,T:Copy+fixed_wide_traits::wide::WideMul> $struct { #[inline] pub fn wide_length_squared(&self) -> U { From a6dc0c37ba6b1a643cc742c6a3b4fea0193b6f94 Mon Sep 17 00:00:00 2001 From: Quaternions Date: Mon, 2 Sep 2024 18:35:37 -0700 Subject: [PATCH 113/227] MACRO MACRO MACRO --- fixed_wide_vectors/src/macros/fixed_wide.rs | 38 +++++++++++++++------ 1 file changed, 28 insertions(+), 10 deletions(-) diff --git a/fixed_wide_vectors/src/macros/fixed_wide.rs b/fixed_wide_vectors/src/macros/fixed_wide.rs index 7679939..ff4e075 100644 --- a/fixed_wide_vectors/src/macros/fixed_wide.rs +++ b/fixed_wide_vectors/src/macros/fixed_wide.rs @@ -1,7 +1,7 @@ #[doc(hidden)] #[macro_export(local_inner_macros)] -macro_rules! impl_wide_vector_operations_const { - ( $lhs:expr, $rhs:expr, ($struct: ident { $($field: ident), + }, $size: expr) ) => { +macro_rules! impl_wide_vector_operations_2arg_not_const_generic { + ( ($lhs:expr, $rhs:expr), ($struct: ident { $($field: ident), + }, $size: expr) ) => { impl $struct>{ paste::item!{ #[inline] @@ -18,16 +18,22 @@ macro_rules! impl_wide_vector_operations_const { } } } - /* - impl,T:Copy+fixed_wide_traits::wide::WideMul> $struct { + } +} +#[doc(hidden)] +#[macro_export(local_inner_macros)] +macro_rules! impl_wide_vector_operations_1arg_not_const_generic { + ( $n:expr, ($struct: ident { $($field: ident), + }, $size: expr) ) => { + impl $struct>{ + paste::item!{ #[inline] - pub fn wide_length_squared(&self) -> U { + pub fn wide_length_squared(&self)->fixed_wide::fixed::Fixed<{$n*2},{$n*2*32}>{ $crate::sum_repeating!( - $( + self.$field.wide_mul(self.$field) ) + + $( + self.$field.[](self.$field) ) + ) } + } } - */ }; } #[doc(hidden)] @@ -36,10 +42,10 @@ macro_rules! do_macro_repeated{ ( $macro:ident, $any:tt, - $(($x:expr, $y:expr)),* + $($repeated:tt),* )=>{ $( - $crate::$macro!($x, $y, $any); + $crate::$macro!($repeated, $any); )* }; } @@ -64,11 +70,23 @@ macro_rules! do_macro_8x8{ }; } +#[doc(hidden)] +#[macro_export(local_inner_macros)] +macro_rules! do_macro_8{ + ( + $macro:ident, + $any:tt + )=>{ + $crate::do_macro_repeated!($macro, $any, 1,2,3,4,5,6,7,8); + }; +} + #[doc(hidden)] #[macro_export(local_inner_macros)] macro_rules! impl_wide_vector_operations { ( $struct: ident { $($field: ident), + }, $size: expr ) => { - $crate::do_macro_8x8!(impl_wide_vector_operations_const,($struct { $($field), + }, $size)); + $crate::do_macro_8!(impl_wide_vector_operations_1arg_not_const_generic,($struct { $($field), + }, $size)); + $crate::do_macro_8x8!(impl_wide_vector_operations_2arg_not_const_generic,($struct { $($field), + }, $size)); }; } From 1bd45283a95e25e21adb715ffbfbce9632fe1a61 Mon Sep 17 00:00:00 2001 From: Quaternions Date: Mon, 2 Sep 2024 18:36:05 -0700 Subject: [PATCH 114/227] delete unused test --- fixed_wide_vectors/src/tests/fixed_wide.rs | 8 -------- 1 file changed, 8 deletions(-) diff --git a/fixed_wide_vectors/src/tests/fixed_wide.rs b/fixed_wide_vectors/src/tests/fixed_wide.rs index 99a72d6..9eb6bec 100644 --- a/fixed_wide_vectors/src/tests/fixed_wide.rs +++ b/fixed_wide_vectors/src/tests/fixed_wide.rs @@ -35,14 +35,6 @@ fn wide_vec3_length_squared(){ assert_eq!(v3,Planar64Wide3::from(3i128.pow(8)*3)); } -#[test] -fn wide_vec_of_vec_dot(){ - let vv=Vector3::>::from_value_2d(Planar64::from(3)); - // do the dot product of the inner vectors multiplied component wise - // this lowers the rank of the data structure and is kind of a weird operation lol - let vv_dot=vv.wide_dot_1_1(vv); - assert_eq!(vv_dot,Vector2::from_value(Planar64Wide1::from(3i128.pow(3)))); -} #[test] fn wide_matrix_dot(){ let m=Matrix3::>::from_value_2d(Planar64::from(3)); From a5094fe873603cb71ef1e080485f60930504d604 Mon Sep 17 00:00:00 2001 From: Quaternions Date: Mon, 2 Sep 2024 14:04:52 -0700 Subject: [PATCH 115/227] common impls between matrix and vector --- fixed_wide_vectors/src/macros/common.rs | 102 ++++++++++++++++++++++++ fixed_wide_vectors/src/macros/matrix.rs | 20 +++++ fixed_wide_vectors/src/macros/mod.rs | 1 + fixed_wide_vectors/src/macros/vector.rs | 97 +--------------------- fixed_wide_vectors/src/matrix.rs | 22 ++--- fixed_wide_vectors/src/vector.rs | 18 ++--- 6 files changed, 146 insertions(+), 114 deletions(-) create mode 100644 fixed_wide_vectors/src/macros/common.rs diff --git a/fixed_wide_vectors/src/macros/common.rs b/fixed_wide_vectors/src/macros/common.rs new file mode 100644 index 0000000..952ff30 --- /dev/null +++ b/fixed_wide_vectors/src/macros/common.rs @@ -0,0 +1,102 @@ +#[doc(hidden)] +#[macro_export(local_inner_macros)] +macro_rules! impl_common { + ( $struct: ident { $($field: ident), + }, ( $($generic: ident), + ), $size: expr ) => { + impl $struct { + /// Constructs a new vector with the specified values for each field. + /// + /// # Example + /// + /// ``` + /// use fixed_wide_vectors::Vector2; + /// + /// let vec2 = Vector2::new(0, 0); + /// + /// assert_eq!(vec2.x, 0); + /// assert_eq!(vec2.y, 0); + /// ``` + #[inline(always)] + pub const fn new( $($field: T), + ) -> Self { + Self { + $( $field ), + + } + } + + /// Consumes the vector and returns its values as an array. + /// + /// # Example + /// + /// ``` + /// use fixed_wide_vectors::Vector2; + /// + /// let vec2 = Vector2::new(0, 0); + /// let array = vec2.to_array(); + /// + /// assert_eq!(array, [0, 0]); + /// ``` + #[inline(always)] + pub fn to_array(self) -> [T; $size] { + [ $(self.$field), + ] + } + + /// Consumes the vector and returns its values as a tuple. + /// + /// # Example + /// + /// ``` + /// use fixed_wide_vectors::Vector2; + /// + /// let vec2 = Vector2::new(0, 0); + /// let tuple = vec2.to_tuple(); + /// + /// assert_eq!(tuple, (0, 0)); + /// ``` + #[inline(always)] + pub fn to_tuple(self) -> ( $($generic), + ) { + ( $(self.$field), + ) + } + + /// Consumes the vector and returns a new vector with the given function applied on each field. + /// + /// # Example + /// + /// ``` + /// use fixed_wide_vectors::Vector2; + /// + /// let vec2 = Vector2::new(1, 2) + /// .map(|i| i * 2); + /// + /// assert_eq!(vec2, Vector2::new(2, 4)); + /// ``` + #[inline] + pub fn map(self, f: F) -> $struct + where + F: Fn(T) -> U + { + $struct { + $( $field: f(self.$field) ), + + } + } + } + + impl $struct { + /// Constructs a vector using the given `value` as the value for all of its fields. + /// + /// # Example + /// + /// ``` + /// use fixed_wide_vectors::Vector2; + /// + /// let vec2 = Vector2::from_value(0); + /// + /// assert_eq!(vec2, Vector2::new(0, 0)); + /// ``` + #[inline(always)] + pub const fn from_value(value: T) -> Self { + Self { + $( $field: value ), + + } + } + } + } +} diff --git a/fixed_wide_vectors/src/macros/matrix.rs b/fixed_wide_vectors/src/macros/matrix.rs index f9375e7..d9a858f 100644 --- a/fixed_wide_vectors/src/macros/matrix.rs +++ b/fixed_wide_vectors/src/macros/matrix.rs @@ -2,6 +2,26 @@ #[doc(hidden)] #[macro_export(local_inner_macros)] macro_rules! impl_matrix { + ( + ($struct_outer: ident { $($field_outer: ident), + }, $vector_outer: ident { $($vector_field_outer: ident), + }, $size_outer: expr), + ( $($generic_outer: tt), + ) + ) => { + $crate::impl_common!($struct_outer { $($field_outer), + }, ( $($generic_outer), + ), $size_outer); + impl $struct_outer { + #[inline(always)] + pub fn to_vector(self) -> $vector_outer { + $vector_outer { + $( + $vector_field_outer: self.$field_outer + ), + + } + } + } + } +} +#[doc(hidden)] +#[macro_export(local_inner_macros)] +macro_rules! impl_matrix_inner { ( ($struct_outer: ident { $($field_outer: ident), + }, $vector_outer: ident { $($vector_field_outer: ident), + }, $size_outer: expr), ($struct_inner: ident { $($field_inner: ident), + }, $matrix_inner: ident { $($matrix_field_inner: ident), + }, $size_inner: expr), diff --git a/fixed_wide_vectors/src/macros/mod.rs b/fixed_wide_vectors/src/macros/mod.rs index 9dfc914..30d20cc 100644 --- a/fixed_wide_vectors/src/macros/mod.rs +++ b/fixed_wide_vectors/src/macros/mod.rs @@ -1,5 +1,6 @@ #[cfg(feature="fixed_wide")] pub mod fixed_wide; +pub mod common; pub mod vector; pub mod matrix; diff --git a/fixed_wide_vectors/src/macros/vector.rs b/fixed_wide_vectors/src/macros/vector.rs index a68d0d7..034f8ed 100644 --- a/fixed_wide_vectors/src/macros/vector.rs +++ b/fixed_wide_vectors/src/macros/vector.rs @@ -3,102 +3,7 @@ #[macro_export(local_inner_macros)] macro_rules! impl_vector { ( $struct: ident { $($field: ident), + }, ( $($generic: ident), + ), $size: expr ) => { - impl $struct { - /// Constructs a new vector with the specified values for each field. - /// - /// # Example - /// - /// ``` - /// use fixed_wide_vectors::Vector2; - /// - /// let vec2 = Vector2::new(0, 0); - /// - /// assert_eq!(vec2.x, 0); - /// assert_eq!(vec2.y, 0); - /// ``` - #[inline(always)] - pub const fn new( $($field: T), + ) -> Self { - Self { - $( $field ), + - } - } - - /// Consumes the vector and returns its values as an array. - /// - /// # Example - /// - /// ``` - /// use fixed_wide_vectors::Vector2; - /// - /// let vec2 = Vector2::new(0, 0); - /// let array = vec2.to_array(); - /// - /// assert_eq!(array, [0, 0]); - /// ``` - #[inline(always)] - pub fn to_array(self) -> [T; $size] { - [ $(self.$field), + ] - } - - /// Consumes the vector and returns its values as a tuple. - /// - /// # Example - /// - /// ``` - /// use fixed_wide_vectors::Vector2; - /// - /// let vec2 = Vector2::new(0, 0); - /// let tuple = vec2.to_tuple(); - /// - /// assert_eq!(tuple, (0, 0)); - /// ``` - #[inline(always)] - pub fn to_tuple(self) -> ( $($generic), + ) { - ( $(self.$field), + ) - } - - /// Consumes the vector and returns a new vector with the given function applied on each field. - /// - /// # Example - /// - /// ``` - /// use fixed_wide_vectors::Vector2; - /// - /// let vec2 = Vector2::new(1, 2) - /// .map(|i| i * 2); - /// - /// assert_eq!(vec2, Vector2::new(2, 4)); - /// ``` - #[inline] - pub fn map(self, f: F) -> $struct - where - F: Fn(T) -> U - { - $struct { - $( $field: f(self.$field) ), + - } - } - } - - impl $struct { - /// Constructs a vector using the given `value` as the value for all of its fields. - /// - /// # Example - /// - /// ``` - /// use fixed_wide_vectors::Vector2; - /// - /// let vec2 = Vector2::from_value(0); - /// - /// assert_eq!(vec2, Vector2::new(0, 0)); - /// ``` - #[inline(always)] - pub const fn from_value(value: T) -> Self { - Self { - $( $field: value ), + - } - } - } + $crate::impl_common!($struct { $($field), + }, ( $($generic), + ), $size); impl From<[T; $size]> for $struct { fn from(from: [T; $size]) -> Self { diff --git a/fixed_wide_vectors/src/matrix.rs b/fixed_wide_vectors/src/matrix.rs index a1e6943..908cd3d 100644 --- a/fixed_wide_vectors/src/matrix.rs +++ b/fixed_wide_vectors/src/matrix.rs @@ -16,15 +16,19 @@ pub struct Matrix4 { pub w_axis: T, } +crate::impl_matrix!((Matrix2 { x_axis, y_axis }, Vector2 { x, y }, 2), (T, T)); +crate::impl_matrix!((Matrix3 { x_axis, y_axis, z_axis }, Vector3 { x, y, z }, 3), (T, T, T)); +crate::impl_matrix!((Matrix4 { x_axis, y_axis, z_axis, w_axis }, Vector4 { x, y, z, w }, 4), (T, T, T, T)); + crate::impl_extend!(Matrix2 { x_axis, y_axis }, Matrix3, z_axis); crate::impl_extend!(Matrix3 { x_axis, y_axis, z_axis }, Matrix4, w_axis); -crate::impl_matrix!((Matrix2 { x_axis, y_axis }, Vector2 { x, y }, 2), (Vector2 { x, y }, Matrix2 { x_axis, y_axis }, 2), ((T, T), (T, T)) ); -crate::impl_matrix!((Matrix2 { x_axis, y_axis }, Vector2 { x, y }, 2), (Vector3 { x, y, z }, Matrix3 { x_axis, y_axis, z_axis }, 3), ((T, T, T), (T, T, T)) ); -crate::impl_matrix!((Matrix2 { x_axis, y_axis }, Vector2 { x, y }, 2), (Vector4 { x, y, z, w }, Matrix4 { x_axis, y_axis, z_axis, w_axis }, 4), ((T, T, T, T), (T, T, T, T)) ); -crate::impl_matrix!((Matrix3 { x_axis, y_axis, z_axis }, Vector3 { x, y, z }, 3), (Vector2 { x, y }, Matrix2 { x_axis, y_axis }, 2), ((T, T), (T, T), (T, T)) ); -crate::impl_matrix!((Matrix3 { x_axis, y_axis, z_axis }, Vector3 { x, y, z }, 3), (Vector3 { x, y, z }, Matrix3 { x_axis, y_axis, z_axis }, 3), ((T, T, T), (T, T, T), (T, T, T)) ); -crate::impl_matrix!((Matrix3 { x_axis, y_axis, z_axis }, Vector3 { x, y, z }, 3), (Vector4 { x, y, z, w }, Matrix4 { x_axis, y_axis, z_axis, w_axis }, 4), ((T, T, T, T), (T, T, T, T), (T, T, T, T)) ); -crate::impl_matrix!((Matrix4 { x_axis, y_axis, z_axis, w_axis }, Vector4 { x, y, z, w }, 4), (Vector2 { x, y }, Matrix2 { x_axis, y_axis }, 2), ((T, T), (T, T), (T, T), (T, T)) ); -crate::impl_matrix!((Matrix4 { x_axis, y_axis, z_axis, w_axis }, Vector4 { x, y, z, w }, 4), (Vector3 { x, y, z }, Matrix3 { x_axis, y_axis, z_axis }, 3), ((T, T, T), (T, T, T), (T, T, T), (T, T, T)) ); -crate::impl_matrix!((Matrix4 { x_axis, y_axis, z_axis, w_axis }, Vector4 { x, y, z, w }, 4), (Vector4 { x, y, z, w }, Matrix4 { x_axis, y_axis, z_axis, w_axis }, 4), ((T, T, T, T), (T, T, T, T), (T, T, T, T), (T, T, T, T)) ); +crate::impl_matrix_inner!((Matrix2 { x_axis, y_axis }, Vector2 { x, y }, 2), (Vector2 { x, y }, Matrix2 { x_axis, y_axis }, 2), ((T, T), (T, T)) ); +crate::impl_matrix_inner!((Matrix2 { x_axis, y_axis }, Vector2 { x, y }, 2), (Vector3 { x, y, z }, Matrix3 { x_axis, y_axis, z_axis }, 3), ((T, T, T), (T, T, T)) ); +crate::impl_matrix_inner!((Matrix2 { x_axis, y_axis }, Vector2 { x, y }, 2), (Vector4 { x, y, z, w }, Matrix4 { x_axis, y_axis, z_axis, w_axis }, 4), ((T, T, T, T), (T, T, T, T)) ); +crate::impl_matrix_inner!((Matrix3 { x_axis, y_axis, z_axis }, Vector3 { x, y, z }, 3), (Vector2 { x, y }, Matrix2 { x_axis, y_axis }, 2), ((T, T), (T, T), (T, T)) ); +crate::impl_matrix_inner!((Matrix3 { x_axis, y_axis, z_axis }, Vector3 { x, y, z }, 3), (Vector3 { x, y, z }, Matrix3 { x_axis, y_axis, z_axis }, 3), ((T, T, T), (T, T, T), (T, T, T)) ); +crate::impl_matrix_inner!((Matrix3 { x_axis, y_axis, z_axis }, Vector3 { x, y, z }, 3), (Vector4 { x, y, z, w }, Matrix4 { x_axis, y_axis, z_axis, w_axis }, 4), ((T, T, T, T), (T, T, T, T), (T, T, T, T)) ); +crate::impl_matrix_inner!((Matrix4 { x_axis, y_axis, z_axis, w_axis }, Vector4 { x, y, z, w }, 4), (Vector2 { x, y }, Matrix2 { x_axis, y_axis }, 2), ((T, T), (T, T), (T, T), (T, T)) ); +crate::impl_matrix_inner!((Matrix4 { x_axis, y_axis, z_axis, w_axis }, Vector4 { x, y, z, w }, 4), (Vector3 { x, y, z }, Matrix3 { x_axis, y_axis, z_axis }, 3), ((T, T, T), (T, T, T), (T, T, T), (T, T, T)) ); +crate::impl_matrix_inner!((Matrix4 { x_axis, y_axis, z_axis, w_axis }, Vector4 { x, y, z, w }, 4), (Vector4 { x, y, z, w }, Matrix4 { x_axis, y_axis, z_axis, w_axis }, 4), ((T, T, T, T), (T, T, T, T), (T, T, T, T), (T, T, T, T)) ); diff --git a/fixed_wide_vectors/src/vector.rs b/fixed_wide_vectors/src/vector.rs index c528b5c..9d9a31e 100644 --- a/fixed_wide_vectors/src/vector.rs +++ b/fixed_wide_vectors/src/vector.rs @@ -70,12 +70,12 @@ crate::impl_vector!(Vector4 { x, y, z, w }, (T, T, T, T), 4); crate::impl_extend!(Vector2 { x, y }, Vector3, z); crate::impl_extend!(Vector3 { x, y, z }, Vector4, w); -crate::impl_matrix!((Vector2 { x, y }, Vector2 { x, y }, 2), (Vector2 { x, y }, Vector2 { x, y }, 2), ((T, T), (T, T)) ); -crate::impl_matrix!((Vector2 { x, y }, Vector2 { x, y }, 2), (Vector3 { x, y, z }, Vector3 { x, y, z }, 3), ((T, T, T), (T, T, T)) ); -crate::impl_matrix!((Vector2 { x, y }, Vector2 { x, y }, 2), (Vector4 { x, y, z, w }, Vector4 { x, y, z, w }, 4), ((T, T, T, T), (T, T, T, T)) ); -crate::impl_matrix!((Vector3 { x, y, z }, Vector3 { x, y, z }, 3), (Vector2 { x, y }, Vector2 { x, y }, 2), ((T, T), (T, T), (T, T)) ); -crate::impl_matrix!((Vector3 { x, y, z }, Vector3 { x, y, z }, 3), (Vector3 { x, y, z }, Vector3 { x, y, z }, 3), ((T, T, T), (T, T, T), (T, T, T)) ); -crate::impl_matrix!((Vector3 { x, y, z }, Vector3 { x, y, z }, 3), (Vector4 { x, y, z, w }, Vector4 { x, y, z, w }, 4), ((T, T, T, T), (T, T, T, T), (T, T, T, T)) ); -crate::impl_matrix!((Vector4 { x, y, z, w }, Vector4 { x, y, z, w }, 4), (Vector2 { x, y }, Vector2 { x, y }, 2), ((T, T), (T, T), (T, T), (T, T)) ); -crate::impl_matrix!((Vector4 { x, y, z, w }, Vector4 { x, y, z, w }, 4), (Vector3 { x, y, z }, Vector3 { x, y, z }, 3), ((T, T, T), (T, T, T), (T, T, T), (T, T, T)) ); -crate::impl_matrix!((Vector4 { x, y, z, w }, Vector4 { x, y, z, w }, 4), (Vector4 { x, y, z, w }, Vector4 { x, y, z, w }, 4), ((T, T, T, T), (T, T, T, T), (T, T, T, T), (T, T, T, T)) ); +crate::impl_matrix_inner!((Vector2 { x, y }, Vector2 { x, y }, 2), (Vector2 { x, y }, Vector2 { x, y }, 2), ((T, T), (T, T)) ); +crate::impl_matrix_inner!((Vector2 { x, y }, Vector2 { x, y }, 2), (Vector3 { x, y, z }, Vector3 { x, y, z }, 3), ((T, T, T), (T, T, T)) ); +crate::impl_matrix_inner!((Vector2 { x, y }, Vector2 { x, y }, 2), (Vector4 { x, y, z, w }, Vector4 { x, y, z, w }, 4), ((T, T, T, T), (T, T, T, T)) ); +crate::impl_matrix_inner!((Vector3 { x, y, z }, Vector3 { x, y, z }, 3), (Vector2 { x, y }, Vector2 { x, y }, 2), ((T, T), (T, T), (T, T)) ); +crate::impl_matrix_inner!((Vector3 { x, y, z }, Vector3 { x, y, z }, 3), (Vector3 { x, y, z }, Vector3 { x, y, z }, 3), ((T, T, T), (T, T, T), (T, T, T)) ); +crate::impl_matrix_inner!((Vector3 { x, y, z }, Vector3 { x, y, z }, 3), (Vector4 { x, y, z, w }, Vector4 { x, y, z, w }, 4), ((T, T, T, T), (T, T, T, T), (T, T, T, T)) ); +crate::impl_matrix_inner!((Vector4 { x, y, z, w }, Vector4 { x, y, z, w }, 4), (Vector2 { x, y }, Vector2 { x, y }, 2), ((T, T), (T, T), (T, T), (T, T)) ); +crate::impl_matrix_inner!((Vector4 { x, y, z, w }, Vector4 { x, y, z, w }, 4), (Vector3 { x, y, z }, Vector3 { x, y, z }, 3), ((T, T, T), (T, T, T), (T, T, T), (T, T, T)) ); +crate::impl_matrix_inner!((Vector4 { x, y, z, w }, Vector4 { x, y, z, w }, 4), (Vector4 { x, y, z, w }, Vector4 { x, y, z, w }, 4), ((T, T, T, T), (T, T, T, T), (T, T, T, T), (T, T, T, T)) ); From 27d96f9b19f63752115b6cfb995db3d5c94009c5 Mon Sep 17 00:00:00 2001 From: Quaternions Date: Tue, 3 Sep 2024 09:20:43 -0700 Subject: [PATCH 116/227] delete tuple impls --- fixed_wide_vectors/src/macros/common.rs | 19 +------------------ fixed_wide_vectors/src/macros/matrix.rs | 13 +++---------- fixed_wide_vectors/src/macros/vector.rs | 14 ++------------ fixed_wide_vectors/src/matrix.rs | 24 ++++++++++++------------ fixed_wide_vectors/src/vector.rs | 24 ++++++++++++------------ 5 files changed, 30 insertions(+), 64 deletions(-) diff --git a/fixed_wide_vectors/src/macros/common.rs b/fixed_wide_vectors/src/macros/common.rs index 952ff30..df335fd 100644 --- a/fixed_wide_vectors/src/macros/common.rs +++ b/fixed_wide_vectors/src/macros/common.rs @@ -1,7 +1,7 @@ #[doc(hidden)] #[macro_export(local_inner_macros)] macro_rules! impl_common { - ( $struct: ident { $($field: ident), + }, ( $($generic: ident), + ), $size: expr ) => { + ( $struct: ident { $($field: ident), + }, $size: expr ) => { impl $struct { /// Constructs a new vector with the specified values for each field. /// @@ -39,23 +39,6 @@ macro_rules! impl_common { [ $(self.$field), + ] } - /// Consumes the vector and returns its values as a tuple. - /// - /// # Example - /// - /// ``` - /// use fixed_wide_vectors::Vector2; - /// - /// let vec2 = Vector2::new(0, 0); - /// let tuple = vec2.to_tuple(); - /// - /// assert_eq!(tuple, (0, 0)); - /// ``` - #[inline(always)] - pub fn to_tuple(self) -> ( $($generic), + ) { - ( $(self.$field), + ) - } - /// Consumes the vector and returns a new vector with the given function applied on each field. /// /// # Example diff --git a/fixed_wide_vectors/src/macros/matrix.rs b/fixed_wide_vectors/src/macros/matrix.rs index d9a858f..fbced95 100644 --- a/fixed_wide_vectors/src/macros/matrix.rs +++ b/fixed_wide_vectors/src/macros/matrix.rs @@ -3,10 +3,9 @@ #[macro_export(local_inner_macros)] macro_rules! impl_matrix { ( - ($struct_outer: ident { $($field_outer: ident), + }, $vector_outer: ident { $($vector_field_outer: ident), + }, $size_outer: expr), - ( $($generic_outer: tt), + ) + ($struct_outer: ident { $($field_outer: ident), + }, $vector_outer: ident { $($vector_field_outer: ident), + }, $size_outer: expr) ) => { - $crate::impl_common!($struct_outer { $($field_outer), + }, ( $($generic_outer), + ), $size_outer); + $crate::impl_common!($struct_outer { $($field_outer), + }, $size_outer); impl $struct_outer { #[inline(always)] pub fn to_vector(self) -> $vector_outer { @@ -24,8 +23,7 @@ macro_rules! impl_matrix { macro_rules! impl_matrix_inner { ( ($struct_outer: ident { $($field_outer: ident), + }, $vector_outer: ident { $($vector_field_outer: ident), + }, $size_outer: expr), - ($struct_inner: ident { $($field_inner: ident), + }, $matrix_inner: ident { $($matrix_field_inner: ident), + }, $size_inner: expr), - ( $($generic_outer: tt), + ) + ($struct_inner: ident { $($field_inner: ident), + }, $matrix_inner: ident { $($matrix_field_inner: ident), + }, $size_inner: expr) ) => { impl $struct_outer<$struct_inner> { #[inline(always)] @@ -33,11 +31,6 @@ macro_rules! impl_matrix_inner { [ $(self.$field_outer.to_array()), + ] } - #[inline(always)] - pub fn to_tuple_2d(self) -> ( $($generic_outer), + ) { - ( $(self.$field_outer.to_tuple()), + ) - } - #[inline] pub fn map_2d(self, f: F) -> $struct_outer<$struct_inner> where diff --git a/fixed_wide_vectors/src/macros/vector.rs b/fixed_wide_vectors/src/macros/vector.rs index 034f8ed..09bfcbe 100644 --- a/fixed_wide_vectors/src/macros/vector.rs +++ b/fixed_wide_vectors/src/macros/vector.rs @@ -2,8 +2,8 @@ #[doc(hidden)] #[macro_export(local_inner_macros)] macro_rules! impl_vector { - ( $struct: ident { $($field: ident), + }, ( $($generic: ident), + ), $size: expr ) => { - $crate::impl_common!($struct { $($field), + }, ( $($generic), + ), $size); + ( $struct: ident { $($field: ident), + }, $size: expr ) => { + $crate::impl_common!($struct { $($field), + }, $size); impl From<[T; $size]> for $struct { fn from(from: [T; $size]) -> Self { @@ -16,16 +16,6 @@ macro_rules! impl_vector { } } - impl From<($($generic), +)> for $struct { - fn from(from: ($($generic), +)) -> Self { - let ( $($field), + ) = from; - - Self { - $( $field ), + - } - } - } - impl core::fmt::Debug for $struct { fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { let identifier = core::stringify!($struct); diff --git a/fixed_wide_vectors/src/matrix.rs b/fixed_wide_vectors/src/matrix.rs index 908cd3d..840c16e 100644 --- a/fixed_wide_vectors/src/matrix.rs +++ b/fixed_wide_vectors/src/matrix.rs @@ -16,19 +16,19 @@ pub struct Matrix4 { pub w_axis: T, } -crate::impl_matrix!((Matrix2 { x_axis, y_axis }, Vector2 { x, y }, 2), (T, T)); -crate::impl_matrix!((Matrix3 { x_axis, y_axis, z_axis }, Vector3 { x, y, z }, 3), (T, T, T)); -crate::impl_matrix!((Matrix4 { x_axis, y_axis, z_axis, w_axis }, Vector4 { x, y, z, w }, 4), (T, T, T, T)); +crate::impl_matrix!((Matrix2 { x_axis, y_axis }, Vector2 { x, y }, 2)); +crate::impl_matrix!((Matrix3 { x_axis, y_axis, z_axis }, Vector3 { x, y, z }, 3)); +crate::impl_matrix!((Matrix4 { x_axis, y_axis, z_axis, w_axis }, Vector4 { x, y, z, w }, 4)); crate::impl_extend!(Matrix2 { x_axis, y_axis }, Matrix3, z_axis); crate::impl_extend!(Matrix3 { x_axis, y_axis, z_axis }, Matrix4, w_axis); -crate::impl_matrix_inner!((Matrix2 { x_axis, y_axis }, Vector2 { x, y }, 2), (Vector2 { x, y }, Matrix2 { x_axis, y_axis }, 2), ((T, T), (T, T)) ); -crate::impl_matrix_inner!((Matrix2 { x_axis, y_axis }, Vector2 { x, y }, 2), (Vector3 { x, y, z }, Matrix3 { x_axis, y_axis, z_axis }, 3), ((T, T, T), (T, T, T)) ); -crate::impl_matrix_inner!((Matrix2 { x_axis, y_axis }, Vector2 { x, y }, 2), (Vector4 { x, y, z, w }, Matrix4 { x_axis, y_axis, z_axis, w_axis }, 4), ((T, T, T, T), (T, T, T, T)) ); -crate::impl_matrix_inner!((Matrix3 { x_axis, y_axis, z_axis }, Vector3 { x, y, z }, 3), (Vector2 { x, y }, Matrix2 { x_axis, y_axis }, 2), ((T, T), (T, T), (T, T)) ); -crate::impl_matrix_inner!((Matrix3 { x_axis, y_axis, z_axis }, Vector3 { x, y, z }, 3), (Vector3 { x, y, z }, Matrix3 { x_axis, y_axis, z_axis }, 3), ((T, T, T), (T, T, T), (T, T, T)) ); -crate::impl_matrix_inner!((Matrix3 { x_axis, y_axis, z_axis }, Vector3 { x, y, z }, 3), (Vector4 { x, y, z, w }, Matrix4 { x_axis, y_axis, z_axis, w_axis }, 4), ((T, T, T, T), (T, T, T, T), (T, T, T, T)) ); -crate::impl_matrix_inner!((Matrix4 { x_axis, y_axis, z_axis, w_axis }, Vector4 { x, y, z, w }, 4), (Vector2 { x, y }, Matrix2 { x_axis, y_axis }, 2), ((T, T), (T, T), (T, T), (T, T)) ); -crate::impl_matrix_inner!((Matrix4 { x_axis, y_axis, z_axis, w_axis }, Vector4 { x, y, z, w }, 4), (Vector3 { x, y, z }, Matrix3 { x_axis, y_axis, z_axis }, 3), ((T, T, T), (T, T, T), (T, T, T), (T, T, T)) ); -crate::impl_matrix_inner!((Matrix4 { x_axis, y_axis, z_axis, w_axis }, Vector4 { x, y, z, w }, 4), (Vector4 { x, y, z, w }, Matrix4 { x_axis, y_axis, z_axis, w_axis }, 4), ((T, T, T, T), (T, T, T, T), (T, T, T, T), (T, T, T, T)) ); +crate::impl_matrix_inner!((Matrix2 { x_axis, y_axis }, Vector2 { x, y }, 2), (Vector2 { x, y }, Matrix2 { x_axis, y_axis }, 2) ); +crate::impl_matrix_inner!((Matrix2 { x_axis, y_axis }, Vector2 { x, y }, 2), (Vector3 { x, y, z }, Matrix3 { x_axis, y_axis, z_axis }, 3) ); +crate::impl_matrix_inner!((Matrix2 { x_axis, y_axis }, Vector2 { x, y }, 2), (Vector4 { x, y, z, w }, Matrix4 { x_axis, y_axis, z_axis, w_axis }, 4) ); +crate::impl_matrix_inner!((Matrix3 { x_axis, y_axis, z_axis }, Vector3 { x, y, z }, 3), (Vector2 { x, y }, Matrix2 { x_axis, y_axis }, 2) ); +crate::impl_matrix_inner!((Matrix3 { x_axis, y_axis, z_axis }, Vector3 { x, y, z }, 3), (Vector3 { x, y, z }, Matrix3 { x_axis, y_axis, z_axis }, 3) ); +crate::impl_matrix_inner!((Matrix3 { x_axis, y_axis, z_axis }, Vector3 { x, y, z }, 3), (Vector4 { x, y, z, w }, Matrix4 { x_axis, y_axis, z_axis, w_axis }, 4) ); +crate::impl_matrix_inner!((Matrix4 { x_axis, y_axis, z_axis, w_axis }, Vector4 { x, y, z, w }, 4), (Vector2 { x, y }, Matrix2 { x_axis, y_axis }, 2) ); +crate::impl_matrix_inner!((Matrix4 { x_axis, y_axis, z_axis, w_axis }, Vector4 { x, y, z, w }, 4), (Vector3 { x, y, z }, Matrix3 { x_axis, y_axis, z_axis }, 3) ); +crate::impl_matrix_inner!((Matrix4 { x_axis, y_axis, z_axis, w_axis }, Vector4 { x, y, z, w }, 4), (Vector4 { x, y, z, w }, Matrix4 { x_axis, y_axis, z_axis, w_axis }, 4) ); diff --git a/fixed_wide_vectors/src/vector.rs b/fixed_wide_vectors/src/vector.rs index 9d9a31e..f7ff0a6 100644 --- a/fixed_wide_vectors/src/vector.rs +++ b/fixed_wide_vectors/src/vector.rs @@ -63,19 +63,19 @@ pub struct Vector4 { } -crate::impl_vector!(Vector2 { x, y }, (T, T), 2); -crate::impl_vector!(Vector3 { x, y, z }, (T, T, T), 3); -crate::impl_vector!(Vector4 { x, y, z, w }, (T, T, T, T), 4); +crate::impl_vector!(Vector2 { x, y }, 2); +crate::impl_vector!(Vector3 { x, y, z }, 3); +crate::impl_vector!(Vector4 { x, y, z, w }, 4); crate::impl_extend!(Vector2 { x, y }, Vector3, z); crate::impl_extend!(Vector3 { x, y, z }, Vector4, w); -crate::impl_matrix_inner!((Vector2 { x, y }, Vector2 { x, y }, 2), (Vector2 { x, y }, Vector2 { x, y }, 2), ((T, T), (T, T)) ); -crate::impl_matrix_inner!((Vector2 { x, y }, Vector2 { x, y }, 2), (Vector3 { x, y, z }, Vector3 { x, y, z }, 3), ((T, T, T), (T, T, T)) ); -crate::impl_matrix_inner!((Vector2 { x, y }, Vector2 { x, y }, 2), (Vector4 { x, y, z, w }, Vector4 { x, y, z, w }, 4), ((T, T, T, T), (T, T, T, T)) ); -crate::impl_matrix_inner!((Vector3 { x, y, z }, Vector3 { x, y, z }, 3), (Vector2 { x, y }, Vector2 { x, y }, 2), ((T, T), (T, T), (T, T)) ); -crate::impl_matrix_inner!((Vector3 { x, y, z }, Vector3 { x, y, z }, 3), (Vector3 { x, y, z }, Vector3 { x, y, z }, 3), ((T, T, T), (T, T, T), (T, T, T)) ); -crate::impl_matrix_inner!((Vector3 { x, y, z }, Vector3 { x, y, z }, 3), (Vector4 { x, y, z, w }, Vector4 { x, y, z, w }, 4), ((T, T, T, T), (T, T, T, T), (T, T, T, T)) ); -crate::impl_matrix_inner!((Vector4 { x, y, z, w }, Vector4 { x, y, z, w }, 4), (Vector2 { x, y }, Vector2 { x, y }, 2), ((T, T), (T, T), (T, T), (T, T)) ); -crate::impl_matrix_inner!((Vector4 { x, y, z, w }, Vector4 { x, y, z, w }, 4), (Vector3 { x, y, z }, Vector3 { x, y, z }, 3), ((T, T, T), (T, T, T), (T, T, T), (T, T, T)) ); -crate::impl_matrix_inner!((Vector4 { x, y, z, w }, Vector4 { x, y, z, w }, 4), (Vector4 { x, y, z, w }, Vector4 { x, y, z, w }, 4), ((T, T, T, T), (T, T, T, T), (T, T, T, T), (T, T, T, T)) ); +crate::impl_matrix_inner!((Vector2 { x, y }, Vector2 { x, y }, 2), (Vector2 { x, y }, Vector2 { x, y }, 2) ); +crate::impl_matrix_inner!((Vector2 { x, y }, Vector2 { x, y }, 2), (Vector3 { x, y, z }, Vector3 { x, y, z }, 3) ); +crate::impl_matrix_inner!((Vector2 { x, y }, Vector2 { x, y }, 2), (Vector4 { x, y, z, w }, Vector4 { x, y, z, w }, 4) ); +crate::impl_matrix_inner!((Vector3 { x, y, z }, Vector3 { x, y, z }, 3), (Vector2 { x, y }, Vector2 { x, y }, 2) ); +crate::impl_matrix_inner!((Vector3 { x, y, z }, Vector3 { x, y, z }, 3), (Vector3 { x, y, z }, Vector3 { x, y, z }, 3) ); +crate::impl_matrix_inner!((Vector3 { x, y, z }, Vector3 { x, y, z }, 3), (Vector4 { x, y, z, w }, Vector4 { x, y, z, w }, 4) ); +crate::impl_matrix_inner!((Vector4 { x, y, z, w }, Vector4 { x, y, z, w }, 4), (Vector2 { x, y }, Vector2 { x, y }, 2) ); +crate::impl_matrix_inner!((Vector4 { x, y, z, w }, Vector4 { x, y, z, w }, 4), (Vector3 { x, y, z }, Vector3 { x, y, z }, 3) ); +crate::impl_matrix_inner!((Vector4 { x, y, z, w }, Vector4 { x, y, z, w }, 4), (Vector4 { x, y, z, w }, Vector4 { x, y, z, w }, 4) ); From f0527714db96744fcfb9e7a8bbe52197780cce13 Mon Sep 17 00:00:00 2001 From: Quaternions Date: Tue, 3 Sep 2024 09:40:08 -0700 Subject: [PATCH 117/227] move macro to mod --- fixed_wide_vectors/src/macros/fixed_wide.rs | 17 ++--------------- fixed_wide_vectors/src/macros/mod.rs | 14 ++++++++++++++ 2 files changed, 16 insertions(+), 15 deletions(-) diff --git a/fixed_wide_vectors/src/macros/fixed_wide.rs b/fixed_wide_vectors/src/macros/fixed_wide.rs index ff4e075..3cb65ce 100644 --- a/fixed_wide_vectors/src/macros/fixed_wide.rs +++ b/fixed_wide_vectors/src/macros/fixed_wide.rs @@ -36,19 +36,6 @@ macro_rules! impl_wide_vector_operations_1arg_not_const_generic { } }; } -#[doc(hidden)] -#[macro_export(local_inner_macros)] -macro_rules! do_macro_repeated{ - ( - $macro:ident, - $any:tt, - $($repeated:tt),* - )=>{ - $( - $crate::$macro!($repeated, $any); - )* - }; -} #[doc(hidden)] #[macro_export(local_inner_macros)] @@ -57,7 +44,7 @@ macro_rules! do_macro_8x8{ $macro:ident, $any:tt )=>{ - $crate::do_macro_repeated!($macro, $any, + $crate::macro_repeated!($macro, $any, (1,1),(2,1),(3,1),(4,1),(5,1),(6,1),(7,1),(8,1), (1,2),(2,2),(3,2),(4,2),(5,2),(6,2),(7,2),(8,2), (1,3),(2,3),(3,3),(4,3),(5,3),(6,3),(7,3),(8,3), @@ -77,7 +64,7 @@ macro_rules! do_macro_8{ $macro:ident, $any:tt )=>{ - $crate::do_macro_repeated!($macro, $any, 1,2,3,4,5,6,7,8); + $crate::macro_repeated!($macro, $any, 1,2,3,4,5,6,7,8); }; } diff --git a/fixed_wide_vectors/src/macros/mod.rs b/fixed_wide_vectors/src/macros/mod.rs index 30d20cc..adf672a 100644 --- a/fixed_wide_vectors/src/macros/mod.rs +++ b/fixed_wide_vectors/src/macros/mod.rs @@ -4,3 +4,17 @@ pub mod fixed_wide; pub mod common; pub mod vector; pub mod matrix; + +#[doc(hidden)] +#[macro_export(local_inner_macros)] +macro_rules! macro_repeated{ + ( + $macro:ident, + $any:tt, + $($repeated:tt),* + )=>{ + $( + $crate::$macro!($repeated, $any); + )* + }; +} From 4017f33447ada1855623bd804fb3ad494b1288cb Mon Sep 17 00:00:00 2001 From: Quaternions Date: Tue, 3 Sep 2024 09:40:15 -0700 Subject: [PATCH 118/227] delete comment --- fixed_wide_vectors/src/macros/matrix.rs | 16 ---------------- 1 file changed, 16 deletions(-) diff --git a/fixed_wide_vectors/src/macros/matrix.rs b/fixed_wide_vectors/src/macros/matrix.rs index fbced95..4acf760 100644 --- a/fixed_wide_vectors/src/macros/matrix.rs +++ b/fixed_wide_vectors/src/macros/matrix.rs @@ -119,22 +119,6 @@ macro_rules! matrix_transpose_inner { } } -/* -macro_rules! nested { - (($($f:ident),*) $args:tt) => { - $(nested!(@call $f $args);)* - }; - (@call $f:ident ($($arg:expr),*)) => { - $f($($arg),*); - }; -} - -nested! { - (show1, show2) - (a, b, c) -} -*/ - #[doc(hidden)] #[macro_export(local_inner_macros)] macro_rules! impl_matrix_operator { From 16048882543fc8f00ed56b519b4729a6f5f55f48 Mon Sep 17 00:00:00 2001 From: Quaternions Date: Tue, 3 Sep 2024 09:23:28 -0700 Subject: [PATCH 119/227] macro macro --- fixed_wide_vectors/src/macros/matrix.rs | 20 ++++++++++++++++++ fixed_wide_vectors/src/matrix.rs | 28 +++++++++++++------------ 2 files changed, 35 insertions(+), 13 deletions(-) diff --git a/fixed_wide_vectors/src/macros/matrix.rs b/fixed_wide_vectors/src/macros/matrix.rs index 4acf760..8e009cb 100644 --- a/fixed_wide_vectors/src/macros/matrix.rs +++ b/fixed_wide_vectors/src/macros/matrix.rs @@ -20,6 +20,26 @@ macro_rules! impl_matrix { } #[doc(hidden)] #[macro_export(local_inner_macros)] +macro_rules! impl_matrix_shim { + ( + $matrix_info:tt, + () + ) => { + $crate::impl_matrix!($matrix_info); + } +} +#[doc(hidden)] +#[macro_export(local_inner_macros)] +macro_rules! impl_matrices { + ( + ($($matrix_info:tt),+), + $vector_infos:tt + ) => { + $crate::macro_repeated!(impl_matrix_shim,(),$($matrix_info),+); + } +} +#[doc(hidden)] +#[macro_export(local_inner_macros)] macro_rules! impl_matrix_inner { ( ($struct_outer: ident { $($field_outer: ident), + }, $vector_outer: ident { $($vector_field_outer: ident), + }, $size_outer: expr), diff --git a/fixed_wide_vectors/src/matrix.rs b/fixed_wide_vectors/src/matrix.rs index 840c16e..9acd5a1 100644 --- a/fixed_wide_vectors/src/matrix.rs +++ b/fixed_wide_vectors/src/matrix.rs @@ -16,19 +16,21 @@ pub struct Matrix4 { pub w_axis: T, } -crate::impl_matrix!((Matrix2 { x_axis, y_axis }, Vector2 { x, y }, 2)); -crate::impl_matrix!((Matrix3 { x_axis, y_axis, z_axis }, Vector3 { x, y, z }, 3)); -crate::impl_matrix!((Matrix4 { x_axis, y_axis, z_axis, w_axis }, Vector4 { x, y, z, w }, 4)); - crate::impl_extend!(Matrix2 { x_axis, y_axis }, Matrix3, z_axis); crate::impl_extend!(Matrix3 { x_axis, y_axis, z_axis }, Matrix4, w_axis); +//TODO: extend vertically -crate::impl_matrix_inner!((Matrix2 { x_axis, y_axis }, Vector2 { x, y }, 2), (Vector2 { x, y }, Matrix2 { x_axis, y_axis }, 2) ); -crate::impl_matrix_inner!((Matrix2 { x_axis, y_axis }, Vector2 { x, y }, 2), (Vector3 { x, y, z }, Matrix3 { x_axis, y_axis, z_axis }, 3) ); -crate::impl_matrix_inner!((Matrix2 { x_axis, y_axis }, Vector2 { x, y }, 2), (Vector4 { x, y, z, w }, Matrix4 { x_axis, y_axis, z_axis, w_axis }, 4) ); -crate::impl_matrix_inner!((Matrix3 { x_axis, y_axis, z_axis }, Vector3 { x, y, z }, 3), (Vector2 { x, y }, Matrix2 { x_axis, y_axis }, 2) ); -crate::impl_matrix_inner!((Matrix3 { x_axis, y_axis, z_axis }, Vector3 { x, y, z }, 3), (Vector3 { x, y, z }, Matrix3 { x_axis, y_axis, z_axis }, 3) ); -crate::impl_matrix_inner!((Matrix3 { x_axis, y_axis, z_axis }, Vector3 { x, y, z }, 3), (Vector4 { x, y, z, w }, Matrix4 { x_axis, y_axis, z_axis, w_axis }, 4) ); -crate::impl_matrix_inner!((Matrix4 { x_axis, y_axis, z_axis, w_axis }, Vector4 { x, y, z, w }, 4), (Vector2 { x, y }, Matrix2 { x_axis, y_axis }, 2) ); -crate::impl_matrix_inner!((Matrix4 { x_axis, y_axis, z_axis, w_axis }, Vector4 { x, y, z, w }, 4), (Vector3 { x, y, z }, Matrix3 { x_axis, y_axis, z_axis }, 3) ); -crate::impl_matrix_inner!((Matrix4 { x_axis, y_axis, z_axis, w_axis }, Vector4 { x, y, z, w }, 4), (Vector4 { x, y, z, w }, Matrix4 { x_axis, y_axis, z_axis, w_axis }, 4) ); +crate::impl_matrices!( + //outer struct and equivalent vector + ( + (Matrix2 { x_axis, y_axis }, Vector2 { x, y }, 2), + (Matrix3 { x_axis, y_axis, z_axis }, Vector3 { x, y, z }, 3), + (Matrix4 { x_axis, y_axis, z_axis, w_axis }, Vector4 { x, y, z, w }, 4) + ), + //inner struct and equivalent matrix + ( + (Vector2 { x, y }, Matrix2 { x_axis, y_axis }, 2), + (Vector3 { x, y, z }, Matrix3 { x_axis, y_axis, z_axis }, 3), + (Vector4 { x, y, z, w }, Matrix4 { x_axis, y_axis, z_axis, w_axis }, 4) + ) +); From 48a8271b994d1d6a9999bba3e1dbfef197d42678 Mon Sep 17 00:00:00 2001 From: Quaternions Date: Tue, 3 Sep 2024 10:10:30 -0700 Subject: [PATCH 120/227] transpose macro_repeated --- fixed_wide_vectors/src/macros/fixed_wide.rs | 10 ++++++++-- fixed_wide_vectors/src/macros/matrix.rs | 4 ++-- fixed_wide_vectors/src/macros/mod.rs | 2 +- 3 files changed, 11 insertions(+), 5 deletions(-) diff --git a/fixed_wide_vectors/src/macros/fixed_wide.rs b/fixed_wide_vectors/src/macros/fixed_wide.rs index 3cb65ce..f0f5ca7 100644 --- a/fixed_wide_vectors/src/macros/fixed_wide.rs +++ b/fixed_wide_vectors/src/macros/fixed_wide.rs @@ -1,7 +1,10 @@ #[doc(hidden)] #[macro_export(local_inner_macros)] macro_rules! impl_wide_vector_operations_2arg_not_const_generic { - ( ($lhs:expr, $rhs:expr), ($struct: ident { $($field: ident), + }, $size: expr) ) => { + ( + ($struct: ident { $($field: ident), + }, $size: expr), + ($lhs:expr, $rhs:expr) + ) => { impl $struct>{ paste::item!{ #[inline] @@ -23,7 +26,10 @@ macro_rules! impl_wide_vector_operations_2arg_not_const_generic { #[doc(hidden)] #[macro_export(local_inner_macros)] macro_rules! impl_wide_vector_operations_1arg_not_const_generic { - ( $n:expr, ($struct: ident { $($field: ident), + }, $size: expr) ) => { + ( + ($struct: ident { $($field: ident), + }, $size: expr), + $n:expr + ) => { impl $struct>{ paste::item!{ #[inline] diff --git a/fixed_wide_vectors/src/macros/matrix.rs b/fixed_wide_vectors/src/macros/matrix.rs index 8e009cb..1e27a07 100644 --- a/fixed_wide_vectors/src/macros/matrix.rs +++ b/fixed_wide_vectors/src/macros/matrix.rs @@ -22,8 +22,8 @@ macro_rules! impl_matrix { #[macro_export(local_inner_macros)] macro_rules! impl_matrix_shim { ( - $matrix_info:tt, - () + (), + $matrix_info:tt ) => { $crate::impl_matrix!($matrix_info); } diff --git a/fixed_wide_vectors/src/macros/mod.rs b/fixed_wide_vectors/src/macros/mod.rs index adf672a..572d35c 100644 --- a/fixed_wide_vectors/src/macros/mod.rs +++ b/fixed_wide_vectors/src/macros/mod.rs @@ -14,7 +14,7 @@ macro_rules! macro_repeated{ $($repeated:tt),* )=>{ $( - $crate::$macro!($repeated, $any); + $crate::$macro!($any, $repeated); )* }; } From b0ecfeb29429edbf74621997c4490a2d8e857116 Mon Sep 17 00:00:00 2001 From: Quaternions Date: Tue, 3 Sep 2024 10:10:46 -0700 Subject: [PATCH 121/227] the matrix super macro --- fixed_wide_vectors/src/macros/matrix.rs | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/fixed_wide_vectors/src/macros/matrix.rs b/fixed_wide_vectors/src/macros/matrix.rs index 1e27a07..d442488 100644 --- a/fixed_wide_vectors/src/macros/matrix.rs +++ b/fixed_wide_vectors/src/macros/matrix.rs @@ -36,6 +36,17 @@ macro_rules! impl_matrices { $vector_infos:tt ) => { $crate::macro_repeated!(impl_matrix_shim,(),$($matrix_info),+); + $crate::macro_repeated!(impl_matrix_inner_shim,$vector_infos,$($matrix_info),+); + } +} +#[doc(hidden)] +#[macro_export(local_inner_macros)] +macro_rules! impl_matrix_inner_shim { + ( + ($($vector_info:tt),+), + $matrix_info:tt + ) => { + $crate::macro_repeated!(impl_matrix_inner,$matrix_info,$($vector_info),+); } } #[doc(hidden)] From eefbdafc160fd2f20b12b6b6a13b0f47ad71ea44 Mon Sep 17 00:00:00 2001 From: Quaternions Date: Tue, 3 Sep 2024 10:40:43 -0700 Subject: [PATCH 122/227] move more impls to common --- fixed_wide_vectors/src/macros/common.rs | 53 +++++++++++++++++++++++++ fixed_wide_vectors/src/macros/vector.rs | 53 ------------------------- 2 files changed, 53 insertions(+), 53 deletions(-) diff --git a/fixed_wide_vectors/src/macros/common.rs b/fixed_wide_vectors/src/macros/common.rs index df335fd..bb92dc7 100644 --- a/fixed_wide_vectors/src/macros/common.rs +++ b/fixed_wide_vectors/src/macros/common.rs @@ -81,5 +81,58 @@ macro_rules! impl_common { } } } + + impl From<[T; $size]> for $struct { + fn from(from: [T; $size]) -> Self { + let mut iterator = from.into_iter(); + + Self { + // SAFETY: We know the size of `from` so `iterator.next()` is always `Some(..)` + $( $field: unsafe { iterator.next().unwrap_unchecked() } ), + + } + } + } + + impl core::fmt::Debug for $struct { + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { + let identifier = core::stringify!($struct); + + f.debug_struct(identifier) + $( .field( core::stringify!($field), &self.$field ) ) + + .finish() + } + } + + impl PartialEq for $struct { + fn eq(&self, other: &Self) -> bool { + $( self.$field == other.$field ) && + + } + } + + impl Eq for $struct { } + + impl core::hash::Hash for $struct { + fn hash(&self, state: &mut H) { + $( self.$field.hash(state); ) + + } + } + + impl Clone for $struct { + fn clone(&self) -> Self { + Self { + $( $field: self.$field.clone() ), + + } + } + } + + impl Copy for $struct { } + + impl Default for $struct { + fn default() -> Self { + Self { + $( $field: T::default() ), + + } + } + } } } diff --git a/fixed_wide_vectors/src/macros/vector.rs b/fixed_wide_vectors/src/macros/vector.rs index 09bfcbe..d3a69e7 100644 --- a/fixed_wide_vectors/src/macros/vector.rs +++ b/fixed_wide_vectors/src/macros/vector.rs @@ -5,59 +5,6 @@ macro_rules! impl_vector { ( $struct: ident { $($field: ident), + }, $size: expr ) => { $crate::impl_common!($struct { $($field), + }, $size); - impl From<[T; $size]> for $struct { - fn from(from: [T; $size]) -> Self { - let mut iterator = from.into_iter(); - - Self { - // SAFETY: We know the size of `from` so `iterator.next()` is always `Some(..)` - $( $field: unsafe { iterator.next().unwrap_unchecked() } ), + - } - } - } - - impl core::fmt::Debug for $struct { - fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { - let identifier = core::stringify!($struct); - - f.debug_struct(identifier) - $( .field( core::stringify!($field), &self.$field ) ) + - .finish() - } - } - - impl PartialEq for $struct { - fn eq(&self, other: &Self) -> bool { - $( self.$field == other.$field ) && + - } - } - - impl Eq for $struct { } - - impl core::hash::Hash for $struct { - fn hash(&self, state: &mut H) { - $( self.$field.hash(state); ) + - } - } - - impl Clone for $struct { - fn clone(&self) -> Self { - Self { - $( $field: self.$field.clone() ), + - } - } - } - - impl Copy for $struct { } - - impl Default for $struct { - fn default() -> Self { - Self { - $( $field: T::default() ), + - } - } - } - impl $struct { pub fn min(self, rhs: Self) -> $struct { $struct{ From 0f9d0c8c394761a3697628f3fd483406426e284e Mon Sep 17 00:00:00 2001 From: Quaternions Date: Mon, 2 Sep 2024 19:05:52 -0700 Subject: [PATCH 123/227] matrix wide dot --- fixed_wide_vectors/src/macros/fixed_wide.rs | 103 ++++++++++++++++++++ fixed_wide_vectors/src/macros/matrix.rs | 2 + 2 files changed, 105 insertions(+) diff --git a/fixed_wide_vectors/src/macros/fixed_wide.rs b/fixed_wide_vectors/src/macros/fixed_wide.rs index f0f5ca7..6d882f9 100644 --- a/fixed_wide_vectors/src/macros/fixed_wide.rs +++ b/fixed_wide_vectors/src/macros/fixed_wide.rs @@ -84,6 +84,109 @@ macro_rules! impl_wide_vector_operations { } +// Notes: +// Mat3.dot(Vec2) -> Vec3 +// Mat3.dot(Mat4) -> Mat3 +// mat.mat can be implemented off the back of mat.vec + +#[doc(hidden)] +#[macro_export(local_inner_macros)] +macro_rules! impl_matrix_wide_mul { + ( + //TODO: Fixed point impls + ($struct_outer: ident { $($field_outer: ident), + }, $vector_outer: ident { $($vector_field_outer: ident), + }, $size_outer: expr), + ($struct_inner: ident { $($field_inner: ident), + }, $matrix_inner: ident { $($matrix_field_inner: ident), + }, $size_inner: expr), + ($rhs_struct_inner: ident { $($rhs_field_inner: ident), + }, $rhs_matrix_inner: ident { $($rhs_matrix_field_inner: ident), + }, $rhs_size_inner: expr), + ($lhs: expr, $rhs: expr) + ) => { + impl $struct_outer<$struct_inner>>{ + paste::item!{ + #[inline] + pub fn [](self,rhs:$matrix_inner<$rhs_struct_inner>>)->$struct_outer<$rhs_struct_inner>>{ + //just made this up, don't trust it + let tr=rhs.transpose(); + //TODO: use a macro expansion instead of transpose and map + self.map(|axis| + tr.map(|trax| + axis.[](trax) + ).to_vector() + ) + } + } + } + } +} + +#[doc(hidden)] +#[macro_export(local_inner_macros)] +macro_rules! impl_matrix_wide_mul_shim3 { + ( + ($outer_info:tt,$inner_info:tt,$rhs_info:tt), + ($lhs: expr, $rhs: expr) + ) => { + $crate::impl_matrix_wide_mul!($outer_info,$inner_info,$rhs_info,($lhs,$rhs)); + } +} +#[doc(hidden)] +#[macro_export(local_inner_macros)] +macro_rules! impl_matrix_wide_mul_shim2 { + ( + ($outer_info:tt,$inner_info:tt), + $rhs_info:tt + ) => { + $crate::do_macro_8x8!(impl_matrix_wide_mul_shim3,($outer_info,$inner_info,$rhs_info)); + } +} +#[doc(hidden)] +#[macro_export(local_inner_macros)] +macro_rules! impl_matrix_wide_mul_shim1 { + ( + ($outer_info:tt,($($rhs_info:tt),+)), + $inner_info:tt + ) => { + $crate::macro_repeated!(impl_matrix_wide_mul_shim2,($outer_info,$inner_info),$($rhs_info),+); + } +} +#[doc(hidden)] +#[macro_export(local_inner_macros)] +macro_rules! impl_wide_matrix_operations_2arg_not_const_generic { + ( + $lhs: expr, $rhs: expr, + ($struct_outer: ident { $($field_outer: ident), + }, $vector_outer: ident { $($vector_field_outer: ident), + }, $size_outer: expr), + ($struct_inner: ident { $($field_inner: ident), + }, $matrix_inner: ident { $($matrix_field_inner: ident), + }, $size_inner: expr) + ) => { + /* TODO: nasty determinant macro + impl,T:Copy+fixed_wide_traits::wide::WideMul> $struct { + #[inline] + pub fn wide_dot(&self) -> U { + $crate::sum_repeating!( + $( + self.$field.wide_mul(self.$field) ) + + ) + } + } + */ + }; +} +#[doc(hidden)] +#[macro_export(local_inner_macros)] +macro_rules! impl_wide_matrix_operations_1arg_not_const_generic { + ( + $n: expr, + ($struct_outer: ident { $($field_outer: ident), + }, $vector_outer: ident { $($vector_field_outer: ident), + }, $size_outer: expr), + ) => { + /* TODO: nasty determinant macro + impl,T:Copy+fixed_wide_traits::wide::WideMul> $struct { + #[inline] + pub fn wide_det(&self) -> U { + $crate::sum_repeating!( + $( + self.$field.wide_mul(self.$field) ) + + ) + } + } + */ + }; +} + // HACK: Allows us to sum repeating tokens in macros. // See: https://stackoverflow.com/a/60187870/17452730 #[doc(hidden)] diff --git a/fixed_wide_vectors/src/macros/matrix.rs b/fixed_wide_vectors/src/macros/matrix.rs index d442488..98d72aa 100644 --- a/fixed_wide_vectors/src/macros/matrix.rs +++ b/fixed_wide_vectors/src/macros/matrix.rs @@ -47,6 +47,8 @@ macro_rules! impl_matrix_inner_shim { $matrix_info:tt ) => { $crate::macro_repeated!(impl_matrix_inner,$matrix_info,$($vector_info),+); + #[cfg(feature="fixed_wide")] + $crate::macro_repeated!(impl_matrix_wide_mul_shim1,($matrix_info,($($vector_info),+)),$($vector_info),+); } } #[doc(hidden)] From 15bd78c0e1ef56483969df6fbad266183f4f2c49 Mon Sep 17 00:00:00 2001 From: Quaternions Date: Tue, 3 Sep 2024 10:43:07 -0700 Subject: [PATCH 124/227] matrix wide dot test --- fixed_wide_vectors/src/tests/fixed_wide.rs | 30 +++++++++++++++++----- 1 file changed, 24 insertions(+), 6 deletions(-) diff --git a/fixed_wide_vectors/src/tests/fixed_wide.rs b/fixed_wide_vectors/src/tests/fixed_wide.rs index 9eb6bec..e382ffa 100644 --- a/fixed_wide_vectors/src/tests/fixed_wide.rs +++ b/fixed_wide_vectors/src/tests/fixed_wide.rs @@ -1,4 +1,4 @@ -use crate::{Vector2,Vector3,Matrix3}; +use crate::{Vector2,Vector3,Vector4,Matrix3,Matrix4}; type Planar64=fixed_wide::types::I32F32; type Planar64Wide1=fixed_wide::types::I64F64; @@ -37,9 +37,27 @@ fn wide_vec3_length_squared(){ #[test] fn wide_matrix_dot(){ - let m=Matrix3::>::from_value_2d(Planar64::from(3)); - //normal matrix product - todo!() - //let m_dot=m.wide_dot_1_1(m); - //assert_eq!(m_dot,Matrix3::>::from_value_2d(Planar64Wide1::from(3i128.pow(2)))); + let lhs=Matrix3::from([ + Vector4::from([Planar64::from(1),Planar64::from(2),Planar64::from(3),Planar64::from(4)]), + Vector4::from([Planar64::from(5),Planar64::from(6),Planar64::from(7),Planar64::from(8)]), + Vector4::from([Planar64::from(9),Planar64::from(10),Planar64::from(11),Planar64::from(12)]), + ]); + let rhs=Matrix4::from([ + Vector2::from([Planar64::from(1),Planar64::from(2)]), + Vector2::from([Planar64::from(3),Planar64::from(4)]), + Vector2::from([Planar64::from(5),Planar64::from(6)]), + Vector2::from([Planar64::from(7),Planar64::from(8)]), + ]); + // Mat3.dot(Mat4) -> Mat3 + let m_dot=lhs.wide_dot_3x4_4x2_1_1(rhs); + //In[1]:= {{1, 2, 3, 4}, {5, 6, 7, 8}, {9, 10, 11, 12}} . {{1, 2}, {3, 4}, {5, 6}, {7, 8}} + //Out[1]= {{50, 60}, {114, 140}, {178, 220}} + assert_eq!( + m_dot, + Matrix3::from([ + Vector2::from([Planar64Wide1::from(50),Planar64Wide1::from(60)]), + Vector2::from([Planar64Wide1::from(114),Planar64Wide1::from(140)]), + Vector2::from([Planar64Wide1::from(178),Planar64Wide1::from(220)]), + ]) + ); } From 176eb762e32929912c303e8246ffe6af66328a2e Mon Sep 17 00:00:00 2001 From: Quaternions Date: Tue, 3 Sep 2024 12:51:19 -0700 Subject: [PATCH 125/227] name macros better --- fixed_wide_vectors/src/macros/fixed_wide.rs | 10 +++++----- fixed_wide_vectors/src/macros/matrix.rs | 2 +- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/fixed_wide_vectors/src/macros/fixed_wide.rs b/fixed_wide_vectors/src/macros/fixed_wide.rs index 6d882f9..b8fbbae 100644 --- a/fixed_wide_vectors/src/macros/fixed_wide.rs +++ b/fixed_wide_vectors/src/macros/fixed_wide.rs @@ -119,7 +119,7 @@ macro_rules! impl_matrix_wide_mul { #[doc(hidden)] #[macro_export(local_inner_macros)] -macro_rules! impl_matrix_wide_mul_shim3 { +macro_rules! impl_matrix_wide_mul_shim { ( ($outer_info:tt,$inner_info:tt,$rhs_info:tt), ($lhs: expr, $rhs: expr) @@ -129,22 +129,22 @@ macro_rules! impl_matrix_wide_mul_shim3 { } #[doc(hidden)] #[macro_export(local_inner_macros)] -macro_rules! impl_matrix_wide_mul_shim2 { +macro_rules! impl_matrix_wide_mul_8x8 { ( ($outer_info:tt,$inner_info:tt), $rhs_info:tt ) => { - $crate::do_macro_8x8!(impl_matrix_wide_mul_shim3,($outer_info,$inner_info,$rhs_info)); + $crate::do_macro_8x8!(impl_matrix_wide_mul_shim,($outer_info,$inner_info,$rhs_info)); } } #[doc(hidden)] #[macro_export(local_inner_macros)] -macro_rules! impl_matrix_wide_mul_shim1 { +macro_rules! impl_matrix_wide_mul_repeat_rhs { ( ($outer_info:tt,($($rhs_info:tt),+)), $inner_info:tt ) => { - $crate::macro_repeated!(impl_matrix_wide_mul_shim2,($outer_info,$inner_info),$($rhs_info),+); + $crate::macro_repeated!(impl_matrix_wide_mul_8x8,($outer_info,$inner_info),$($rhs_info),+); } } #[doc(hidden)] diff --git a/fixed_wide_vectors/src/macros/matrix.rs b/fixed_wide_vectors/src/macros/matrix.rs index 98d72aa..e457ced 100644 --- a/fixed_wide_vectors/src/macros/matrix.rs +++ b/fixed_wide_vectors/src/macros/matrix.rs @@ -48,7 +48,7 @@ macro_rules! impl_matrix_inner_shim { ) => { $crate::macro_repeated!(impl_matrix_inner,$matrix_info,$($vector_info),+); #[cfg(feature="fixed_wide")] - $crate::macro_repeated!(impl_matrix_wide_mul_shim1,($matrix_info,($($vector_info),+)),$($vector_info),+); + $crate::macro_repeated!(impl_matrix_wide_mul_repeat_rhs,($matrix_info,($($vector_info),+)),$($vector_info),+); } } #[doc(hidden)] From e5f95b97ce0f5a9a5db2710bb33af44e10bf21d9 Mon Sep 17 00:00:00 2001 From: Quaternions Date: Tue, 3 Sep 2024 12:01:15 -0700 Subject: [PATCH 126/227] matrix: macro mat mul --- fixed_wide_vectors/src/macros/fixed_wide.rs | 111 +++++++++++++++++--- fixed_wide_vectors/src/macros/matrix.rs | 2 +- 2 files changed, 96 insertions(+), 17 deletions(-) diff --git a/fixed_wide_vectors/src/macros/fixed_wide.rs b/fixed_wide_vectors/src/macros/fixed_wide.rs index b8fbbae..824dc54 100644 --- a/fixed_wide_vectors/src/macros/fixed_wide.rs +++ b/fixed_wide_vectors/src/macros/fixed_wide.rs @@ -83,17 +83,94 @@ macro_rules! impl_wide_vector_operations { }; } +#[doc(hidden)] +#[macro_export(local_inner_macros)] +macro_rules! impl_matrix_wide_dot_transpose_helper { + ( + $value:ident, + ($struct: ident { $($field: ident), + }), + ($from_struct: ident { $($from_field: ident), + }), + $static_field: ident + ) => { + $struct { + $( + $field: $value.$from_field.$static_field + ), + + } + } +} +#[doc(hidden)] +#[macro_export(local_inner_macros)] +macro_rules! impl_matrix_wide_dot_inner { + ( + // MatY.MatX = MatY + $lhs:ident, $lhs_field_outer:ident, $wide_dot:ident, $rhs:ident, + $struct_inner_thru: tt, //VecX + ($struct_inner: ident { $($field_inner: ident), + }), //VecX + ($rhs_struct_inner: ident { $($rhs_field_inner: ident), + }), //VecZ + $rhs_outer: tt //MatX + ) => { + $rhs_struct_inner { + $( + $rhs_field_inner: $lhs.$lhs_field_outer.$wide_dot( + //construct a transposed vector with the same width as $struct_outer + $crate::impl_matrix_wide_dot_transpose_helper!{ + $rhs, + $struct_inner_thru, //VecZ + $rhs_outer, //MatX + $rhs_field_inner + } + ) + ), + + } + } +} +#[doc(hidden)] +#[macro_export(local_inner_macros)] +macro_rules! impl_matrix_wide_dot_outer { + ( + // MatY.MatX = MatY + $lhs:ident, $wide_dot:ident, $rhs:ident, + //result matrix shape + ($struct_outer: ident { $($field_outer: ident), + }),//MatY + $rhs_struct_inner: tt,//VecZ + //inner loop shape + $struct_inner: tt,//VecX + $rhs_matrix: tt//MatX + + ) => { + $struct_outer { + $( + $field_outer: $crate::impl_matrix_wide_dot_inner!{ + $lhs, $field_outer, $wide_dot, $rhs, + $struct_inner, //VecX + $struct_inner, //VecX + $rhs_struct_inner, //VecZ + $rhs_matrix //MatX + } + ), + + } + } +} // Notes: // Mat3.dot(Vec2) -> Vec3 +// lhs.dot(rhs) -> out +// lhs = Mat3 +// rhs = Mat4 +// out = Mat3 // Mat3.dot(Mat4) -> Mat3 -// mat.mat can be implemented off the back of mat.vec +// how to matrix multiply: +// RHS TRANSPOSE +// Mat4 -> Mat2 +// rhs_t = Mat2 +// inner loop: +// out[y][x] = lhs[y].dot(rhs_t[x]) #[doc(hidden)] #[macro_export(local_inner_macros)] -macro_rules! impl_matrix_wide_mul { +macro_rules! impl_matrix_wide_dot { ( - //TODO: Fixed point impls ($struct_outer: ident { $($field_outer: ident), + }, $vector_outer: ident { $($vector_field_outer: ident), + }, $size_outer: expr), ($struct_inner: ident { $($field_inner: ident), + }, $matrix_inner: ident { $($matrix_field_inner: ident), + }, $size_inner: expr), ($rhs_struct_inner: ident { $($rhs_field_inner: ident), + }, $rhs_matrix_inner: ident { $($rhs_matrix_field_inner: ident), + }, $rhs_size_inner: expr), @@ -103,13 +180,15 @@ macro_rules! impl_matrix_wide_mul { paste::item!{ #[inline] pub fn [](self,rhs:$matrix_inner<$rhs_struct_inner>>)->$struct_outer<$rhs_struct_inner>>{ - //just made this up, don't trust it - let tr=rhs.transpose(); - //TODO: use a macro expansion instead of transpose and map - self.map(|axis| - tr.map(|trax| - axis.[](trax) - ).to_vector() + $crate::impl_matrix_wide_dot_outer!( + //constituent idents + self,[],rhs, + //result matrix shape + ($struct_outer { $($field_outer), + }), + ($rhs_struct_inner { $($rhs_field_inner), + }), + //inner loop shape + ($struct_inner { $($field_inner), + }), + ($matrix_inner { $($matrix_field_inner), + }) ) } } @@ -119,32 +198,32 @@ macro_rules! impl_matrix_wide_mul { #[doc(hidden)] #[macro_export(local_inner_macros)] -macro_rules! impl_matrix_wide_mul_shim { +macro_rules! impl_matrix_wide_dot_shim { ( ($outer_info:tt,$inner_info:tt,$rhs_info:tt), ($lhs: expr, $rhs: expr) ) => { - $crate::impl_matrix_wide_mul!($outer_info,$inner_info,$rhs_info,($lhs,$rhs)); + $crate::impl_matrix_wide_dot!($outer_info,$inner_info,$rhs_info,($lhs,$rhs)); } } #[doc(hidden)] #[macro_export(local_inner_macros)] -macro_rules! impl_matrix_wide_mul_8x8 { +macro_rules! impl_matrix_wide_dot_8x8 { ( ($outer_info:tt,$inner_info:tt), $rhs_info:tt ) => { - $crate::do_macro_8x8!(impl_matrix_wide_mul_shim,($outer_info,$inner_info,$rhs_info)); + $crate::do_macro_8x8!(impl_matrix_wide_dot_shim,($outer_info,$inner_info,$rhs_info)); } } #[doc(hidden)] #[macro_export(local_inner_macros)] -macro_rules! impl_matrix_wide_mul_repeat_rhs { +macro_rules! impl_matrix_wide_dot_repeat_rhs { ( ($outer_info:tt,($($rhs_info:tt),+)), $inner_info:tt ) => { - $crate::macro_repeated!(impl_matrix_wide_mul_8x8,($outer_info,$inner_info),$($rhs_info),+); + $crate::macro_repeated!(impl_matrix_wide_dot_8x8,($outer_info,$inner_info),$($rhs_info),+); } } #[doc(hidden)] diff --git a/fixed_wide_vectors/src/macros/matrix.rs b/fixed_wide_vectors/src/macros/matrix.rs index e457ced..eeed579 100644 --- a/fixed_wide_vectors/src/macros/matrix.rs +++ b/fixed_wide_vectors/src/macros/matrix.rs @@ -48,7 +48,7 @@ macro_rules! impl_matrix_inner_shim { ) => { $crate::macro_repeated!(impl_matrix_inner,$matrix_info,$($vector_info),+); #[cfg(feature="fixed_wide")] - $crate::macro_repeated!(impl_matrix_wide_mul_repeat_rhs,($matrix_info,($($vector_info),+)),$($vector_info),+); + $crate::macro_repeated!(impl_matrix_wide_dot_repeat_rhs,($matrix_info,($($vector_info),+)),$($vector_info),+); } } #[doc(hidden)] From 823a05c101995b481cbc94d6ceb8889512c040fe Mon Sep 17 00:00:00 2001 From: Quaternions Date: Wed, 4 Sep 2024 12:03:12 -0700 Subject: [PATCH 127/227] matrix: directly implement dot product to avoid a copy --- fixed_wide_vectors/src/macros/fixed_wide.rs | 35 ++++++++++----------- 1 file changed, 16 insertions(+), 19 deletions(-) diff --git a/fixed_wide_vectors/src/macros/fixed_wide.rs b/fixed_wide_vectors/src/macros/fixed_wide.rs index 824dc54..98398c3 100644 --- a/fixed_wide_vectors/src/macros/fixed_wide.rs +++ b/fixed_wide_vectors/src/macros/fixed_wide.rs @@ -87,16 +87,14 @@ macro_rules! impl_wide_vector_operations { #[macro_export(local_inner_macros)] macro_rules! impl_matrix_wide_dot_transpose_helper { ( - $value:ident, + $lhs_axis:expr, $wide_mul:ident, $rhs:ident, ($struct: ident { $($field: ident), + }), ($from_struct: ident { $($from_field: ident), + }), $static_field: ident ) => { - $struct { - $( - $field: $value.$from_field.$static_field - ), + - } + $crate::sum_repeating!( + $( + $lhs_axis.$field.$wide_mul($rhs.$from_field.$static_field) ) + + ) } } #[doc(hidden)] @@ -104,7 +102,7 @@ macro_rules! impl_matrix_wide_dot_transpose_helper { macro_rules! impl_matrix_wide_dot_inner { ( // MatY.MatX = MatY - $lhs:ident, $lhs_field_outer:ident, $wide_dot:ident, $rhs:ident, + $lhs:ident, $lhs_field_outer:ident, $wide_mul:ident, $rhs:ident, $struct_inner_thru: tt, //VecX ($struct_inner: ident { $($field_inner: ident), + }), //VecX ($rhs_struct_inner: ident { $($rhs_field_inner: ident), + }), //VecZ @@ -112,15 +110,14 @@ macro_rules! impl_matrix_wide_dot_inner { ) => { $rhs_struct_inner { $( - $rhs_field_inner: $lhs.$lhs_field_outer.$wide_dot( - //construct a transposed vector with the same width as $struct_outer - $crate::impl_matrix_wide_dot_transpose_helper!{ - $rhs, - $struct_inner_thru, //VecZ - $rhs_outer, //MatX - $rhs_field_inner - } - ) + //directly dot product to avoid a copy + $rhs_field_inner: $crate::impl_matrix_wide_dot_transpose_helper!{ + //lhs.axis.wide_mul(rhs_t.axis) + $lhs.$lhs_field_outer,$wide_mul,$rhs, + $struct_inner_thru, //VecZ + $rhs_outer, //MatX + $rhs_field_inner + } ), + } } @@ -130,7 +127,7 @@ macro_rules! impl_matrix_wide_dot_inner { macro_rules! impl_matrix_wide_dot_outer { ( // MatY.MatX = MatY - $lhs:ident, $wide_dot:ident, $rhs:ident, + $lhs:ident, $wide_mul:ident, $rhs:ident, //result matrix shape ($struct_outer: ident { $($field_outer: ident), + }),//MatY $rhs_struct_inner: tt,//VecZ @@ -142,7 +139,7 @@ macro_rules! impl_matrix_wide_dot_outer { $struct_outer { $( $field_outer: $crate::impl_matrix_wide_dot_inner!{ - $lhs, $field_outer, $wide_dot, $rhs, + $lhs, $field_outer, $wide_mul, $rhs, $struct_inner, //VecX $struct_inner, //VecX $rhs_struct_inner, //VecZ @@ -182,7 +179,7 @@ macro_rules! impl_matrix_wide_dot { pub fn [](self,rhs:$matrix_inner<$rhs_struct_inner>>)->$struct_outer<$rhs_struct_inner>>{ $crate::impl_matrix_wide_dot_outer!( //constituent idents - self,[],rhs, + self,[],rhs, //result matrix shape ($struct_outer { $($field_outer), + }), ($rhs_struct_inner { $($rhs_field_inner), + }), From cf17460b77df6ba9e73a7ade63c636a2a9fc1707 Mon Sep 17 00:00:00 2001 From: Quaternions Date: Wed, 4 Sep 2024 13:38:29 -0700 Subject: [PATCH 128/227] special case 3d vectors and matrices --- fixed_wide_vectors/src/macros/fixed_wide.rs | 96 +++++++++++++++++++++ fixed_wide_vectors/src/macros/matrix.rs | 9 ++ fixed_wide_vectors/src/macros/vector.rs | 9 ++ fixed_wide_vectors/src/matrix.rs | 3 + fixed_wide_vectors/src/vector.rs | 3 + 5 files changed, 120 insertions(+) diff --git a/fixed_wide_vectors/src/macros/fixed_wide.rs b/fixed_wide_vectors/src/macros/fixed_wide.rs index 98398c3..3812d86 100644 --- a/fixed_wide_vectors/src/macros/fixed_wide.rs +++ b/fixed_wide_vectors/src/macros/fixed_wide.rs @@ -83,6 +83,36 @@ macro_rules! impl_wide_vector_operations { }; } +#[doc(hidden)] +#[macro_export(local_inner_macros)] +macro_rules! impl_vector_3_wide_cross { + ( + (), + ($lhs:expr, $rhs:expr) + )=>{ + impl Vector3>{ + paste::item!{ + #[inline] + pub fn [](self,rhs:Vector3>)->Vector3>{ + Vector3{ + x:self.y.[](rhs.z)-self.z.[](rhs.y), + y:self.z.[](rhs.x)-self.x.[](rhs.z), + z:self.x.[](rhs.y)-self.y.[](rhs.x) + } + } + } + } + } +} + +#[doc(hidden)] +#[macro_export(local_inner_macros)] +macro_rules! impl_vector_wide_3 { + ()=>{ + $crate::do_macro_8x8!(impl_vector_3_wide_cross,()); + } +} + #[doc(hidden)] #[macro_export(local_inner_macros)] macro_rules! impl_matrix_wide_dot_transpose_helper { @@ -263,6 +293,72 @@ macro_rules! impl_wide_matrix_operations_1arg_not_const_generic { }; } +#[doc(hidden)] +#[macro_export(local_inner_macros)] +macro_rules! do_macro_4_dumb{ + ( + $macro:ident, + $any:tt + )=>{ + $crate::macro_repeated!($macro, $any, (1,2),(2,4),(3,6),(4,8)); + }; +} + +#[doc(hidden)] +#[macro_export(local_inner_macros)] +macro_rules! impl_matrix_wide_3x3_det_not_const_generic { + ( + $n: expr, + $_2n: expr + )=>{ + impl Matrix3>>{ + paste::item!{ + pub fn [](self)->fixed_wide::fixed::Fixed<{$n*3},{$n*3*32}>{ + //[] will not compile, so the doubles are hardcoded above + self.x_axis.[](self.y_axis.[](self.z_axis)) + } + } + } + } +} +#[doc(hidden)] +#[macro_export(local_inner_macros)] +macro_rules! impl_matrix_wide_3x3_det_not_const_generic_shim { + ( + (),($n: expr,$_2n: expr) + )=>{ + $crate::impl_matrix_wide_3x3_det_not_const_generic!($n,$_2n); + } +} +#[doc(hidden)] +#[macro_export(local_inner_macros)] +macro_rules! impl_matrix_wide_3x3_adjugate_not_const_generic { + ( + (), + $n: expr + )=>{ + impl Matrix3>>{ + paste::item!{ + pub fn [](self)->Matrix3>>{ + Matrix3{ + x_axis:Vector3{x:self.y_axis.y.[](self.z_axis.z)-self.y_axis.z.[](self.z_axis.y),y:self.x_axis.z.[](self.z_axis.y)-self.x_axis.y.[](self.z_axis.z),z:self.x_axis.y.[](self.y_axis.z)-self.x_axis.z.[](self.y_axis.y)}, + y_axis:Vector3{x:self.y_axis.z.[](self.z_axis.x)-self.y_axis.x.[](self.z_axis.z),y:self.x_axis.x.[](self.z_axis.z)-self.x_axis.z.[](self.z_axis.x),z:self.x_axis.z.[](self.y_axis.x)-self.x_axis.x.[](self.y_axis.z)}, + z_axis:Vector3{x:self.y_axis.x.[](self.z_axis.y)-self.y_axis.y.[](self.z_axis.x),y:self.x_axis.y.[](self.z_axis.x)-self.x_axis.x.[](self.z_axis.y),z:self.x_axis.x.[](self.y_axis.y)-self.x_axis.y.[](self.y_axis.x)}, + } + } + } + } + } +} +#[doc(hidden)] +#[macro_export(local_inner_macros)] +macro_rules! impl_matrix_wide_3x3 { + ()=>{ + $crate::do_macro_4_dumb!(impl_matrix_wide_3x3_det_not_const_generic_shim,()); + $crate::do_macro_8!(impl_matrix_wide_3x3_adjugate_not_const_generic,()); + } +} + // HACK: Allows us to sum repeating tokens in macros. // See: https://stackoverflow.com/a/60187870/17452730 #[doc(hidden)] diff --git a/fixed_wide_vectors/src/macros/matrix.rs b/fixed_wide_vectors/src/macros/matrix.rs index eeed579..37b3b99 100644 --- a/fixed_wide_vectors/src/macros/matrix.rs +++ b/fixed_wide_vectors/src/macros/matrix.rs @@ -152,6 +152,15 @@ macro_rules! matrix_transpose_inner { } } +#[doc(hidden)] +#[macro_export(local_inner_macros)] +macro_rules! impl_matrix_3x3 { + ()=>{ + #[cfg(feature="fixed_wide")] + $crate::impl_matrix_wide_3x3!(); + } +} + #[doc(hidden)] #[macro_export(local_inner_macros)] macro_rules! impl_matrix_operator { diff --git a/fixed_wide_vectors/src/macros/vector.rs b/fixed_wide_vectors/src/macros/vector.rs index d3a69e7..ad7a72e 100644 --- a/fixed_wide_vectors/src/macros/vector.rs +++ b/fixed_wide_vectors/src/macros/vector.rs @@ -144,3 +144,12 @@ macro_rules! impl_vector_operator { } }; } + +#[doc(hidden)] +#[macro_export(local_inner_macros)] +macro_rules! impl_vector_3 { + ()=>{ + #[cfg(feature="fixed_wide")] + $crate::impl_vector_wide_3!(); + } +} diff --git a/fixed_wide_vectors/src/matrix.rs b/fixed_wide_vectors/src/matrix.rs index 9acd5a1..4966f28 100644 --- a/fixed_wide_vectors/src/matrix.rs +++ b/fixed_wide_vectors/src/matrix.rs @@ -34,3 +34,6 @@ crate::impl_matrices!( (Vector4 { x, y, z, w }, Matrix4 { x_axis, y_axis, z_axis, w_axis }, 4) ) ); + +//Special case 3x3 matrix operations because I cba to write macros for the arbitrary cases +crate::impl_matrix_3x3!(); diff --git a/fixed_wide_vectors/src/vector.rs b/fixed_wide_vectors/src/vector.rs index f7ff0a6..5016c97 100644 --- a/fixed_wide_vectors/src/vector.rs +++ b/fixed_wide_vectors/src/vector.rs @@ -79,3 +79,6 @@ crate::impl_matrix_inner!((Vector3 { x, y, z }, Vector3 { x, y, z }, 3), (Vector crate::impl_matrix_inner!((Vector4 { x, y, z, w }, Vector4 { x, y, z, w }, 4), (Vector2 { x, y }, Vector2 { x, y }, 2) ); crate::impl_matrix_inner!((Vector4 { x, y, z, w }, Vector4 { x, y, z, w }, 4), (Vector3 { x, y, z }, Vector3 { x, y, z }, 3) ); crate::impl_matrix_inner!((Vector4 { x, y, z, w }, Vector4 { x, y, z, w }, 4), (Vector4 { x, y, z, w }, Vector4 { x, y, z, w }, 4) ); + +//cross product +crate::impl_vector_3!(); From 103697fbdd1fb360e667f92ed2c9d50b63aec350 Mon Sep 17 00:00:00 2001 From: Quaternions Date: Wed, 4 Sep 2024 13:55:11 -0700 Subject: [PATCH 129/227] matrix: test det + adjugate --- fixed_wide_vectors/src/tests/fixed_wide.rs | 31 ++++++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/fixed_wide_vectors/src/tests/fixed_wide.rs b/fixed_wide_vectors/src/tests/fixed_wide.rs index e382ffa..1f87fb0 100644 --- a/fixed_wide_vectors/src/tests/fixed_wide.rs +++ b/fixed_wide_vectors/src/tests/fixed_wide.rs @@ -61,3 +61,34 @@ fn wide_matrix_dot(){ ]) ); } + +#[test] +fn wide_matrix_det(){ + let m=Matrix3::from([ + Vector3::from([Planar64::from(1),Planar64::from(2),Planar64::from(3)]), + Vector3::from([Planar64::from(4),Planar64::from(5),Planar64::from(7)]), + Vector3::from([Planar64::from(6),Planar64::from(8),Planar64::from(9)]), + ]); + // In[2]:= Det[{{1, 2, 3}, {4, 5, 7}, {6, 8, 9}}] + // Out[2]= 7 + assert_eq!(m.wide_det_3x3_1(),fixed_wide::fixed::Fixed::<3,96>::from(7)); +} + +#[test] +fn wide_matrix_adjugate(){ + let m=Matrix3::from([ + Vector3::from([Planar64::from(1),Planar64::from(2),Planar64::from(3)]), + Vector3::from([Planar64::from(4),Planar64::from(5),Planar64::from(7)]), + Vector3::from([Planar64::from(6),Planar64::from(8),Planar64::from(9)]), + ]); + // In[6]:= Adjugate[{{1, 2, 3}, {4, 5, 7}, {6, 8, 9}}] + // Out[6]= {{-11, 6, -1}, {6, -9, 5}, {2, 4, -3}} + assert_eq!( + m.wide_adjugate_3x3_1(), + Matrix3::from([ + Vector3::from([Planar64Wide1::from(-11),Planar64Wide1::from(6),Planar64Wide1::from(-1)]), + Vector3::from([Planar64Wide1::from(6),Planar64Wide1::from(-9),Planar64Wide1::from(5)]), + Vector3::from([Planar64Wide1::from(2),Planar64Wide1::from(4),Planar64Wide1::from(-3)]), + ]) + ); +} From c3026c67e987a8f142d46dffadb6b432aca11186 Mon Sep 17 00:00:00 2001 From: Quaternions Date: Thu, 5 Sep 2024 12:49:20 -0700 Subject: [PATCH 130/227] delete everything and start over --- fixed_wide/Cargo.toml | 1 - fixed_wide_vectors/Cargo.toml | 4 +- fixed_wide_vectors/src/macros/common.rs | 137 -------- fixed_wide_vectors/src/macros/fixed_wide.rs | 369 -------------------- fixed_wide_vectors/src/macros/matrix.rs | 200 ----------- fixed_wide_vectors/src/macros/mod.rs | 14 - fixed_wide_vectors/src/macros/vector.rs | 154 -------- fixed_wide_vectors/src/matrix.rs | 22 +- fixed_wide_vectors/src/vector.rs | 66 +--- 9 files changed, 14 insertions(+), 953 deletions(-) diff --git a/fixed_wide/Cargo.toml b/fixed_wide/Cargo.toml index cc218bc..eb8c705 100644 --- a/fixed_wide/Cargo.toml +++ b/fixed_wide/Cargo.toml @@ -11,4 +11,3 @@ zeroes=["ratio","dep:arrayvec"] [dependencies] bnum = "0.11.0" arrayvec = { version = "0.7.6", optional = true } -paste = "1.0.15" diff --git a/fixed_wide_vectors/Cargo.toml b/fixed_wide_vectors/Cargo.toml index b2f5856..556dee1 100644 --- a/fixed_wide_vectors/Cargo.toml +++ b/fixed_wide_vectors/Cargo.toml @@ -4,9 +4,9 @@ version = "0.1.0" edition = "2021" [features] -default=["fixed_wide"] +default=["fixed_wide","named-fields"] +named-fields=[] fixed_wide=["dep:fixed_wide"] [dependencies] fixed_wide = { version = "0.1.0", path = "../fixed_wide", optional = true } -paste = "1.0.15" diff --git a/fixed_wide_vectors/src/macros/common.rs b/fixed_wide_vectors/src/macros/common.rs index bb92dc7..8b13789 100644 --- a/fixed_wide_vectors/src/macros/common.rs +++ b/fixed_wide_vectors/src/macros/common.rs @@ -1,138 +1 @@ -#[doc(hidden)] -#[macro_export(local_inner_macros)] -macro_rules! impl_common { - ( $struct: ident { $($field: ident), + }, $size: expr ) => { - impl $struct { - /// Constructs a new vector with the specified values for each field. - /// - /// # Example - /// - /// ``` - /// use fixed_wide_vectors::Vector2; - /// - /// let vec2 = Vector2::new(0, 0); - /// - /// assert_eq!(vec2.x, 0); - /// assert_eq!(vec2.y, 0); - /// ``` - #[inline(always)] - pub const fn new( $($field: T), + ) -> Self { - Self { - $( $field ), + - } - } - /// Consumes the vector and returns its values as an array. - /// - /// # Example - /// - /// ``` - /// use fixed_wide_vectors::Vector2; - /// - /// let vec2 = Vector2::new(0, 0); - /// let array = vec2.to_array(); - /// - /// assert_eq!(array, [0, 0]); - /// ``` - #[inline(always)] - pub fn to_array(self) -> [T; $size] { - [ $(self.$field), + ] - } - - /// Consumes the vector and returns a new vector with the given function applied on each field. - /// - /// # Example - /// - /// ``` - /// use fixed_wide_vectors::Vector2; - /// - /// let vec2 = Vector2::new(1, 2) - /// .map(|i| i * 2); - /// - /// assert_eq!(vec2, Vector2::new(2, 4)); - /// ``` - #[inline] - pub fn map(self, f: F) -> $struct - where - F: Fn(T) -> U - { - $struct { - $( $field: f(self.$field) ), + - } - } - } - - impl $struct { - /// Constructs a vector using the given `value` as the value for all of its fields. - /// - /// # Example - /// - /// ``` - /// use fixed_wide_vectors::Vector2; - /// - /// let vec2 = Vector2::from_value(0); - /// - /// assert_eq!(vec2, Vector2::new(0, 0)); - /// ``` - #[inline(always)] - pub const fn from_value(value: T) -> Self { - Self { - $( $field: value ), + - } - } - } - - impl From<[T; $size]> for $struct { - fn from(from: [T; $size]) -> Self { - let mut iterator = from.into_iter(); - - Self { - // SAFETY: We know the size of `from` so `iterator.next()` is always `Some(..)` - $( $field: unsafe { iterator.next().unwrap_unchecked() } ), + - } - } - } - - impl core::fmt::Debug for $struct { - fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { - let identifier = core::stringify!($struct); - - f.debug_struct(identifier) - $( .field( core::stringify!($field), &self.$field ) ) + - .finish() - } - } - - impl PartialEq for $struct { - fn eq(&self, other: &Self) -> bool { - $( self.$field == other.$field ) && + - } - } - - impl Eq for $struct { } - - impl core::hash::Hash for $struct { - fn hash(&self, state: &mut H) { - $( self.$field.hash(state); ) + - } - } - - impl Clone for $struct { - fn clone(&self) -> Self { - Self { - $( $field: self.$field.clone() ), + - } - } - } - - impl Copy for $struct { } - - impl Default for $struct { - fn default() -> Self { - Self { - $( $field: T::default() ), + - } - } - } - } -} diff --git a/fixed_wide_vectors/src/macros/fixed_wide.rs b/fixed_wide_vectors/src/macros/fixed_wide.rs index 3812d86..8b13789 100644 --- a/fixed_wide_vectors/src/macros/fixed_wide.rs +++ b/fixed_wide_vectors/src/macros/fixed_wide.rs @@ -1,370 +1 @@ -#[doc(hidden)] -#[macro_export(local_inner_macros)] -macro_rules! impl_wide_vector_operations_2arg_not_const_generic { - ( - ($struct: ident { $($field: ident), + }, $size: expr), - ($lhs:expr, $rhs:expr) - ) => { - impl $struct>{ - paste::item!{ - #[inline] - pub fn [](self,rhs:$struct>)->$struct>{ - $struct{ - $( $field: self.$field.[](rhs.$field) ), + - } - } - #[inline] - pub fn [](self,rhs:$struct>)->fixed_wide::fixed::Fixed<{$lhs+$rhs},{($lhs+$rhs)*32}>{ - $crate::sum_repeating!( - $( + (self.$field.[](rhs.$field)) ) + - ) - } - } - } - } -} -#[doc(hidden)] -#[macro_export(local_inner_macros)] -macro_rules! impl_wide_vector_operations_1arg_not_const_generic { - ( - ($struct: ident { $($field: ident), + }, $size: expr), - $n:expr - ) => { - impl $struct>{ - paste::item!{ - #[inline] - pub fn wide_length_squared(&self)->fixed_wide::fixed::Fixed<{$n*2},{$n*2*32}>{ - $crate::sum_repeating!( - $( + self.$field.[](self.$field) ) + - ) - } - } - } - }; -} -#[doc(hidden)] -#[macro_export(local_inner_macros)] -macro_rules! do_macro_8x8{ - ( - $macro:ident, - $any:tt - )=>{ - $crate::macro_repeated!($macro, $any, - (1,1),(2,1),(3,1),(4,1),(5,1),(6,1),(7,1),(8,1), - (1,2),(2,2),(3,2),(4,2),(5,2),(6,2),(7,2),(8,2), - (1,3),(2,3),(3,3),(4,3),(5,3),(6,3),(7,3),(8,3), - (1,4),(2,4),(3,4),(4,4),(5,4),(6,4),(7,4),(8,4), - (1,5),(2,5),(3,5),(4,5),(5,5),(6,5),(7,5),(8,5), - (1,6),(2,6),(3,6),(4,6),(5,6),(6,6),(7,6),(8,6), - (1,7),(2,7),(3,7),(4,7),(5,7),(6,7),(7,7),(8,7), - (1,8),(2,8),(3,8),(4,8),(5,8),(6,8),(7,8),(8,8) - ); - }; -} - -#[doc(hidden)] -#[macro_export(local_inner_macros)] -macro_rules! do_macro_8{ - ( - $macro:ident, - $any:tt - )=>{ - $crate::macro_repeated!($macro, $any, 1,2,3,4,5,6,7,8); - }; -} - -#[doc(hidden)] -#[macro_export(local_inner_macros)] -macro_rules! impl_wide_vector_operations { - ( $struct: ident { $($field: ident), + }, $size: expr ) => { - $crate::do_macro_8!(impl_wide_vector_operations_1arg_not_const_generic,($struct { $($field), + }, $size)); - $crate::do_macro_8x8!(impl_wide_vector_operations_2arg_not_const_generic,($struct { $($field), + }, $size)); - }; -} - -#[doc(hidden)] -#[macro_export(local_inner_macros)] -macro_rules! impl_vector_3_wide_cross { - ( - (), - ($lhs:expr, $rhs:expr) - )=>{ - impl Vector3>{ - paste::item!{ - #[inline] - pub fn [](self,rhs:Vector3>)->Vector3>{ - Vector3{ - x:self.y.[](rhs.z)-self.z.[](rhs.y), - y:self.z.[](rhs.x)-self.x.[](rhs.z), - z:self.x.[](rhs.y)-self.y.[](rhs.x) - } - } - } - } - } -} - -#[doc(hidden)] -#[macro_export(local_inner_macros)] -macro_rules! impl_vector_wide_3 { - ()=>{ - $crate::do_macro_8x8!(impl_vector_3_wide_cross,()); - } -} - -#[doc(hidden)] -#[macro_export(local_inner_macros)] -macro_rules! impl_matrix_wide_dot_transpose_helper { - ( - $lhs_axis:expr, $wide_mul:ident, $rhs:ident, - ($struct: ident { $($field: ident), + }), - ($from_struct: ident { $($from_field: ident), + }), - $static_field: ident - ) => { - $crate::sum_repeating!( - $( + $lhs_axis.$field.$wide_mul($rhs.$from_field.$static_field) ) + - ) - } -} -#[doc(hidden)] -#[macro_export(local_inner_macros)] -macro_rules! impl_matrix_wide_dot_inner { - ( - // MatY.MatX = MatY - $lhs:ident, $lhs_field_outer:ident, $wide_mul:ident, $rhs:ident, - $struct_inner_thru: tt, //VecX - ($struct_inner: ident { $($field_inner: ident), + }), //VecX - ($rhs_struct_inner: ident { $($rhs_field_inner: ident), + }), //VecZ - $rhs_outer: tt //MatX - ) => { - $rhs_struct_inner { - $( - //directly dot product to avoid a copy - $rhs_field_inner: $crate::impl_matrix_wide_dot_transpose_helper!{ - //lhs.axis.wide_mul(rhs_t.axis) - $lhs.$lhs_field_outer,$wide_mul,$rhs, - $struct_inner_thru, //VecZ - $rhs_outer, //MatX - $rhs_field_inner - } - ), + - } - } -} -#[doc(hidden)] -#[macro_export(local_inner_macros)] -macro_rules! impl_matrix_wide_dot_outer { - ( - // MatY.MatX = MatY - $lhs:ident, $wide_mul:ident, $rhs:ident, - //result matrix shape - ($struct_outer: ident { $($field_outer: ident), + }),//MatY - $rhs_struct_inner: tt,//VecZ - //inner loop shape - $struct_inner: tt,//VecX - $rhs_matrix: tt//MatX - - ) => { - $struct_outer { - $( - $field_outer: $crate::impl_matrix_wide_dot_inner!{ - $lhs, $field_outer, $wide_mul, $rhs, - $struct_inner, //VecX - $struct_inner, //VecX - $rhs_struct_inner, //VecZ - $rhs_matrix //MatX - } - ), + - } - } -} - -// Notes: -// Mat3.dot(Vec2) -> Vec3 -// lhs.dot(rhs) -> out -// lhs = Mat3 -// rhs = Mat4 -// out = Mat3 -// Mat3.dot(Mat4) -> Mat3 -// how to matrix multiply: -// RHS TRANSPOSE -// Mat4 -> Mat2 -// rhs_t = Mat2 -// inner loop: -// out[y][x] = lhs[y].dot(rhs_t[x]) - -#[doc(hidden)] -#[macro_export(local_inner_macros)] -macro_rules! impl_matrix_wide_dot { - ( - ($struct_outer: ident { $($field_outer: ident), + }, $vector_outer: ident { $($vector_field_outer: ident), + }, $size_outer: expr), - ($struct_inner: ident { $($field_inner: ident), + }, $matrix_inner: ident { $($matrix_field_inner: ident), + }, $size_inner: expr), - ($rhs_struct_inner: ident { $($rhs_field_inner: ident), + }, $rhs_matrix_inner: ident { $($rhs_matrix_field_inner: ident), + }, $rhs_size_inner: expr), - ($lhs: expr, $rhs: expr) - ) => { - impl $struct_outer<$struct_inner>>{ - paste::item!{ - #[inline] - pub fn [](self,rhs:$matrix_inner<$rhs_struct_inner>>)->$struct_outer<$rhs_struct_inner>>{ - $crate::impl_matrix_wide_dot_outer!( - //constituent idents - self,[],rhs, - //result matrix shape - ($struct_outer { $($field_outer), + }), - ($rhs_struct_inner { $($rhs_field_inner), + }), - //inner loop shape - ($struct_inner { $($field_inner), + }), - ($matrix_inner { $($matrix_field_inner), + }) - ) - } - } - } - } -} - -#[doc(hidden)] -#[macro_export(local_inner_macros)] -macro_rules! impl_matrix_wide_dot_shim { - ( - ($outer_info:tt,$inner_info:tt,$rhs_info:tt), - ($lhs: expr, $rhs: expr) - ) => { - $crate::impl_matrix_wide_dot!($outer_info,$inner_info,$rhs_info,($lhs,$rhs)); - } -} -#[doc(hidden)] -#[macro_export(local_inner_macros)] -macro_rules! impl_matrix_wide_dot_8x8 { - ( - ($outer_info:tt,$inner_info:tt), - $rhs_info:tt - ) => { - $crate::do_macro_8x8!(impl_matrix_wide_dot_shim,($outer_info,$inner_info,$rhs_info)); - } -} -#[doc(hidden)] -#[macro_export(local_inner_macros)] -macro_rules! impl_matrix_wide_dot_repeat_rhs { - ( - ($outer_info:tt,($($rhs_info:tt),+)), - $inner_info:tt - ) => { - $crate::macro_repeated!(impl_matrix_wide_dot_8x8,($outer_info,$inner_info),$($rhs_info),+); - } -} -#[doc(hidden)] -#[macro_export(local_inner_macros)] -macro_rules! impl_wide_matrix_operations_2arg_not_const_generic { - ( - $lhs: expr, $rhs: expr, - ($struct_outer: ident { $($field_outer: ident), + }, $vector_outer: ident { $($vector_field_outer: ident), + }, $size_outer: expr), - ($struct_inner: ident { $($field_inner: ident), + }, $matrix_inner: ident { $($matrix_field_inner: ident), + }, $size_inner: expr) - ) => { - /* TODO: nasty determinant macro - impl,T:Copy+fixed_wide_traits::wide::WideMul> $struct { - #[inline] - pub fn wide_dot(&self) -> U { - $crate::sum_repeating!( - $( + self.$field.wide_mul(self.$field) ) + - ) - } - } - */ - }; -} -#[doc(hidden)] -#[macro_export(local_inner_macros)] -macro_rules! impl_wide_matrix_operations_1arg_not_const_generic { - ( - $n: expr, - ($struct_outer: ident { $($field_outer: ident), + }, $vector_outer: ident { $($vector_field_outer: ident), + }, $size_outer: expr), - ) => { - /* TODO: nasty determinant macro - impl,T:Copy+fixed_wide_traits::wide::WideMul> $struct { - #[inline] - pub fn wide_det(&self) -> U { - $crate::sum_repeating!( - $( + self.$field.wide_mul(self.$field) ) + - ) - } - } - */ - }; -} - -#[doc(hidden)] -#[macro_export(local_inner_macros)] -macro_rules! do_macro_4_dumb{ - ( - $macro:ident, - $any:tt - )=>{ - $crate::macro_repeated!($macro, $any, (1,2),(2,4),(3,6),(4,8)); - }; -} - -#[doc(hidden)] -#[macro_export(local_inner_macros)] -macro_rules! impl_matrix_wide_3x3_det_not_const_generic { - ( - $n: expr, - $_2n: expr - )=>{ - impl Matrix3>>{ - paste::item!{ - pub fn [](self)->fixed_wide::fixed::Fixed<{$n*3},{$n*3*32}>{ - //[] will not compile, so the doubles are hardcoded above - self.x_axis.[](self.y_axis.[](self.z_axis)) - } - } - } - } -} -#[doc(hidden)] -#[macro_export(local_inner_macros)] -macro_rules! impl_matrix_wide_3x3_det_not_const_generic_shim { - ( - (),($n: expr,$_2n: expr) - )=>{ - $crate::impl_matrix_wide_3x3_det_not_const_generic!($n,$_2n); - } -} -#[doc(hidden)] -#[macro_export(local_inner_macros)] -macro_rules! impl_matrix_wide_3x3_adjugate_not_const_generic { - ( - (), - $n: expr - )=>{ - impl Matrix3>>{ - paste::item!{ - pub fn [](self)->Matrix3>>{ - Matrix3{ - x_axis:Vector3{x:self.y_axis.y.[](self.z_axis.z)-self.y_axis.z.[](self.z_axis.y),y:self.x_axis.z.[](self.z_axis.y)-self.x_axis.y.[](self.z_axis.z),z:self.x_axis.y.[](self.y_axis.z)-self.x_axis.z.[](self.y_axis.y)}, - y_axis:Vector3{x:self.y_axis.z.[](self.z_axis.x)-self.y_axis.x.[](self.z_axis.z),y:self.x_axis.x.[](self.z_axis.z)-self.x_axis.z.[](self.z_axis.x),z:self.x_axis.z.[](self.y_axis.x)-self.x_axis.x.[](self.y_axis.z)}, - z_axis:Vector3{x:self.y_axis.x.[](self.z_axis.y)-self.y_axis.y.[](self.z_axis.x),y:self.x_axis.y.[](self.z_axis.x)-self.x_axis.x.[](self.z_axis.y),z:self.x_axis.x.[](self.y_axis.y)-self.x_axis.y.[](self.y_axis.x)}, - } - } - } - } - } -} -#[doc(hidden)] -#[macro_export(local_inner_macros)] -macro_rules! impl_matrix_wide_3x3 { - ()=>{ - $crate::do_macro_4_dumb!(impl_matrix_wide_3x3_det_not_const_generic_shim,()); - $crate::do_macro_8!(impl_matrix_wide_3x3_adjugate_not_const_generic,()); - } -} - -// HACK: Allows us to sum repeating tokens in macros. -// See: https://stackoverflow.com/a/60187870/17452730 -#[doc(hidden)] -#[macro_export(local_inner_macros)] -macro_rules! sum_repeating { - ( + $($item: tt) * ) => { - $($item) * - }; -} diff --git a/fixed_wide_vectors/src/macros/matrix.rs b/fixed_wide_vectors/src/macros/matrix.rs index 37b3b99..8b13789 100644 --- a/fixed_wide_vectors/src/macros/matrix.rs +++ b/fixed_wide_vectors/src/macros/matrix.rs @@ -1,201 +1 @@ -// Stolen from https://github.com/c1m50c/fixed-vectors (MIT license) -#[doc(hidden)] -#[macro_export(local_inner_macros)] -macro_rules! impl_matrix { - ( - ($struct_outer: ident { $($field_outer: ident), + }, $vector_outer: ident { $($vector_field_outer: ident), + }, $size_outer: expr) - ) => { - $crate::impl_common!($struct_outer { $($field_outer), + }, $size_outer); - impl $struct_outer { - #[inline(always)] - pub fn to_vector(self) -> $vector_outer { - $vector_outer { - $( - $vector_field_outer: self.$field_outer - ), + - } - } - } - } -} -#[doc(hidden)] -#[macro_export(local_inner_macros)] -macro_rules! impl_matrix_shim { - ( - (), - $matrix_info:tt - ) => { - $crate::impl_matrix!($matrix_info); - } -} -#[doc(hidden)] -#[macro_export(local_inner_macros)] -macro_rules! impl_matrices { - ( - ($($matrix_info:tt),+), - $vector_infos:tt - ) => { - $crate::macro_repeated!(impl_matrix_shim,(),$($matrix_info),+); - $crate::macro_repeated!(impl_matrix_inner_shim,$vector_infos,$($matrix_info),+); - } -} -#[doc(hidden)] -#[macro_export(local_inner_macros)] -macro_rules! impl_matrix_inner_shim { - ( - ($($vector_info:tt),+), - $matrix_info:tt - ) => { - $crate::macro_repeated!(impl_matrix_inner,$matrix_info,$($vector_info),+); - #[cfg(feature="fixed_wide")] - $crate::macro_repeated!(impl_matrix_wide_dot_repeat_rhs,($matrix_info,($($vector_info),+)),$($vector_info),+); - } -} -#[doc(hidden)] -#[macro_export(local_inner_macros)] -macro_rules! impl_matrix_inner { - ( - ($struct_outer: ident { $($field_outer: ident), + }, $vector_outer: ident { $($vector_field_outer: ident), + }, $size_outer: expr), - ($struct_inner: ident { $($field_inner: ident), + }, $matrix_inner: ident { $($matrix_field_inner: ident), + }, $size_inner: expr) - ) => { - impl $struct_outer<$struct_inner> { - #[inline(always)] - pub fn to_array_2d(self) -> [[T; $size_inner]; $size_outer] { - [ $(self.$field_outer.to_array()), + ] - } - #[inline] - pub fn map_2d(self, f: F) -> $struct_outer<$struct_inner> - where - F: Fn(T) -> U - { - $crate::matrix_map2d_outer!{f,self,($struct_outer { $($field_outer), + }),($struct_inner { $($field_inner), + })} - } - - #[inline] - pub fn transpose(self) -> $matrix_inner<$vector_outer>{ - $crate::matrix_transpose_outer!{self, - ($matrix_inner { $($matrix_field_inner), + }),($struct_inner { $($field_inner), + }), - ($vector_outer { $($vector_field_outer), + }),($struct_outer { $($field_outer), + }) - } - } - } - - impl $struct_outer<$struct_inner> { - #[inline(always)] - pub const fn from_value_2d(value: T) -> Self { - Self { - $( $field_outer: $struct_inner::from_value(value) ), + - } - } - //TODO: diagonal - } - - // Impl floating-point based methods - //#[cfg(feature="fixed_wide_traits")] - //$crate::impl_wide_matrix_operations!( ($struct_outer { $($field_outer), + }, $size_outer), ($struct_inner, $size_inner), $fields_inner ); - }; -} - - -#[doc(hidden)] -#[macro_export(local_inner_macros)] -macro_rules! matrix_map2d_outer { - ( $f:ident, $value:ident, ($struct_outer: ident { $($field_outer: ident), + }), $unparsed_inner:tt ) => { - $struct_outer { - $( - $field_outer: $crate::matrix_map2d_inner!{$f,$value,$field_outer,$unparsed_inner} - ), + - } - } -} -#[doc(hidden)] -#[macro_export(local_inner_macros)] -macro_rules! matrix_map2d_inner { - ( $f:ident, $value:ident, $field_outer:ident, ($struct_inner: ident { $($field_inner: ident), + }) ) => { - $struct_inner { - $( - $field_inner: $f($value.$field_outer.$field_inner) - ), + - } - } -} -#[doc(hidden)] -#[macro_export(local_inner_macros)] -macro_rules! matrix_transpose_outer { - ( - $value:ident, - ($struct_outer: ident { $($field_outer: ident), + }), - ($old_outer: ident { $($old_field_outer: ident), + }), - $fields_inner:tt, - $old_fields_inner:tt - ) => { - $struct_outer { - $( - $field_outer: $crate::matrix_transpose_inner!{$value,$old_field_outer,$fields_inner,$old_fields_inner} - ), + - } - } -} -#[doc(hidden)] -#[macro_export(local_inner_macros)] -macro_rules! matrix_transpose_inner { - ( $value:ident, $field_outer:ident, - ($struct_inner: ident { $($field_inner: ident), + }), - ($old_struct_inner: ident { $($old_field_inner: ident), + }) - ) => { - $struct_inner { - $( - $field_inner: $value.$old_field_inner.$field_outer - ), + - } - } -} - -#[doc(hidden)] -#[macro_export(local_inner_macros)] -macro_rules! impl_matrix_3x3 { - ()=>{ - #[cfg(feature="fixed_wide")] - $crate::impl_matrix_wide_3x3!(); - } -} - -#[doc(hidden)] -#[macro_export(local_inner_macros)] -macro_rules! impl_matrix_operator { - ( $struct: ident { $($field: ident), + }, $trait: ident, $method: ident, $output: ty ) => { - impl> core::ops::$trait for $struct { - type Output = $output; - - fn $method(self, other: Self) -> Self::Output { - Self { - $( $field: self.$field.$method(other.$field) ), + - } - } - } - impl+Copy> core::ops::$trait for $struct{ - type Output = $output; - - fn $method(self, other: T) -> Self::Output { - $struct { - $( $field: self.$field.$method(other) ), + - } - } - } - }; - - ( $struct: ident { $($field: ident), + }, $trait: ident, $method: ident ) => { - impl core::ops::$trait for $struct { - fn $method(&mut self, other: Self) { - $( self.$field.$method(other.$field) ); + - } - } - - impl core::ops::$trait for $struct { - fn $method(&mut self, other: T) { - $( self.$field.$method(other) ); + - } - } - }; -} diff --git a/fixed_wide_vectors/src/macros/mod.rs b/fixed_wide_vectors/src/macros/mod.rs index 572d35c..30d20cc 100644 --- a/fixed_wide_vectors/src/macros/mod.rs +++ b/fixed_wide_vectors/src/macros/mod.rs @@ -4,17 +4,3 @@ pub mod fixed_wide; pub mod common; pub mod vector; pub mod matrix; - -#[doc(hidden)] -#[macro_export(local_inner_macros)] -macro_rules! macro_repeated{ - ( - $macro:ident, - $any:tt, - $($repeated:tt),* - )=>{ - $( - $crate::$macro!($any, $repeated); - )* - }; -} diff --git a/fixed_wide_vectors/src/macros/vector.rs b/fixed_wide_vectors/src/macros/vector.rs index ad7a72e..8b13789 100644 --- a/fixed_wide_vectors/src/macros/vector.rs +++ b/fixed_wide_vectors/src/macros/vector.rs @@ -1,155 +1 @@ -// Stolen from https://github.com/c1m50c/fixed-vectors (MIT license) -#[doc(hidden)] -#[macro_export(local_inner_macros)] -macro_rules! impl_vector { - ( $struct: ident { $($field: ident), + }, $size: expr ) => { - $crate::impl_common!($struct { $($field), + }, $size); - impl $struct { - pub fn min(self, rhs: Self) -> $struct { - $struct{ - $( $field: self.$field.min(rhs.$field) ), + - } - } - pub fn max(self, rhs: Self) -> $struct { - $struct{ - $( $field: self.$field.max(rhs.$field) ), + - } - } - pub fn cmp(self, rhs: Self) -> $struct { - $struct{ - $( $field: self.$field.cmp(&rhs.$field) ), + - } - } - pub fn lt(self, rhs: Self) -> $struct { - $struct{ - $( $field: self.$field.lt(&rhs.$field) ), + - } - } - pub fn gt(self, rhs: Self) -> $struct { - $struct{ - $( $field: self.$field.gt(&rhs.$field) ), + - } - } - pub fn ge(self, rhs: Self) -> $struct { - $struct{ - $( $field: self.$field.ge(&rhs.$field) ), + - } - } - pub fn le(self, rhs: Self) -> $struct { - $struct{ - $( $field: self.$field.le(&rhs.$field) ), + - } - } - } - - impl $struct{ - pub fn all(&self)->bool{ - const ALL:[bool;$size]=[true;$size]; - core::matches!(self.to_array(),ALL) - } - pub fn any(&self)->bool{ - $( self.$field )|| + - } - } - - impl> core::ops::Neg for $struct { - type Output = Self; - - fn neg(self) -> Self::Output { - Self { - $( $field: -self.$field ), + - } - } - } - - // Impl arithmetic pperators - $crate::impl_vector_operator!( $struct { $($field), + }, AddAssign, add_assign ); - $crate::impl_vector_operator!( $struct { $($field), + }, Add, add, Self ); - $crate::impl_vector_operator!( $struct { $($field), + }, SubAssign, sub_assign ); - $crate::impl_vector_operator!( $struct { $($field), + }, Sub, sub, Self ); - $crate::impl_vector_operator!( $struct { $($field), + }, MulAssign, mul_assign ); - $crate::impl_vector_operator!( $struct { $($field), + }, Mul, mul, Self ); - $crate::impl_vector_operator!( $struct { $($field), + }, DivAssign, div_assign ); - $crate::impl_vector_operator!( $struct { $($field), + }, Div, div, Self ); - $crate::impl_vector_operator!( $struct { $($field), + }, RemAssign, rem_assign ); - $crate::impl_vector_operator!( $struct { $($field), + }, Rem, rem, Self ); - - // Impl bitwise operators - $crate::impl_vector_operator!( $struct { $($field), + }, BitAndAssign, bitand_assign ); - $crate::impl_vector_operator!( $struct { $($field), + }, BitAnd, bitand, Self ); - $crate::impl_vector_operator!( $struct { $($field), + }, BitOrAssign, bitor_assign ); - $crate::impl_vector_operator!( $struct { $($field), + }, BitOr, bitor, Self ); - $crate::impl_vector_operator!( $struct { $($field), + }, BitXorAssign, bitxor_assign ); - $crate::impl_vector_operator!( $struct { $($field), + }, BitXor, bitxor, Self ); - - // Impl floating-point based methods - #[cfg(feature="fixed_wide")] - $crate::impl_wide_vector_operations!( $struct { $($field), + }, $size ); - }; -} - - -#[doc(hidden)] -#[macro_export(local_inner_macros)] -macro_rules! impl_extend { - ( $struct: ident { $($field: ident), + }, $struct_extended: ident, $field_extended: ident ) => { - impl $struct { - #[inline(always)] - pub fn extend(self,value:T) -> $struct_extended { - $struct_extended { - $( $field:self.$field, ) + - $field_extended:value - } - } - } - }; -} - -#[doc(hidden)] -#[macro_export(local_inner_macros)] -macro_rules! impl_vector_operator { - ( $struct: ident { $($field: ident), + }, $trait: ident, $method: ident, $output: ty ) => { - impl> core::ops::$trait for $struct { - type Output = $output; - - fn $method(self, other: Self) -> Self::Output { - Self { - $( $field: self.$field.$method(other.$field) ), + - } - } - } - impl+Copy> core::ops::$trait for $struct{ - type Output = $output; - - fn $method(self, other: T) -> Self::Output { - $struct { - $( $field: self.$field.$method(other) ), + - } - } - } - }; - - ( $struct: ident { $($field: ident), + }, $trait: ident, $method: ident ) => { - impl core::ops::$trait for $struct { - fn $method(&mut self, other: Self) { - $( self.$field.$method(other.$field) ); + - } - } - - impl core::ops::$trait for $struct { - fn $method(&mut self, other: T) { - $( self.$field.$method(other) ); + - } - } - }; -} - -#[doc(hidden)] -#[macro_export(local_inner_macros)] -macro_rules! impl_vector_3 { - ()=>{ - #[cfg(feature="fixed_wide")] - $crate::impl_vector_wide_3!(); - } -} diff --git a/fixed_wide_vectors/src/matrix.rs b/fixed_wide_vectors/src/matrix.rs index 4966f28..41579df 100644 --- a/fixed_wide_vectors/src/matrix.rs +++ b/fixed_wide_vectors/src/matrix.rs @@ -16,22 +16,18 @@ pub struct Matrix4 { pub w_axis: T, } -crate::impl_extend!(Matrix2 { x_axis, y_axis }, Matrix3, z_axis); -crate::impl_extend!(Matrix3 { x_axis, y_axis, z_axis }, Matrix4, w_axis); -//TODO: extend vertically - -crate::impl_matrices!( - //outer struct and equivalent vector +crate::impl_matrix_named_fields!( + //outer struct ( - (Matrix2 { x_axis, y_axis }, Vector2 { x, y }, 2), - (Matrix3 { x_axis, y_axis, z_axis }, Vector3 { x, y, z }, 3), - (Matrix4 { x_axis, y_axis, z_axis, w_axis }, Vector4 { x, y, z, w }, 4) + (Matrix2 { x_axis, y_axis }, 2), + (Matrix3 { x_axis, y_axis, z_axis }, 3), + (Matrix4 { x_axis, y_axis, z_axis, w_axis }, 4) ), - //inner struct and equivalent matrix + //inner struct ( - (Vector2 { x, y }, Matrix2 { x_axis, y_axis }, 2), - (Vector3 { x, y, z }, Matrix3 { x_axis, y_axis, z_axis }, 3), - (Vector4 { x, y, z, w }, Matrix4 { x_axis, y_axis, z_axis, w_axis }, 4) + (Vector2 { x, y }, 2), + (Vector3 { x, y, z }, 3), + (Vector4 { x, y, z, w }, 4) ) ); diff --git a/fixed_wide_vectors/src/vector.rs b/fixed_wide_vectors/src/vector.rs index 5016c97..12ed55a 100644 --- a/fixed_wide_vectors/src/vector.rs +++ b/fixed_wide_vectors/src/vector.rs @@ -1,60 +1,14 @@ -// Stolen from https://github.com/c1m50c/fixed-vectors (MIT license) - -/// Vector for holding two-dimensional values. -/// -/// # Example -/// -/// ``` -/// use fixed_wide_vectors::Vector2; -/// -/// let mut vec2 = Vector2::new(1, 2); -/// vec2 += Vector2::new(1, 2); -/// -/// assert_eq!(vec2.x, 2); -/// assert_eq!(vec2.y, 4); -/// ``` pub struct Vector2 { pub x: T, pub y: T, } - -/// Vector for holding three-dimensional values. -/// -/// # Example -/// -/// ``` -/// use fixed_wide_vectors::Vector3; -/// -/// let mut vec3 = Vector3::new(1, 2, 3); -/// vec3 += Vector3::new(1, 2, 3); -/// -/// assert_eq!(vec3.x, 2); -/// assert_eq!(vec3.y, 4); -/// assert_eq!(vec3.z, 6); -/// ``` pub struct Vector3 { pub x: T, pub y: T, pub z: T, } - -/// Vector for holding four-dimensional values. -/// -/// # Example -/// -/// ``` -/// use fixed_wide_vectors::Vector4; -/// -/// let mut vec4 = Vector4::new(1, 2, 3, 4); -/// vec4 += Vector4::new(1, 2, 3, 4); -/// -/// assert_eq!(vec4.x, 2); -/// assert_eq!(vec4.y, 4); -/// assert_eq!(vec4.z, 6); -/// assert_eq!(vec4.w, 8); -/// ``` pub struct Vector4 { pub x: T, pub y: T, @@ -62,23 +16,9 @@ pub struct Vector4 { pub w: T, } - -crate::impl_vector!(Vector2 { x, y }, 2); -crate::impl_vector!(Vector3 { x, y, z }, 3); -crate::impl_vector!(Vector4 { x, y, z, w }, 4); - -crate::impl_extend!(Vector2 { x, y }, Vector3, z); -crate::impl_extend!(Vector3 { x, y, z }, Vector4, w); - -crate::impl_matrix_inner!((Vector2 { x, y }, Vector2 { x, y }, 2), (Vector2 { x, y }, Vector2 { x, y }, 2) ); -crate::impl_matrix_inner!((Vector2 { x, y }, Vector2 { x, y }, 2), (Vector3 { x, y, z }, Vector3 { x, y, z }, 3) ); -crate::impl_matrix_inner!((Vector2 { x, y }, Vector2 { x, y }, 2), (Vector4 { x, y, z, w }, Vector4 { x, y, z, w }, 4) ); -crate::impl_matrix_inner!((Vector3 { x, y, z }, Vector3 { x, y, z }, 3), (Vector2 { x, y }, Vector2 { x, y }, 2) ); -crate::impl_matrix_inner!((Vector3 { x, y, z }, Vector3 { x, y, z }, 3), (Vector3 { x, y, z }, Vector3 { x, y, z }, 3) ); -crate::impl_matrix_inner!((Vector3 { x, y, z }, Vector3 { x, y, z }, 3), (Vector4 { x, y, z, w }, Vector4 { x, y, z, w }, 4) ); -crate::impl_matrix_inner!((Vector4 { x, y, z, w }, Vector4 { x, y, z, w }, 4), (Vector2 { x, y }, Vector2 { x, y }, 2) ); -crate::impl_matrix_inner!((Vector4 { x, y, z, w }, Vector4 { x, y, z, w }, 4), (Vector3 { x, y, z }, Vector3 { x, y, z }, 3) ); -crate::impl_matrix_inner!((Vector4 { x, y, z, w }, Vector4 { x, y, z, w }, 4), (Vector4 { x, y, z, w }, Vector4 { x, y, z, w }, 4) ); +crate::impl_vector_named_fields!(Vector2 { x, y }, 2); +crate::impl_vector_named_fields!(Vector3 { x, y, z }, 3); +crate::impl_vector_named_fields!(Vector4 { x, y, z, w }, 4); //cross product crate::impl_vector_3!(); From e475da5fb458008ea23ce4f35243ab9bcc7e657a Mon Sep 17 00:00:00 2001 From: Quaternions Date: Thu, 5 Sep 2024 13:16:02 -0700 Subject: [PATCH 131/227] put that back --- fixed_wide/Cargo.toml | 1 + fixed_wide_vectors/Cargo.lock | 1 - fixed_wide_vectors/src/macros/mod.rs | 14 ++++++++++++++ 3 files changed, 15 insertions(+), 1 deletion(-) diff --git a/fixed_wide/Cargo.toml b/fixed_wide/Cargo.toml index eb8c705..cc218bc 100644 --- a/fixed_wide/Cargo.toml +++ b/fixed_wide/Cargo.toml @@ -11,3 +11,4 @@ zeroes=["ratio","dep:arrayvec"] [dependencies] bnum = "0.11.0" arrayvec = { version = "0.7.6", optional = true } +paste = "1.0.15" diff --git a/fixed_wide_vectors/Cargo.lock b/fixed_wide_vectors/Cargo.lock index 7c320dd..5bb2156 100644 --- a/fixed_wide_vectors/Cargo.lock +++ b/fixed_wide_vectors/Cargo.lock @@ -28,7 +28,6 @@ name = "fixed_wide_vectors" version = "0.1.0" dependencies = [ "fixed_wide", - "paste", ] [[package]] diff --git a/fixed_wide_vectors/src/macros/mod.rs b/fixed_wide_vectors/src/macros/mod.rs index 30d20cc..572d35c 100644 --- a/fixed_wide_vectors/src/macros/mod.rs +++ b/fixed_wide_vectors/src/macros/mod.rs @@ -4,3 +4,17 @@ pub mod fixed_wide; pub mod common; pub mod vector; pub mod matrix; + +#[doc(hidden)] +#[macro_export(local_inner_macros)] +macro_rules! macro_repeated{ + ( + $macro:ident, + $any:tt, + $($repeated:tt),* + )=>{ + $( + $crate::$macro!($any, $repeated); + )* + }; +} From e026f6efed0b78861da57f5f0f0767f0adffa14f Mon Sep 17 00:00:00 2001 From: Quaternions Date: Thu, 5 Sep 2024 13:36:38 -0700 Subject: [PATCH 132/227] wip --- fixed_wide_vectors/src/lib.rs | 14 ++--- fixed_wide_vectors/src/macros/matrix.rs | 49 ++++++++++++++++++ fixed_wide_vectors/src/macros/vector.rs | 24 +++++++++ fixed_wide_vectors/src/matrix.rs | 35 ++----------- fixed_wide_vectors/src/named.rs | 59 ++++++++++++++++++++++ fixed_wide_vectors/src/tests/fixed_wide.rs | 2 +- fixed_wide_vectors/src/types.rs | 18 +++++++ fixed_wide_vectors/src/vector.rs | 24 ++------- 8 files changed, 164 insertions(+), 61 deletions(-) create mode 100644 fixed_wide_vectors/src/named.rs create mode 100644 fixed_wide_vectors/src/types.rs diff --git a/fixed_wide_vectors/src/lib.rs b/fixed_wide_vectors/src/lib.rs index a9c0b41..628ca4e 100644 --- a/fixed_wide_vectors/src/lib.rs +++ b/fixed_wide_vectors/src/lib.rs @@ -1,14 +1,10 @@ mod macros; -mod vector; -mod matrix; +pub mod types; +pub mod vector; +pub mod matrix; -pub use vector::Vector2; -pub use vector::Vector3; -pub use vector::Vector4; - -pub use matrix::Matrix2; -pub use matrix::Matrix3; -pub use matrix::Matrix4; +#[cfg(feature="named-fields")] +mod named; #[cfg(test)] mod tests; diff --git a/fixed_wide_vectors/src/macros/matrix.rs b/fixed_wide_vectors/src/macros/matrix.rs index 8b13789..518315b 100644 --- a/fixed_wide_vectors/src/macros/matrix.rs +++ b/fixed_wide_vectors/src/macros/matrix.rs @@ -1 +1,50 @@ +#[doc(hidden)] +#[macro_export(local_inner_macros)] +macro_rules! impl_matrix { + () => { + //$crate::impl_common!(); + } +} +#[doc(hidden)] +#[macro_export(local_inner_macros)] +macro_rules! impl_matrix_named_fields_shape { + ( + ($struct_outer:ident, $size_outer: expr), + ($struct_inner:ident, $size_inner: expr) + ) => { + impl core::ops::Deref for Matrix<$size_outer,$size_inner,T>{ + type Target=$struct_outer<$struct_inner>; + fn deref(&self)->&Self::Target{ + unsafe{core::mem::transmute(&self.array)} + } + } + impl core::ops::DerefMut for Matrix<$size_outer,$size_inner,T>{ + fn deref_mut(&mut self)->&mut Self::Target{ + unsafe{core::mem::transmute(&mut self.array)} + } + } + } +} + +#[doc(hidden)] +#[macro_export(local_inner_macros)] +macro_rules! impl_matrix_named_fields_shape_shim { + ( + ($($vector_info:tt),+), + $matrix_info:tt + ) => { + $crate::macro_repeated!(impl_matrix_named_fields_shape,$matrix_info,$($vector_info),+); + } +} + +#[doc(hidden)] +#[macro_export(local_inner_macros)] +macro_rules! impl_matrix_named_fields { + ( + ($($matrix_info:tt),+), + $vector_infos:tt + ) => { + $crate::macro_repeated!(impl_matrix_named_fields_shape_shim,$vector_infos,$($matrix_info),+); + } +} diff --git a/fixed_wide_vectors/src/macros/vector.rs b/fixed_wide_vectors/src/macros/vector.rs index 8b13789..fc28750 100644 --- a/fixed_wide_vectors/src/macros/vector.rs +++ b/fixed_wide_vectors/src/macros/vector.rs @@ -1 +1,25 @@ +#[doc(hidden)] +#[macro_export(local_inner_macros)] +macro_rules! impl_vector { + () => { + //$crate::impl_common!(); + } +} +#[doc(hidden)] +#[macro_export(local_inner_macros)] +macro_rules! impl_vector_named_fields { + ( $struct:ident, $size: expr ) => { + impl core::ops::Deref for Vector<$size,T>{ + type Target=$struct; + fn deref(&self)->&Self::Target{ + unsafe{core::mem::transmute(&self.array)} + } + } + impl core::ops::DerefMut for Vector<$size,T>{ + fn deref_mut(&mut self)->&mut Self::Target{ + unsafe{core::mem::transmute(&mut self.array)} + } + } + } +} diff --git a/fixed_wide_vectors/src/matrix.rs b/fixed_wide_vectors/src/matrix.rs index 41579df..331424b 100644 --- a/fixed_wide_vectors/src/matrix.rs +++ b/fixed_wide_vectors/src/matrix.rs @@ -1,35 +1,8 @@ -use crate::{Vector2,Vector3,Vector4}; - -pub struct Matrix2 { - pub x_axis: T, - pub y_axis: T, -} -pub struct Matrix3 { - pub x_axis: T, - pub y_axis: T, - pub z_axis: T, -} -pub struct Matrix4 { - pub x_axis: T, - pub y_axis: T, - pub z_axis: T, - pub w_axis: T, +pub struct Matrix{ + pub(crate) array:[[T;Y];X], } -crate::impl_matrix_named_fields!( - //outer struct - ( - (Matrix2 { x_axis, y_axis }, 2), - (Matrix3 { x_axis, y_axis, z_axis }, 3), - (Matrix4 { x_axis, y_axis, z_axis, w_axis }, 4) - ), - //inner struct - ( - (Vector2 { x, y }, 2), - (Vector3 { x, y, z }, 3), - (Vector4 { x, y, z, w }, 4) - ) -); +crate::impl_matrix!(); //Special case 3x3 matrix operations because I cba to write macros for the arbitrary cases -crate::impl_matrix_3x3!(); +//crate::impl_matrix_3x3!(); diff --git a/fixed_wide_vectors/src/named.rs b/fixed_wide_vectors/src/named.rs new file mode 100644 index 0000000..f490ee9 --- /dev/null +++ b/fixed_wide_vectors/src/named.rs @@ -0,0 +1,59 @@ +use crate::vector::Vector; +use crate::matrix::Matrix; + +#[repr(C)] +pub struct Vector2 { + pub x: T, + pub y: T, +} +#[repr(C)] +pub struct Vector3 { + pub x: T, + pub y: T, + pub z: T, +} +#[repr(C)] +pub struct Vector4 { + pub x: T, + pub y: T, + pub z: T, + pub w: T, +} + +crate::impl_vector_named_fields!(Vector2, 2); +crate::impl_vector_named_fields!(Vector3, 3); +crate::impl_vector_named_fields!(Vector4, 4); + +#[repr(C)] +pub struct Matrix2 { + pub x_axis: T, + pub y_axis: T, +} +#[repr(C)] +pub struct Matrix3 { + pub x_axis: T, + pub y_axis: T, + pub z_axis: T, +} +#[repr(C)] +pub struct Matrix4 { + pub x_axis: T, + pub y_axis: T, + pub z_axis: T, + pub w_axis: T, +} + +crate::impl_matrix_named_fields!( + //outer struct + ( + (Matrix2, 2), + (Matrix3, 3), + (Matrix4, 4) + ), + //inner struct + ( + (Vector2, 2), + (Vector3, 3), + (Vector4, 4) + ) +); diff --git a/fixed_wide_vectors/src/tests/fixed_wide.rs b/fixed_wide_vectors/src/tests/fixed_wide.rs index 1f87fb0..b5cecd3 100644 --- a/fixed_wide_vectors/src/tests/fixed_wide.rs +++ b/fixed_wide_vectors/src/tests/fixed_wide.rs @@ -1,4 +1,4 @@ -use crate::{Vector2,Vector3,Vector4,Matrix3,Matrix4}; +use crate::types::{Vector2,Vector3,Vector4,Matrix3,Matrix4}; type Planar64=fixed_wide::types::I32F32; type Planar64Wide1=fixed_wide::types::I64F64; diff --git a/fixed_wide_vectors/src/types.rs b/fixed_wide_vectors/src/types.rs new file mode 100644 index 0000000..6abf17f --- /dev/null +++ b/fixed_wide_vectors/src/types.rs @@ -0,0 +1,18 @@ +use crate::vector::Vector; +use crate::matrix::Matrix; + +pub type Vector2=Vector<2,T>; +pub type Vector3=Vector<3,T>; +pub type Vector4=Vector<4,T>; + +pub type Matrix2=Matrix<2,2,T>; +pub type Matrix2x3=Matrix<2,3,T>; +pub type Matrix2x4=Matrix<2,4,T>; + +pub type Matrix3x2=Matrix<3,2,T>; +pub type Matrix3=Matrix<3,3,T>; +pub type Matrix3x4=Matrix<3,4,T>; + +pub type Matrix4x2=Matrix<4,2,T>; +pub type Matrix4x3=Matrix<4,3,T>; +pub type Matrix4=Matrix<4,4,T>; diff --git a/fixed_wide_vectors/src/vector.rs b/fixed_wide_vectors/src/vector.rs index 12ed55a..3d3e956 100644 --- a/fixed_wide_vectors/src/vector.rs +++ b/fixed_wide_vectors/src/vector.rs @@ -1,24 +1,8 @@ -pub struct Vector2 { - pub x: T, - pub y: T, +pub struct Vector{ + pub(crate) array:[T;N], } -pub struct Vector3 { - pub x: T, - pub y: T, - pub z: T, -} - -pub struct Vector4 { - pub x: T, - pub y: T, - pub z: T, - pub w: T, -} - -crate::impl_vector_named_fields!(Vector2 { x, y }, 2); -crate::impl_vector_named_fields!(Vector3 { x, y, z }, 3); -crate::impl_vector_named_fields!(Vector4 { x, y, z, w }, 4); +crate::impl_vector!(); //cross product -crate::impl_vector_3!(); +//crate::impl_vector_3!(); From 56b781fcb87ee8401b34dc18dd0a04de5b86fd86 Mon Sep 17 00:00:00 2001 From: Quaternions Date: Thu, 5 Sep 2024 13:52:54 -0700 Subject: [PATCH 133/227] we build --- fixed_wide_vectors/src/macros/matrix.rs | 6 +++++- fixed_wide_vectors/src/macros/vector.rs | 13 ++++++++++++- 2 files changed, 17 insertions(+), 2 deletions(-) diff --git a/fixed_wide_vectors/src/macros/matrix.rs b/fixed_wide_vectors/src/macros/matrix.rs index 518315b..71ec8e7 100644 --- a/fixed_wide_vectors/src/macros/matrix.rs +++ b/fixed_wide_vectors/src/macros/matrix.rs @@ -2,7 +2,11 @@ #[macro_export(local_inner_macros)] macro_rules! impl_matrix { () => { - //$crate::impl_common!(); + impl Matrix{ + pub const fn new(array:[[T;Y];X])->Self{ + Self{array} + } + } } } diff --git a/fixed_wide_vectors/src/macros/vector.rs b/fixed_wide_vectors/src/macros/vector.rs index fc28750..8a0fe4e 100644 --- a/fixed_wide_vectors/src/macros/vector.rs +++ b/fixed_wide_vectors/src/macros/vector.rs @@ -2,7 +2,18 @@ #[macro_export(local_inner_macros)] macro_rules! impl_vector { () => { - //$crate::impl_common!(); + impl Vector{ + pub const fn new(array:[T;N])->Self{ + Self{array} + } + } + impl Vector{ + pub const fn from_value(value:T)->Self{ + Self{ + array:[value;N] + } + } + } } } From 990a92346362f0b338bfd062812fc9caf99b6ddb Mon Sep 17 00:00:00 2001 From: Quaternions Date: Thu, 5 Sep 2024 13:53:03 -0700 Subject: [PATCH 134/227] fixup tests --- fixed_wide_vectors/src/tests/fixed_wide.rs | 52 +++++++++++----------- 1 file changed, 26 insertions(+), 26 deletions(-) diff --git a/fixed_wide_vectors/src/tests/fixed_wide.rs b/fixed_wide_vectors/src/tests/fixed_wide.rs index b5cecd3..7dabd1d 100644 --- a/fixed_wide_vectors/src/tests/fixed_wide.rs +++ b/fixed_wide_vectors/src/tests/fixed_wide.rs @@ -1,4 +1,4 @@ -use crate::types::{Vector2,Vector3,Vector4,Matrix3,Matrix4}; +use crate::types::{Matrix3,Matrix3x2,Matrix3x4,Matrix4x2,Vector3}; type Planar64=fixed_wide::types::I32F32; type Planar64Wide1=fixed_wide::types::I64F64; @@ -37,16 +37,16 @@ fn wide_vec3_length_squared(){ #[test] fn wide_matrix_dot(){ - let lhs=Matrix3::from([ - Vector4::from([Planar64::from(1),Planar64::from(2),Planar64::from(3),Planar64::from(4)]), - Vector4::from([Planar64::from(5),Planar64::from(6),Planar64::from(7),Planar64::from(8)]), - Vector4::from([Planar64::from(9),Planar64::from(10),Planar64::from(11),Planar64::from(12)]), + let lhs=Matrix3x4::new([ + [Planar64::from(1),Planar64::from(2),Planar64::from(3),Planar64::from(4)], + [Planar64::from(5),Planar64::from(6),Planar64::from(7),Planar64::from(8)], + [Planar64::from(9),Planar64::from(10),Planar64::from(11),Planar64::from(12)], ]); - let rhs=Matrix4::from([ - Vector2::from([Planar64::from(1),Planar64::from(2)]), - Vector2::from([Planar64::from(3),Planar64::from(4)]), - Vector2::from([Planar64::from(5),Planar64::from(6)]), - Vector2::from([Planar64::from(7),Planar64::from(8)]), + let rhs=Matrix4x2::new([ + [Planar64::from(1),Planar64::from(2)], + [Planar64::from(3),Planar64::from(4)], + [Planar64::from(5),Planar64::from(6)], + [Planar64::from(7),Planar64::from(8)], ]); // Mat3.dot(Mat4) -> Mat3 let m_dot=lhs.wide_dot_3x4_4x2_1_1(rhs); @@ -54,20 +54,20 @@ fn wide_matrix_dot(){ //Out[1]= {{50, 60}, {114, 140}, {178, 220}} assert_eq!( m_dot, - Matrix3::from([ - Vector2::from([Planar64Wide1::from(50),Planar64Wide1::from(60)]), - Vector2::from([Planar64Wide1::from(114),Planar64Wide1::from(140)]), - Vector2::from([Planar64Wide1::from(178),Planar64Wide1::from(220)]), + Matrix3x2::new([ + [Planar64Wide1::from(50),Planar64Wide1::from(60)], + [Planar64Wide1::from(114),Planar64Wide1::from(140)], + [Planar64Wide1::from(178),Planar64Wide1::from(220)], ]) ); } #[test] fn wide_matrix_det(){ - let m=Matrix3::from([ - Vector3::from([Planar64::from(1),Planar64::from(2),Planar64::from(3)]), - Vector3::from([Planar64::from(4),Planar64::from(5),Planar64::from(7)]), - Vector3::from([Planar64::from(6),Planar64::from(8),Planar64::from(9)]), + let m=Matrix3::new([ + [Planar64::from(1),Planar64::from(2),Planar64::from(3)], + [Planar64::from(4),Planar64::from(5),Planar64::from(7)], + [Planar64::from(6),Planar64::from(8),Planar64::from(9)], ]); // In[2]:= Det[{{1, 2, 3}, {4, 5, 7}, {6, 8, 9}}] // Out[2]= 7 @@ -76,19 +76,19 @@ fn wide_matrix_det(){ #[test] fn wide_matrix_adjugate(){ - let m=Matrix3::from([ - Vector3::from([Planar64::from(1),Planar64::from(2),Planar64::from(3)]), - Vector3::from([Planar64::from(4),Planar64::from(5),Planar64::from(7)]), - Vector3::from([Planar64::from(6),Planar64::from(8),Planar64::from(9)]), + let m=Matrix3::new([ + [Planar64::from(1),Planar64::from(2),Planar64::from(3)], + [Planar64::from(4),Planar64::from(5),Planar64::from(7)], + [Planar64::from(6),Planar64::from(8),Planar64::from(9)], ]); // In[6]:= Adjugate[{{1, 2, 3}, {4, 5, 7}, {6, 8, 9}}] // Out[6]= {{-11, 6, -1}, {6, -9, 5}, {2, 4, -3}} assert_eq!( m.wide_adjugate_3x3_1(), - Matrix3::from([ - Vector3::from([Planar64Wide1::from(-11),Planar64Wide1::from(6),Planar64Wide1::from(-1)]), - Vector3::from([Planar64Wide1::from(6),Planar64Wide1::from(-9),Planar64Wide1::from(5)]), - Vector3::from([Planar64Wide1::from(2),Planar64Wide1::from(4),Planar64Wide1::from(-3)]), + Matrix3::new([ + [Planar64Wide1::from(-11),Planar64Wide1::from(6),Planar64Wide1::from(-1)], + [Planar64Wide1::from(6),Planar64Wide1::from(-9),Planar64Wide1::from(5)], + [Planar64Wide1::from(2),Planar64Wide1::from(4),Planar64Wide1::from(-3)], ]) ); } From c3620810037cbcf97c337a4908347bf3e56dfaf3 Mon Sep 17 00:00:00 2001 From: Quaternions Date: Thu, 5 Sep 2024 15:41:39 -0700 Subject: [PATCH 135/227] implement a bunch of stuff --- fixed_wide_vectors/src/macros/matrix.rs | 46 +++++++++++ fixed_wide_vectors/src/macros/vector.rs | 100 ++++++++++++++++++++++++ fixed_wide_vectors/src/matrix.rs | 1 + fixed_wide_vectors/src/vector.rs | 1 + 4 files changed, 148 insertions(+) diff --git a/fixed_wide_vectors/src/macros/matrix.rs b/fixed_wide_vectors/src/macros/matrix.rs index 71ec8e7..05a213f 100644 --- a/fixed_wide_vectors/src/macros/matrix.rs +++ b/fixed_wide_vectors/src/macros/matrix.rs @@ -3,9 +3,55 @@ macro_rules! impl_matrix { () => { impl Matrix{ + #[inline(always)] pub const fn new(array:[[T;Y];X])->Self{ Self{array} } + #[inline(always)] + pub fn to_array(self)->[[T;Y];X]{ + self.array + } + #[inline] + pub fn map(self,f:F)->Matrix + where + F:Fn(T)->U + { + Matrix{ + array:self.array.map(|inner|inner.map(&f)), + } + } + } + impl Matrix + where + T:Copy + { + pub const fn from_value(value:T)->Self{ + Self{ + array:[[value;Y];X] + } + } + } + + impl PartialEq for Matrix{ + fn eq(&self,other:&Self)->bool{ + self.array==other.array + } + } + + impl Eq for Matrix{} + + impl core::hash::Hash for Matrix{ + fn hash(&self,state:&mut H){ + self.array.hash(state); + } + } + + impl Default for Matrix{ + fn default()->Self{ + Self{ + array:core::array::from_fn(|_|core::array::from_fn(|_|Default::default())) + } + } } } } diff --git a/fixed_wide_vectors/src/macros/vector.rs b/fixed_wide_vectors/src/macros/vector.rs index 8a0fe4e..24fe199 100644 --- a/fixed_wide_vectors/src/macros/vector.rs +++ b/fixed_wide_vectors/src/macros/vector.rs @@ -3,17 +3,117 @@ macro_rules! impl_vector { () => { impl Vector{ + #[inline(always)] pub const fn new(array:[T;N])->Self{ Self{array} } + #[inline(always)] + pub fn to_array(self)->[T;N]{ + self.array + } + #[inline] + pub fn map(self,f:F)->Vector + where + F:Fn(T)->U + { + Vector{ + array:self.array.map(f), + } + } + #[inline] + pub fn map_zip(self,other:Vector,f:F)->Vector + where + F:Fn((T,U))->V, + { + let mut iter=self.array.into_iter().zip(other.array); + Vector{ + array:core::array::from_fn(|_|f(iter.next().unwrap())), + } + } } impl Vector{ + #[inline(always)] pub const fn from_value(value:T)->Self{ Self{ array:[value;N] } } } + + impl PartialEq for Vector{ + fn eq(&self,other:&Self)->bool{ + self.array==other.array + } + } + + impl Eq for Vector{} + + impl core::hash::Hash for Vector{ + fn hash(&self,state:&mut H){ + self.array.hash(state); + } + } + + impl Default for Vector{ + fn default()->Self{ + Self{ + array:core::array::from_fn(|_|Default::default()) + } + } + } + + impl Vector{ + #[inline] + pub fn min(self,rhs:Self)->Self{ + self.map_zip(rhs,|(a,b)|a.min(b)) + } + #[inline] + pub fn max(self,rhs:Self)->Self{ + self.map_zip(rhs,|(a,b)|a.max(b)) + } + #[inline] + pub fn cmp(self,rhs:Self)->Vector{ + self.map_zip(rhs,|(a,b)|a.cmp(&b)) + } + #[inline] + pub fn lt(self,rhs:Self)->Vector{ + self.map_zip(rhs,|(a,b)|a.lt(&b)) + } + #[inline] + pub fn gt(self,rhs:Self)->Vector{ + self.map_zip(rhs,|(a,b)|a.gt(&b)) + } + #[inline] + pub fn ge(self,rhs:Self)->Vector{ + self.map_zip(rhs,|(a,b)|a.ge(&b)) + } + #[inline] + pub fn le(self,rhs:Self)->Vector{ + self.map_zip(rhs,|(a,b)|a.le(&b)) + } + } + + impl Vector{ + const ALL:[bool;N]=[true;N]; + const NONE:[bool;N]=[false;N]; + #[inline] + pub fn all(&self)->bool{ + core::matches!(self.array,ALL) + } + #[inline] + pub fn any(&self)->bool{ + !core::matches!(self.array,NONE) + } + } + + impl> core::ops::Neg for Vector{ + type Output=Self; + fn neg(self)->Self::Output{ + Self{ + array:self.array.map(|t|-t) + } + } + } } } diff --git a/fixed_wide_vectors/src/matrix.rs b/fixed_wide_vectors/src/matrix.rs index 331424b..a4ec526 100644 --- a/fixed_wide_vectors/src/matrix.rs +++ b/fixed_wide_vectors/src/matrix.rs @@ -1,3 +1,4 @@ +#[derive(Clone,Copy)] pub struct Matrix{ pub(crate) array:[[T;Y];X], } diff --git a/fixed_wide_vectors/src/vector.rs b/fixed_wide_vectors/src/vector.rs index 3d3e956..b706670 100644 --- a/fixed_wide_vectors/src/vector.rs +++ b/fixed_wide_vectors/src/vector.rs @@ -1,3 +1,4 @@ +#[derive(Clone,Copy)] pub struct Vector{ pub(crate) array:[T;N], } From f4d28dd3c3f46627085126d9251c0c94f749b12b Mon Sep 17 00:00:00 2001 From: Quaternions Date: Thu, 5 Sep 2024 15:43:02 -0700 Subject: [PATCH 136/227] use derive macros --- fixed_wide_vectors/src/macros/matrix.rs | 14 -------------- fixed_wide_vectors/src/macros/vector.rs | 14 -------------- fixed_wide_vectors/src/matrix.rs | 2 +- fixed_wide_vectors/src/vector.rs | 2 +- 4 files changed, 2 insertions(+), 30 deletions(-) diff --git a/fixed_wide_vectors/src/macros/matrix.rs b/fixed_wide_vectors/src/macros/matrix.rs index 05a213f..1964dff 100644 --- a/fixed_wide_vectors/src/macros/matrix.rs +++ b/fixed_wide_vectors/src/macros/matrix.rs @@ -32,20 +32,6 @@ macro_rules! impl_matrix { } } - impl PartialEq for Matrix{ - fn eq(&self,other:&Self)->bool{ - self.array==other.array - } - } - - impl Eq for Matrix{} - - impl core::hash::Hash for Matrix{ - fn hash(&self,state:&mut H){ - self.array.hash(state); - } - } - impl Default for Matrix{ fn default()->Self{ Self{ diff --git a/fixed_wide_vectors/src/macros/vector.rs b/fixed_wide_vectors/src/macros/vector.rs index 24fe199..2ea5dfb 100644 --- a/fixed_wide_vectors/src/macros/vector.rs +++ b/fixed_wide_vectors/src/macros/vector.rs @@ -40,20 +40,6 @@ macro_rules! impl_vector { } } - impl PartialEq for Vector{ - fn eq(&self,other:&Self)->bool{ - self.array==other.array - } - } - - impl Eq for Vector{} - - impl core::hash::Hash for Vector{ - fn hash(&self,state:&mut H){ - self.array.hash(state); - } - } - impl Default for Vector{ fn default()->Self{ Self{ diff --git a/fixed_wide_vectors/src/matrix.rs b/fixed_wide_vectors/src/matrix.rs index a4ec526..4ca1236 100644 --- a/fixed_wide_vectors/src/matrix.rs +++ b/fixed_wide_vectors/src/matrix.rs @@ -1,4 +1,4 @@ -#[derive(Clone,Copy)] +#[derive(Clone,Copy,Hash,Eq,PartialEq)] pub struct Matrix{ pub(crate) array:[[T;Y];X], } diff --git a/fixed_wide_vectors/src/vector.rs b/fixed_wide_vectors/src/vector.rs index b706670..ffea1f0 100644 --- a/fixed_wide_vectors/src/vector.rs +++ b/fixed_wide_vectors/src/vector.rs @@ -1,4 +1,4 @@ -#[derive(Clone,Copy)] +#[derive(Clone,Copy,Hash,Eq,PartialEq)] pub struct Vector{ pub(crate) array:[T;N], } From 345d5737a2e9becda5b61cf9338a479b6a821f7b Mon Sep 17 00:00:00 2001 From: Quaternions Date: Thu, 5 Sep 2024 15:56:35 -0700 Subject: [PATCH 137/227] more generic Neg operator --- fixed_wide_vectors/src/macros/vector.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/fixed_wide_vectors/src/macros/vector.rs b/fixed_wide_vectors/src/macros/vector.rs index 2ea5dfb..732dbff 100644 --- a/fixed_wide_vectors/src/macros/vector.rs +++ b/fixed_wide_vectors/src/macros/vector.rs @@ -92,10 +92,10 @@ macro_rules! impl_vector { } } - impl> core::ops::Neg for Vector{ - type Output=Self; + impl,V> core::ops::Neg for Vector{ + type Output=Vector; fn neg(self)->Self::Output{ - Self{ + Vector{ array:self.array.map(|t|-t) } } From a0da6873c14d0914e1cc897912def0f8a8f6514b Mon Sep 17 00:00:00 2001 From: Quaternions Date: Thu, 5 Sep 2024 15:56:44 -0700 Subject: [PATCH 138/227] vector operators --- fixed_wide_vectors/src/macros/vector.rs | 48 +++++++++++++++++++++++++ 1 file changed, 48 insertions(+) diff --git a/fixed_wide_vectors/src/macros/vector.rs b/fixed_wide_vectors/src/macros/vector.rs index 732dbff..2596138 100644 --- a/fixed_wide_vectors/src/macros/vector.rs +++ b/fixed_wide_vectors/src/macros/vector.rs @@ -100,6 +100,54 @@ macro_rules! impl_vector { } } } + + // Impl arithmetic operators + $crate::impl_vector_assign_operator!(AddAssign, add_assign ); + $crate::impl_vector_operator!(Add, add ); + $crate::impl_vector_assign_operator!(SubAssign, sub_assign ); + $crate::impl_vector_operator!(Sub, sub ); + $crate::impl_vector_assign_operator!(MulAssign, mul_assign ); + $crate::impl_vector_operator!(Mul, mul ); + $crate::impl_vector_assign_operator!(DivAssign, div_assign ); + $crate::impl_vector_operator!(Div, div ); + $crate::impl_vector_assign_operator!(RemAssign, rem_assign ); + $crate::impl_vector_operator!(Rem, rem ); + + // Impl bitwise operators + $crate::impl_vector_assign_operator!(BitAndAssign, bitand_assign ); + $crate::impl_vector_operator!(BitAnd, bitand ); + $crate::impl_vector_assign_operator!(BitOrAssign, bitor_assign ); + $crate::impl_vector_operator!(BitOr, bitor ); + $crate::impl_vector_assign_operator!(BitXorAssign, bitxor_assign ); + $crate::impl_vector_operator!(BitXor, bitxor ); + + // Impl floating-point based methods + //#[cfg(feature="fixed_wide")] + //$crate::impl_wide_vector_operations!( $struct { $($field), + }, $size ); + } +} +#[doc(hidden)] +#[macro_export(local_inner_macros)] +macro_rules! impl_vector_operator { + ($trait: ident, $method: ident ) => { + impl,U,V> core::ops::$trait> for Vector{ + type Output=Vector; + fn $method(self,rhs:Vector)->Self::Output{ + self.map_zip(rhs,|(a,b)|a.$method(b)) + } + } + } +} +#[doc(hidden)] +#[macro_export(local_inner_macros)] +macro_rules! impl_vector_assign_operator { + ($trait: ident, $method: ident ) => { + impl,U> core::ops::$trait> for Vector{ + fn $method(&mut self,rhs:Vector){ + self.array.iter_mut().zip(rhs.array) + .for_each(|(a,b)|a.$method(b)) + } + } } } From 5cdd2c3ee1021a2ba5be38e130e3b78f3c3174cd Mon Sep 17 00:00:00 2001 From: Quaternions Date: Thu, 5 Sep 2024 16:05:47 -0700 Subject: [PATCH 139/227] must be less generic to avoid conflict with convenience operators --- fixed_wide_vectors/src/macros/vector.rs | 22 +++++++++++++++++----- 1 file changed, 17 insertions(+), 5 deletions(-) diff --git a/fixed_wide_vectors/src/macros/vector.rs b/fixed_wide_vectors/src/macros/vector.rs index 2596138..d8766be 100644 --- a/fixed_wide_vectors/src/macros/vector.rs +++ b/fixed_wide_vectors/src/macros/vector.rs @@ -130,24 +130,36 @@ macro_rules! impl_vector { #[macro_export(local_inner_macros)] macro_rules! impl_vector_operator { ($trait: ident, $method: ident ) => { - impl,U,V> core::ops::$trait> for Vector{ - type Output=Vector; - fn $method(self,rhs:Vector)->Self::Output{ + impl> core::ops::$trait for Vector{ + type Output=Self; + fn $method(self,rhs:Self)->Self::Output{ self.map_zip(rhs,|(a,b)|a.$method(b)) } } + impl+Copy> core::ops::$trait for Vector{ + type Output=Self; + fn $method(self,rhs:T)->Self::Output{ + self.map(|t|t.$method(rhs)) + } + } } } #[doc(hidden)] #[macro_export(local_inner_macros)] macro_rules! impl_vector_assign_operator { ($trait: ident, $method: ident ) => { - impl,U> core::ops::$trait> for Vector{ - fn $method(&mut self,rhs:Vector){ + impl core::ops::$trait for Vector{ + fn $method(&mut self,rhs:Self){ self.array.iter_mut().zip(rhs.array) .for_each(|(a,b)|a.$method(b)) } } + impl core::ops::$trait for Vector{ + fn $method(&mut self,rhs:T){ + self.array.iter_mut() + .for_each(|t|t.$method(rhs)) + } + } } } From 488a6b64963ccc5576b2ea3a77393c16bfc96b34 Mon Sep 17 00:00:00 2001 From: Quaternions Date: Thu, 5 Sep 2024 16:06:00 -0700 Subject: [PATCH 140/227] fix vector bool code --- fixed_wide_vectors/src/macros/vector.rs | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/fixed_wide_vectors/src/macros/vector.rs b/fixed_wide_vectors/src/macros/vector.rs index d8766be..c542dfe 100644 --- a/fixed_wide_vectors/src/macros/vector.rs +++ b/fixed_wide_vectors/src/macros/vector.rs @@ -80,15 +80,13 @@ macro_rules! impl_vector { } impl Vector{ - const ALL:[bool;N]=[true;N]; - const NONE:[bool;N]=[false;N]; #[inline] pub fn all(&self)->bool{ - core::matches!(self.array,ALL) + self.array==[true;N] } #[inline] pub fn any(&self)->bool{ - !core::matches!(self.array,NONE) + self.array!=[false;N] } } From e375173625c31e5fb2e37e61c773c802e6e8a539 Mon Sep 17 00:00:00 2001 From: Quaternions Date: Thu, 5 Sep 2024 16:17:47 -0700 Subject: [PATCH 141/227] keep generic operators and only implement i64 convenience operator --- fixed_wide_vectors/src/macros/vector.rs | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/fixed_wide_vectors/src/macros/vector.rs b/fixed_wide_vectors/src/macros/vector.rs index c542dfe..6b24583 100644 --- a/fixed_wide_vectors/src/macros/vector.rs +++ b/fixed_wide_vectors/src/macros/vector.rs @@ -128,15 +128,15 @@ macro_rules! impl_vector { #[macro_export(local_inner_macros)] macro_rules! impl_vector_operator { ($trait: ident, $method: ident ) => { - impl> core::ops::$trait for Vector{ - type Output=Self; - fn $method(self,rhs:Self)->Self::Output{ + impl,U,V> core::ops::$trait> for Vector{ + type Output=Vector; + fn $method(self,rhs:Vector)->Self::Output{ self.map_zip(rhs,|(a,b)|a.$method(b)) } } - impl+Copy> core::ops::$trait for Vector{ + impl> core::ops::$trait for Vector{ type Output=Self; - fn $method(self,rhs:T)->Self::Output{ + fn $method(self,rhs:i64)->Self::Output{ self.map(|t|t.$method(rhs)) } } @@ -146,14 +146,14 @@ macro_rules! impl_vector_operator { #[macro_export(local_inner_macros)] macro_rules! impl_vector_assign_operator { ($trait: ident, $method: ident ) => { - impl core::ops::$trait for Vector{ - fn $method(&mut self,rhs:Self){ + impl,U> core::ops::$trait> for Vector{ + fn $method(&mut self,rhs:Vector){ self.array.iter_mut().zip(rhs.array) .for_each(|(a,b)|a.$method(b)) } } - impl core::ops::$trait for Vector{ - fn $method(&mut self,rhs:T){ + impl> core::ops::$trait for Vector{ + fn $method(&mut self,rhs:i64){ self.array.iter_mut() .for_each(|t|t.$method(rhs)) } From 41cdd03b1b1abdc3cb1340afb193708ebc104577 Mon Sep 17 00:00:00 2001 From: Quaternions Date: Thu, 5 Sep 2024 16:32:19 -0700 Subject: [PATCH 142/227] wip fixed wide --- fixed_wide_vectors/Cargo.lock | 1 + fixed_wide_vectors/Cargo.toml | 3 +- fixed_wide_vectors/src/macros/fixed_wide.rs | 37 ++++++++++++++++++++- 3 files changed, 39 insertions(+), 2 deletions(-) diff --git a/fixed_wide_vectors/Cargo.lock b/fixed_wide_vectors/Cargo.lock index 5bb2156..7c320dd 100644 --- a/fixed_wide_vectors/Cargo.lock +++ b/fixed_wide_vectors/Cargo.lock @@ -28,6 +28,7 @@ name = "fixed_wide_vectors" version = "0.1.0" dependencies = [ "fixed_wide", + "paste", ] [[package]] diff --git a/fixed_wide_vectors/Cargo.toml b/fixed_wide_vectors/Cargo.toml index 556dee1..ce607be 100644 --- a/fixed_wide_vectors/Cargo.toml +++ b/fixed_wide_vectors/Cargo.toml @@ -6,7 +6,8 @@ edition = "2021" [features] default=["fixed_wide","named-fields"] named-fields=[] -fixed_wide=["dep:fixed_wide"] +fixed_wide=["dep:fixed_wide","dep:paste"] [dependencies] fixed_wide = { version = "0.1.0", path = "../fixed_wide", optional = true } +paste = { version = "1.0.15", optional = true } diff --git a/fixed_wide_vectors/src/macros/fixed_wide.rs b/fixed_wide_vectors/src/macros/fixed_wide.rs index 8b13789..dabb773 100644 --- a/fixed_wide_vectors/src/macros/fixed_wide.rs +++ b/fixed_wide_vectors/src/macros/fixed_wide.rs @@ -1 +1,36 @@ - +#[doc(hidden)] +#[macro_export(local_inner_macros)] +macro_rules! impl_wide_vector_operations_2arg_not_const_generic { + ( + ($lhs:expr, $rhs:expr) + ) => { + impl Vector>{ + paste::item!{ + #[inline] + pub fn [](self,rhs:Vector>)->Vector>{ + self.array.map_zip(|(a,b)|a.[](b)) + } + #[inline] + pub fn [](self,rhs:Vector>)->fixed_wide::fixed::Fixed<{$lhs+$rhs},{($lhs+$rhs)*32}>{ + self.array.into_iter().zip(rhs.array).map(|(a,b)|a.[](b)).sum() + } + } + } + } +} +#[doc(hidden)] +#[macro_export(local_inner_macros)] +macro_rules! impl_wide_vector_operations_1arg_not_const_generic { + ( + $n:expr + ) => { + impl $struct>{ + paste::item!{ + #[inline] + pub fn wide_length_squared(&self)->fixed_wide::fixed::Fixed<{$n*2},{$n*2*32}>{ + self.array.into_iter().map(|t|t.[](t)).sum() + } + } + } + }; +} From 504ff37c4758ea335f7de7315c4bb84c4bd69823 Mon Sep 17 00:00:00 2001 From: Quaternions Date: Thu, 5 Sep 2024 16:45:44 -0700 Subject: [PATCH 143/227] write a test --- fixed_wide_vectors/src/tests/tests.rs | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/fixed_wide_vectors/src/tests/tests.rs b/fixed_wide_vectors/src/tests/tests.rs index 8b13789..ed0d8d8 100644 --- a/fixed_wide_vectors/src/tests/tests.rs +++ b/fixed_wide_vectors/src/tests/tests.rs @@ -1 +1,9 @@ +use crate::types::Vector3; +#[test] +fn test_bool(){ + assert_eq!(Vector3::new([false,false,false]).any(),false); + assert_eq!(Vector3::new([false,false,true]).any(),true); + assert_eq!(Vector3::new([false,false,true]).all(),false); + assert_eq!(Vector3::new([true,true,true]).all(),true); +} From e95f675e91c522d059139570691cff39348ac30f Mon Sep 17 00:00:00 2001 From: Quaternions Date: Thu, 5 Sep 2024 16:53:30 -0700 Subject: [PATCH 144/227] test named fields --- fixed_wide_vectors/src/tests/mod.rs | 2 ++ fixed_wide_vectors/src/tests/named.rs | 30 +++++++++++++++++++++++++++ 2 files changed, 32 insertions(+) create mode 100644 fixed_wide_vectors/src/tests/named.rs diff --git a/fixed_wide_vectors/src/tests/mod.rs b/fixed_wide_vectors/src/tests/mod.rs index 67fb0b3..06e9ee5 100644 --- a/fixed_wide_vectors/src/tests/mod.rs +++ b/fixed_wide_vectors/src/tests/mod.rs @@ -1,5 +1,7 @@ mod tests; +#[cfg(feature="named-fields")] +mod named; #[cfg(feature="fixed_wide")] mod fixed_wide; diff --git a/fixed_wide_vectors/src/tests/named.rs b/fixed_wide_vectors/src/tests/named.rs new file mode 100644 index 0000000..04b0a08 --- /dev/null +++ b/fixed_wide_vectors/src/tests/named.rs @@ -0,0 +1,30 @@ +use crate::types::{Vector3,Matrix3}; + +#[test] +fn test_vector(){ + let mut v=Vector3::new([1,2,3]); + assert_eq!(v.x,1); + assert_eq!(v.y,2); + assert_eq!(v.z,3); + + v.x=5; + assert_eq!(v.x,5); + + v.y*=v.x; + assert_eq!(v.y,10); +} + + +#[test] +fn test_matrix(){ + let mut v=Matrix3::from_value(2); + assert_eq!(v.x_axis.x,2); + assert_eq!(v.y_axis.y,2); + assert_eq!(v.z_axis.z,2); + + v.x_axis.x=5; + assert_eq!(v.x_axis.x,5); + + v.y_axis.z*=v.x_axis.x; + assert_eq!(v.y_axis.z,10); +} From 1a6ece13121d5420cb037f978e3b98c13047df6c Mon Sep 17 00:00:00 2001 From: Quaternions Date: Thu, 5 Sep 2024 17:15:41 -0700 Subject: [PATCH 145/227] epic const generic array transpose verified that this loop unrolls on compiler explorer --- fixed_wide_vectors/src/macros/matrix.rs | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/fixed_wide_vectors/src/macros/matrix.rs b/fixed_wide_vectors/src/macros/matrix.rs index 1964dff..bba1e65 100644 --- a/fixed_wide_vectors/src/macros/matrix.rs +++ b/fixed_wide_vectors/src/macros/matrix.rs @@ -20,6 +20,18 @@ macro_rules! impl_matrix { array:self.array.map(|inner|inner.map(&f)), } } + #[inline] + pub fn transpose(self)->Matrix{ + //how did I think of this + let mut array_of_iterators=self.array.map(|axis|axis.into_iter()); + Matrix{ + array:core::array::from_fn(|_| + array_of_iterators.each_mut().map(|iter| + iter.next().unwrap() + ) + ) + } + } } impl Matrix where From 34450d6a133a9798cdf9f6de597add53b9935dac Mon Sep 17 00:00:00 2001 From: Quaternions Date: Thu, 5 Sep 2024 17:36:37 -0700 Subject: [PATCH 146/227] matrix multiplication --- fixed_wide_vectors/src/macros/matrix.rs | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/fixed_wide_vectors/src/macros/matrix.rs b/fixed_wide_vectors/src/macros/matrix.rs index bba1e65..73023db 100644 --- a/fixed_wide_vectors/src/macros/matrix.rs +++ b/fixed_wide_vectors/src/macros/matrix.rs @@ -32,6 +32,29 @@ macro_rules! impl_matrix { ) } } + #[inline] + // MatX.MatY = MatX + pub fn dot(self,rhs:Matrix)->Matrix + where + T:core::ops::Mul+Copy, + V:core::iter::Sum, + { + let mut array_of_iterators=rhs.array.map(|axis|axis.into_iter()); + Matrix{ + array:self.array.map(|axis| + core::array::from_fn(|_| + // axis dot product with transposed rhs array + axis.into_iter().zip( + array_of_iterators.each_mut().map(|iter| + iter.next().unwrap() + ) + ).map(|(a,b)| + a*b + ).sum() + ) + ) + } + } } impl Matrix where From 4d2aa0b2c8b9c1e878f6ee54cd2581b4a5f9b1a5 Mon Sep 17 00:00:00 2001 From: Quaternions Date: Thu, 5 Sep 2024 17:44:44 -0700 Subject: [PATCH 147/227] is this better? --- fixed_wide_vectors/src/macros/matrix.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/fixed_wide_vectors/src/macros/matrix.rs b/fixed_wide_vectors/src/macros/matrix.rs index 73023db..6123736 100644 --- a/fixed_wide_vectors/src/macros/matrix.rs +++ b/fixed_wide_vectors/src/macros/matrix.rs @@ -44,11 +44,11 @@ macro_rules! impl_matrix { array:self.array.map(|axis| core::array::from_fn(|_| // axis dot product with transposed rhs array - axis.into_iter().zip( + axis.iter().zip( array_of_iterators.each_mut().map(|iter| iter.next().unwrap() ) - ).map(|(a,b)| + ).map(|(&a,b)| a*b ).sum() ) From 2312ee27b786d5e16e0b37c862281f0793a84fbf Mon Sep 17 00:00:00 2001 From: Quaternions Date: Thu, 5 Sep 2024 17:47:28 -0700 Subject: [PATCH 148/227] test vector and matrix (TODO: Debug trait) --- fixed_wide_vectors/src/tests/tests.rs | 35 ++++++++++++++++++++++++++- 1 file changed, 34 insertions(+), 1 deletion(-) diff --git a/fixed_wide_vectors/src/tests/tests.rs b/fixed_wide_vectors/src/tests/tests.rs index ed0d8d8..a3530ea 100644 --- a/fixed_wide_vectors/src/tests/tests.rs +++ b/fixed_wide_vectors/src/tests/tests.rs @@ -1,4 +1,4 @@ -use crate::types::Vector3; +use crate::types::{Vector3,Matrix3x4,Matrix4x2,Matrix3x2}; #[test] fn test_bool(){ @@ -7,3 +7,36 @@ fn test_bool(){ assert_eq!(Vector3::new([false,false,true]).all(),false); assert_eq!(Vector3::new([true,true,true]).all(),true); } + +#[test] +fn test_arithmetic(){ + let a=Vector3::new([1,2,3]); + assert_eq!((a+a*2).array,Vector3::new([1*3,2*3,3*3]).array); +} + +#[test] +fn matrix_dot(){ + let lhs=Matrix3x4::new([ + [1.0,2.0,3.0,4.0], + [5.0,6.0,7.0,8.0], + [9.0,1.0,1.0,1.0], + ]); + let rhs=Matrix4x2::new([ + [1.0,2.0], + [3.0,4.0], + [5.0,6.0], + [7.0,8.0], + ]); + // Mat3.dot(Mat4) -> Mat3 + let m_dot=lhs.dot(rhs); + //In[1]:= {{1, 2, 3, 4}, {5, 6, 7, 8}, {9, 10, 11, 12}} . {{1, 2}, {3, 4}, {5, 6}, {7, 8}} + //Out[1]= {{50, 60}, {114, 140}, {178, 220}} + assert_eq!( + m_dot.array, + Matrix3x2::new([ + [50.0,60.0], + [114.0,140.0], + [178.0,220.0], + ]).array + ); +} From 607706ee2af6e35f60f4880cbe04f83d6d9d2dc4 Mon Sep 17 00:00:00 2001 From: Quaternions Date: Thu, 5 Sep 2024 17:56:04 -0700 Subject: [PATCH 149/227] nope --- fixed_wide_vectors/src/macros/matrix.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/fixed_wide_vectors/src/macros/matrix.rs b/fixed_wide_vectors/src/macros/matrix.rs index 6123736..0c1c371 100644 --- a/fixed_wide_vectors/src/macros/matrix.rs +++ b/fixed_wide_vectors/src/macros/matrix.rs @@ -38,8 +38,9 @@ macro_rules! impl_matrix { where T:core::ops::Mul+Copy, V:core::iter::Sum, + U:Clone, { - let mut array_of_iterators=rhs.array.map(|axis|axis.into_iter()); + let mut array_of_iterators=rhs.array.map(|axis|axis.into_iter().cycle()); Matrix{ array:self.array.map(|axis| core::array::from_fn(|_| From 5cad8637cd9a794a0d627e2e883ffc6a252f53cc Mon Sep 17 00:00:00 2001 From: Quaternions Date: Fri, 6 Sep 2024 10:36:24 -0700 Subject: [PATCH 150/227] tweak dot --- fixed_wide_vectors/src/macros/matrix.rs | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/fixed_wide_vectors/src/macros/matrix.rs b/fixed_wide_vectors/src/macros/matrix.rs index 0c1c371..cde4330 100644 --- a/fixed_wide_vectors/src/macros/matrix.rs +++ b/fixed_wide_vectors/src/macros/matrix.rs @@ -38,7 +38,7 @@ macro_rules! impl_matrix { where T:core::ops::Mul+Copy, V:core::iter::Sum, - U:Clone, + U:Copy, { let mut array_of_iterators=rhs.array.map(|axis|axis.into_iter().cycle()); Matrix{ @@ -46,11 +46,9 @@ macro_rules! impl_matrix { core::array::from_fn(|_| // axis dot product with transposed rhs array axis.iter().zip( - array_of_iterators.each_mut().map(|iter| - iter.next().unwrap() - ) - ).map(|(&a,b)| - a*b + array_of_iterators.iter_mut() + ).map(|(&lhs_value,rhs_iter)| + lhs_value*rhs_iter.next().unwrap() ).sum() ) ) From d5bd82761abf3bdc5afb7154f2b3c0307b4444ab Mon Sep 17 00:00:00 2001 From: Quaternions Date: Fri, 6 Sep 2024 10:36:34 -0700 Subject: [PATCH 151/227] fix dot test --- fixed_wide_vectors/src/tests/tests.rs | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/fixed_wide_vectors/src/tests/tests.rs b/fixed_wide_vectors/src/tests/tests.rs index a3530ea..91336ca 100644 --- a/fixed_wide_vectors/src/tests/tests.rs +++ b/fixed_wide_vectors/src/tests/tests.rs @@ -16,16 +16,17 @@ fn test_arithmetic(){ #[test] fn matrix_dot(){ + + let rhs=Matrix4x2::new([ + [ 1.0, 2.0], + [ 3.0, 4.0], + [ 5.0, 6.0], + [ 7.0, 8.0], + ]); let lhs=Matrix3x4::new([ - [1.0,2.0,3.0,4.0], - [5.0,6.0,7.0,8.0], - [9.0,1.0,1.0,1.0], - ]); - let rhs=Matrix4x2::new([ - [1.0,2.0], - [3.0,4.0], - [5.0,6.0], - [7.0,8.0], + [1.0, 2.0, 3.0, 4.0],// [ 50.0, 60.0], + [5.0, 6.0, 7.0, 8.0],// [114.0,140.0], + [9.0,10.0,11.0,12.0],// [178.0,220.0], ]); // Mat3.dot(Mat4) -> Mat3 let m_dot=lhs.dot(rhs); From 4a1eff40dad4c100ba0f8afbd4725b327ca09212 Mon Sep 17 00:00:00 2001 From: Quaternions Date: Fri, 6 Sep 2024 10:44:30 -0700 Subject: [PATCH 152/227] matrix multiplication ascii art --- fixed_wide_vectors/src/tests/tests.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/fixed_wide_vectors/src/tests/tests.rs b/fixed_wide_vectors/src/tests/tests.rs index 91336ca..1c658dc 100644 --- a/fixed_wide_vectors/src/tests/tests.rs +++ b/fixed_wide_vectors/src/tests/tests.rs @@ -17,13 +17,13 @@ fn test_arithmetic(){ #[test] fn matrix_dot(){ - let rhs=Matrix4x2::new([ + let rhs=Matrix4x2::new([ [ 1.0, 2.0], [ 3.0, 4.0], [ 5.0, 6.0], [ 7.0, 8.0], - ]); - let lhs=Matrix3x4::new([ + ]); // | | | + let lhs=Matrix3x4::new([ // | | | [1.0, 2.0, 3.0, 4.0],// [ 50.0, 60.0], [5.0, 6.0, 7.0, 8.0],// [114.0,140.0], [9.0,10.0,11.0,12.0],// [178.0,220.0], From dae72d73d5ad0538570c7e9eb7fc4ede0a3eb2d6 Mon Sep 17 00:00:00 2001 From: Quaternions Date: Fri, 6 Sep 2024 10:52:17 -0700 Subject: [PATCH 153/227] convert to row-major --- fixed_wide_vectors/src/macros/matrix.rs | 10 +++++----- fixed_wide_vectors/src/matrix.rs | 2 +- fixed_wide_vectors/src/tests/tests.rs | 8 ++++---- 3 files changed, 10 insertions(+), 10 deletions(-) diff --git a/fixed_wide_vectors/src/macros/matrix.rs b/fixed_wide_vectors/src/macros/matrix.rs index cde4330..e564df4 100644 --- a/fixed_wide_vectors/src/macros/matrix.rs +++ b/fixed_wide_vectors/src/macros/matrix.rs @@ -4,11 +4,11 @@ macro_rules! impl_matrix { () => { impl Matrix{ #[inline(always)] - pub const fn new(array:[[T;Y];X])->Self{ + pub const fn new(array:[[T;X];Y])->Self{ Self{array} } #[inline(always)] - pub fn to_array(self)->[[T;Y];X]{ + pub fn to_array(self)->[[T;X];Y]{ self.array } #[inline] @@ -33,8 +33,8 @@ macro_rules! impl_matrix { } } #[inline] - // MatX.MatY = MatX - pub fn dot(self,rhs:Matrix)->Matrix + // MatY.MatX = MatY + pub fn dot(self,rhs:Matrix)->Matrix where T:core::ops::Mul+Copy, V:core::iter::Sum, @@ -61,7 +61,7 @@ macro_rules! impl_matrix { { pub const fn from_value(value:T)->Self{ Self{ - array:[[value;Y];X] + array:[[value;X];Y] } } } diff --git a/fixed_wide_vectors/src/matrix.rs b/fixed_wide_vectors/src/matrix.rs index 4ca1236..784433c 100644 --- a/fixed_wide_vectors/src/matrix.rs +++ b/fixed_wide_vectors/src/matrix.rs @@ -1,6 +1,6 @@ #[derive(Clone,Copy,Hash,Eq,PartialEq)] pub struct Matrix{ - pub(crate) array:[[T;Y];X], + pub(crate) array:[[T;X];Y], } crate::impl_matrix!(); diff --git a/fixed_wide_vectors/src/tests/tests.rs b/fixed_wide_vectors/src/tests/tests.rs index 1c658dc..d81a7e0 100644 --- a/fixed_wide_vectors/src/tests/tests.rs +++ b/fixed_wide_vectors/src/tests/tests.rs @@ -1,4 +1,4 @@ -use crate::types::{Vector3,Matrix3x4,Matrix4x2,Matrix3x2}; +use crate::types::{Vector3,Matrix4x3,Matrix2x4,Matrix2x3}; #[test] fn test_bool(){ @@ -17,13 +17,13 @@ fn test_arithmetic(){ #[test] fn matrix_dot(){ - let rhs=Matrix4x2::new([ + let rhs=Matrix2x4::new([ [ 1.0, 2.0], [ 3.0, 4.0], [ 5.0, 6.0], [ 7.0, 8.0], ]); // | | | - let lhs=Matrix3x4::new([ // | | | + let lhs=Matrix4x3::new([ // | | | [1.0, 2.0, 3.0, 4.0],// [ 50.0, 60.0], [5.0, 6.0, 7.0, 8.0],// [114.0,140.0], [9.0,10.0,11.0,12.0],// [178.0,220.0], @@ -34,7 +34,7 @@ fn matrix_dot(){ //Out[1]= {{50, 60}, {114, 140}, {178, 220}} assert_eq!( m_dot.array, - Matrix3x2::new([ + Matrix2x3::new([ [50.0,60.0], [114.0,140.0], [178.0,220.0], From f2fec0b3b964ac6e36d72a3765953c77310a2541 Mon Sep 17 00:00:00 2001 From: Quaternions Date: Fri, 6 Sep 2024 11:25:46 -0700 Subject: [PATCH 154/227] implement a bunch of fixed wide stuff --- fixed_wide/src/fixed.rs | 9 ++ fixed_wide_vectors/src/macros/fixed_wide.rs | 142 +++++++++++++++++++- fixed_wide_vectors/src/macros/matrix.rs | 13 +- fixed_wide_vectors/src/macros/vector.rs | 13 +- fixed_wide_vectors/src/matrix.rs | 2 +- fixed_wide_vectors/src/named.rs | 6 +- fixed_wide_vectors/src/vector.rs | 2 +- 7 files changed, 176 insertions(+), 11 deletions(-) diff --git a/fixed_wide/src/fixed.rs b/fixed_wide/src/fixed.rs index d0aad2d..ee7662e 100644 --- a/fixed_wide/src/fixed.rs +++ b/fixed_wide/src/fixed.rs @@ -201,6 +201,15 @@ macro_rules! impl_multiplicatave_assign_operator { } }; } +impl std::iter::Sum for Fixed{ + fn sum>(iter:I)->Self{ + let mut sum=Self::ZERO; + for elem in iter{ + sum+=elem; + } + sum + } +} macro_rules! impl_operator_16 { ( $macro: ident, $struct: ident, $trait: ident, $method: ident, $output: ty ) => { diff --git a/fixed_wide_vectors/src/macros/fixed_wide.rs b/fixed_wide_vectors/src/macros/fixed_wide.rs index dabb773..76458d6 100644 --- a/fixed_wide_vectors/src/macros/fixed_wide.rs +++ b/fixed_wide_vectors/src/macros/fixed_wide.rs @@ -2,13 +2,14 @@ #[macro_export(local_inner_macros)] macro_rules! impl_wide_vector_operations_2arg_not_const_generic { ( + (), ($lhs:expr, $rhs:expr) ) => { impl Vector>{ paste::item!{ #[inline] pub fn [](self,rhs:Vector>)->Vector>{ - self.array.map_zip(|(a,b)|a.[](b)) + self.map_zip(rhs,|(a,b)|a.[](b)) } #[inline] pub fn [](self,rhs:Vector>)->fixed_wide::fixed::Fixed<{$lhs+$rhs},{($lhs+$rhs)*32}>{ @@ -22,9 +23,10 @@ macro_rules! impl_wide_vector_operations_2arg_not_const_generic { #[macro_export(local_inner_macros)] macro_rules! impl_wide_vector_operations_1arg_not_const_generic { ( + (), $n:expr ) => { - impl $struct>{ + impl Vector>{ paste::item!{ #[inline] pub fn wide_length_squared(&self)->fixed_wide::fixed::Fixed<{$n*2},{$n*2*32}>{ @@ -34,3 +36,139 @@ macro_rules! impl_wide_vector_operations_1arg_not_const_generic { } }; } + +#[doc(hidden)] +#[macro_export(local_inner_macros)] +macro_rules! do_macro_8x8{ + ( + $macro:ident, + $any:tt + )=>{ + $crate::macro_repeated!($macro, $any, + (1,1),(2,1),(3,1),(4,1),(5,1),(6,1),(7,1),(8,1), + (1,2),(2,2),(3,2),(4,2),(5,2),(6,2),(7,2),(8,2), + (1,3),(2,3),(3,3),(4,3),(5,3),(6,3),(7,3),(8,3), + (1,4),(2,4),(3,4),(4,4),(5,4),(6,4),(7,4),(8,4), + (1,5),(2,5),(3,5),(4,5),(5,5),(6,5),(7,5),(8,5), + (1,6),(2,6),(3,6),(4,6),(5,6),(6,6),(7,6),(8,6), + (1,7),(2,7),(3,7),(4,7),(5,7),(6,7),(7,7),(8,7), + (1,8),(2,8),(3,8),(4,8),(5,8),(6,8),(7,8),(8,8) + ); + }; +} + +#[doc(hidden)] +#[macro_export(local_inner_macros)] +macro_rules! do_macro_8{ + ( + $macro:ident, + $any:tt + )=>{ + $crate::macro_repeated!($macro, $any, 1,2,3,4,5,6,7,8); + }; +} + +#[doc(hidden)] +#[macro_export(local_inner_macros)] +macro_rules! impl_wide_vector_operations { + () => { + $crate::do_macro_8!(impl_wide_vector_operations_1arg_not_const_generic,()); + $crate::do_macro_8x8!(impl_wide_vector_operations_2arg_not_const_generic,()); + }; +} + +#[doc(hidden)] +#[macro_export(local_inner_macros)] +macro_rules! impl_vector_3_wide_cross { + ( + (), + ($lhs:expr, $rhs:expr) + )=>{ + impl Vector<3,fixed_wide::fixed::Fixed<{$lhs},{$lhs*32}>>{ + paste::item!{ + #[inline] + pub fn [](self,rhs:Vector<3,fixed_wide::fixed::Fixed<{$rhs},{$rhs*32}>>)->Vector<3,fixed_wide::fixed::Fixed<{$lhs+$rhs},{($lhs+$rhs)*32}>>{ + Vector{array:[ + self.y.[](rhs.z)-self.z.[](rhs.y), + self.z.[](rhs.x)-self.x.[](rhs.z), + self.x.[](rhs.y)-self.y.[](rhs.x), + ]} + } + } + } + } +} + +#[doc(hidden)] +#[macro_export(local_inner_macros)] +macro_rules! impl_vector_wide_3 { + ()=>{ + $crate::do_macro_8x8!(impl_vector_3_wide_cross,()); + } +} + +#[doc(hidden)] +#[macro_export(local_inner_macros)] +macro_rules! do_macro_4_dumb{ + ( + $macro:ident, + $any:tt + )=>{ + $crate::macro_repeated!($macro, $any, (1,2),(2,4),(3,6),(4,8)); + }; +} + +#[doc(hidden)] +#[macro_export(local_inner_macros)] +macro_rules! impl_matrix_wide_3x3_det_not_const_generic { + ( + $n: expr, + $_2n: expr + )=>{ + impl Matrix<3,3,fixed_wide::fixed::Fixed<$n,{$n*32}>>{ + paste::item!{ + pub fn [](self)->fixed_wide::fixed::Fixed<{$n*3},{$n*3*32}>{ + //[] will not compile, so the doubles are hardcoded above + self.x_axis.[](self.y_axis.[](self.z_axis)) + } + } + } + } +} +#[doc(hidden)] +#[macro_export(local_inner_macros)] +macro_rules! impl_matrix_wide_3x3_det_not_const_generic_shim { + ( + (),($n: expr,$_2n: expr) + )=>{ + $crate::impl_matrix_wide_3x3_det_not_const_generic!($n,$_2n); + } +} +#[doc(hidden)] +#[macro_export(local_inner_macros)] +macro_rules! impl_matrix_wide_3x3_adjugate_not_const_generic { + ( + (), + $n: expr + )=>{ + impl Matrix<3,3,fixed_wide::fixed::Fixed<$n,{$n*32}>>{ + paste::item!{ + pub fn [](self)->Matrix<3,3,fixed_wide::fixed::Fixed<{$n*2},{$n*2*32}>>{ + Matrix{array:[ + [self.y_axis.y.[](self.z_axis.z)-self.y_axis.z.[](self.z_axis.y),self.x_axis.z.[](self.z_axis.y)-self.x_axis.y.[](self.z_axis.z),self.x_axis.y.[](self.y_axis.z)-self.x_axis.z.[](self.y_axis.y)], + [self.y_axis.z.[](self.z_axis.x)-self.y_axis.x.[](self.z_axis.z),self.x_axis.x.[](self.z_axis.z)-self.x_axis.z.[](self.z_axis.x),self.x_axis.z.[](self.y_axis.x)-self.x_axis.x.[](self.y_axis.z)], + [self.y_axis.x.[](self.z_axis.y)-self.y_axis.y.[](self.z_axis.x),self.x_axis.y.[](self.z_axis.x)-self.x_axis.x.[](self.z_axis.y),self.x_axis.x.[](self.y_axis.y)-self.x_axis.y.[](self.y_axis.x)], + ]} + } + } + } + } +} +#[doc(hidden)] +#[macro_export(local_inner_macros)] +macro_rules! impl_matrix_wide_3x3 { + ()=>{ + $crate::do_macro_4_dumb!(impl_matrix_wide_3x3_det_not_const_generic_shim,()); + $crate::do_macro_8!(impl_matrix_wide_3x3_adjugate_not_const_generic,()); + } +} diff --git a/fixed_wide_vectors/src/macros/matrix.rs b/fixed_wide_vectors/src/macros/matrix.rs index e564df4..14013ac 100644 --- a/fixed_wide_vectors/src/macros/matrix.rs +++ b/fixed_wide_vectors/src/macros/matrix.rs @@ -81,10 +81,10 @@ macro_rules! impl_matrix { macro_rules! impl_matrix_named_fields_shape { ( ($struct_outer:ident, $size_outer: expr), - ($struct_inner:ident, $size_inner: expr) + ($size_inner: expr) ) => { impl core::ops::Deref for Matrix<$size_outer,$size_inner,T>{ - type Target=$struct_outer<$struct_inner>; + type Target=$struct_outer>; fn deref(&self)->&Self::Target{ unsafe{core::mem::transmute(&self.array)} } @@ -118,3 +118,12 @@ macro_rules! impl_matrix_named_fields { $crate::macro_repeated!(impl_matrix_named_fields_shape_shim,$vector_infos,$($matrix_info),+); } } + +#[doc(hidden)] +#[macro_export(local_inner_macros)] +macro_rules! impl_matrix_3x3 { + ()=>{ + #[cfg(feature="fixed_wide")] + $crate::impl_matrix_wide_3x3!(); + } +} diff --git a/fixed_wide_vectors/src/macros/vector.rs b/fixed_wide_vectors/src/macros/vector.rs index 6b24583..8d26a27 100644 --- a/fixed_wide_vectors/src/macros/vector.rs +++ b/fixed_wide_vectors/src/macros/vector.rs @@ -120,8 +120,8 @@ macro_rules! impl_vector { $crate::impl_vector_operator!(BitXor, bitxor ); // Impl floating-point based methods - //#[cfg(feature="fixed_wide")] - //$crate::impl_wide_vector_operations!( $struct { $($field), + }, $size ); + #[cfg(feature="fixed_wide")] + $crate::impl_wide_vector_operations!(); } } #[doc(hidden)] @@ -178,3 +178,12 @@ macro_rules! impl_vector_named_fields { } } } + +#[doc(hidden)] +#[macro_export(local_inner_macros)] +macro_rules! impl_vector_3 { + ()=>{ + #[cfg(feature="fixed_wide")] + $crate::impl_vector_wide_3!(); + } +} diff --git a/fixed_wide_vectors/src/matrix.rs b/fixed_wide_vectors/src/matrix.rs index 784433c..02070ec 100644 --- a/fixed_wide_vectors/src/matrix.rs +++ b/fixed_wide_vectors/src/matrix.rs @@ -6,4 +6,4 @@ pub struct Matrix{ crate::impl_matrix!(); //Special case 3x3 matrix operations because I cba to write macros for the arbitrary cases -//crate::impl_matrix_3x3!(); +crate::impl_matrix_3x3!(); diff --git a/fixed_wide_vectors/src/named.rs b/fixed_wide_vectors/src/named.rs index f490ee9..b467357 100644 --- a/fixed_wide_vectors/src/named.rs +++ b/fixed_wide_vectors/src/named.rs @@ -52,8 +52,8 @@ crate::impl_matrix_named_fields!( ), //inner struct ( - (Vector2, 2), - (Vector3, 3), - (Vector4, 4) + (2), + (3), + (4) ) ); diff --git a/fixed_wide_vectors/src/vector.rs b/fixed_wide_vectors/src/vector.rs index ffea1f0..212f126 100644 --- a/fixed_wide_vectors/src/vector.rs +++ b/fixed_wide_vectors/src/vector.rs @@ -6,4 +6,4 @@ pub struct Vector{ crate::impl_vector!(); //cross product -//crate::impl_vector_3!(); +crate::impl_vector_3!(); From 9ad90cea2e01c9db2751697692eef785f27d599e Mon Sep 17 00:00:00 2001 From: Quaternions Date: Fri, 6 Sep 2024 11:25:51 -0700 Subject: [PATCH 155/227] fix tests --- fixed_wide_vectors/src/tests/fixed_wide.rs | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/fixed_wide_vectors/src/tests/fixed_wide.rs b/fixed_wide_vectors/src/tests/fixed_wide.rs index 7dabd1d..994532a 100644 --- a/fixed_wide_vectors/src/tests/fixed_wide.rs +++ b/fixed_wide_vectors/src/tests/fixed_wide.rs @@ -1,4 +1,4 @@ -use crate::types::{Matrix3,Matrix3x2,Matrix3x4,Matrix4x2,Vector3}; +use crate::types::{Matrix3,Matrix2x3,Matrix4x3,Matrix2x4,Vector3}; type Planar64=fixed_wide::types::I32F32; type Planar64Wide1=fixed_wide::types::I64F64; @@ -12,7 +12,7 @@ fn wide_vec3(){ let v2=v1.wide_mul_2_2(v1); let v3=v2.wide_mul_4_4(v2); - assert_eq!(v3,Vector3::from_value(Planar64Wide3::from(3i128.pow(8)))); + assert_eq!(v3.array,Vector3::from_value(Planar64Wide3::from(3i128.pow(8))).array); } #[test] @@ -35,32 +35,34 @@ fn wide_vec3_length_squared(){ assert_eq!(v3,Planar64Wide3::from(3i128.pow(8)*3)); } +/* #[test] fn wide_matrix_dot(){ - let lhs=Matrix3x4::new([ + let lhs=Matrix4x3::new([ [Planar64::from(1),Planar64::from(2),Planar64::from(3),Planar64::from(4)], [Planar64::from(5),Planar64::from(6),Planar64::from(7),Planar64::from(8)], [Planar64::from(9),Planar64::from(10),Planar64::from(11),Planar64::from(12)], ]); - let rhs=Matrix4x2::new([ + let rhs=Matrix2x4::new([ [Planar64::from(1),Planar64::from(2)], [Planar64::from(3),Planar64::from(4)], [Planar64::from(5),Planar64::from(6)], [Planar64::from(7),Planar64::from(8)], ]); // Mat3.dot(Mat4) -> Mat3 - let m_dot=lhs.wide_dot_3x4_4x2_1_1(rhs); + let m_dot=lhs.wide_dot_1_1(rhs); //In[1]:= {{1, 2, 3, 4}, {5, 6, 7, 8}, {9, 10, 11, 12}} . {{1, 2}, {3, 4}, {5, 6}, {7, 8}} //Out[1]= {{50, 60}, {114, 140}, {178, 220}} assert_eq!( - m_dot, - Matrix3x2::new([ + m_dot.array, + Matrix2x3::new([ [Planar64Wide1::from(50),Planar64Wide1::from(60)], [Planar64Wide1::from(114),Planar64Wide1::from(140)], [Planar64Wide1::from(178),Planar64Wide1::from(220)], - ]) + ]).array ); } +*/ #[test] fn wide_matrix_det(){ @@ -84,11 +86,11 @@ fn wide_matrix_adjugate(){ // In[6]:= Adjugate[{{1, 2, 3}, {4, 5, 7}, {6, 8, 9}}] // Out[6]= {{-11, 6, -1}, {6, -9, 5}, {2, 4, -3}} assert_eq!( - m.wide_adjugate_3x3_1(), + m.wide_adjugate_3x3_1().array, Matrix3::new([ [Planar64Wide1::from(-11),Planar64Wide1::from(6),Planar64Wide1::from(-1)], [Planar64Wide1::from(6),Planar64Wide1::from(-9),Planar64Wide1::from(5)], [Planar64Wide1::from(2),Planar64Wide1::from(4),Planar64Wide1::from(-3)], - ]) + ]).array ); } From 7a9aaf9fe07cf1a5aebb2646fbe39418227a99f8 Mon Sep 17 00:00:00 2001 From: Quaternions Date: Fri, 6 Sep 2024 11:38:22 -0700 Subject: [PATCH 156/227] matrix mul --- fixed_wide_vectors/src/macros/fixed_wide.rs | 38 +++++++++++++++++++++ fixed_wide_vectors/src/macros/matrix.rs | 2 ++ 2 files changed, 40 insertions(+) diff --git a/fixed_wide_vectors/src/macros/fixed_wide.rs b/fixed_wide_vectors/src/macros/fixed_wide.rs index 76458d6..cc213c5 100644 --- a/fixed_wide_vectors/src/macros/fixed_wide.rs +++ b/fixed_wide_vectors/src/macros/fixed_wide.rs @@ -118,6 +118,44 @@ macro_rules! do_macro_4_dumb{ }; } +#[doc(hidden)] +#[macro_export(local_inner_macros)] +macro_rules! impl_matrix_wide_dot { + ( + (), + ($lhs: expr, $rhs: expr) + ) => { + impl Matrix>{ + paste::item!{ + #[inline] + pub fn [](self,rhs:Matrix>)->Matrix>{ + let mut array_of_iterators=rhs.array.map(|axis|axis.into_iter().cycle()); + Matrix{ + array:self.array.map(|axis| + core::array::from_fn(|_| + // axis dot product with transposed rhs array + axis.iter().zip( + array_of_iterators.iter_mut() + ).map(|(&lhs_value,rhs_iter)| + lhs_value.[](rhs_iter.next().unwrap()) + ).sum() + ) + ) + } + } + } + } + } +} + +#[doc(hidden)] +#[macro_export(local_inner_macros)] +macro_rules! impl_matrix_wide_dot_8x8 { + () => { + $crate::do_macro_8x8!(impl_matrix_wide_dot,()); + } +} + #[doc(hidden)] #[macro_export(local_inner_macros)] macro_rules! impl_matrix_wide_3x3_det_not_const_generic { diff --git a/fixed_wide_vectors/src/macros/matrix.rs b/fixed_wide_vectors/src/macros/matrix.rs index 14013ac..269cdcb 100644 --- a/fixed_wide_vectors/src/macros/matrix.rs +++ b/fixed_wide_vectors/src/macros/matrix.rs @@ -73,6 +73,8 @@ macro_rules! impl_matrix { } } } + #[cfg(feature="fixed_wide")] + $crate::impl_matrix_wide_dot_8x8!(); } } From 5f2bec75f5e5e5de95248c2c990b141fa81cd4d9 Mon Sep 17 00:00:00 2001 From: Quaternions Date: Fri, 6 Sep 2024 11:38:29 -0700 Subject: [PATCH 157/227] enable matrix mul test --- fixed_wide_vectors/src/tests/fixed_wide.rs | 2 -- 1 file changed, 2 deletions(-) diff --git a/fixed_wide_vectors/src/tests/fixed_wide.rs b/fixed_wide_vectors/src/tests/fixed_wide.rs index 994532a..b0f4895 100644 --- a/fixed_wide_vectors/src/tests/fixed_wide.rs +++ b/fixed_wide_vectors/src/tests/fixed_wide.rs @@ -35,7 +35,6 @@ fn wide_vec3_length_squared(){ assert_eq!(v3,Planar64Wide3::from(3i128.pow(8)*3)); } -/* #[test] fn wide_matrix_dot(){ let lhs=Matrix4x3::new([ @@ -62,7 +61,6 @@ fn wide_matrix_dot(){ ]).array ); } -*/ #[test] fn wide_matrix_det(){ From 36c769346c47923534afc50d82c7e5ee417cf489 Mon Sep 17 00:00:00 2001 From: Quaternions Date: Fri, 6 Sep 2024 11:44:43 -0700 Subject: [PATCH 158/227] use inline const constructor because it's a little bit prettier --- fixed_wide_vectors/src/macros/fixed_wide.rs | 14 +++++------ fixed_wide_vectors/src/macros/matrix.rs | 28 ++++++++++----------- fixed_wide_vectors/src/macros/vector.rs | 28 ++++++++++----------- 3 files changed, 33 insertions(+), 37 deletions(-) diff --git a/fixed_wide_vectors/src/macros/fixed_wide.rs b/fixed_wide_vectors/src/macros/fixed_wide.rs index cc213c5..0a2e0eb 100644 --- a/fixed_wide_vectors/src/macros/fixed_wide.rs +++ b/fixed_wide_vectors/src/macros/fixed_wide.rs @@ -88,11 +88,11 @@ macro_rules! impl_vector_3_wide_cross { paste::item!{ #[inline] pub fn [](self,rhs:Vector<3,fixed_wide::fixed::Fixed<{$rhs},{$rhs*32}>>)->Vector<3,fixed_wide::fixed::Fixed<{$lhs+$rhs},{($lhs+$rhs)*32}>>{ - Vector{array:[ + Vector::new([ self.y.[](rhs.z)-self.z.[](rhs.y), self.z.[](rhs.x)-self.x.[](rhs.z), self.x.[](rhs.y)-self.y.[](rhs.x), - ]} + ]) } } } @@ -130,8 +130,8 @@ macro_rules! impl_matrix_wide_dot { #[inline] pub fn [](self,rhs:Matrix>)->Matrix>{ let mut array_of_iterators=rhs.array.map(|axis|axis.into_iter().cycle()); - Matrix{ - array:self.array.map(|axis| + Matrix::new( + self.array.map(|axis| core::array::from_fn(|_| // axis dot product with transposed rhs array axis.iter().zip( @@ -141,7 +141,7 @@ macro_rules! impl_matrix_wide_dot { ).sum() ) ) - } + ) } } } @@ -192,11 +192,11 @@ macro_rules! impl_matrix_wide_3x3_adjugate_not_const_generic { impl Matrix<3,3,fixed_wide::fixed::Fixed<$n,{$n*32}>>{ paste::item!{ pub fn [](self)->Matrix<3,3,fixed_wide::fixed::Fixed<{$n*2},{$n*2*32}>>{ - Matrix{array:[ + Matrix::new([ [self.y_axis.y.[](self.z_axis.z)-self.y_axis.z.[](self.z_axis.y),self.x_axis.z.[](self.z_axis.y)-self.x_axis.y.[](self.z_axis.z),self.x_axis.y.[](self.y_axis.z)-self.x_axis.z.[](self.y_axis.y)], [self.y_axis.z.[](self.z_axis.x)-self.y_axis.x.[](self.z_axis.z),self.x_axis.x.[](self.z_axis.z)-self.x_axis.z.[](self.z_axis.x),self.x_axis.z.[](self.y_axis.x)-self.x_axis.x.[](self.y_axis.z)], [self.y_axis.x.[](self.z_axis.y)-self.y_axis.y.[](self.z_axis.x),self.x_axis.y.[](self.z_axis.x)-self.x_axis.x.[](self.z_axis.y),self.x_axis.x.[](self.y_axis.y)-self.x_axis.y.[](self.y_axis.x)], - ]} + ]) } } } diff --git a/fixed_wide_vectors/src/macros/matrix.rs b/fixed_wide_vectors/src/macros/matrix.rs index 269cdcb..e5ec16e 100644 --- a/fixed_wide_vectors/src/macros/matrix.rs +++ b/fixed_wide_vectors/src/macros/matrix.rs @@ -16,21 +16,21 @@ macro_rules! impl_matrix { where F:Fn(T)->U { - Matrix{ - array:self.array.map(|inner|inner.map(&f)), - } + Matrix::new( + self.array.map(|inner|inner.map(&f)), + ) } #[inline] pub fn transpose(self)->Matrix{ //how did I think of this let mut array_of_iterators=self.array.map(|axis|axis.into_iter()); - Matrix{ - array:core::array::from_fn(|_| + Matrix::new( + core::array::from_fn(|_| array_of_iterators.each_mut().map(|iter| iter.next().unwrap() ) ) - } + ) } #[inline] // MatY.MatX = MatY @@ -41,8 +41,8 @@ macro_rules! impl_matrix { U:Copy, { let mut array_of_iterators=rhs.array.map(|axis|axis.into_iter().cycle()); - Matrix{ - array:self.array.map(|axis| + Matrix::new( + self.array.map(|axis| core::array::from_fn(|_| // axis dot product with transposed rhs array axis.iter().zip( @@ -52,7 +52,7 @@ macro_rules! impl_matrix { ).sum() ) ) - } + ) } } impl Matrix @@ -60,17 +60,15 @@ macro_rules! impl_matrix { T:Copy { pub const fn from_value(value:T)->Self{ - Self{ - array:[[value;X];Y] - } + Self::new([[value;X];Y]) } } impl Default for Matrix{ fn default()->Self{ - Self{ - array:core::array::from_fn(|_|core::array::from_fn(|_|Default::default())) - } + Self::new( + core::array::from_fn(|_|core::array::from_fn(|_|Default::default())) + ) } } #[cfg(feature="fixed_wide")] diff --git a/fixed_wide_vectors/src/macros/vector.rs b/fixed_wide_vectors/src/macros/vector.rs index 8d26a27..9d976e9 100644 --- a/fixed_wide_vectors/src/macros/vector.rs +++ b/fixed_wide_vectors/src/macros/vector.rs @@ -16,9 +16,9 @@ macro_rules! impl_vector { where F:Fn(T)->U { - Vector{ - array:self.array.map(f), - } + Vector::new( + self.array.map(f) + ) } #[inline] pub fn map_zip(self,other:Vector,f:F)->Vector @@ -26,25 +26,23 @@ macro_rules! impl_vector { F:Fn((T,U))->V, { let mut iter=self.array.into_iter().zip(other.array); - Vector{ - array:core::array::from_fn(|_|f(iter.next().unwrap())), - } + Vector::new( + core::array::from_fn(|_|f(iter.next().unwrap())), + ) } } impl Vector{ #[inline(always)] pub const fn from_value(value:T)->Self{ - Self{ - array:[value;N] - } + Self::new([value;N]) } } impl Default for Vector{ fn default()->Self{ - Self{ - array:core::array::from_fn(|_|Default::default()) - } + Self::new( + core::array::from_fn(|_|Default::default()) + ) } } @@ -93,9 +91,9 @@ macro_rules! impl_vector { impl,V> core::ops::Neg for Vector{ type Output=Vector; fn neg(self)->Self::Output{ - Vector{ - array:self.array.map(|t|-t) - } + Vector::new( + self.array.map(|t|-t) + ) } } From 66186c7354e68b54056d03f66b32bdd208ccb158 Mon Sep 17 00:00:00 2001 From: Quaternions Date: Fri, 6 Sep 2024 13:03:55 -0700 Subject: [PATCH 159/227] doc --- fixed_wide_vectors/src/vector.rs | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/fixed_wide_vectors/src/vector.rs b/fixed_wide_vectors/src/vector.rs index 212f126..0cc1ec8 100644 --- a/fixed_wide_vectors/src/vector.rs +++ b/fixed_wide_vectors/src/vector.rs @@ -1,3 +1,8 @@ +/// An array-backed vector type. Named fields are made accessible via the Deref/DerefMut traits which are implmented for 2-4 dimensions. +/// let mut v = Vector::new([1.0,2.0,3.0]); +/// v.x += v.z; +/// println!("v.x={}",v.x); + #[derive(Clone,Copy,Hash,Eq,PartialEq)] pub struct Vector{ pub(crate) array:[T;N], From 898407a0e92133d3ca5943a1ebe16f3cf9bd08b5 Mon Sep 17 00:00:00 2001 From: Quaternions Date: Fri, 6 Sep 2024 13:23:55 -0700 Subject: [PATCH 160/227] matrix and vector extend functions --- fixed_wide_vectors/src/macros/matrix.rs | 26 +++++++++++++++++++++++++ fixed_wide_vectors/src/macros/vector.rs | 16 +++++++++++++++ fixed_wide_vectors/src/matrix.rs | 7 +++++++ fixed_wide_vectors/src/vector.rs | 4 ++++ 4 files changed, 53 insertions(+) diff --git a/fixed_wide_vectors/src/macros/matrix.rs b/fixed_wide_vectors/src/macros/matrix.rs index e5ec16e..34b7fd8 100644 --- a/fixed_wide_vectors/src/macros/matrix.rs +++ b/fixed_wide_vectors/src/macros/matrix.rs @@ -76,6 +76,32 @@ macro_rules! impl_matrix { } } +#[doc(hidden)] +#[macro_export(local_inner_macros)] +macro_rules! impl_matrix_extend { + ( $x: expr, $y: expr ) => { + impl Matrix<$x,$y,T>{ + #[inline] + pub fn extend_row(self,value:Vector<$x,T>)->Matrix<$x,{$y+1},T>{ + let mut iter=self.array.into_iter().chain(core::iter::once(value.array)); + Matrix::new( + core::array::from_fn(|_|iter.next().unwrap()), + ) + } + #[inline] + pub fn extend_column(self,value:Vector<$y,T>)->Matrix<{$x+1},$y,T>{ + let mut iter_rows=value.array.into_iter(); + Matrix::new( + self.array.map(|axis|{ + let mut elements_iter=axis.into_iter().chain(core::iter::once(iter_rows.next().unwrap())); + core::array::from_fn(|_|elements_iter.next().unwrap()) + }) + ) + } + } + } +} + #[doc(hidden)] #[macro_export(local_inner_macros)] macro_rules! impl_matrix_named_fields_shape { diff --git a/fixed_wide_vectors/src/macros/vector.rs b/fixed_wide_vectors/src/macros/vector.rs index 9d976e9..3f016ee 100644 --- a/fixed_wide_vectors/src/macros/vector.rs +++ b/fixed_wide_vectors/src/macros/vector.rs @@ -159,6 +159,22 @@ macro_rules! impl_vector_assign_operator { } } +#[doc(hidden)] +#[macro_export(local_inner_macros)] +macro_rules! impl_vector_extend { + ( $size: expr ) => { + impl Vector<$size,T>{ + #[inline] + pub fn extend(self,value:T)->Vector<{$size+1},T>{ + let mut iter=self.array.into_iter().chain(core::iter::once(value)); + Vector::new( + core::array::from_fn(|_|iter.next().unwrap()), + ) + } + } + } +} + #[doc(hidden)] #[macro_export(local_inner_macros)] macro_rules! impl_vector_named_fields { diff --git a/fixed_wide_vectors/src/matrix.rs b/fixed_wide_vectors/src/matrix.rs index 02070ec..5a6b914 100644 --- a/fixed_wide_vectors/src/matrix.rs +++ b/fixed_wide_vectors/src/matrix.rs @@ -1,3 +1,5 @@ +use crate::vector::Vector; + #[derive(Clone,Copy,Hash,Eq,PartialEq)] pub struct Matrix{ pub(crate) array:[[T;X];Y], @@ -5,5 +7,10 @@ pub struct Matrix{ crate::impl_matrix!(); +crate::impl_matrix_extend!(2,2); +crate::impl_matrix_extend!(2,3); +crate::impl_matrix_extend!(3,2); +crate::impl_matrix_extend!(3,3); + //Special case 3x3 matrix operations because I cba to write macros for the arbitrary cases crate::impl_matrix_3x3!(); diff --git a/fixed_wide_vectors/src/vector.rs b/fixed_wide_vectors/src/vector.rs index 0cc1ec8..3b7a15d 100644 --- a/fixed_wide_vectors/src/vector.rs +++ b/fixed_wide_vectors/src/vector.rs @@ -10,5 +10,9 @@ pub struct Vector{ crate::impl_vector!(); +// Needs const generics for generic case +crate::impl_vector_extend!(2); +crate::impl_vector_extend!(3); + //cross product crate::impl_vector_3!(); From d3c4d530b6f9ce0d37d956c8ab2b4e93da6f8c0b Mon Sep 17 00:00:00 2001 From: Quaternions Date: Mon, 9 Sep 2024 13:00:51 -0700 Subject: [PATCH 161/227] refactor macros, move things around --- fixed_wide/src/fixed.rs | 154 +++++++++++++++++----------------------- 1 file changed, 67 insertions(+), 87 deletions(-) diff --git a/fixed_wide/src/fixed.rs b/fixed_wide/src/fixed.rs index ee7662e..c754857 100644 --- a/fixed_wide/src/fixed.rs +++ b/fixed_wide/src/fixed.rs @@ -70,6 +70,15 @@ impl std::ops::Neg for Fixed{ Self::from_bits(self.bits.neg()) } } +impl std::iter::Sum for Fixed{ + fn sum>(iter:I)->Self{ + let mut sum=Self::ZERO; + for elem in iter{ + sum+=elem; + } + sum + } +} macro_rules! impl_additive_operator { ( $struct: ident, $trait: ident, $method: ident, $output: ty ) => { @@ -126,8 +135,8 @@ impl_additive_operator!( Fixed, BitOr, bitor, Self ); impl_additive_assign_operator!( Fixed, BitXorAssign, bitxor_assign ); impl_additive_operator!( Fixed, BitXor, bitxor, Self ); -macro_rules! impl_multiply_operator_const { - ( $width:expr, $struct: ident, $trait: ident, $method: ident, $output: ty ) => { +macro_rules! impl_multiply_operator_not_const_generic { + ( ($struct: ident, $trait: ident, $method: ident, $output: ty ), $width:expr ) => { impl core::ops::$trait for $struct<$width,F>{ type Output = $output; @@ -140,8 +149,8 @@ macro_rules! impl_multiply_operator_const { } }; } -macro_rules! impl_multiply_assign_operator_const { - ( $width:expr, $struct: ident, $trait: ident, $method: ident ) => { +macro_rules! impl_multiply_assign_operator_not_const_generic { + ( ($struct: ident, $trait: ident, $method: ident ), $width:expr ) => { impl core::ops::$trait for $struct<$width,F>{ fn $method(&mut self, other: Self) { self.bits.$method(other.bits); @@ -150,8 +159,8 @@ macro_rules! impl_multiply_assign_operator_const { }; } -macro_rules! impl_divide_operator_const { - ( $width:expr, $struct: ident, $trait: ident, $method: ident, $output: ty ) => { +macro_rules! impl_divide_operator_not_const_generic { + ( ($struct: ident, $trait: ident, $method: ident, $output: ty ), $width:expr ) => { impl core::ops::$trait for $struct<$width,F>{ type Output = $output; @@ -165,8 +174,8 @@ macro_rules! impl_divide_operator_const { } }; } -macro_rules! impl_divide_assign_operator_const { - ( $width:expr, $struct: ident, $trait: ident, $method: ident ) => { +macro_rules! impl_divide_assign_operator_not_const_generic { + ( ($struct: ident, $trait: ident, $method: ident ), $width:expr ) => { impl core::ops::$trait for $struct<$width,F>{ fn $method(&mut self, other: Self) { self.bits.$method(other.bits); @@ -201,61 +210,29 @@ macro_rules! impl_multiplicatave_assign_operator { } }; } -impl std::iter::Sum for Fixed{ - fn sum>(iter:I)->Self{ - let mut sum=Self::ZERO; - for elem in iter{ - sum+=elem; - } - sum + +macro_rules! macro_repeated{ + ( + $macro:ident, + $any:tt, + $($repeated:tt),* + )=>{ + $( + $macro!($any, $repeated); + )* + }; +} + +macro_rules! macro_16 { + ( $macro: ident, $any:tt ) => { + macro_repeated!($macro,$any,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16); } } -macro_rules! impl_operator_16 { - ( $macro: ident, $struct: ident, $trait: ident, $method: ident, $output: ty ) => { - $macro!(1,$struct,$trait,$method,$output); - $macro!(2,$struct,$trait,$method,$output); - $macro!(3,$struct,$trait,$method,$output); - $macro!(4,$struct,$trait,$method,$output); - $macro!(5,$struct,$trait,$method,$output); - $macro!(6,$struct,$trait,$method,$output); - $macro!(7,$struct,$trait,$method,$output); - $macro!(8,$struct,$trait,$method,$output); - $macro!(9,$struct,$trait,$method,$output); - $macro!(10,$struct,$trait,$method,$output); - $macro!(11,$struct,$trait,$method,$output); - $macro!(12,$struct,$trait,$method,$output); - $macro!(13,$struct,$trait,$method,$output); - $macro!(14,$struct,$trait,$method,$output); - $macro!(15,$struct,$trait,$method,$output); - $macro!(16,$struct,$trait,$method,$output); - } -} -macro_rules! impl_assign_operator_16 { - ( $macro: ident, $struct: ident, $trait: ident, $method: ident ) => { - $macro!(1,$struct,$trait,$method); - $macro!(2,$struct,$trait,$method); - $macro!(3,$struct,$trait,$method); - $macro!(4,$struct,$trait,$method); - $macro!(5,$struct,$trait,$method); - $macro!(6,$struct,$trait,$method); - $macro!(7,$struct,$trait,$method); - $macro!(8,$struct,$trait,$method); - $macro!(9,$struct,$trait,$method); - $macro!(10,$struct,$trait,$method); - $macro!(11,$struct,$trait,$method); - $macro!(12,$struct,$trait,$method); - $macro!(13,$struct,$trait,$method); - $macro!(14,$struct,$trait,$method); - $macro!(15,$struct,$trait,$method); - $macro!(16,$struct,$trait,$method); - } -} - -impl_assign_operator_16!( impl_multiply_assign_operator_const, Fixed, MulAssign, mul_assign ); -impl_operator_16!( impl_multiply_operator_const, Fixed, Mul, mul, Self ); -impl_assign_operator_16!( impl_divide_assign_operator_const, Fixed, DivAssign, div_assign ); -impl_operator_16!( impl_divide_operator_const, Fixed, Div, div, Self ); +macro_16!( impl_multiply_assign_operator_not_const_generic, (Fixed, MulAssign, mul_assign) ); +macro_16!( impl_multiply_operator_not_const_generic, (Fixed, Mul, mul, Self) ); +macro_16!( impl_divide_assign_operator_not_const_generic, (Fixed, DivAssign, div_assign) ); +macro_16!( impl_divide_operator_not_const_generic, (Fixed, Div, div, Self) ); impl_multiplicatave_assign_operator!( Fixed, MulAssign, mul_assign ); impl_multiplicatave_operator!( Fixed, Mul, mul, Self ); impl_multiplicatave_assign_operator!( Fixed, DivAssign, div_assign ); @@ -290,7 +267,10 @@ impl_shift_operator!( Fixed, Shr, shr, Self ); // let a = I32F32::ONE; // let b:I64F64 = a.wide_mul(a); macro_rules! impl_wide_mul{ - ($lhs:expr,$rhs:expr)=>{ + ( + (), + ($lhs:expr,$rhs:expr) + )=>{ impl Fixed<$lhs,{$lhs*32}> { paste::item!{ @@ -302,24 +282,24 @@ macro_rules! impl_wide_mul{ }; } -macro_rules! impl_wide_mul_all{ - ($(($x:expr, $y:expr)),*)=>{ - $( - impl_wide_mul!($x, $y); - )* - }; -} - //const generics sidestepped wahoo -impl_wide_mul_all!( - (1,1),(2,1),(3,1),(4,1),(5,1),(6,1),(7,1),(8,1), - (1,2),(2,2),(3,2),(4,2),(5,2),(6,2),(7,2),(8,2), - (1,3),(2,3),(3,3),(4,3),(5,3),(6,3),(7,3),(8,3), - (1,4),(2,4),(3,4),(4,4),(5,4),(6,4),(7,4),(8,4), - (1,5),(2,5),(3,5),(4,5),(5,5),(6,5),(7,5),(8,5), - (1,6),(2,6),(3,6),(4,6),(5,6),(6,6),(7,6),(8,6), - (1,7),(2,7),(3,7),(4,7),(5,7),(6,7),(7,7),(8,7), - (1,8),(2,8),(3,8),(4,8),(5,8),(6,8),(7,8),(8,8) +macro_repeated!( + impl_wide_mul,(), + (1,1),(2,1),(3,1),(4,1),(5,1),(6,1),(7,1),(8,1),(9,1),(10,1),(11,1),(12,1),(13,1),(14,1),(15,1), + (1,2),(2,2),(3,2),(4,2),(5,2),(6,2),(7,2),(8,2),(9,2),(10,2),(11,2),(12,2),(13,2),(14,2), + (1,3),(2,3),(3,3),(4,3),(5,3),(6,3),(7,3),(8,3),(9,3),(10,3),(11,3),(12,3),(13,3), + (1,4),(2,4),(3,4),(4,4),(5,4),(6,4),(7,4),(8,4),(9,4),(10,4),(11,4),(12,4), + (1,5),(2,5),(3,5),(4,5),(5,5),(6,5),(7,5),(8,5),(9,5),(10,5),(11,5), + (1,6),(2,6),(3,6),(4,6),(5,6),(6,6),(7,6),(8,6),(9,6),(10,6), + (1,7),(2,7),(3,7),(4,7),(5,7),(6,7),(7,7),(8,7),(9,7), + (1,8),(2,8),(3,8),(4,8),(5,8),(6,8),(7,8),(8,8), + (1,9),(2,9),(3,9),(4,9),(5,9),(6,9),(7,9), + (1,10),(2,10),(3,10),(4,10),(5,10),(6,10), + (1,11),(2,11),(3,11),(4,11),(5,11), + (1,12),(2,12),(3,12),(4,12), + (1,13),(2,13),(3,13), + (1,14),(2,14), + (1,15) ); impl Fixed{ pub fn resize_into(self)->Fixed{ @@ -327,7 +307,7 @@ impl Fixed{ } } -macro_rules! impl_const{ +macro_rules! impl_not_const_generic{ ($n:expr)=>{ impl Fixed<{$n*2},{$n*2*32}>{ pub fn halve_precision(self)->Fixed<$n,{$n*32}>{ @@ -376,11 +356,11 @@ macro_rules! impl_const{ } } } -impl_const!(1); -impl_const!(2); -impl_const!(3); -impl_const!(4); -impl_const!(5); -impl_const!(6); -impl_const!(7); -impl_const!(8); +impl_not_const_generic!(1); +impl_not_const_generic!(2); +impl_not_const_generic!(3); +impl_not_const_generic!(4); +impl_not_const_generic!(5); +impl_not_const_generic!(6); +impl_not_const_generic!(7); +impl_not_const_generic!(8); From 62419e94e16f9f7620e88d0ed7c069e0dc7af1b0 Mon Sep 17 00:00:00 2001 From: Quaternions Date: Mon, 9 Sep 2024 13:00:57 -0700 Subject: [PATCH 162/227] consistency --- fixed_wide/src/fixed.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fixed_wide/src/fixed.rs b/fixed_wide/src/fixed.rs index c754857..29f59b4 100644 --- a/fixed_wide/src/fixed.rs +++ b/fixed_wide/src/fixed.rs @@ -113,7 +113,7 @@ macro_rules! impl_additive_assign_operator { BInt:::From, { fn $method(&mut self, other: U) { - self.bits.$method(BInt::::from(other)<::from(other).shl(F as u32)); } } }; From 803f1bea9e1bb56b3a7997432f30b01a5a82f021 Mon Sep 17 00:00:00 2001 From: Quaternions Date: Mon, 9 Sep 2024 13:58:24 -0700 Subject: [PATCH 163/227] extract trait impls into named functions + fix spelling --- fixed_wide/src/fixed.rs | 85 +++++++++++++++++++++++------------------ 1 file changed, 48 insertions(+), 37 deletions(-) diff --git a/fixed_wide/src/fixed.rs b/fixed_wide/src/fixed.rs index 29f59b4..4cdfdef 100644 --- a/fixed_wide/src/fixed.rs +++ b/fixed_wide/src/fixed.rs @@ -82,11 +82,16 @@ impl std::iter::Sum for Fixed{ macro_rules! impl_additive_operator { ( $struct: ident, $trait: ident, $method: ident, $output: ty ) => { + impl $struct{ + #[inline] + pub const fn $method(self, other: Self) -> Self { + Self::from_bits(self.bits.$method(other.bits)) + } + } impl core::ops::$trait for $struct{ type Output = $output; - fn $method(self, other: Self) -> Self::Output { - Self::from_bits(self.bits.$method(other.bits)) + self.$method(other) } } impl core::ops::$trait for $struct @@ -94,7 +99,6 @@ macro_rules! impl_additive_operator { BInt:::From, { type Output = $output; - fn $method(self, other: U) -> Self::Output { Self::from_bits(self.bits.$method(BInt::::from(other).shl(F as u32))) } @@ -135,56 +139,63 @@ impl_additive_operator!( Fixed, BitOr, bitor, Self ); impl_additive_assign_operator!( Fixed, BitXorAssign, bitxor_assign ); impl_additive_operator!( Fixed, BitXor, bitxor, Self ); -macro_rules! impl_multiply_operator_not_const_generic { +macro_rules! impl_multiplicative_operator_not_const_generic { ( ($struct: ident, $trait: ident, $method: ident, $output: ty ), $width:expr ) => { impl core::ops::$trait for $struct<$width,F>{ type Output = $output; - fn $method(self, other: Self) -> Self::Output { - //this can be done better but that is a job for later + paste::item!{ + self.[](other) + } + } + } + }; +} +macro_rules! impl_multiplicative_assign_operator_not_const_generic { + ( ($struct: ident, $trait: ident, $method: ident, $non_assign_method: ident ), $width:expr ) => { + impl core::ops::$trait for $struct<$width,F>{ + fn $method(&mut self, other: Self) { + paste::item!{ + *self=self.[](other); + } + } + } + }; +} + +macro_rules! impl_multiply_operator_not_const_generic { + ( ($struct: ident, $trait: ident, $method: ident, $output: ty ), $width:expr ) => { + impl $struct<$width,F>{ + paste::item!{ + #[inline] + pub fn [](self, other: Self) -> Self { let lhs=self.bits.as_::>(); let rhs=other.bits.as_::>(); Self::from_bits(lhs.mul(rhs).shr(F as u32).as_()) } - } - }; -} -macro_rules! impl_multiply_assign_operator_not_const_generic { - ( ($struct: ident, $trait: ident, $method: ident ), $width:expr ) => { - impl core::ops::$trait for $struct<$width,F>{ - fn $method(&mut self, other: Self) { - self.bits.$method(other.bits); } } - }; + impl_multiplicative_operator_not_const_generic!(($struct, $trait, $method, $output ), $width); + } } - macro_rules! impl_divide_operator_not_const_generic { ( ($struct: ident, $trait: ident, $method: ident, $output: ty ), $width:expr ) => { - impl core::ops::$trait for $struct<$width,F>{ - type Output = $output; - - fn $method(self, other: Self) -> Self::Output { - //this can be done better but that is a job for later + impl $struct<$width,F>{ + paste::item!{ + #[inline] + pub fn [](self, other: Self) -> Self { //this only needs to be $width+F as u32/64+1 but MUH CONST GENERICS!!!!! let lhs=self.bits.as_::>().shl(F as u32); let rhs=other.bits.as_::>(); Self::from_bits(lhs.div(rhs).as_()) } - } - }; -} -macro_rules! impl_divide_assign_operator_not_const_generic { - ( ($struct: ident, $trait: ident, $method: ident ), $width:expr ) => { - impl core::ops::$trait for $struct<$width,F>{ - fn $method(&mut self, other: Self) { - self.bits.$method(other.bits); } } + impl_multiplicative_operator_not_const_generic!(($struct, $trait, $method, $output ), $width); }; } -macro_rules! impl_multiplicatave_operator { +macro_rules! impl_multiplicative_operator { ( $struct: ident, $trait: ident, $method: ident, $output: ty ) => { impl core::ops::$trait for $struct where @@ -198,7 +209,7 @@ macro_rules! impl_multiplicatave_operator { } }; } -macro_rules! impl_multiplicatave_assign_operator { +macro_rules! impl_multiplicative_assign_operator { ( $struct: ident, $trait: ident, $method: ident ) => { impl core::ops::$trait for $struct where @@ -229,14 +240,14 @@ macro_rules! macro_16 { } } -macro_16!( impl_multiply_assign_operator_not_const_generic, (Fixed, MulAssign, mul_assign) ); +macro_16!( impl_multiplicative_assign_operator_not_const_generic, (Fixed, MulAssign, mul_assign, mul) ); macro_16!( impl_multiply_operator_not_const_generic, (Fixed, Mul, mul, Self) ); -macro_16!( impl_divide_assign_operator_not_const_generic, (Fixed, DivAssign, div_assign) ); +macro_16!( impl_multiplicative_assign_operator_not_const_generic, (Fixed, DivAssign, div_assign, div) ); macro_16!( impl_divide_operator_not_const_generic, (Fixed, Div, div, Self) ); -impl_multiplicatave_assign_operator!( Fixed, MulAssign, mul_assign ); -impl_multiplicatave_operator!( Fixed, Mul, mul, Self ); -impl_multiplicatave_assign_operator!( Fixed, DivAssign, div_assign ); -impl_multiplicatave_operator!( Fixed, Div, div, Self ); +impl_multiplicative_assign_operator!( Fixed, MulAssign, mul_assign ); +impl_multiplicative_operator!( Fixed, Mul, mul, Self ); +impl_multiplicative_assign_operator!( Fixed, DivAssign, div_assign ); +impl_multiplicative_operator!( Fixed, Div, div, Self ); macro_rules! impl_shift_operator { ( $struct: ident, $trait: ident, $method: ident, $output: ty ) => { From 8ee6204a42e8a6a9c4db3a4f166429961678ea24 Mon Sep 17 00:00:00 2001 From: Quaternions Date: Mon, 9 Sep 2024 14:45:47 -0700 Subject: [PATCH 164/227] invent wide_div + test --- fixed_wide/src/fixed.rs | 17 ++++++++++++++--- fixed_wide/src/tests.rs | 14 ++++++++++++++ 2 files changed, 28 insertions(+), 3 deletions(-) diff --git a/fixed_wide/src/fixed.rs b/fixed_wide/src/fixed.rs index 4cdfdef..c8b1969 100644 --- a/fixed_wide/src/fixed.rs +++ b/fixed_wide/src/fixed.rs @@ -277,7 +277,7 @@ impl_shift_operator!( Fixed, Shr, shr, Self ); // WIDE MUL: multiply into a wider type // let a = I32F32::ONE; // let b:I64F64 = a.wide_mul(a); -macro_rules! impl_wide_mul{ +macro_rules! impl_wide_not_const_generic{ ( (), ($lhs:expr,$rhs:expr) @@ -286,7 +286,18 @@ macro_rules! impl_wide_mul{ { paste::item!{ pub fn [](self,rhs:Fixed<$rhs,{$rhs*32}>)->Fixed<{$lhs+$rhs},{($lhs+$rhs)*32}>{ - Fixed::from_bits(self.bits.as_::>()*rhs.bits.as_::>()) + let lhs=self.bits.as_::>(); + let rhs=rhs.bits.as_::>(); + Fixed::from_bits(lhs*rhs) + } + /// This operation cannot represent the fraction exactly, + /// but it shapes the output to have precision for the + /// largest and smallest possible fractions. + pub fn [](self,rhs:Fixed<$rhs,{$rhs*32}>)->Fixed<{$lhs+$rhs},{($lhs+$rhs)*32}>{ + // (lhs/2^LHS_FRAC)/(rhs/2^RHS_FRAC) + let lhs=self.bits.as_::>().shl($rhs*64); + let rhs=rhs.bits.as_::>(); + Fixed::from_bits(lhs/rhs) } } } @@ -295,7 +306,7 @@ macro_rules! impl_wide_mul{ //const generics sidestepped wahoo macro_repeated!( - impl_wide_mul,(), + impl_wide_not_const_generic,(), (1,1),(2,1),(3,1),(4,1),(5,1),(6,1),(7,1),(8,1),(9,1),(10,1),(11,1),(12,1),(13,1),(14,1),(15,1), (1,2),(2,2),(3,2),(4,2),(5,2),(6,2),(7,2),(8,2),(9,2),(10,2),(11,2),(12,2),(13,2),(14,2), (1,3),(2,3),(3,3),(4,3),(5,3),(6,3),(7,3),(8,3),(9,3),(10,3),(11,3),(12,3),(13,3), diff --git a/fixed_wide/src/tests.rs b/fixed_wide/src/tests.rs index 01fb9f1..43fa2ab 100644 --- a/fixed_wide/src/tests.rs +++ b/fixed_wide/src/tests.rs @@ -20,6 +20,20 @@ fn test_wide_mul(){ assert_eq!(aa,crate::types::I64F64::ONE); } +#[test] +fn test_wide_div(){ + let a=I32F32::ONE*4; + let b=I32F32::ONE*2; + let wide_a=a.wide_mul_1_1(I32F32::ONE); + let wide_b=b.wide_mul_1_1(I32F32::ONE); + let ab=a.wide_div_1_1(b); + assert_eq!(ab,crate::types::I64F64::ONE*2); + let wab=wide_a.wide_div_2_1(b); + assert_eq!(wab,crate::fixed::Fixed::<3,96>::ONE*2); + let awb=a.wide_div_1_2(wide_b); + assert_eq!(awb,crate::fixed::Fixed::<3,96>::ONE*2); +} + #[test] fn test_wide_mul_repeated() { let a=I32F32::from(2); From 206e2194673dcb852416d0a5c6057c95d63aa97f Mon Sep 17 00:00:00 2001 From: Quaternions Date: Fri, 6 Sep 2024 12:49:10 -0700 Subject: [PATCH 165/227] wide-mul crate feature --- fixed_wide/Cargo.toml | 3 ++- fixed_wide/src/fixed.rs | 40 ++++++++++++++++++++++++++++++++++++++++ fixed_wide/src/tests.rs | 2 +- 3 files changed, 43 insertions(+), 2 deletions(-) diff --git a/fixed_wide/Cargo.toml b/fixed_wide/Cargo.toml index cc218bc..ab20a56 100644 --- a/fixed_wide/Cargo.toml +++ b/fixed_wide/Cargo.toml @@ -4,8 +4,9 @@ version = "0.1.0" edition = "2021" [features] -default=["zeroes"] +default=["zeroes","wide-mul"] ratio=[] +wide-mul=[] zeroes=["ratio","dep:arrayvec"] [dependencies] diff --git a/fixed_wide/src/fixed.rs b/fixed_wide/src/fixed.rs index c8b1969..79f7579 100644 --- a/fixed_wide/src/fixed.rs +++ b/fixed_wide/src/fixed.rs @@ -1,6 +1,7 @@ use bnum::{BInt,cast::As}; #[derive(Clone,Copy,Debug,Hash)] +/// A Fixed point number for which multiply operations widen the bits in the output. (when the wide-mul feature is enabled) /// N is the number of u64s to use /// F is the number of fractional bits (always N*32 lol) pub struct Fixed{ @@ -139,6 +140,10 @@ impl_additive_operator!( Fixed, BitOr, bitor, Self ); impl_additive_assign_operator!( Fixed, BitXorAssign, bitxor_assign ); impl_additive_operator!( Fixed, BitXor, bitxor, Self ); +// non-wide operators. The result is the same width as the inputs. + +// This macro is not used in the default configuration. +#[allow(unused_macros)] macro_rules! impl_multiplicative_operator_not_const_generic { ( ($struct: ident, $trait: ident, $method: ident, $output: ty ), $width:expr ) => { impl core::ops::$trait for $struct<$width,F>{ @@ -175,6 +180,7 @@ macro_rules! impl_multiply_operator_not_const_generic { } } } + #[cfg(not(feature="wide-mul"))] impl_multiplicative_operator_not_const_generic!(($struct, $trait, $method, $output ), $width); } } @@ -191,6 +197,7 @@ macro_rules! impl_divide_operator_not_const_generic { } } } + #[cfg(all(not(feature="wide-mul"),not(feature="ratio")))] impl_multiplicative_operator_not_const_generic!(($struct, $trait, $method, $output ), $width); }; } @@ -248,6 +255,13 @@ impl_multiplicative_assign_operator!( Fixed, MulAssign, mul_assign ); impl_multiplicative_operator!( Fixed, Mul, mul, Self ); impl_multiplicative_assign_operator!( Fixed, DivAssign, div_assign ); impl_multiplicative_operator!( Fixed, Div, div, Self ); +#[cfg(feature="ratio")] +impl core::ops::Div> for Fixed{ + type Output=crate::ratio::Ratio,Fixed>; + fn div(self, other: Fixed)->Self::Output{ + crate::ratio::Ratio::new(self,other) + } +} macro_rules! impl_shift_operator { ( $struct: ident, $trait: ident, $method: ident, $output: ty ) => { @@ -274,6 +288,30 @@ impl_shift_operator!( Fixed, Shl, shl, Self ); impl_shift_assign_operator!( Fixed, ShrAssign, shr_assign ); impl_shift_operator!( Fixed, Shr, shr, Self ); +// wide operators. The result width is the sum of the input widths, i.e. none of the multiplication + +macro_rules! impl_wide_operators{ + ($lhs:expr,$rhs:expr)=>{ + impl core::ops::Mul> for Fixed<$lhs,{$lhs*32}>{ + type Output=Fixed<{$lhs+$rhs},{($lhs+$rhs)*32}>; + fn mul(self, other: Fixed<$rhs,{$rhs*32}>)->Self::Output{ + paste::item!{ + self.[](other) + } + } + } + #[cfg(not(feature="ratio"))] + impl core::ops::Div> for Fixed<$lhs,{$lhs*32}>{ + type Output=Fixed<{$lhs+$rhs},{($lhs+$rhs)*32}>; + fn div(self, other: Fixed<$rhs,{$rhs*32}>)->Self::Output{ + paste::item!{ + self.[](other) + } + } + } + } +} + // WIDE MUL: multiply into a wider type // let a = I32F32::ONE; // let b:I64F64 = a.wide_mul(a); @@ -301,6 +339,8 @@ macro_rules! impl_wide_not_const_generic{ } } } + #[cfg(feature="wide-mul")] + impl_wide_operators!($lhs,$rhs); }; } diff --git a/fixed_wide/src/tests.rs b/fixed_wide/src/tests.rs index 43fa2ab..2f9aaa6 100644 --- a/fixed_wide/src/tests.rs +++ b/fixed_wide/src/tests.rs @@ -65,7 +65,7 @@ fn test_sqrt_zero(){ #[test] fn test_sqrt_low(){ let a=I32F32::HALF; - let b=a*a; + let b=a.fixed_mul(a); assert_eq!(b.sqrt(),a); } fn find_equiv_sqrt_via_f64(n:I32F32)->I32F32{ From 53bb1522ebfbf5c257c7347ddf43f12f7b74a82e Mon Sep 17 00:00:00 2001 From: Quaternions Date: Mon, 9 Sep 2024 16:37:00 -0700 Subject: [PATCH 166/227] impl dot + cross + length_squared with trait bounds --- fixed_wide_vectors/src/macros/vector.rs | 39 +++++++++++++++++++++++++ fixed_wide_vectors/src/tests/tests.rs | 5 ++++ 2 files changed, 44 insertions(+) diff --git a/fixed_wide_vectors/src/macros/vector.rs b/fixed_wide_vectors/src/macros/vector.rs index 3f016ee..5264958 100644 --- a/fixed_wide_vectors/src/macros/vector.rs +++ b/fixed_wide_vectors/src/macros/vector.rs @@ -97,6 +97,29 @@ macro_rules! impl_vector { } } + impl Vector + { + #[inline] + pub fn dot(self,rhs:Vector)->V + where + T:core::ops::Mul, + V:core::iter::Sum, + { + self.array.into_iter().zip(rhs.array).map(|(a,b)|a*b).sum() + } + } + + impl Vector + where + T:core::ops::Mul+Copy, + V:core::iter::Sum, + { + #[inline] + pub fn length_squared(self)->V{ + self.array.into_iter().map(|t|t*t).sum() + } + } + // Impl arithmetic operators $crate::impl_vector_assign_operator!(AddAssign, add_assign ); $crate::impl_vector_operator!(Add, add ); @@ -197,6 +220,22 @@ macro_rules! impl_vector_named_fields { #[macro_export(local_inner_macros)] macro_rules! impl_vector_3 { ()=>{ + impl Vector<3,T> + { + #[inline] + pub fn cross(self,rhs:Vector<3,U>)->Vector<3,::Output> + where + T:core::ops::Mul+Copy, + U:Copy, + V:core::ops::Sub, + { + Vector::new([ + self.y*rhs.z-self.z*rhs.y, + self.z*rhs.x-self.x*rhs.z, + self.x*rhs.y-self.y*rhs.x, + ]) + } + } #[cfg(feature="fixed_wide")] $crate::impl_vector_wide_3!(); } diff --git a/fixed_wide_vectors/src/tests/tests.rs b/fixed_wide_vectors/src/tests/tests.rs index d81a7e0..8883fa2 100644 --- a/fixed_wide_vectors/src/tests/tests.rs +++ b/fixed_wide_vectors/src/tests/tests.rs @@ -8,6 +8,11 @@ fn test_bool(){ assert_eq!(Vector3::new([true,true,true]).all(),true); } +#[test] +fn test_length_squared(){ + assert_eq!(Vector3::new([1,2,3]).length_squared(),14); +} + #[test] fn test_arithmetic(){ let a=Vector3::new([1,2,3]); From b6d260bf2cd5855057b9024f3e2ec3431728d88e Mon Sep 17 00:00:00 2001 From: Quaternions Date: Mon, 9 Sep 2024 16:55:44 -0700 Subject: [PATCH 167/227] update tests to use new ideas --- fixed_wide_vectors/src/tests/fixed_wide.rs | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/fixed_wide_vectors/src/tests/fixed_wide.rs b/fixed_wide_vectors/src/tests/fixed_wide.rs index b0f4895..366240d 100644 --- a/fixed_wide_vectors/src/tests/fixed_wide.rs +++ b/fixed_wide_vectors/src/tests/fixed_wide.rs @@ -8,9 +8,9 @@ type Planar64Wide3=fixed_wide::types::I256F256; #[test] fn wide_vec3(){ let v=Vector3::from_value(Planar64::from(3)); - let v1=v.wide_mul_1_1(v); - let v2=v1.wide_mul_2_2(v1); - let v3=v2.wide_mul_4_4(v2); + let v1=v*v; + let v2=v1*v1; + let v3=v2*v2; assert_eq!(v3.array,Vector3::from_value(Planar64Wide3::from(3i128.pow(8))).array); } @@ -18,9 +18,9 @@ fn wide_vec3(){ #[test] fn wide_vec3_dot(){ let v=Vector3::from_value(Planar64::from(3)); - let v1=v.wide_mul_1_1(v); - let v2=v1.wide_mul_2_2(v1); - let v3=v2.wide_dot_4_4(v2); + let v1=v*v; + let v2=v1*v1; + let v3=v2.dot(v2); assert_eq!(v3,Planar64Wide3::from(3i128.pow(8)*3)); } @@ -28,9 +28,9 @@ fn wide_vec3_dot(){ #[test] fn wide_vec3_length_squared(){ let v=Vector3::from_value(Planar64::from(3)); - let v1=v.wide_mul_1_1(v); - let v2=v1.wide_mul_2_2(v1); - let v3=v2.wide_length_squared(); + let v1=v*v; + let v2=v1*v1; + let v3=v2.length_squared(); assert_eq!(v3,Planar64Wide3::from(3i128.pow(8)*3)); } @@ -49,7 +49,7 @@ fn wide_matrix_dot(){ [Planar64::from(7),Planar64::from(8)], ]); // Mat3.dot(Mat4) -> Mat3 - let m_dot=lhs.wide_dot_1_1(rhs); + let m_dot=lhs.dot(rhs); //In[1]:= {{1, 2, 3, 4}, {5, 6, 7, 8}, {9, 10, 11, 12}} . {{1, 2}, {3, 4}, {5, 6}, {7, 8}} //Out[1]= {{50, 60}, {114, 140}, {178, 220}} assert_eq!( From 6cbd3446e5caf4dfb0ea1d8b6ae120fb1b197169 Mon Sep 17 00:00:00 2001 From: Quaternions Date: Mon, 9 Sep 2024 17:01:52 -0700 Subject: [PATCH 168/227] impl matrix multiplication with Mul --- fixed_wide_vectors/src/macros/matrix.rs | 12 ++++++++++++ fixed_wide_vectors/src/tests/fixed_wide.rs | 2 +- fixed_wide_vectors/src/tests/tests.rs | 2 +- 3 files changed, 14 insertions(+), 2 deletions(-) diff --git a/fixed_wide_vectors/src/macros/matrix.rs b/fixed_wide_vectors/src/macros/matrix.rs index 34b7fd8..6a10406 100644 --- a/fixed_wide_vectors/src/macros/matrix.rs +++ b/fixed_wide_vectors/src/macros/matrix.rs @@ -71,6 +71,18 @@ macro_rules! impl_matrix { ) } } + impl core::ops::Mul> for Matrix + where + T:core::ops::Mul+Copy, + V:core::iter::Sum, + U:Copy, + { + type Output=Matrix; + #[inline] + fn mul(self,rhs:Matrix)->Self::Output{ + self.dot(rhs) + } + } #[cfg(feature="fixed_wide")] $crate::impl_matrix_wide_dot_8x8!(); } diff --git a/fixed_wide_vectors/src/tests/fixed_wide.rs b/fixed_wide_vectors/src/tests/fixed_wide.rs index 366240d..5701f8e 100644 --- a/fixed_wide_vectors/src/tests/fixed_wide.rs +++ b/fixed_wide_vectors/src/tests/fixed_wide.rs @@ -49,7 +49,7 @@ fn wide_matrix_dot(){ [Planar64::from(7),Planar64::from(8)], ]); // Mat3.dot(Mat4) -> Mat3 - let m_dot=lhs.dot(rhs); + let m_dot=lhs*rhs; //In[1]:= {{1, 2, 3, 4}, {5, 6, 7, 8}, {9, 10, 11, 12}} . {{1, 2}, {3, 4}, {5, 6}, {7, 8}} //Out[1]= {{50, 60}, {114, 140}, {178, 220}} assert_eq!( diff --git a/fixed_wide_vectors/src/tests/tests.rs b/fixed_wide_vectors/src/tests/tests.rs index 8883fa2..04a5d55 100644 --- a/fixed_wide_vectors/src/tests/tests.rs +++ b/fixed_wide_vectors/src/tests/tests.rs @@ -34,7 +34,7 @@ fn matrix_dot(){ [9.0,10.0,11.0,12.0],// [178.0,220.0], ]); // Mat3.dot(Mat4) -> Mat3 - let m_dot=lhs.dot(rhs); + let m_dot=lhs*rhs; //In[1]:= {{1, 2, 3, 4}, {5, 6, 7, 8}, {9, 10, 11, 12}} . {{1, 2}, {3, 4}, {5, 6}, {7, 8}} //Out[1]= {{50, 60}, {114, 140}, {178, 220}} assert_eq!( From dd2140d1d26f97384a7958dc87d490fd037ec7e6 Mon Sep 17 00:00:00 2001 From: Quaternions Date: Mon, 9 Sep 2024 17:02:03 -0700 Subject: [PATCH 169/227] forgotten inlines --- fixed_wide_vectors/src/macros/matrix.rs | 4 ++++ fixed_wide_vectors/src/macros/vector.rs | 8 ++++++++ 2 files changed, 12 insertions(+) diff --git a/fixed_wide_vectors/src/macros/matrix.rs b/fixed_wide_vectors/src/macros/matrix.rs index 6a10406..fedf100 100644 --- a/fixed_wide_vectors/src/macros/matrix.rs +++ b/fixed_wide_vectors/src/macros/matrix.rs @@ -59,12 +59,14 @@ macro_rules! impl_matrix { where T:Copy { + #[inline(always)] pub const fn from_value(value:T)->Self{ Self::new([[value;X];Y]) } } impl Default for Matrix{ + #[inline] fn default()->Self{ Self::new( core::array::from_fn(|_|core::array::from_fn(|_|Default::default())) @@ -123,11 +125,13 @@ macro_rules! impl_matrix_named_fields_shape { ) => { impl core::ops::Deref for Matrix<$size_outer,$size_inner,T>{ type Target=$struct_outer>; + #[inline] fn deref(&self)->&Self::Target{ unsafe{core::mem::transmute(&self.array)} } } impl core::ops::DerefMut for Matrix<$size_outer,$size_inner,T>{ + #[inline] fn deref_mut(&mut self)->&mut Self::Target{ unsafe{core::mem::transmute(&mut self.array)} } diff --git a/fixed_wide_vectors/src/macros/vector.rs b/fixed_wide_vectors/src/macros/vector.rs index 5264958..17f5406 100644 --- a/fixed_wide_vectors/src/macros/vector.rs +++ b/fixed_wide_vectors/src/macros/vector.rs @@ -39,6 +39,7 @@ macro_rules! impl_vector { } impl Default for Vector{ + #[inline] fn default()->Self{ Self::new( core::array::from_fn(|_|Default::default()) @@ -90,6 +91,7 @@ macro_rules! impl_vector { impl,V> core::ops::Neg for Vector{ type Output=Vector; + #[inline] fn neg(self)->Self::Output{ Vector::new( self.array.map(|t|-t) @@ -151,12 +153,14 @@ macro_rules! impl_vector_operator { ($trait: ident, $method: ident ) => { impl,U,V> core::ops::$trait> for Vector{ type Output=Vector; + #[inline] fn $method(self,rhs:Vector)->Self::Output{ self.map_zip(rhs,|(a,b)|a.$method(b)) } } impl> core::ops::$trait for Vector{ type Output=Self; + #[inline] fn $method(self,rhs:i64)->Self::Output{ self.map(|t|t.$method(rhs)) } @@ -168,12 +172,14 @@ macro_rules! impl_vector_operator { macro_rules! impl_vector_assign_operator { ($trait: ident, $method: ident ) => { impl,U> core::ops::$trait> for Vector{ + #[inline] fn $method(&mut self,rhs:Vector){ self.array.iter_mut().zip(rhs.array) .for_each(|(a,b)|a.$method(b)) } } impl> core::ops::$trait for Vector{ + #[inline] fn $method(&mut self,rhs:i64){ self.array.iter_mut() .for_each(|t|t.$method(rhs)) @@ -204,11 +210,13 @@ macro_rules! impl_vector_named_fields { ( $struct:ident, $size: expr ) => { impl core::ops::Deref for Vector<$size,T>{ type Target=$struct; + #[inline] fn deref(&self)->&Self::Target{ unsafe{core::mem::transmute(&self.array)} } } impl core::ops::DerefMut for Vector<$size,T>{ + #[inline] fn deref_mut(&mut self)->&mut Self::Target{ unsafe{core::mem::transmute(&mut self.array)} } From b7726471371cacb9a276fdd9781f87bb600ee818 Mon Sep 17 00:00:00 2001 From: Quaternions Date: Mon, 9 Sep 2024 17:22:37 -0700 Subject: [PATCH 170/227] impl Mat*Vec --- fixed_wide_vectors/src/macros/matrix.rs | 26 +++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/fixed_wide_vectors/src/macros/matrix.rs b/fixed_wide_vectors/src/macros/matrix.rs index fedf100..ecd0d85 100644 --- a/fixed_wide_vectors/src/macros/matrix.rs +++ b/fixed_wide_vectors/src/macros/matrix.rs @@ -54,6 +54,20 @@ macro_rules! impl_matrix { ) ) } + #[inline] + // MatY.VecX = VecY + pub fn transform_vector(self,rhs:Vector)->Vector + where + T:core::ops::Mul, + V:core::iter::Sum, + U:Copy, + { + Vector::new( + self.array.map(|axis| + Vector::new(axis).dot(rhs) + ) + ) + } } impl Matrix where @@ -85,6 +99,18 @@ macro_rules! impl_matrix { self.dot(rhs) } } + impl core::ops::Mul> for Matrix + where + T:core::ops::Mul, + V:core::iter::Sum, + U:Copy, + { + type Output=Vector; + #[inline] + fn mul(self,rhs:Vector)->Self::Output{ + self.transform_vector(rhs) + } + } #[cfg(feature="fixed_wide")] $crate::impl_matrix_wide_dot_8x8!(); } From 57c3f2dd9e9ce9a4dcc76f4b7550a485c39ba7ff Mon Sep 17 00:00:00 2001 From: Quaternions Date: Mon, 9 Sep 2024 17:32:39 -0700 Subject: [PATCH 171/227] write m*v test --- fixed_wide_vectors/src/tests/tests.rs | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/fixed_wide_vectors/src/tests/tests.rs b/fixed_wide_vectors/src/tests/tests.rs index 04a5d55..41233b2 100644 --- a/fixed_wide_vectors/src/tests/tests.rs +++ b/fixed_wide_vectors/src/tests/tests.rs @@ -1,4 +1,4 @@ -use crate::types::{Vector3,Matrix4x3,Matrix2x4,Matrix2x3}; +use crate::types::{Vector2,Vector3,Matrix4x3,Matrix2x4,Matrix2x3,Matrix3x2}; #[test] fn test_bool(){ @@ -19,6 +19,17 @@ fn test_arithmetic(){ assert_eq!((a+a*2).array,Vector3::new([1*3,2*3,3*3]).array); } +#[test] +fn matrix_transform_vector(){ + let m=Matrix3x2::new([ + [1,2,3], + [4,5,6], + ]); + let v=Vector3::new([1,2,3]); + let transformed=m*v; + assert_eq!(transformed.array,Vector2::new([14,32]).array); +} + #[test] fn matrix_dot(){ From eb7eb30814c7269e71c416b0349636a135e61405 Mon Sep 17 00:00:00 2001 From: Quaternions Date: Mon, 9 Sep 2024 18:02:05 -0700 Subject: [PATCH 172/227] impl det + adjugate with trait bounds --- fixed_wide_vectors/src/macros/matrix.rs | 26 ++++++++++++++++++++++ fixed_wide_vectors/src/tests/fixed_wide.rs | 4 ++-- 2 files changed, 28 insertions(+), 2 deletions(-) diff --git a/fixed_wide_vectors/src/macros/matrix.rs b/fixed_wide_vectors/src/macros/matrix.rs index ecd0d85..da7f209 100644 --- a/fixed_wide_vectors/src/macros/matrix.rs +++ b/fixed_wide_vectors/src/macros/matrix.rs @@ -191,6 +191,32 @@ macro_rules! impl_matrix_named_fields { #[macro_export(local_inner_macros)] macro_rules! impl_matrix_3x3 { ()=>{ + impl Matrix<3,3,T> + where + //cross + T:core::ops::Mul+Copy, + T2:core::ops::Sub, + //dot + T:core::ops::Mul<::Output,Output=T3>, + T3:core::iter::Sum, + { + pub fn det(self)->T3{ + self.x_axis.dot(self.y_axis.cross(self.z_axis)) + } + } + impl Matrix<3,3,T> + where + T:core::ops::Mul+Copy, + T2:core::ops::Sub, + { + pub fn adjugate(self)->Matrix<3,3,::Output>{ + Matrix::new([ + [self.y_axis.y*self.z_axis.z-self.y_axis.z*self.z_axis.y,self.x_axis.z*self.z_axis.y-self.x_axis.y*self.z_axis.z,self.x_axis.y*self.y_axis.z-self.x_axis.z*self.y_axis.y], + [self.y_axis.z*self.z_axis.x-self.y_axis.x*self.z_axis.z,self.x_axis.x*self.z_axis.z-self.x_axis.z*self.z_axis.x,self.x_axis.z*self.y_axis.x-self.x_axis.x*self.y_axis.z], + [self.y_axis.x*self.z_axis.y-self.y_axis.y*self.z_axis.x,self.x_axis.y*self.z_axis.x-self.x_axis.x*self.z_axis.y,self.x_axis.x*self.y_axis.y-self.x_axis.y*self.y_axis.x], + ]) + } + } #[cfg(feature="fixed_wide")] $crate::impl_matrix_wide_3x3!(); } diff --git a/fixed_wide_vectors/src/tests/fixed_wide.rs b/fixed_wide_vectors/src/tests/fixed_wide.rs index 5701f8e..9b363bb 100644 --- a/fixed_wide_vectors/src/tests/fixed_wide.rs +++ b/fixed_wide_vectors/src/tests/fixed_wide.rs @@ -71,7 +71,7 @@ fn wide_matrix_det(){ ]); // In[2]:= Det[{{1, 2, 3}, {4, 5, 7}, {6, 8, 9}}] // Out[2]= 7 - assert_eq!(m.wide_det_3x3_1(),fixed_wide::fixed::Fixed::<3,96>::from(7)); + assert_eq!(m.det(),fixed_wide::fixed::Fixed::<3,96>::from(7)); } #[test] @@ -84,7 +84,7 @@ fn wide_matrix_adjugate(){ // In[6]:= Adjugate[{{1, 2, 3}, {4, 5, 7}, {6, 8, 9}}] // Out[6]= {{-11, 6, -1}, {6, -9, 5}, {2, 4, -3}} assert_eq!( - m.wide_adjugate_3x3_1().array, + m.adjugate().array, Matrix3::new([ [Planar64Wide1::from(-11),Planar64Wide1::from(6),Planar64Wide1::from(-1)], [Planar64Wide1::from(6),Planar64Wide1::from(-9),Planar64Wide1::from(5)], From e66a245c7804a716e13bc9db9e18cb3fbaf78688 Mon Sep 17 00:00:00 2001 From: Quaternions Date: Tue, 10 Sep 2024 10:02:11 -0700 Subject: [PATCH 173/227] delete fixed-wide --- fixed_wide_vectors/Cargo.lock | 1 - fixed_wide_vectors/Cargo.toml | 8 +- fixed_wide_vectors/src/macros/fixed_wide.rs | 212 -------------------- fixed_wide_vectors/src/macros/matrix.rs | 4 - fixed_wide_vectors/src/macros/mod.rs | 3 - fixed_wide_vectors/src/macros/vector.rs | 6 - fixed_wide_vectors/src/tests/mod.rs | 1 - 7 files changed, 3 insertions(+), 232 deletions(-) delete mode 100644 fixed_wide_vectors/src/macros/fixed_wide.rs diff --git a/fixed_wide_vectors/Cargo.lock b/fixed_wide_vectors/Cargo.lock index 7c320dd..5bb2156 100644 --- a/fixed_wide_vectors/Cargo.lock +++ b/fixed_wide_vectors/Cargo.lock @@ -28,7 +28,6 @@ name = "fixed_wide_vectors" version = "0.1.0" dependencies = [ "fixed_wide", - "paste", ] [[package]] diff --git a/fixed_wide_vectors/Cargo.toml b/fixed_wide_vectors/Cargo.toml index ce607be..7b1c0f5 100644 --- a/fixed_wide_vectors/Cargo.toml +++ b/fixed_wide_vectors/Cargo.toml @@ -4,10 +4,8 @@ version = "0.1.0" edition = "2021" [features] -default=["fixed_wide","named-fields"] +default=["named-fields"] named-fields=[] -fixed_wide=["dep:fixed_wide","dep:paste"] -[dependencies] -fixed_wide = { version = "0.1.0", path = "../fixed_wide", optional = true } -paste = { version = "1.0.15", optional = true } +[dev-dependencies] +fixed_wide = { version = "0.1.0", path = "../fixed_wide" } diff --git a/fixed_wide_vectors/src/macros/fixed_wide.rs b/fixed_wide_vectors/src/macros/fixed_wide.rs deleted file mode 100644 index 0a2e0eb..0000000 --- a/fixed_wide_vectors/src/macros/fixed_wide.rs +++ /dev/null @@ -1,212 +0,0 @@ -#[doc(hidden)] -#[macro_export(local_inner_macros)] -macro_rules! impl_wide_vector_operations_2arg_not_const_generic { - ( - (), - ($lhs:expr, $rhs:expr) - ) => { - impl Vector>{ - paste::item!{ - #[inline] - pub fn [](self,rhs:Vector>)->Vector>{ - self.map_zip(rhs,|(a,b)|a.[](b)) - } - #[inline] - pub fn [](self,rhs:Vector>)->fixed_wide::fixed::Fixed<{$lhs+$rhs},{($lhs+$rhs)*32}>{ - self.array.into_iter().zip(rhs.array).map(|(a,b)|a.[](b)).sum() - } - } - } - } -} -#[doc(hidden)] -#[macro_export(local_inner_macros)] -macro_rules! impl_wide_vector_operations_1arg_not_const_generic { - ( - (), - $n:expr - ) => { - impl Vector>{ - paste::item!{ - #[inline] - pub fn wide_length_squared(&self)->fixed_wide::fixed::Fixed<{$n*2},{$n*2*32}>{ - self.array.into_iter().map(|t|t.[](t)).sum() - } - } - } - }; -} - -#[doc(hidden)] -#[macro_export(local_inner_macros)] -macro_rules! do_macro_8x8{ - ( - $macro:ident, - $any:tt - )=>{ - $crate::macro_repeated!($macro, $any, - (1,1),(2,1),(3,1),(4,1),(5,1),(6,1),(7,1),(8,1), - (1,2),(2,2),(3,2),(4,2),(5,2),(6,2),(7,2),(8,2), - (1,3),(2,3),(3,3),(4,3),(5,3),(6,3),(7,3),(8,3), - (1,4),(2,4),(3,4),(4,4),(5,4),(6,4),(7,4),(8,4), - (1,5),(2,5),(3,5),(4,5),(5,5),(6,5),(7,5),(8,5), - (1,6),(2,6),(3,6),(4,6),(5,6),(6,6),(7,6),(8,6), - (1,7),(2,7),(3,7),(4,7),(5,7),(6,7),(7,7),(8,7), - (1,8),(2,8),(3,8),(4,8),(5,8),(6,8),(7,8),(8,8) - ); - }; -} - -#[doc(hidden)] -#[macro_export(local_inner_macros)] -macro_rules! do_macro_8{ - ( - $macro:ident, - $any:tt - )=>{ - $crate::macro_repeated!($macro, $any, 1,2,3,4,5,6,7,8); - }; -} - -#[doc(hidden)] -#[macro_export(local_inner_macros)] -macro_rules! impl_wide_vector_operations { - () => { - $crate::do_macro_8!(impl_wide_vector_operations_1arg_not_const_generic,()); - $crate::do_macro_8x8!(impl_wide_vector_operations_2arg_not_const_generic,()); - }; -} - -#[doc(hidden)] -#[macro_export(local_inner_macros)] -macro_rules! impl_vector_3_wide_cross { - ( - (), - ($lhs:expr, $rhs:expr) - )=>{ - impl Vector<3,fixed_wide::fixed::Fixed<{$lhs},{$lhs*32}>>{ - paste::item!{ - #[inline] - pub fn [](self,rhs:Vector<3,fixed_wide::fixed::Fixed<{$rhs},{$rhs*32}>>)->Vector<3,fixed_wide::fixed::Fixed<{$lhs+$rhs},{($lhs+$rhs)*32}>>{ - Vector::new([ - self.y.[](rhs.z)-self.z.[](rhs.y), - self.z.[](rhs.x)-self.x.[](rhs.z), - self.x.[](rhs.y)-self.y.[](rhs.x), - ]) - } - } - } - } -} - -#[doc(hidden)] -#[macro_export(local_inner_macros)] -macro_rules! impl_vector_wide_3 { - ()=>{ - $crate::do_macro_8x8!(impl_vector_3_wide_cross,()); - } -} - -#[doc(hidden)] -#[macro_export(local_inner_macros)] -macro_rules! do_macro_4_dumb{ - ( - $macro:ident, - $any:tt - )=>{ - $crate::macro_repeated!($macro, $any, (1,2),(2,4),(3,6),(4,8)); - }; -} - -#[doc(hidden)] -#[macro_export(local_inner_macros)] -macro_rules! impl_matrix_wide_dot { - ( - (), - ($lhs: expr, $rhs: expr) - ) => { - impl Matrix>{ - paste::item!{ - #[inline] - pub fn [](self,rhs:Matrix>)->Matrix>{ - let mut array_of_iterators=rhs.array.map(|axis|axis.into_iter().cycle()); - Matrix::new( - self.array.map(|axis| - core::array::from_fn(|_| - // axis dot product with transposed rhs array - axis.iter().zip( - array_of_iterators.iter_mut() - ).map(|(&lhs_value,rhs_iter)| - lhs_value.[](rhs_iter.next().unwrap()) - ).sum() - ) - ) - ) - } - } - } - } -} - -#[doc(hidden)] -#[macro_export(local_inner_macros)] -macro_rules! impl_matrix_wide_dot_8x8 { - () => { - $crate::do_macro_8x8!(impl_matrix_wide_dot,()); - } -} - -#[doc(hidden)] -#[macro_export(local_inner_macros)] -macro_rules! impl_matrix_wide_3x3_det_not_const_generic { - ( - $n: expr, - $_2n: expr - )=>{ - impl Matrix<3,3,fixed_wide::fixed::Fixed<$n,{$n*32}>>{ - paste::item!{ - pub fn [](self)->fixed_wide::fixed::Fixed<{$n*3},{$n*3*32}>{ - //[] will not compile, so the doubles are hardcoded above - self.x_axis.[](self.y_axis.[](self.z_axis)) - } - } - } - } -} -#[doc(hidden)] -#[macro_export(local_inner_macros)] -macro_rules! impl_matrix_wide_3x3_det_not_const_generic_shim { - ( - (),($n: expr,$_2n: expr) - )=>{ - $crate::impl_matrix_wide_3x3_det_not_const_generic!($n,$_2n); - } -} -#[doc(hidden)] -#[macro_export(local_inner_macros)] -macro_rules! impl_matrix_wide_3x3_adjugate_not_const_generic { - ( - (), - $n: expr - )=>{ - impl Matrix<3,3,fixed_wide::fixed::Fixed<$n,{$n*32}>>{ - paste::item!{ - pub fn [](self)->Matrix<3,3,fixed_wide::fixed::Fixed<{$n*2},{$n*2*32}>>{ - Matrix::new([ - [self.y_axis.y.[](self.z_axis.z)-self.y_axis.z.[](self.z_axis.y),self.x_axis.z.[](self.z_axis.y)-self.x_axis.y.[](self.z_axis.z),self.x_axis.y.[](self.y_axis.z)-self.x_axis.z.[](self.y_axis.y)], - [self.y_axis.z.[](self.z_axis.x)-self.y_axis.x.[](self.z_axis.z),self.x_axis.x.[](self.z_axis.z)-self.x_axis.z.[](self.z_axis.x),self.x_axis.z.[](self.y_axis.x)-self.x_axis.x.[](self.y_axis.z)], - [self.y_axis.x.[](self.z_axis.y)-self.y_axis.y.[](self.z_axis.x),self.x_axis.y.[](self.z_axis.x)-self.x_axis.x.[](self.z_axis.y),self.x_axis.x.[](self.y_axis.y)-self.x_axis.y.[](self.y_axis.x)], - ]) - } - } - } - } -} -#[doc(hidden)] -#[macro_export(local_inner_macros)] -macro_rules! impl_matrix_wide_3x3 { - ()=>{ - $crate::do_macro_4_dumb!(impl_matrix_wide_3x3_det_not_const_generic_shim,()); - $crate::do_macro_8!(impl_matrix_wide_3x3_adjugate_not_const_generic,()); - } -} diff --git a/fixed_wide_vectors/src/macros/matrix.rs b/fixed_wide_vectors/src/macros/matrix.rs index da7f209..56634b6 100644 --- a/fixed_wide_vectors/src/macros/matrix.rs +++ b/fixed_wide_vectors/src/macros/matrix.rs @@ -111,8 +111,6 @@ macro_rules! impl_matrix { self.transform_vector(rhs) } } - #[cfg(feature="fixed_wide")] - $crate::impl_matrix_wide_dot_8x8!(); } } @@ -217,7 +215,5 @@ macro_rules! impl_matrix_3x3 { ]) } } - #[cfg(feature="fixed_wide")] - $crate::impl_matrix_wide_3x3!(); } } diff --git a/fixed_wide_vectors/src/macros/mod.rs b/fixed_wide_vectors/src/macros/mod.rs index 572d35c..d551722 100644 --- a/fixed_wide_vectors/src/macros/mod.rs +++ b/fixed_wide_vectors/src/macros/mod.rs @@ -1,6 +1,3 @@ -#[cfg(feature="fixed_wide")] -pub mod fixed_wide; - pub mod common; pub mod vector; pub mod matrix; diff --git a/fixed_wide_vectors/src/macros/vector.rs b/fixed_wide_vectors/src/macros/vector.rs index 17f5406..37654b6 100644 --- a/fixed_wide_vectors/src/macros/vector.rs +++ b/fixed_wide_vectors/src/macros/vector.rs @@ -141,10 +141,6 @@ macro_rules! impl_vector { $crate::impl_vector_operator!(BitOr, bitor ); $crate::impl_vector_assign_operator!(BitXorAssign, bitxor_assign ); $crate::impl_vector_operator!(BitXor, bitxor ); - - // Impl floating-point based methods - #[cfg(feature="fixed_wide")] - $crate::impl_wide_vector_operations!(); } } #[doc(hidden)] @@ -244,7 +240,5 @@ macro_rules! impl_vector_3 { ]) } } - #[cfg(feature="fixed_wide")] - $crate::impl_vector_wide_3!(); } } diff --git a/fixed_wide_vectors/src/tests/mod.rs b/fixed_wide_vectors/src/tests/mod.rs index 06e9ee5..5bdf283 100644 --- a/fixed_wide_vectors/src/tests/mod.rs +++ b/fixed_wide_vectors/src/tests/mod.rs @@ -3,5 +3,4 @@ mod tests; #[cfg(feature="named-fields")] mod named; -#[cfg(feature="fixed_wide")] mod fixed_wide; From c20a0a4a8937fb7ebd4754ca33244b777032c923 Mon Sep 17 00:00:00 2001 From: Quaternions Date: Tue, 10 Sep 2024 11:14:12 -0700 Subject: [PATCH 174/227] compare with From types --- fixed_wide/src/fixed.rs | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/fixed_wide/src/fixed.rs b/fixed_wide/src/fixed.rs index 79f7579..df6b957 100644 --- a/fixed_wide/src/fixed.rs +++ b/fixed_wide/src/fixed.rs @@ -52,6 +52,15 @@ impl PartialEq for Fixed{ self.bits.eq(&other.bits) } } +impl PartialEq for Fixed +where + T:Copy, + BInt:::From, +{ + fn eq(&self,&other:&T)->bool{ + self.bits.eq(&other.into()) + } +} impl Eq for Fixed{} impl PartialOrd for Fixed{ @@ -59,6 +68,15 @@ impl PartialOrd for Fixed{ self.bits.partial_cmp(&other.bits) } } +impl PartialOrd for Fixed + where + T:Copy, + BInt:::From, +{ + fn partial_cmp(&self,&other:&T)->Option{ + self.bits.partial_cmp(&other.into()) + } +} impl Ord for Fixed{ fn cmp(&self,other:&Self)->std::cmp::Ordering{ self.bits.cmp(&other.bits) From fa8614891dc5956d36e147a44abe0baf427191a1 Mon Sep 17 00:00:00 2001 From: Quaternions Date: Tue, 10 Sep 2024 11:26:46 -0700 Subject: [PATCH 175/227] zeroes function uses type transformation, drops direct ratio dep from zeroes --- fixed_wide/Cargo.toml | 4 ++-- fixed_wide/src/fixed.rs | 5 +++-- fixed_wide/src/zeroes.rs | 29 +++++++++++++++-------------- 3 files changed, 20 insertions(+), 18 deletions(-) diff --git a/fixed_wide/Cargo.toml b/fixed_wide/Cargo.toml index ab20a56..f24c634 100644 --- a/fixed_wide/Cargo.toml +++ b/fixed_wide/Cargo.toml @@ -4,10 +4,10 @@ version = "0.1.0" edition = "2021" [features] -default=["zeroes","wide-mul"] +default=["ratio","zeroes","wide-mul"] ratio=[] wide-mul=[] -zeroes=["ratio","dep:arrayvec"] +zeroes=["dep:arrayvec"] [dependencies] bnum = "0.11.0" diff --git a/fixed_wide/src/fixed.rs b/fixed_wide/src/fixed.rs index df6b957..2e75e08 100644 --- a/fixed_wide/src/fixed.rs +++ b/fixed_wide/src/fixed.rs @@ -408,11 +408,12 @@ macro_rules! impl_not_const_generic{ let mut result=Self::ZERO; //multiply by one to make the types match (hack) - let wide_self=self.[](Self::ONE); + //TODO: use resize method + let wide_self:::Output=self*Self::ONE; //descend down the bits and check if flipping each bit would push the square over the input value for shift in (0..=max_shift).rev(){ let new_result=result|Self::from_bits(BInt::from_bits(bnum::BUint::power_of_two(shift))); - if new_result.[](new_result)<=wide_self{ + if new_result*new_result<=wide_self{ result=new_result; } } diff --git a/fixed_wide/src/zeroes.rs b/fixed_wide/src/zeroes.rs index 5966615..3634a02 100644 --- a/fixed_wide/src/zeroes.rs +++ b/fixed_wide/src/zeroes.rs @@ -1,5 +1,4 @@ use crate::fixed::Fixed; -use crate::ratio::Ratio; use arrayvec::ArrayVec; use std::cmp::Ordering; @@ -7,36 +6,38 @@ macro_rules! impl_zeroes{ ($n:expr)=>{ impl Fixed<$n,{$n*32}>{ #[inline] - pub fn zeroes2(a0:Self,a1:Self,a2:Self)->ArrayVec,2>{ + pub fn zeroes2(a0:Self,a1:Self,a2:Self)->ArrayVec<::Output,2>{ let a2pos=match a2.cmp(&Self::ZERO){ Ordering::Greater=>true, Ordering::Equal=>return ArrayVec::from_iter(Self::zeroes1(a0,a1).into_iter()), Ordering::Less=>true, }; paste::item!{ - let radicand=a1.[](a1)-a2.[](a0)*4; + let radicand=a1*a1-a2*a0*4; } - match radicand.cmp(&Fixed::<{$n*2},{$n*2*32}>::ZERO){ + match radicand.cmp(&::Output::ZERO){ Ordering::Greater=>{ - let planar_radicand=radicand.sqrt().halve_precision(); + //TODO: use resize method + let planar_radicand:Self=radicand.sqrt().halve_precision(); //sort roots ascending and avoid taking the difference of large numbers - match (a2pos,Self::ZERO[Ratio::new(-a1-planar_radicand,a2*2),Ratio::new(a0*2,-a1-planar_radicand)].into(), - (true, false)=>[Ratio::new(a0*2,-a1+planar_radicand),Ratio::new(-a1+planar_radicand,a2*2)].into(), - (false,true )=>[Ratio::new(a0*2,-a1-planar_radicand),Ratio::new(-a1-planar_radicand,a2*2)].into(), - (false,false)=>[Ratio::new(-a1+planar_radicand,a2*2),Ratio::new(a0*2,-a1+planar_radicand)].into(), - } + let zeroes=match (a2pos,Self::ZERO[(-a1-planar_radicand)/(a2*2),(a0*2)/(-a1-planar_radicand)], + (true, false)=>[(a0*2)/(-a1+planar_radicand),(-a1+planar_radicand)/(a2*2)], + (false,true )=>[(a0*2)/(-a1-planar_radicand),(-a1-planar_radicand)/(a2*2)], + (false,false)=>[(-a1+planar_radicand)/(a2*2),(a0*2)/(-a1+planar_radicand)], + }; + ArrayVec::from_iter(zeroes) }, - Ordering::Equal=>ArrayVec::from_iter([Ratio::new(a1,a2*-2)]), + Ordering::Equal=>ArrayVec::from_iter([(a1)/(a2*-2)]), Ordering::Less=>ArrayVec::new_const(), } } #[inline] - pub fn zeroes1(a0:Self,a1:Self)->ArrayVec,1>{ + pub fn zeroes1(a0:Self,a1:Self)->ArrayVec<::Output,1>{ if a1==Self::ZERO{ ArrayVec::new_const() }else{ - ArrayVec::from_iter([Ratio::new(-a0,a1)]) + ArrayVec::from_iter([(-a0)/(a1)]) } } } From 4eaf8794f6cf1dfbbc6b2d490dad74780c4bb57e Mon Sep 17 00:00:00 2001 From: Quaternions Date: Tue, 10 Sep 2024 11:32:42 -0700 Subject: [PATCH 176/227] fix compile without named fields --- fixed_wide_vectors/src/matrix.rs | 1 + fixed_wide_vectors/src/tests/fixed_wide.rs | 2 ++ fixed_wide_vectors/src/vector.rs | 1 + 3 files changed, 4 insertions(+) diff --git a/fixed_wide_vectors/src/matrix.rs b/fixed_wide_vectors/src/matrix.rs index 5a6b914..be59900 100644 --- a/fixed_wide_vectors/src/matrix.rs +++ b/fixed_wide_vectors/src/matrix.rs @@ -13,4 +13,5 @@ crate::impl_matrix_extend!(3,2); crate::impl_matrix_extend!(3,3); //Special case 3x3 matrix operations because I cba to write macros for the arbitrary cases +#[cfg(feature="named-fields")] crate::impl_matrix_3x3!(); diff --git a/fixed_wide_vectors/src/tests/fixed_wide.rs b/fixed_wide_vectors/src/tests/fixed_wide.rs index 9b363bb..f0ee366 100644 --- a/fixed_wide_vectors/src/tests/fixed_wide.rs +++ b/fixed_wide_vectors/src/tests/fixed_wide.rs @@ -63,6 +63,7 @@ fn wide_matrix_dot(){ } #[test] +#[cfg(feature="named-fields")] fn wide_matrix_det(){ let m=Matrix3::new([ [Planar64::from(1),Planar64::from(2),Planar64::from(3)], @@ -75,6 +76,7 @@ fn wide_matrix_det(){ } #[test] +#[cfg(feature="named-fields")] fn wide_matrix_adjugate(){ let m=Matrix3::new([ [Planar64::from(1),Planar64::from(2),Planar64::from(3)], diff --git a/fixed_wide_vectors/src/vector.rs b/fixed_wide_vectors/src/vector.rs index 3b7a15d..b5a41e5 100644 --- a/fixed_wide_vectors/src/vector.rs +++ b/fixed_wide_vectors/src/vector.rs @@ -15,4 +15,5 @@ crate::impl_vector_extend!(2); crate::impl_vector_extend!(3); //cross product +#[cfg(feature="named-fields")] crate::impl_vector_3!(); From fc65d0f1f4e96ad757982ec40c99b67d4aedb763 Mon Sep 17 00:00:00 2001 From: Quaternions Date: Tue, 10 Sep 2024 11:47:37 -0700 Subject: [PATCH 177/227] rename fixed_wide_vectors to linear_ops --- {fixed_wide_vectors => linear_ops}/.gitignore | 0 {fixed_wide_vectors => linear_ops}/Cargo.lock | 2 +- {fixed_wide_vectors => linear_ops}/Cargo.toml | 2 +- {fixed_wide_vectors => linear_ops}/src/lib.rs | 0 {fixed_wide_vectors => linear_ops}/src/macros/common.rs | 0 {fixed_wide_vectors => linear_ops}/src/macros/matrix.rs | 0 {fixed_wide_vectors => linear_ops}/src/macros/mod.rs | 0 {fixed_wide_vectors => linear_ops}/src/macros/vector.rs | 0 {fixed_wide_vectors => linear_ops}/src/matrix.rs | 0 {fixed_wide_vectors => linear_ops}/src/named.rs | 0 {fixed_wide_vectors => linear_ops}/src/tests/fixed_wide.rs | 0 {fixed_wide_vectors => linear_ops}/src/tests/mod.rs | 0 {fixed_wide_vectors => linear_ops}/src/tests/named.rs | 0 {fixed_wide_vectors => linear_ops}/src/tests/tests.rs | 0 {fixed_wide_vectors => linear_ops}/src/types.rs | 0 {fixed_wide_vectors => linear_ops}/src/vector.rs | 0 16 files changed, 2 insertions(+), 2 deletions(-) rename {fixed_wide_vectors => linear_ops}/.gitignore (100%) rename {fixed_wide_vectors => linear_ops}/Cargo.lock (96%) rename {fixed_wide_vectors => linear_ops}/Cargo.toml (86%) rename {fixed_wide_vectors => linear_ops}/src/lib.rs (100%) rename {fixed_wide_vectors => linear_ops}/src/macros/common.rs (100%) rename {fixed_wide_vectors => linear_ops}/src/macros/matrix.rs (100%) rename {fixed_wide_vectors => linear_ops}/src/macros/mod.rs (100%) rename {fixed_wide_vectors => linear_ops}/src/macros/vector.rs (100%) rename {fixed_wide_vectors => linear_ops}/src/matrix.rs (100%) rename {fixed_wide_vectors => linear_ops}/src/named.rs (100%) rename {fixed_wide_vectors => linear_ops}/src/tests/fixed_wide.rs (100%) rename {fixed_wide_vectors => linear_ops}/src/tests/mod.rs (100%) rename {fixed_wide_vectors => linear_ops}/src/tests/named.rs (100%) rename {fixed_wide_vectors => linear_ops}/src/tests/tests.rs (100%) rename {fixed_wide_vectors => linear_ops}/src/types.rs (100%) rename {fixed_wide_vectors => linear_ops}/src/vector.rs (100%) diff --git a/fixed_wide_vectors/.gitignore b/linear_ops/.gitignore similarity index 100% rename from fixed_wide_vectors/.gitignore rename to linear_ops/.gitignore diff --git a/fixed_wide_vectors/Cargo.lock b/linear_ops/Cargo.lock similarity index 96% rename from fixed_wide_vectors/Cargo.lock rename to linear_ops/Cargo.lock index 5bb2156..4e0f92e 100644 --- a/fixed_wide_vectors/Cargo.lock +++ b/linear_ops/Cargo.lock @@ -24,7 +24,7 @@ dependencies = [ ] [[package]] -name = "fixed_wide_vectors" +name = "lin_ops" version = "0.1.0" dependencies = [ "fixed_wide", diff --git a/fixed_wide_vectors/Cargo.toml b/linear_ops/Cargo.toml similarity index 86% rename from fixed_wide_vectors/Cargo.toml rename to linear_ops/Cargo.toml index 7b1c0f5..351534e 100644 --- a/fixed_wide_vectors/Cargo.toml +++ b/linear_ops/Cargo.toml @@ -1,5 +1,5 @@ [package] -name = "fixed_wide_vectors" +name = "linear_ops" version = "0.1.0" edition = "2021" diff --git a/fixed_wide_vectors/src/lib.rs b/linear_ops/src/lib.rs similarity index 100% rename from fixed_wide_vectors/src/lib.rs rename to linear_ops/src/lib.rs diff --git a/fixed_wide_vectors/src/macros/common.rs b/linear_ops/src/macros/common.rs similarity index 100% rename from fixed_wide_vectors/src/macros/common.rs rename to linear_ops/src/macros/common.rs diff --git a/fixed_wide_vectors/src/macros/matrix.rs b/linear_ops/src/macros/matrix.rs similarity index 100% rename from fixed_wide_vectors/src/macros/matrix.rs rename to linear_ops/src/macros/matrix.rs diff --git a/fixed_wide_vectors/src/macros/mod.rs b/linear_ops/src/macros/mod.rs similarity index 100% rename from fixed_wide_vectors/src/macros/mod.rs rename to linear_ops/src/macros/mod.rs diff --git a/fixed_wide_vectors/src/macros/vector.rs b/linear_ops/src/macros/vector.rs similarity index 100% rename from fixed_wide_vectors/src/macros/vector.rs rename to linear_ops/src/macros/vector.rs diff --git a/fixed_wide_vectors/src/matrix.rs b/linear_ops/src/matrix.rs similarity index 100% rename from fixed_wide_vectors/src/matrix.rs rename to linear_ops/src/matrix.rs diff --git a/fixed_wide_vectors/src/named.rs b/linear_ops/src/named.rs similarity index 100% rename from fixed_wide_vectors/src/named.rs rename to linear_ops/src/named.rs diff --git a/fixed_wide_vectors/src/tests/fixed_wide.rs b/linear_ops/src/tests/fixed_wide.rs similarity index 100% rename from fixed_wide_vectors/src/tests/fixed_wide.rs rename to linear_ops/src/tests/fixed_wide.rs diff --git a/fixed_wide_vectors/src/tests/mod.rs b/linear_ops/src/tests/mod.rs similarity index 100% rename from fixed_wide_vectors/src/tests/mod.rs rename to linear_ops/src/tests/mod.rs diff --git a/fixed_wide_vectors/src/tests/named.rs b/linear_ops/src/tests/named.rs similarity index 100% rename from fixed_wide_vectors/src/tests/named.rs rename to linear_ops/src/tests/named.rs diff --git a/fixed_wide_vectors/src/tests/tests.rs b/linear_ops/src/tests/tests.rs similarity index 100% rename from fixed_wide_vectors/src/tests/tests.rs rename to linear_ops/src/tests/tests.rs diff --git a/fixed_wide_vectors/src/types.rs b/linear_ops/src/types.rs similarity index 100% rename from fixed_wide_vectors/src/types.rs rename to linear_ops/src/types.rs diff --git a/fixed_wide_vectors/src/vector.rs b/linear_ops/src/vector.rs similarity index 100% rename from fixed_wide_vectors/src/vector.rs rename to linear_ops/src/vector.rs From 91b96e4b5d4c6ee149c31f7ece91db86f01190bc Mon Sep 17 00:00:00 2001 From: Quaternions Date: Tue, 10 Sep 2024 12:04:18 -0700 Subject: [PATCH 178/227] move ratio to own crate (again) --- fixed_wide/Cargo.lock | 5 +++++ fixed_wide/Cargo.toml | 5 +++-- fixed_wide/src/fixed.rs | 10 +++++----- fixed_wide/src/lib.rs | 2 -- linear_ops/Cargo.lock | 7 ++++++- ratio_ops/.gitignore | 1 + ratio_ops/Cargo.lock | 7 +++++++ ratio_ops/Cargo.toml | 6 ++++++ ratio_ops/src/lib.rs | 1 + {fixed_wide => ratio_ops}/src/ratio.rs | 0 10 files changed, 34 insertions(+), 10 deletions(-) create mode 100644 ratio_ops/.gitignore create mode 100644 ratio_ops/Cargo.lock create mode 100644 ratio_ops/Cargo.toml create mode 100644 ratio_ops/src/lib.rs rename {fixed_wide => ratio_ops}/src/ratio.rs (100%) diff --git a/fixed_wide/Cargo.lock b/fixed_wide/Cargo.lock index ff09daa..1f6a13a 100644 --- a/fixed_wide/Cargo.lock +++ b/fixed_wide/Cargo.lock @@ -21,6 +21,7 @@ dependencies = [ "arrayvec", "bnum", "paste", + "ratio_ops", ] [[package]] @@ -28,3 +29,7 @@ name = "paste" version = "1.0.15" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "57c0d7b74b563b49d38dae00a0c37d4d6de9b432382b2892f0574ddcae73fd0a" + +[[package]] +name = "ratio_ops" +version = "0.1.0" diff --git a/fixed_wide/Cargo.toml b/fixed_wide/Cargo.toml index f24c634..7b025ab 100644 --- a/fixed_wide/Cargo.toml +++ b/fixed_wide/Cargo.toml @@ -4,8 +4,8 @@ version = "0.1.0" edition = "2021" [features] -default=["ratio","zeroes","wide-mul"] -ratio=[] +default=["deferred-division","zeroes","wide-mul"] +deferred-division=["dep:ratio_ops"] wide-mul=[] zeroes=["dep:arrayvec"] @@ -13,3 +13,4 @@ zeroes=["dep:arrayvec"] bnum = "0.11.0" arrayvec = { version = "0.7.6", optional = true } paste = "1.0.15" +ratio_ops = { path = "../ratio_ops", optional = true } diff --git a/fixed_wide/src/fixed.rs b/fixed_wide/src/fixed.rs index 2e75e08..906ce49 100644 --- a/fixed_wide/src/fixed.rs +++ b/fixed_wide/src/fixed.rs @@ -215,7 +215,7 @@ macro_rules! impl_divide_operator_not_const_generic { } } } - #[cfg(all(not(feature="wide-mul"),not(feature="ratio")))] + #[cfg(all(not(feature="wide-mul"),not(feature="deferred-division")))] impl_multiplicative_operator_not_const_generic!(($struct, $trait, $method, $output ), $width); }; } @@ -273,11 +273,11 @@ impl_multiplicative_assign_operator!( Fixed, MulAssign, mul_assign ); impl_multiplicative_operator!( Fixed, Mul, mul, Self ); impl_multiplicative_assign_operator!( Fixed, DivAssign, div_assign ); impl_multiplicative_operator!( Fixed, Div, div, Self ); -#[cfg(feature="ratio")] +#[cfg(feature="deferred-division")] impl core::ops::Div> for Fixed{ - type Output=crate::ratio::Ratio,Fixed>; + type Output=ratio_ops::ratio::Ratio,Fixed>; fn div(self, other: Fixed)->Self::Output{ - crate::ratio::Ratio::new(self,other) + ratio_ops::ratio::Ratio::new(self,other) } } @@ -318,7 +318,7 @@ macro_rules! impl_wide_operators{ } } } - #[cfg(not(feature="ratio"))] + #[cfg(not(feature="deferred-division"))] impl core::ops::Div> for Fixed<$lhs,{$lhs*32}>{ type Output=Fixed<{$lhs+$rhs},{($lhs+$rhs)*32}>; fn div(self, other: Fixed<$rhs,{$rhs*32}>)->Self::Output{ diff --git a/fixed_wide/src/lib.rs b/fixed_wide/src/lib.rs index eee0ec3..8767a20 100644 --- a/fixed_wide/src/lib.rs +++ b/fixed_wide/src/lib.rs @@ -3,8 +3,6 @@ pub mod types; #[cfg(feature="zeroes")] pub mod zeroes; -#[cfg(feature="ratio")] -pub mod ratio; #[cfg(test)] mod tests; diff --git a/linear_ops/Cargo.lock b/linear_ops/Cargo.lock index 4e0f92e..d88a4c6 100644 --- a/linear_ops/Cargo.lock +++ b/linear_ops/Cargo.lock @@ -21,10 +21,11 @@ dependencies = [ "arrayvec", "bnum", "paste", + "ratio_ops", ] [[package]] -name = "lin_ops" +name = "linear_ops" version = "0.1.0" dependencies = [ "fixed_wide", @@ -35,3 +36,7 @@ name = "paste" version = "1.0.15" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "57c0d7b74b563b49d38dae00a0c37d4d6de9b432382b2892f0574ddcae73fd0a" + +[[package]] +name = "ratio_ops" +version = "0.1.0" diff --git a/ratio_ops/.gitignore b/ratio_ops/.gitignore new file mode 100644 index 0000000..ea8c4bf --- /dev/null +++ b/ratio_ops/.gitignore @@ -0,0 +1 @@ +/target diff --git a/ratio_ops/Cargo.lock b/ratio_ops/Cargo.lock new file mode 100644 index 0000000..a45b452 --- /dev/null +++ b/ratio_ops/Cargo.lock @@ -0,0 +1,7 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "ratio_ops" +version = "0.1.0" diff --git a/ratio_ops/Cargo.toml b/ratio_ops/Cargo.toml new file mode 100644 index 0000000..d7e0e92 --- /dev/null +++ b/ratio_ops/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "ratio_ops" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/ratio_ops/src/lib.rs b/ratio_ops/src/lib.rs new file mode 100644 index 0000000..96b877a --- /dev/null +++ b/ratio_ops/src/lib.rs @@ -0,0 +1 @@ +pub mod ratio; diff --git a/fixed_wide/src/ratio.rs b/ratio_ops/src/ratio.rs similarity index 100% rename from fixed_wide/src/ratio.rs rename to ratio_ops/src/ratio.rs From 1fd7a6eafd940cefc99b2fa524eb594fc34deaee Mon Sep 17 00:00:00 2001 From: Quaternions Date: Tue, 10 Sep 2024 12:45:33 -0700 Subject: [PATCH 179/227] fixed: inline functions Q_Q --- fixed_wide/src/fixed.rs | 30 ++++++++++++++++++++++++++++-- 1 file changed, 28 insertions(+), 2 deletions(-) diff --git a/fixed_wide/src/fixed.rs b/fixed_wide/src/fixed.rs index 906ce49..26b9d2a 100644 --- a/fixed_wide/src/fixed.rs +++ b/fixed_wide/src/fixed.rs @@ -42,12 +42,14 @@ impl From for Fixed where BInt:From { + #[inline] fn from(value:T)->Self{ Self::from_bits(BInt::<{N}>::from(value)< PartialEq for Fixed{ + #[inline] fn eq(&self,other:&Self)->bool{ self.bits.eq(&other.bits) } @@ -57,6 +59,7 @@ where T:Copy, BInt:::From, { + #[inline] fn eq(&self,&other:&T)->bool{ self.bits.eq(&other.into()) } @@ -64,6 +67,7 @@ where impl Eq for Fixed{} impl PartialOrd for Fixed{ + #[inline] fn partial_cmp(&self,other:&Self)->Option{ self.bits.partial_cmp(&other.bits) } @@ -73,11 +77,13 @@ impl PartialOrd for Fixed T:Copy, BInt:::From, { + #[inline] fn partial_cmp(&self,&other:&T)->Option{ self.bits.partial_cmp(&other.into()) } } impl Ord for Fixed{ + #[inline] fn cmp(&self,other:&Self)->std::cmp::Ordering{ self.bits.cmp(&other.bits) } @@ -85,11 +91,13 @@ impl Ord for Fixed{ impl std::ops::Neg for Fixed{ type Output=Self; + #[inline] fn neg(self)->Self{ Self::from_bits(self.bits.neg()) } } impl std::iter::Sum for Fixed{ + #[inline] fn sum>(iter:I)->Self{ let mut sum=Self::ZERO; for elem in iter{ @@ -109,6 +117,7 @@ macro_rules! impl_additive_operator { } impl core::ops::$trait for $struct{ type Output = $output; + #[inline] fn $method(self, other: Self) -> Self::Output { self.$method(other) } @@ -118,6 +127,7 @@ macro_rules! impl_additive_operator { BInt:::From, { type Output = $output; + #[inline] fn $method(self, other: U) -> Self::Output { Self::from_bits(self.bits.$method(BInt::::from(other).shl(F as u32))) } @@ -127,6 +137,7 @@ macro_rules! impl_additive_operator { macro_rules! impl_additive_assign_operator { ( $struct: ident, $trait: ident, $method: ident ) => { impl core::ops::$trait for $struct{ + #[inline] fn $method(&mut self, other: Self) { self.bits.$method(other.bits); } @@ -135,6 +146,7 @@ macro_rules! impl_additive_assign_operator { where BInt:::From, { + #[inline] fn $method(&mut self, other: U) { self.bits.$method(BInt::::from(other).shl(F as u32)); } @@ -166,6 +178,7 @@ macro_rules! impl_multiplicative_operator_not_const_generic { ( ($struct: ident, $trait: ident, $method: ident, $output: ty ), $width:expr ) => { impl core::ops::$trait for $struct<$width,F>{ type Output = $output; + #[inline] fn $method(self, other: Self) -> Self::Output { paste::item!{ self.[](other) @@ -177,6 +190,7 @@ macro_rules! impl_multiplicative_operator_not_const_generic { macro_rules! impl_multiplicative_assign_operator_not_const_generic { ( ($struct: ident, $trait: ident, $method: ident, $non_assign_method: ident ), $width:expr ) => { impl core::ops::$trait for $struct<$width,F>{ + #[inline] fn $method(&mut self, other: Self) { paste::item!{ *self=self.[](other); @@ -227,7 +241,7 @@ macro_rules! impl_multiplicative_operator { BInt:::From+core::ops::$trait, { type Output = $output; - + #[inline] fn $method(self, other: U) -> Self::Output { Self::from_bits(self.bits.$method(BInt::::from(other))) } @@ -240,6 +254,7 @@ macro_rules! impl_multiplicative_assign_operator { where BInt:::From+core::ops::$trait, { + #[inline] fn $method(&mut self, other: U) { self.bits.$method(BInt::::from(other)); } @@ -276,6 +291,7 @@ impl_multiplicative_operator!( Fixed, Div, div, Self ); #[cfg(feature="deferred-division")] impl core::ops::Div> for Fixed{ type Output=ratio_ops::ratio::Ratio,Fixed>; + #[inline] fn div(self, other: Fixed)->Self::Output{ ratio_ops::ratio::Ratio::new(self,other) } @@ -285,7 +301,7 @@ macro_rules! impl_shift_operator { ( $struct: ident, $trait: ident, $method: ident, $output: ty ) => { impl core::ops::$trait for $struct{ type Output = $output; - + #[inline] fn $method(self, other: u32) -> Self::Output { Self::from_bits(self.bits.$method(other)) } @@ -295,6 +311,7 @@ macro_rules! impl_shift_operator { macro_rules! impl_shift_assign_operator { ( $struct: ident, $trait: ident, $method: ident ) => { impl core::ops::$trait for $struct{ + #[inline] fn $method(&mut self, other: u32) { self.bits.$method(other); } @@ -312,6 +329,7 @@ macro_rules! impl_wide_operators{ ($lhs:expr,$rhs:expr)=>{ impl core::ops::Mul> for Fixed<$lhs,{$lhs*32}>{ type Output=Fixed<{$lhs+$rhs},{($lhs+$rhs)*32}>; + #[inline] fn mul(self, other: Fixed<$rhs,{$rhs*32}>)->Self::Output{ paste::item!{ self.[](other) @@ -321,6 +339,7 @@ macro_rules! impl_wide_operators{ #[cfg(not(feature="deferred-division"))] impl core::ops::Div> for Fixed<$lhs,{$lhs*32}>{ type Output=Fixed<{$lhs+$rhs},{($lhs+$rhs)*32}>; + #[inline] fn div(self, other: Fixed<$rhs,{$rhs*32}>)->Self::Output{ paste::item!{ self.[](other) @@ -341,6 +360,7 @@ macro_rules! impl_wide_not_const_generic{ impl Fixed<$lhs,{$lhs*32}> { paste::item!{ + #[inline] pub fn [](self,rhs:Fixed<$rhs,{$rhs*32}>)->Fixed<{$lhs+$rhs},{($lhs+$rhs)*32}>{ let lhs=self.bits.as_::>(); let rhs=rhs.bits.as_::>(); @@ -349,6 +369,7 @@ macro_rules! impl_wide_not_const_generic{ /// This operation cannot represent the fraction exactly, /// but it shapes the output to have precision for the /// largest and smallest possible fractions. + #[inline] pub fn [](self,rhs:Fixed<$rhs,{$rhs*32}>)->Fixed<{$lhs+$rhs},{($lhs+$rhs)*32}>{ // (lhs/2^LHS_FRAC)/(rhs/2^RHS_FRAC) let lhs=self.bits.as_::>().shl($rhs*64); @@ -382,6 +403,7 @@ macro_repeated!( (1,15) ); impl Fixed{ + #[inline] pub fn resize_into(self)->Fixed{ Fixed::from_bits(self.bits.as_::>()) } @@ -390,12 +412,14 @@ impl Fixed{ macro_rules! impl_not_const_generic{ ($n:expr)=>{ impl Fixed<{$n*2},{$n*2*32}>{ + #[inline] pub fn halve_precision(self)->Fixed<$n,{$n*32}>{ Fixed::from_bits(bnum::cast::As::as_(self.bits.shr($n*32))) } } impl Fixed<$n,{$n*32}>{ paste::item!{ + #[inline] pub fn sqrt_unchecked(self)->Self{ //1<Self{ if selfOption{ if self Date: Tue, 10 Sep 2024 13:04:43 -0700 Subject: [PATCH 180/227] ratio operators --- ratio_ops/src/ratio.rs | 165 ++++++++++++++++++++++++++++++++++++++++- 1 file changed, 163 insertions(+), 2 deletions(-) diff --git a/ratio_ops/src/ratio.rs b/ratio_ops/src/ratio.rs index 6ae0ad2..7f806da 100644 --- a/ratio_ops/src/ratio.rs +++ b/ratio_ops/src/ratio.rs @@ -1,10 +1,171 @@ #[derive(Clone,Copy,Debug,Hash)] pub struct Ratio{ - pub(crate)num:Num, - pub(crate)den:Den, + pub num:Num, + pub den:Den, } impl Ratio{ + #[inline(always)] pub const fn new(num:Num,den:Den)->Self{ Self{num,den} } } + +impl Ratio + where + Num:core::ops::Div, +{ + #[inline] + pub fn divide(num:Num,den:Den)->>::Output{ + num/den + } +} + +//take care to use the ratio methods to avoid nested ratios + +impl Ratio{ + #[inline] + pub fn mul_ratio(self,rhs:Ratio)->Ratio<>::Output,>::Output> + where + LhsNum:core::ops::Mul, + LhsDen:core::ops::Mul, + { + Ratio::new(self.num*rhs.num,self.den*rhs.den) + } + #[inline] + pub fn div_ratio(self,rhs:Ratio)->Ratio<>::Output,>::Output> + where + LhsNum:core::ops::Mul, + LhsDen:core::ops::Mul, + { + Ratio::new(self.num*rhs.den,self.den*rhs.num) + } +} +macro_rules! impl_ratio_method { + ($trait:ident, $method:ident, $ratio_method:ident) => { + impl Ratio{ + #[inline] + pub fn $ratio_method(self,rhs:Ratio)->Ratio<>::Output,>::Output> + where + LhsNum:core::ops::Mul, + LhsDen:core::ops::Mul, + LhsDen:core::ops::Mul, + LhsDen:Copy, + RhsDen:Copy, + LhsCrossMul:core::ops::$trait, + { + Ratio::new((self.num*rhs.den).$method(self.den*rhs.num),self.den*rhs.den) + } + } + }; +} +impl_ratio_method!(Add,add,add_ratio); +impl_ratio_method!(Sub,sub,sub_ratio); +impl_ratio_method!(Rem,rem,rem_ratio); + +/* generic rhs mul is not possible! +impl core::ops::Mul> for Lhs + where + Lhs:core::ops::Mul, +{ + type Output=Ratio<>::Output,RhsDen>; + #[inline] + fn mul(self,rhs:Ratio)->Self::Output{ + Ratio::new(self*rhs.num,rhs.den) + } +} +*/ + +//operators + +impl core::ops::Neg for Ratio + where + LhsNum:core::ops::Neg, +{ + type Output=Ratio<::Output,LhsDen>; + #[inline] + fn neg(self)->Self::Output{ + Ratio::new(-self.num,self.den) + } +} +impl core::ops::Mul for Ratio + where + LhsNum:core::ops::Mul, +{ + type Output=Ratio<>::Output,LhsDen>; + #[inline] + fn mul(self,rhs:Rhs)->Self::Output{ + Ratio::new(self.num*rhs,self.den) + } +} +impl core::ops::Div for Ratio + where + LhsDen:core::ops::Mul, +{ + type Output=Ratio>::Output>; + #[inline] + fn div(self,rhs:Rhs)->Self::Output{ + Ratio::new(self.num,self.den*rhs) + } +} + +macro_rules! impl_ratio_operator { + ($trait:ident, $method:ident) => { + impl core::ops::$trait for Ratio + where + LhsNum:core::ops::$trait, + LhsDen:Copy, + Rhs:core::ops::Mul, + { + type Output=Ratio<>::Output,LhsDen>; + #[inline] + fn $method(self,rhs:Rhs)->Self::Output{ + Ratio::new(self.num.$method(rhs*self.den),self.den) + } + } + }; +} + +impl_ratio_operator!(Add,add); +impl_ratio_operator!(Sub,sub); +impl_ratio_operator!(Rem,rem); + +//assign operators + +impl core::ops::MulAssign for Ratio + where + LhsNum:core::ops::MulAssign, +{ + #[inline] + fn mul_assign(&mut self,rhs:Rhs){ + self.num*=rhs; + } +} +impl core::ops::DivAssign for Ratio + where + LhsDen:core::ops::MulAssign, +{ + #[inline] + fn div_assign(&mut self,rhs:Rhs){ + self.den*=rhs; + } +} + +macro_rules! impl_ratio_assign_operator { + ($trait:ident, $method:ident) => { + impl core::ops::$trait for Ratio + where + LhsNum:core::ops::$trait, + LhsDen:Copy, + Rhs:core::ops::Mul, + { + #[inline] + fn $method(&mut self,rhs:Rhs){ + self.num.$method(rhs*self.den) + } + } + }; +} + +impl_ratio_assign_operator!(AddAssign,add_assign); +impl_ratio_assign_operator!(SubAssign,sub_assign); +impl_ratio_assign_operator!(RemAssign,rem_assign); From 338669b60f4a0085da9aa7a34e175eca07d629fa Mon Sep 17 00:00:00 2001 From: Quaternions Date: Tue, 10 Sep 2024 13:45:12 -0700 Subject: [PATCH 181/227] implement shift operators --- linear_ops/src/macros/vector.rs | 46 +++++++++++++++++++++++++++++++++ 1 file changed, 46 insertions(+) diff --git a/linear_ops/src/macros/vector.rs b/linear_ops/src/macros/vector.rs index 37654b6..8d4c7de 100644 --- a/linear_ops/src/macros/vector.rs +++ b/linear_ops/src/macros/vector.rs @@ -141,6 +141,12 @@ macro_rules! impl_vector { $crate::impl_vector_operator!(BitOr, bitor ); $crate::impl_vector_assign_operator!(BitXorAssign, bitxor_assign ); $crate::impl_vector_operator!(BitXor, bitxor ); + + // Impl shift operators + $crate::impl_vector_shift_assign_operator!(ShlAssign, shl_assign); + $crate::impl_vector_shift_operator!(Shl, shl); + $crate::impl_vector_shift_assign_operator!(ShrAssign, shr_assign); + $crate::impl_vector_shift_operator!(Shr, shr); } } #[doc(hidden)] @@ -183,6 +189,46 @@ macro_rules! impl_vector_assign_operator { } } } +#[doc(hidden)] +#[macro_export(local_inner_macros)] +macro_rules! impl_vector_shift_operator { + ($trait: ident, $method: ident ) => { + impl,U,V> core::ops::$trait> for Vector{ + type Output=Vector; + #[inline] + fn $method(self,rhs:Vector)->Self::Output{ + self.map_zip(rhs,|(a,b)|a.$method(b)) + } + } + impl,V> core::ops::$trait for Vector{ + type Output=Vector; + #[inline] + fn $method(self,rhs:u32)->Self::Output{ + self.map(|t|t.$method(rhs)) + } + } + } +} +#[doc(hidden)] +#[macro_export(local_inner_macros)] +macro_rules! impl_vector_shift_assign_operator { + ($trait: ident, $method: ident ) => { + impl,U> core::ops::$trait> for Vector{ + #[inline] + fn $method(&mut self,rhs:Vector){ + self.array.iter_mut().zip(rhs.array) + .for_each(|(a,b)|a.$method(b)) + } + } + impl> core::ops::$trait for Vector{ + #[inline] + fn $method(&mut self,rhs:u32){ + self.array.iter_mut() + .for_each(|t|t.$method(rhs)) + } + } + } +} #[doc(hidden)] #[macro_export(local_inner_macros)] From 021d7f9d1f7460ecb2ca917d8d8633d0131f4f9d Mon Sep 17 00:00:00 2001 From: Quaternions Date: Tue, 10 Sep 2024 14:20:07 -0700 Subject: [PATCH 182/227] implement mul + div only for scalars (otherwise conflicting implementations) --- linear_ops/src/macros/vector.rs | 37 +++++++++++++++++++++++++++++---- 1 file changed, 33 insertions(+), 4 deletions(-) diff --git a/linear_ops/src/macros/vector.rs b/linear_ops/src/macros/vector.rs index 8d4c7de..3802f4a 100644 --- a/linear_ops/src/macros/vector.rs +++ b/linear_ops/src/macros/vector.rs @@ -127,13 +127,16 @@ macro_rules! impl_vector { $crate::impl_vector_operator!(Add, add ); $crate::impl_vector_assign_operator!(SubAssign, sub_assign ); $crate::impl_vector_operator!(Sub, sub ); - $crate::impl_vector_assign_operator!(MulAssign, mul_assign ); - $crate::impl_vector_operator!(Mul, mul ); - $crate::impl_vector_assign_operator!(DivAssign, div_assign ); - $crate::impl_vector_operator!(Div, div ); $crate::impl_vector_assign_operator!(RemAssign, rem_assign ); $crate::impl_vector_operator!(Rem, rem ); + // mul and div are special, usually you multiply by a scalar + // and implementing both vec*vec and vec*scalar is conflicting implementations Q_Q + $crate::impl_vector_assign_operator_scalar!(MulAssign, mul_assign ); + $crate::impl_vector_operator_scalar!(Mul, mul ); + $crate::impl_vector_assign_operator_scalar!(DivAssign, div_assign ); + $crate::impl_vector_operator_scalar!(Div, div ); + // Impl bitwise operators $crate::impl_vector_assign_operator!(BitAndAssign, bitand_assign ); $crate::impl_vector_operator!(BitAnd, bitand ); @@ -151,6 +154,19 @@ macro_rules! impl_vector { } #[doc(hidden)] #[macro_export(local_inner_macros)] +macro_rules! impl_vector_operator_scalar { + ($trait: ident, $method: ident ) => { + impl,U:Copy,V> core::ops::$trait for Vector{ + type Output=Vector; + #[inline] + fn $method(self,rhs:U)->Self::Output{ + self.map(|t|t.$method(rhs)) + } + } + } +} +#[doc(hidden)] +#[macro_export(local_inner_macros)] macro_rules! impl_vector_operator { ($trait: ident, $method: ident ) => { impl,U,V> core::ops::$trait> for Vector{ @@ -171,6 +187,19 @@ macro_rules! impl_vector_operator { } #[doc(hidden)] #[macro_export(local_inner_macros)] +macro_rules! impl_vector_assign_operator_scalar { + ($trait: ident, $method: ident ) => { + impl,U:Copy> core::ops::$trait for Vector{ + #[inline] + fn $method(&mut self,rhs:U){ + self.array.iter_mut() + .for_each(|t|t.$method(rhs)) + } + } + } +} +#[doc(hidden)] +#[macro_export(local_inner_macros)] macro_rules! impl_vector_assign_operator { ($trait: ident, $method: ident ) => { impl,U> core::ops::$trait> for Vector{ From 7b78338c767b8c3800d13ab3f1c39c957d2f0952 Mon Sep 17 00:00:00 2001 From: Quaternions Date: Tue, 10 Sep 2024 14:50:35 -0700 Subject: [PATCH 183/227] fix tests :/ --- linear_ops/src/tests/fixed_wide.rs | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/linear_ops/src/tests/fixed_wide.rs b/linear_ops/src/tests/fixed_wide.rs index f0ee366..ae11c41 100644 --- a/linear_ops/src/tests/fixed_wide.rs +++ b/linear_ops/src/tests/fixed_wide.rs @@ -8,9 +8,9 @@ type Planar64Wide3=fixed_wide::types::I256F256; #[test] fn wide_vec3(){ let v=Vector3::from_value(Planar64::from(3)); - let v1=v*v; - let v2=v1*v1; - let v3=v2*v2; + let v1=v*v.x; + let v2=v1*v1.y; + let v3=v2*v2.z; assert_eq!(v3.array,Vector3::from_value(Planar64Wide3::from(3i128.pow(8))).array); } @@ -18,8 +18,8 @@ fn wide_vec3(){ #[test] fn wide_vec3_dot(){ let v=Vector3::from_value(Planar64::from(3)); - let v1=v*v; - let v2=v1*v1; + let v1=v*v.x; + let v2=v1*v1.y; let v3=v2.dot(v2); assert_eq!(v3,Planar64Wide3::from(3i128.pow(8)*3)); @@ -28,8 +28,8 @@ fn wide_vec3_dot(){ #[test] fn wide_vec3_length_squared(){ let v=Vector3::from_value(Planar64::from(3)); - let v1=v*v; - let v2=v1*v1; + let v1=v*v.x; + let v2=v1*v1.y; let v3=v2.length_squared(); assert_eq!(v3,Planar64Wide3::from(3i128.pow(8)*3)); From 9f77531995aef3a7f85306bca1963ac487345337 Mon Sep 17 00:00:00 2001 From: Quaternions Date: Wed, 11 Sep 2024 12:06:58 -0700 Subject: [PATCH 184/227] implement Debug + Display --- fixed_wide/src/fixed.rs | 45 +++++++++++++++++++++++++++++++++ linear_ops/src/macros/matrix.rs | 16 ++++++++++++ linear_ops/src/macros/vector.rs | 11 ++++++++ linear_ops/src/matrix.rs | 2 +- linear_ops/src/vector.rs | 2 +- 5 files changed, 74 insertions(+), 2 deletions(-) diff --git a/fixed_wide/src/fixed.rs b/fixed_wide/src/fixed.rs index 26b9d2a..78885b7 100644 --- a/fixed_wide/src/fixed.rs +++ b/fixed_wide/src/fixed.rs @@ -33,6 +33,17 @@ impl Fixed{ self.bits } #[inline] + pub const fn raw_digit(value:i64)->Self{ + let mut digits=[0u64;N]; + digits[0]=value.abs() as u64; + //sign bit + digits[N-1]|=(value&i64::MIN) as u64; + Self::from_bits(BInt::from_bits(bnum::BUint::from_digits(digits))) + } +} +impl Fixed<1,F>{ + /// My old code called this function everywhere so let's provide it + #[inline] pub const fn raw(value:i64)->Self{ Self::from_bits(BInt::from_bits(bnum::BUint::from_digit(value as u64))) } @@ -107,6 +118,40 @@ impl std::iter::Sum for Fixed{ } } +macro_rules! impl_into_float { + ( $output: ty ) => { + impl Into<$output> for Fixed{ + #[inline] + fn into(self)->$output{ + let mut total=0.0; + let bits=self.bits.to_bits(); + let digits=bits.digits(); + for (i,digit) in digits[0..N-1].iter().enumerate(){ + // (i*64-F) as i32 will interpret the highest order bit as a sign bit but whatever + total+=(*digit as $output)*(2.0 as $output).powi((i*64-F) as i32); + } + //most significant digit holds the sign bit + //assume we are using a number with at least 1 digit... + total+=((*digits.last().unwrap() as i64).abs() as $output)*(2.0 as $output).powi(((N-1)*64-F) as i32); + if self.bits.is_negative(){ + total=-total; + } + total + } + } + } +} +impl_into_float!(f32); +impl_into_float!(f64); + +impl core::fmt::Display for Fixed{ + #[inline] + fn fmt(&self,f:&mut core::fmt::Formatter)->Result<(),core::fmt::Error>{ + let float:f32=(*self).into(); + core::write!(f,"{:.3}",float) + } +} + macro_rules! impl_additive_operator { ( $struct: ident, $trait: ident, $method: ident, $output: ty ) => { impl $struct{ diff --git a/linear_ops/src/macros/matrix.rs b/linear_ops/src/macros/matrix.rs index 56634b6..bc3866f 100644 --- a/linear_ops/src/macros/matrix.rs +++ b/linear_ops/src/macros/matrix.rs @@ -87,6 +87,22 @@ macro_rules! impl_matrix { ) } } + + impl core::fmt::Display for Matrix{ + #[inline] + fn fmt(&self,f:&mut core::fmt::Formatter)->Result<(),core::fmt::Error>{ + for row in &self.array[0..Y]{ + core::write!(f,"\n")?; + for elem in &row[0..X-1]{ + core::write!(f,"{}, ",elem)?; + } + // assume we will be using matrices of size 1x1 or greater + core::write!(f,"{}",row.last().unwrap())?; + } + Ok(()) + } + } + impl core::ops::Mul> for Matrix where T:core::ops::Mul+Copy, diff --git a/linear_ops/src/macros/vector.rs b/linear_ops/src/macros/vector.rs index 3802f4a..cf1714f 100644 --- a/linear_ops/src/macros/vector.rs +++ b/linear_ops/src/macros/vector.rs @@ -47,6 +47,17 @@ macro_rules! impl_vector { } } + impl core::fmt::Display for Vector{ + #[inline] + fn fmt(&self,f:&mut core::fmt::Formatter)->Result<(),core::fmt::Error>{ + for elem in &self.array[0..N-1]{ + core::write!(f,"{}, ",elem)?; + } + // assume we will be using vectors of length 1 or greater + core::write!(f,"{}",self.array.last().unwrap()) + } + } + impl Vector{ #[inline] pub fn min(self,rhs:Self)->Self{ diff --git a/linear_ops/src/matrix.rs b/linear_ops/src/matrix.rs index be59900..2c7dfb5 100644 --- a/linear_ops/src/matrix.rs +++ b/linear_ops/src/matrix.rs @@ -1,6 +1,6 @@ use crate::vector::Vector; -#[derive(Clone,Copy,Hash,Eq,PartialEq)] +#[derive(Clone,Copy,Debug,Hash,Eq,PartialEq)] pub struct Matrix{ pub(crate) array:[[T;X];Y], } diff --git a/linear_ops/src/vector.rs b/linear_ops/src/vector.rs index b5a41e5..8d223de 100644 --- a/linear_ops/src/vector.rs +++ b/linear_ops/src/vector.rs @@ -3,7 +3,7 @@ /// v.x += v.z; /// println!("v.x={}",v.x); -#[derive(Clone,Copy,Hash,Eq,PartialEq)] +#[derive(Clone,Copy,Debug,Hash,Eq,PartialEq)] pub struct Vector{ pub(crate) array:[T;N], } From 1a24de3cd97ceb14bcd4487b704e4b15d422c32c Mon Sep 17 00:00:00 2001 From: Quaternions Date: Wed, 11 Sep 2024 12:20:17 -0700 Subject: [PATCH 185/227] deferred division for vector + matrix --- linear_ops/Cargo.lock | 1 + linear_ops/Cargo.toml | 4 ++++ linear_ops/src/macros/matrix.rs | 16 ++++++++++++++++ linear_ops/src/macros/vector.rs | 16 ++++++++++++++++ 4 files changed, 37 insertions(+) diff --git a/linear_ops/Cargo.lock b/linear_ops/Cargo.lock index d88a4c6..6a24c51 100644 --- a/linear_ops/Cargo.lock +++ b/linear_ops/Cargo.lock @@ -29,6 +29,7 @@ name = "linear_ops" version = "0.1.0" dependencies = [ "fixed_wide", + "ratio_ops", ] [[package]] diff --git a/linear_ops/Cargo.toml b/linear_ops/Cargo.toml index 351534e..c2a73c3 100644 --- a/linear_ops/Cargo.toml +++ b/linear_ops/Cargo.toml @@ -6,6 +6,10 @@ edition = "2021" [features] default=["named-fields"] named-fields=[] +deferred-division=["dep:ratio_ops"] + +[dependencies] +ratio_ops = { path = "../ratio_ops", optional = true } [dev-dependencies] fixed_wide = { version = "0.1.0", path = "../fixed_wide" } diff --git a/linear_ops/src/macros/matrix.rs b/linear_ops/src/macros/matrix.rs index bc3866f..ead9f0a 100644 --- a/linear_ops/src/macros/matrix.rs +++ b/linear_ops/src/macros/matrix.rs @@ -127,6 +127,22 @@ macro_rules! impl_matrix { self.transform_vector(rhs) } } + #[cfg(feature="deferred-division")] + $crate::impl_matrix_deferred_division!(); + } +} + +#[doc(hidden)] +#[macro_export(local_inner_macros)] +macro_rules! impl_matrix_deferred_division { + () => { + impl core::ops::Div for Matrix{ + type Output=ratio_ops::ratio::Ratio,U>; + #[inline] + fn div(self,rhs:U)->Self::Output{ + ratio_ops::ratio::Ratio::new(self,rhs) + } + } } } diff --git a/linear_ops/src/macros/vector.rs b/linear_ops/src/macros/vector.rs index cf1714f..2cd63fb 100644 --- a/linear_ops/src/macros/vector.rs +++ b/linear_ops/src/macros/vector.rs @@ -146,7 +146,10 @@ macro_rules! impl_vector { $crate::impl_vector_assign_operator_scalar!(MulAssign, mul_assign ); $crate::impl_vector_operator_scalar!(Mul, mul ); $crate::impl_vector_assign_operator_scalar!(DivAssign, div_assign ); + #[cfg(not(feature="deferred-division"))] $crate::impl_vector_operator_scalar!(Div, div ); + #[cfg(feature="deferred-division")] + $crate::impl_vector_deferred_division!(); // Impl bitwise operators $crate::impl_vector_assign_operator!(BitAndAssign, bitand_assign ); @@ -165,6 +168,19 @@ macro_rules! impl_vector { } #[doc(hidden)] #[macro_export(local_inner_macros)] +macro_rules! impl_vector_deferred_division { + () => { + impl core::ops::Div for Vector{ + type Output=ratio_ops::ratio::Ratio,U>; + #[inline] + fn div(self,rhs:U)->Self::Output{ + ratio_ops::ratio::Ratio::new(self,rhs) + } + } + } +} +#[doc(hidden)] +#[macro_export(local_inner_macros)] macro_rules! impl_vector_operator_scalar { ($trait: ident, $method: ident ) => { impl,U:Copy,V> core::ops::$trait for Vector{ From 44ac6fe4bee22b4ed677196a09e81e357c097a11 Mon Sep 17 00:00:00 2001 From: Quaternions Date: Wed, 11 Sep 2024 12:59:22 -0700 Subject: [PATCH 186/227] fixed_wide: no default features --- fixed_wide/Cargo.toml | 2 +- linear_ops/Cargo.lock | 8 -------- linear_ops/Cargo.toml | 2 +- 3 files changed, 2 insertions(+), 10 deletions(-) diff --git a/fixed_wide/Cargo.toml b/fixed_wide/Cargo.toml index 7b025ab..40d6321 100644 --- a/fixed_wide/Cargo.toml +++ b/fixed_wide/Cargo.toml @@ -4,7 +4,7 @@ version = "0.1.0" edition = "2021" [features] -default=["deferred-division","zeroes","wide-mul"] +default=[] deferred-division=["dep:ratio_ops"] wide-mul=[] zeroes=["dep:arrayvec"] diff --git a/linear_ops/Cargo.lock b/linear_ops/Cargo.lock index 6a24c51..3f34821 100644 --- a/linear_ops/Cargo.lock +++ b/linear_ops/Cargo.lock @@ -2,12 +2,6 @@ # It is not intended for manual editing. version = 3 -[[package]] -name = "arrayvec" -version = "0.7.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7c02d123df017efcdfbd739ef81735b36c5ba83ec3c59c80a9d7ecc718f92e50" - [[package]] name = "bnum" version = "0.11.0" @@ -18,10 +12,8 @@ checksum = "3e31ea183f6ee62ac8b8a8cf7feddd766317adfb13ff469de57ce033efd6a790" name = "fixed_wide" version = "0.1.0" dependencies = [ - "arrayvec", "bnum", "paste", - "ratio_ops", ] [[package]] diff --git a/linear_ops/Cargo.toml b/linear_ops/Cargo.toml index c2a73c3..885f45f 100644 --- a/linear_ops/Cargo.toml +++ b/linear_ops/Cargo.toml @@ -12,4 +12,4 @@ deferred-division=["dep:ratio_ops"] ratio_ops = { path = "../ratio_ops", optional = true } [dev-dependencies] -fixed_wide = { version = "0.1.0", path = "../fixed_wide" } +fixed_wide = { version = "0.1.0", path = "../fixed_wide", features = ["wide-mul"] } From a73a32f2adfc469c238aa6905b6e408ca44d947b Mon Sep 17 00:00:00 2001 From: Quaternions Date: Wed, 11 Sep 2024 12:59:33 -0700 Subject: [PATCH 187/227] Divide trait --- fixed_wide/src/fixed.rs | 20 ++++++++++++++++++++ linear_ops/src/macros/matrix.rs | 7 +++++++ linear_ops/src/macros/vector.rs | 7 +++++++ ratio_ops/src/ratio.rs | 12 +++++++++--- 4 files changed, 43 insertions(+), 3 deletions(-) diff --git a/fixed_wide/src/fixed.rs b/fixed_wide/src/fixed.rs index 78885b7..6a86be8 100644 --- a/fixed_wide/src/fixed.rs +++ b/fixed_wide/src/fixed.rs @@ -276,6 +276,16 @@ macro_rules! impl_divide_operator_not_const_generic { } #[cfg(all(not(feature="wide-mul"),not(feature="deferred-division")))] impl_multiplicative_operator_not_const_generic!(($struct, $trait, $method, $output ), $width); + #[cfg(all(not(feature="wide-mul"),feature="deferred-division"))] + impl ratio_ops::ratio::Divide for $struct<$width,F>{ + type Output = $output; + #[inline] + fn divide(self, other: Self) -> Self::Output { + paste::item!{ + self.[](other) + } + } + } }; } @@ -391,6 +401,16 @@ macro_rules! impl_wide_operators{ } } } + #[cfg(feature="deferred-division")] + impl ratio_ops::ratio::Divide> for Fixed<$lhs,{$lhs*32}>{ + type Output=Fixed<{$lhs+$rhs},{($lhs+$rhs)*32}>; + #[inline] + fn divide(self, other: Fixed<$rhs,{$rhs*32}>)->Self::Output{ + paste::item!{ + self.[](other) + } + } + } } } diff --git a/linear_ops/src/macros/matrix.rs b/linear_ops/src/macros/matrix.rs index ead9f0a..184b2c9 100644 --- a/linear_ops/src/macros/matrix.rs +++ b/linear_ops/src/macros/matrix.rs @@ -136,6 +136,13 @@ macro_rules! impl_matrix { #[macro_export(local_inner_macros)] macro_rules! impl_matrix_deferred_division { () => { + impl,U:Copy,V> ratio_ops::ratio::Divide for Matrix{ + type Output=Matrix; + #[inline] + fn divide(self,rhs:U)->Self::Output{ + self.map(|t|t.divide(rhs)) + } + } impl core::ops::Div for Matrix{ type Output=ratio_ops::ratio::Ratio,U>; #[inline] diff --git a/linear_ops/src/macros/vector.rs b/linear_ops/src/macros/vector.rs index 2cd63fb..b375509 100644 --- a/linear_ops/src/macros/vector.rs +++ b/linear_ops/src/macros/vector.rs @@ -170,6 +170,13 @@ macro_rules! impl_vector { #[macro_export(local_inner_macros)] macro_rules! impl_vector_deferred_division { () => { + impl,U:Copy,V> ratio_ops::ratio::Divide for Vector{ + type Output=Vector; + #[inline] + fn divide(self,rhs:U)->Self::Output{ + self.map(|t|t.divide(rhs)) + } + } impl core::ops::Div for Vector{ type Output=ratio_ops::ratio::Ratio,U>; #[inline] diff --git a/ratio_ops/src/ratio.rs b/ratio_ops/src/ratio.rs index 7f806da..fdb5f39 100644 --- a/ratio_ops/src/ratio.rs +++ b/ratio_ops/src/ratio.rs @@ -10,13 +10,19 @@ impl Ratio{ } } +/// The actual divide implementation, Div is replaced with a Ratio constructor +pub trait Divide{ + type Output; + fn divide(self,rhs:Rhs)->Self::Output; +} + impl Ratio where - Num:core::ops::Div, + Num:Divide, { #[inline] - pub fn divide(num:Num,den:Den)->>::Output{ - num/den + pub fn divide(self)->>::Output{ + self.num.divide(self.den) } } From db5c37c2fb53d36909ab0e82f988a0709a8cc0a6 Mon Sep 17 00:00:00 2001 From: Quaternions Date: Wed, 11 Sep 2024 13:59:33 -0700 Subject: [PATCH 188/227] implement 'fix' function that changes the fixed point --- fixed_wide/src/fixed.rs | 126 ++++++++++++++++++++++++++++++++------- fixed_wide/src/tests.rs | 5 ++ fixed_wide/src/zeroes.rs | 7 +-- 3 files changed, 111 insertions(+), 27 deletions(-) diff --git a/fixed_wide/src/fixed.rs b/fixed_wide/src/fixed.rs index 6a86be8..91d4eae 100644 --- a/fixed_wide/src/fixed.rs +++ b/fixed_wide/src/fixed.rs @@ -380,6 +380,7 @@ impl_shift_operator!( Fixed, Shr, shr, Self ); // wide operators. The result width is the sum of the input widths, i.e. none of the multiplication +#[allow(unused_macros)] macro_rules! impl_wide_operators{ ($lhs:expr,$rhs:expr)=>{ impl core::ops::Mul> for Fixed<$lhs,{$lhs*32}>{ @@ -467,21 +468,101 @@ macro_repeated!( (1,14),(2,14), (1,15) ); -impl Fixed{ - #[inline] - pub fn resize_into(self)->Fixed{ - Fixed::from_bits(self.bits.as_::>()) + +macro_rules! impl_fix_rhs_lt_lhs_not_const_generic{ + ( + (), + ($lhs:expr,$rhs:expr) + )=>{ + impl Fixed<$lhs,{$lhs*32}> + { + paste::item!{ + #[inline] + pub fn [](self)->Fixed<$rhs,{$rhs*32}>{ + Fixed::from_bits(bnum::cast::As::as_::>(self.bits).shr(($lhs-$rhs)*32)) + } + } + } + } +} +macro_rules! impl_fix_lhs_lt_rhs_not_const_generic{ + ( + (), + ($lhs:expr,$rhs:expr) + )=>{ + impl Fixed<$lhs,{$lhs*32}> + { + paste::item!{ + #[inline] + pub fn [](self)->Fixed<$rhs,{$rhs*32}>{ + Fixed::from_bits(bnum::cast::As::as_::>(self.bits).shl(($rhs-$lhs)*32)) + } + } + } + } +} +macro_rules! impl_fix_lhs_eq_rhs_not_const_generic{ + ( + (), + ($lhs:expr,$rhs:expr) + )=>{ + impl Fixed<$lhs,{$lhs*32}> + { + paste::item!{ + #[inline] + pub fn [](self)->Fixed<$rhs,{$rhs*32}>{ + self + } + } + } } } +// I LOVE NOT BEING ABLE TO USE CONST GENERICS + +macro_repeated!( + impl_fix_rhs_lt_lhs_not_const_generic,(), + (2,1),(3,1),(4,1),(5,1),(6,1),(7,1),(8,1),(9,1),(10,1),(11,1),(12,1),(13,1),(14,1),(15,1),(16,1), + (3,2),(4,2),(5,2),(6,2),(7,2),(8,2),(9,2),(10,2),(11,2),(12,2),(13,2),(14,2),(15,2),(16,2), + (4,3),(5,3),(6,3),(7,3),(8,3),(9,3),(10,3),(11,3),(12,3),(13,3),(14,3),(15,3),(16,3), + (5,4),(6,4),(7,4),(8,4),(9,4),(10,4),(11,4),(12,4),(13,4),(14,4),(15,4),(16,4), + (6,5),(7,5),(8,5),(9,5),(10,5),(11,5),(12,5),(13,5),(14,5),(15,5),(16,5), + (7,6),(8,6),(9,6),(10,6),(11,6),(12,6),(13,6),(14,6),(15,6),(16,6), + (8,7),(9,7),(10,7),(11,7),(12,7),(13,7),(14,7),(15,7),(16,7), + (9,8),(10,8),(11,8),(12,8),(13,8),(14,8),(15,8),(16,8), + (10,9),(11,9),(12,9),(13,9),(14,9),(15,9),(16,9), + (11,10),(12,10),(13,10),(14,10),(15,10),(16,10), + (12,11),(13,11),(14,11),(15,11),(16,11), + (13,12),(14,12),(15,12),(16,12), + (14,13),(15,13),(16,13), + (15,14),(16,14), + (16,15) +); +macro_repeated!( + impl_fix_lhs_lt_rhs_not_const_generic,(), + (1,2), + (1,3),(2,3), + (1,4),(2,4),(3,4), + (1,5),(2,5),(3,5),(4,5), + (1,6),(2,6),(3,6),(4,6),(5,6), + (1,7),(2,7),(3,7),(4,7),(5,7),(6,7), + (1,8),(2,8),(3,8),(4,8),(5,8),(6,8),(7,8), + (1,9),(2,9),(3,9),(4,9),(5,9),(6,9),(7,9),(8,9), + (1,10),(2,10),(3,10),(4,10),(5,10),(6,10),(7,10),(8,10),(9,10), + (1,11),(2,11),(3,11),(4,11),(5,11),(6,11),(7,11),(8,11),(9,11),(10,11), + (1,12),(2,12),(3,12),(4,12),(5,12),(6,12),(7,12),(8,12),(9,12),(10,12),(11,12), + (1,13),(2,13),(3,13),(4,13),(5,13),(6,13),(7,13),(8,13),(9,13),(10,13),(11,13),(12,13), + (1,14),(2,14),(3,14),(4,14),(5,14),(6,14),(7,14),(8,14),(9,14),(10,14),(11,14),(12,14),(13,14), + (1,15),(2,15),(3,15),(4,15),(5,15),(6,15),(7,15),(8,15),(9,15),(10,15),(11,15),(12,15),(13,15),(14,15), + (1,16),(2,16),(3,16),(4,16),(5,16),(6,16),(7,16),(8,16),(9,16),(10,16),(11,16),(12,16),(13,16),(14,16),(15,16) +); +macro_repeated!( + impl_fix_lhs_eq_rhs_not_const_generic,(), + (1,1),(2,2),(3,3),(4,4),(5,5),(6,6),(7,7),(8,8),(9,9),(10,10),(11,11),(12,12),(13,13),(14,14),(15,15),(16,16) +); + macro_rules! impl_not_const_generic{ - ($n:expr)=>{ - impl Fixed<{$n*2},{$n*2*32}>{ - #[inline] - pub fn halve_precision(self)->Fixed<$n,{$n*32}>{ - Fixed::from_bits(bnum::cast::As::as_(self.bits.shr($n*32))) - } - } + ($n:expr,$_2n:expr)=>{ impl Fixed<$n,{$n*32}>{ paste::item!{ #[inline] @@ -496,13 +577,12 @@ macro_rules! impl_not_const_generic{ let max_shift=((used_bits>>1)+($n*32) as i32) as u32; let mut result=Self::ZERO; - //multiply by one to make the types match (hack) - //TODO: use resize method - let wide_self:::Output=self*Self::ONE; + //resize self to match the wide mul output + let wide_self=self.[](); //descend down the bits and check if flipping each bit would push the square over the input value for shift in (0..=max_shift).rev(){ let new_result=result|Self::from_bits(BInt::from_bits(bnum::BUint::power_of_two(shift))); - if new_result*new_result<=wide_self{ + if new_result.[](new_result)<=wide_self{ result=new_result; } } @@ -528,11 +608,11 @@ macro_rules! impl_not_const_generic{ } } } -impl_not_const_generic!(1); -impl_not_const_generic!(2); -impl_not_const_generic!(3); -impl_not_const_generic!(4); -impl_not_const_generic!(5); -impl_not_const_generic!(6); -impl_not_const_generic!(7); -impl_not_const_generic!(8); +impl_not_const_generic!(1,2); +impl_not_const_generic!(2,4); +impl_not_const_generic!(3,6); +impl_not_const_generic!(4,8); +impl_not_const_generic!(5,10); +impl_not_const_generic!(6,12); +impl_not_const_generic!(7,14); +impl_not_const_generic!(8,16); diff --git a/fixed_wide/src/tests.rs b/fixed_wide/src/tests.rs index 2f9aaa6..f7278ce 100644 --- a/fixed_wide/src/tests.rs +++ b/fixed_wide/src/tests.rs @@ -52,6 +52,11 @@ fn test_bint(){ assert_eq!(a*2,I32F32::from(2)); } +#[test] +fn test_fix(){ + let a=I32F32::ONE; + assert_eq!(a.fix_8(),I256F256::ONE); +} #[test] fn test_sqrt(){ let a=I32F32::ONE*4; diff --git a/fixed_wide/src/zeroes.rs b/fixed_wide/src/zeroes.rs index 3634a02..621e22e 100644 --- a/fixed_wide/src/zeroes.rs +++ b/fixed_wide/src/zeroes.rs @@ -12,13 +12,12 @@ macro_rules! impl_zeroes{ Ordering::Equal=>return ArrayVec::from_iter(Self::zeroes1(a0,a1).into_iter()), Ordering::Less=>true, }; - paste::item!{ let radicand=a1*a1-a2*a0*4; - } match radicand.cmp(&::Output::ZERO){ Ordering::Greater=>{ - //TODO: use resize method - let planar_radicand:Self=radicand.sqrt().halve_precision(); + paste::item!{ + let planar_radicand=radicand.sqrt().[](); + } //sort roots ascending and avoid taking the difference of large numbers let zeroes=match (a2pos,Self::ZERO[(-a1-planar_radicand)/(a2*2),(a0*2)/(-a1-planar_radicand)], From 6cb639317c43fd538f0a712ed24e1274276864e3 Mon Sep 17 00:00:00 2001 From: Quaternions Date: Wed, 11 Sep 2024 15:15:06 -0700 Subject: [PATCH 189/227] const helpers --- fixed_wide/src/fixed.rs | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/fixed_wide/src/fixed.rs b/fixed_wide/src/fixed.rs index 91d4eae..da334f5 100644 --- a/fixed_wide/src/fixed.rs +++ b/fixed_wide/src/fixed.rs @@ -40,6 +40,22 @@ impl Fixed{ digits[N-1]|=(value&i64::MIN) as u64; Self::from_bits(BInt::from_bits(bnum::BUint::from_digits(digits))) } + #[inline] + pub const fn is_zero(self)->bool{ + self.bits.is_zero() + } + #[inline] + pub const fn is_negative(self)->bool{ + self.bits.is_negative() + } + #[inline] + pub const fn is_positive(self)->bool{ + self.bits.is_positive() + } + #[inline] + pub const fn abs(self)->Self{ + Self::from_bits(self.bits.abs()) + } } impl Fixed<1,F>{ /// My old code called this function everywhere so let's provide it From 5646bd3b5a1e7c27f0aa787ef1ee5df2cd241ae8 Mon Sep 17 00:00:00 2001 From: Quaternions Date: Thu, 12 Sep 2024 10:10:04 -0700 Subject: [PATCH 190/227] fixed width specific impls --- linear_ops/Cargo.toml | 7 ++- linear_ops/src/macros/fixed_wide.rs | 79 +++++++++++++++++++++++++++++ linear_ops/src/macros/mod.rs | 3 ++ linear_ops/src/macros/vector.rs | 4 ++ 4 files changed, 91 insertions(+), 2 deletions(-) create mode 100644 linear_ops/src/macros/fixed_wide.rs diff --git a/linear_ops/Cargo.toml b/linear_ops/Cargo.toml index 885f45f..c1bc3ef 100644 --- a/linear_ops/Cargo.toml +++ b/linear_ops/Cargo.toml @@ -4,12 +4,15 @@ version = "0.1.0" edition = "2021" [features] -default=["named-fields"] +default=["named-fields","fixed-wide"] named-fields=[] +fixed-wide=["dep:fixed_wide","dep:paste"] deferred-division=["dep:ratio_ops"] [dependencies] ratio_ops = { path = "../ratio_ops", optional = true } +fixed_wide = { path = "../fixed_wide", optional = true } +paste = { version = "1.0.15", optional = true } [dev-dependencies] -fixed_wide = { version = "0.1.0", path = "../fixed_wide", features = ["wide-mul"] } +fixed_wide = { path = "../fixed_wide", features = ["wide-mul"] } diff --git a/linear_ops/src/macros/fixed_wide.rs b/linear_ops/src/macros/fixed_wide.rs new file mode 100644 index 0000000..199e7fb --- /dev/null +++ b/linear_ops/src/macros/fixed_wide.rs @@ -0,0 +1,79 @@ +#[doc(hidden)] +#[macro_export(local_inner_macros)] +macro_rules! impl_fixed_wide_vector_not_const_generic { + ( + (), + $n:expr + ) => { + impl Vector>{ + #[inline] + pub fn length(self)-> as core::ops::Mul>::Output{ + self.length_squared().sqrt_unchecked() + } + #[inline] + pub fn with_length(self,length:U)-> as core::ops::Div< as core::ops::Mul>::Output>>::Output + where + fixed_wide::fixed::Fixed<$n,{$n*32}>:core::ops::Mul, + U:Copy, + V:core::ops::Div< as core::ops::Mul>::Output>, + { + self*length/self.length() + } + } + }; +} + +#[doc(hidden)] +#[macro_export(local_inner_macros)] +macro_rules! macro_4 { + ( $macro: ident, $any:tt ) => { + $crate::macro_repeated!($macro,$any,1,2,3,4); + } +} + +#[doc(hidden)] +#[macro_export(local_inner_macros)] +macro_rules! impl_fixed_wide_vector { + () => { + $crate::macro_4!(impl_fixed_wide_vector_not_const_generic,()); + // I LOVE NOT BEING ABLE TO USE CONST GENERICS + $crate::macro_repeated!( + impl_fix_not_const_generic,(), + (1,1),(2,1),(3,1),(4,1),(5,1),(6,1),(7,1),(8,1),(9,1),(10,1),(11,1),(12,1),(13,1),(14,1),(15,1),(16,1), + (1,2),(2,2),(3,2),(4,2),(5,2),(6,2),(7,2),(8,2),(9,2),(10,2),(11,2),(12,2),(13,2),(14,2),(15,2),(16,2), + (1,3),(2,3),(3,3),(4,3),(5,3),(6,3),(7,3),(8,3),(9,3),(10,3),(11,3),(12,3),(13,3),(14,3),(15,3),(16,3), + (1,4),(2,4),(3,4),(4,4),(5,4),(6,4),(7,4),(8,4),(9,4),(10,4),(11,4),(12,4),(13,4),(14,4),(15,4),(16,4), + (1,5),(2,5),(3,5),(4,5),(5,5),(6,5),(7,5),(8,5),(9,5),(10,5),(11,5),(12,5),(13,5),(14,5),(15,5),(16,5), + (1,6),(2,6),(3,6),(4,6),(5,6),(6,6),(7,6),(8,6),(9,6),(10,6),(11,6),(12,6),(13,6),(14,6),(15,6),(16,6), + (1,7),(2,7),(3,7),(4,7),(5,7),(6,7),(7,7),(8,7),(9,7),(10,7),(11,7),(12,7),(13,7),(14,7),(15,7),(16,7), + (1,8),(2,8),(3,8),(4,8),(5,8),(6,8),(7,8),(8,8),(9,8),(10,8),(11,8),(12,8),(13,8),(14,8),(15,8),(16,8), + (1,9),(2,9),(3,9),(4,9),(5,9),(6,9),(7,9),(8,9),(9,9),(10,9),(11,9),(12,9),(13,9),(14,9),(15,9),(16,9), + (1,10),(2,10),(3,10),(4,10),(5,10),(6,10),(7,10),(8,10),(9,10),(10,10),(11,10),(12,10),(13,10),(14,10),(15,10),(16,10), + (1,11),(2,11),(3,11),(4,11),(5,11),(6,11),(7,11),(8,11),(9,11),(10,11),(11,11),(12,11),(13,11),(14,11),(15,11),(16,11), + (1,12),(2,12),(3,12),(4,12),(5,12),(6,12),(7,12),(8,12),(9,12),(10,12),(11,12),(12,12),(13,12),(14,12),(15,12),(16,12), + (1,13),(2,13),(3,13),(4,13),(5,13),(6,13),(7,13),(8,13),(9,13),(10,13),(11,13),(12,13),(13,13),(14,13),(15,13),(16,13), + (1,14),(2,14),(3,14),(4,14),(5,14),(6,14),(7,14),(8,14),(9,14),(10,14),(11,14),(12,14),(13,14),(14,14),(15,14),(16,14), + (1,15),(2,15),(3,15),(4,15),(5,15),(6,15),(7,15),(8,15),(9,15),(10,15),(11,15),(12,15),(13,15),(14,15),(15,15),(16,15), + (1,16),(2,16),(3,16),(4,16),(5,16),(6,16),(7,16),(8,16),(9,16),(10,16),(11,16),(12,16),(13,16),(14,16),(15,16),(16,16) + ); + }; +} + +#[doc(hidden)] +#[macro_export(local_inner_macros)] +macro_rules! impl_fix_not_const_generic{ + ( + (), + ($lhs:expr,$rhs:expr) + )=>{ + impl Vector> + { + paste::item!{ + #[inline] + pub fn [](self)->Vector>{ + self.map(|t|t.[]()) + } + } + } + } +} diff --git a/linear_ops/src/macros/mod.rs b/linear_ops/src/macros/mod.rs index d551722..e0a9d02 100644 --- a/linear_ops/src/macros/mod.rs +++ b/linear_ops/src/macros/mod.rs @@ -2,6 +2,9 @@ pub mod common; pub mod vector; pub mod matrix; +#[cfg(feature="fixed-wide")] +pub mod fixed_wide; + #[doc(hidden)] #[macro_export(local_inner_macros)] macro_rules! macro_repeated{ diff --git a/linear_ops/src/macros/vector.rs b/linear_ops/src/macros/vector.rs index b375509..d3beecf 100644 --- a/linear_ops/src/macros/vector.rs +++ b/linear_ops/src/macros/vector.rs @@ -164,6 +164,10 @@ macro_rules! impl_vector { $crate::impl_vector_shift_operator!(Shl, shl); $crate::impl_vector_shift_assign_operator!(ShrAssign, shr_assign); $crate::impl_vector_shift_operator!(Shr, shr); + + // dedicated methods for this type + #[cfg(feature="fixed-wide")] + $crate::impl_fixed_wide_vector!(); } } #[doc(hidden)] From 10e56fb0b90a141106eadb2c107e11c14e2cd366 Mon Sep 17 00:00:00 2001 From: Quaternions Date: Thu, 12 Sep 2024 12:16:41 -0700 Subject: [PATCH 191/227] default numba (use with care) --- fixed_wide/src/fixed.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fixed_wide/src/fixed.rs b/fixed_wide/src/fixed.rs index da334f5..f777c11 100644 --- a/fixed_wide/src/fixed.rs +++ b/fixed_wide/src/fixed.rs @@ -1,6 +1,6 @@ use bnum::{BInt,cast::As}; -#[derive(Clone,Copy,Debug,Hash)] +#[derive(Clone,Copy,Debug,Default,Hash)] /// A Fixed point number for which multiply operations widen the bits in the output. (when the wide-mul feature is enabled) /// N is the number of u64s to use /// F is the number of fractional bits (always N*32 lol) From ec82745c6d6116a61cc596a4171f9af567428598 Mon Sep 17 00:00:00 2001 From: Quaternions Date: Thu, 12 Sep 2024 12:16:44 -0700 Subject: [PATCH 192/227] matrix: from_rows --- linear_ops/src/macros/matrix.rs | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/linear_ops/src/macros/matrix.rs b/linear_ops/src/macros/matrix.rs index 184b2c9..c04e965 100644 --- a/linear_ops/src/macros/matrix.rs +++ b/linear_ops/src/macros/matrix.rs @@ -12,6 +12,13 @@ macro_rules! impl_matrix { self.array } #[inline] + pub fn from_rows(rows:[Vector;Y])->Self + { + Matrix::new( + rows.map(|row|row.array), + ) + } + #[inline] pub fn map(self,f:F)->Matrix where F:Fn(T)->U From 260ed0fd5c38ec09f815e8da74bcab78a97380c7 Mon Sep 17 00:00:00 2001 From: Quaternions Date: Fri, 13 Sep 2024 14:00:13 -0700 Subject: [PATCH 193/227] ratio: PartialEq, Eq, PartialOrd, Ord --- ratio_ops/src/ratio.rs | 45 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 45 insertions(+) diff --git a/ratio_ops/src/ratio.rs b/ratio_ops/src/ratio.rs index fdb5f39..a7f8928 100644 --- a/ratio_ops/src/ratio.rs +++ b/ratio_ops/src/ratio.rs @@ -175,3 +175,48 @@ macro_rules! impl_ratio_assign_operator { impl_ratio_assign_operator!(AddAssign,add_assign); impl_ratio_assign_operator!(SubAssign,sub_assign); impl_ratio_assign_operator!(RemAssign,rem_assign); + +// Only implement PartialEq +// Rust's operators aren't actually that good + +impl PartialEq for Ratio + where + Num:Copy, + Den:Copy, + Num:core::ops::Mul, + T:PartialEq, +{ + #[inline] + fn eq(&self,&other:&Self)->bool{ + (self.num*other.den).eq(&(other.num*self.den)) + } +} +impl Eq for Ratio + where + Ratio:PartialEq, +{} + +impl PartialOrd for Ratio + where + Num:Copy, + Den:Copy, + Num:core::ops::Mul, + T:PartialOrd, +{ + #[inline] + fn partial_cmp(&self,&other:&Self)->Option{ + (self.num*other.den).partial_cmp(&(other.num*self.den)) + } +} +impl Ord for Ratio + where + Num:Copy, + Den:Copy, + Num:core::ops::Mul, + T:Ord, +{ + #[inline] + fn cmp(&self,other:&Self)->std::cmp::Ordering{ + (self.num*other.den).cmp(&(other.num*self.den)) + } +} From 0cd28e402ec14d8238225b31b6ac476ab5ec9af2 Mon Sep 17 00:00:00 2001 From: Quaternions Date: Fri, 13 Sep 2024 14:00:40 -0700 Subject: [PATCH 194/227] fixed: special case for convenience --- fixed_wide/src/fixed.rs | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/fixed_wide/src/fixed.rs b/fixed_wide/src/fixed.rs index f777c11..c0751e1 100644 --- a/fixed_wide/src/fixed.rs +++ b/fixed_wide/src/fixed.rs @@ -275,6 +275,14 @@ macro_rules! impl_multiply_operator_not_const_generic { } #[cfg(not(feature="wide-mul"))] impl_multiplicative_operator_not_const_generic!(($struct, $trait, $method, $output ), $width); + #[cfg(feature="deferred-division")] + impl ratio_ops::ratio::Divide for Fixed<$width,{$width*32}>{ + type Output=Self; + #[inline] + fn divide(self, other: i64)->Self::Output{ + Self::from_bits(self.bits/BInt::from(other)) + } + } } } macro_rules! impl_divide_operator_not_const_generic { From 4e284311e1c73d9e93d69d41749b4ef918ea243c Mon Sep 17 00:00:00 2001 From: Quaternions Date: Sun, 15 Sep 2024 20:30:09 -0700 Subject: [PATCH 195/227] this depends on that --- linear_ops/Cargo.lock | 1 + 1 file changed, 1 insertion(+) diff --git a/linear_ops/Cargo.lock b/linear_ops/Cargo.lock index 3f34821..917b30f 100644 --- a/linear_ops/Cargo.lock +++ b/linear_ops/Cargo.lock @@ -21,6 +21,7 @@ name = "linear_ops" version = "0.1.0" dependencies = [ "fixed_wide", + "paste", "ratio_ops", ] From 0734122e759828cd9c69348f4cbf272f7a51bf47 Mon Sep 17 00:00:00 2001 From: Quaternions Date: Mon, 16 Sep 2024 11:46:05 -0700 Subject: [PATCH 196/227] ratio: ord methods --- ratio_ops/src/ratio.rs | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/ratio_ops/src/ratio.rs b/ratio_ops/src/ratio.rs index a7f8928..55732be 100644 --- a/ratio_ops/src/ratio.rs +++ b/ratio_ops/src/ratio.rs @@ -68,6 +68,32 @@ impl_ratio_method!(Add,add,add_ratio); impl_ratio_method!(Sub,sub,sub_ratio); impl_ratio_method!(Rem,rem,rem_ratio); +macro_rules! impl_ratio_ord_method { + ($method:ident, $ratio_method:ident, $output:ty) => { + impl Ratio{ + #[inline] + pub fn $ratio_method(self,rhs:Ratio)->$output + where + LhsNum:core::ops::Mul, + LhsDen:core::ops::Mul, + T:Ord, + { + (self.num*rhs.den).$method(&(self.den*rhs.num)) + } + } + } +} +//PartialEq +impl_ratio_ord_method!(eq,eq_ratio,bool); +//PartialOrd +impl_ratio_ord_method!(lt,lt_ratio,bool); +impl_ratio_ord_method!(gt,gt_ratio,bool); +impl_ratio_ord_method!(le,le_ratio,bool); +impl_ratio_ord_method!(ge,ge_ratio,bool); +impl_ratio_ord_method!(partial_cmp,partial_cmp_ratio,Option); +//Ord +impl_ratio_ord_method!(cmp,cmp_ratio,core::cmp::Ordering); + /* generic rhs mul is not possible! impl core::ops::Mul> for Lhs where From a100f182e17a73eba8fe7e21d0baf722ecf3936b Mon Sep 17 00:00:00 2001 From: Quaternions Date: Mon, 16 Sep 2024 15:02:31 -0700 Subject: [PATCH 197/227] Fix trait --- fixed_wide/src/fixed.rs | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/fixed_wide/src/fixed.rs b/fixed_wide/src/fixed.rs index c0751e1..37253a7 100644 --- a/fixed_wide/src/fixed.rs +++ b/fixed_wide/src/fixed.rs @@ -493,6 +493,10 @@ macro_repeated!( (1,15) ); +pub trait Fix{ + fn fix(self)->Out; +} + macro_rules! impl_fix_rhs_lt_lhs_not_const_generic{ ( (), @@ -507,6 +511,13 @@ macro_rules! impl_fix_rhs_lt_lhs_not_const_generic{ } } } + impl Fix> for Fixed<$lhs,{$lhs*32}>{ + fn fix(self)->Fixed<$rhs,{$rhs*32}>{ + paste::item!{ + self.[]() + } + } + } } } macro_rules! impl_fix_lhs_lt_rhs_not_const_generic{ @@ -523,6 +534,13 @@ macro_rules! impl_fix_lhs_lt_rhs_not_const_generic{ } } } + impl Fix> for Fixed<$lhs,{$lhs*32}>{ + fn fix(self)->Fixed<$rhs,{$rhs*32}>{ + paste::item!{ + self.[]() + } + } + } } } macro_rules! impl_fix_lhs_eq_rhs_not_const_generic{ @@ -539,6 +557,13 @@ macro_rules! impl_fix_lhs_eq_rhs_not_const_generic{ } } } + impl Fix> for Fixed<$lhs,{$lhs*32}>{ + fn fix(self)->Fixed<$rhs,{$rhs*32}>{ + paste::item!{ + self.[]() + } + } + } } } From 655a6da251cc267d1c14430dd378ab3bf82d3c48 Mon Sep 17 00:00:00 2001 From: Quaternions Date: Mon, 16 Sep 2024 15:02:43 -0700 Subject: [PATCH 198/227] cheese extrapolate div --- fixed_wide/src/fixed.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/fixed_wide/src/fixed.rs b/fixed_wide/src/fixed.rs index 37253a7..a54a2af 100644 --- a/fixed_wide/src/fixed.rs +++ b/fixed_wide/src/fixed.rs @@ -483,7 +483,7 @@ macro_repeated!( (1,5),(2,5),(3,5),(4,5),(5,5),(6,5),(7,5),(8,5),(9,5),(10,5),(11,5), (1,6),(2,6),(3,6),(4,6),(5,6),(6,6),(7,6),(8,6),(9,6),(10,6), (1,7),(2,7),(3,7),(4,7),(5,7),(6,7),(7,7),(8,7),(9,7), - (1,8),(2,8),(3,8),(4,8),(5,8),(6,8),(7,8),(8,8), + (1,8),(2,8),(3,8),(4,8),(5,8),(6,8),(7,8),(8,8),(9,8), (1,9),(2,9),(3,9),(4,9),(5,9),(6,9),(7,9), (1,10),(2,10),(3,10),(4,10),(5,10),(6,10), (1,11),(2,11),(3,11),(4,11),(5,11), @@ -571,7 +571,7 @@ macro_rules! impl_fix_lhs_eq_rhs_not_const_generic{ macro_repeated!( impl_fix_rhs_lt_lhs_not_const_generic,(), - (2,1),(3,1),(4,1),(5,1),(6,1),(7,1),(8,1),(9,1),(10,1),(11,1),(12,1),(13,1),(14,1),(15,1),(16,1), + (2,1),(3,1),(4,1),(5,1),(6,1),(7,1),(8,1),(9,1),(10,1),(11,1),(12,1),(13,1),(14,1),(15,1),(16,1),(17,1), (3,2),(4,2),(5,2),(6,2),(7,2),(8,2),(9,2),(10,2),(11,2),(12,2),(13,2),(14,2),(15,2),(16,2), (4,3),(5,3),(6,3),(7,3),(8,3),(9,3),(10,3),(11,3),(12,3),(13,3),(14,3),(15,3),(16,3), (5,4),(6,4),(7,4),(8,4),(9,4),(10,4),(11,4),(12,4),(13,4),(14,4),(15,4),(16,4), From 6dbe96fca2a028da8189e6f913ac7f81e7017818 Mon Sep 17 00:00:00 2001 From: Quaternions Date: Mon, 16 Sep 2024 15:48:52 -0700 Subject: [PATCH 199/227] Fixed<1,_>::to_raw() --- fixed_wide/src/fixed.rs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/fixed_wide/src/fixed.rs b/fixed_wide/src/fixed.rs index a54a2af..84667bc 100644 --- a/fixed_wide/src/fixed.rs +++ b/fixed_wide/src/fixed.rs @@ -63,6 +63,10 @@ impl Fixed<1,F>{ pub const fn raw(value:i64)->Self{ Self::from_bits(BInt::from_bits(bnum::BUint::from_digit(value as u64))) } + #[inline] + pub const fn to_raw(self)->i64{ + self.to_bits().to_bits().digits()[0] as i64 + } } impl From for Fixed From 031cd6e77182ea80c9452ca9ccc42418747fab69 Mon Sep 17 00:00:00 2001 From: Quaternions Date: Tue, 17 Sep 2024 14:47:14 -0700 Subject: [PATCH 200/227] float builder (debug version) --- fixed_wide/src/fixed.rs | 73 ++++++++++++++++++++++++++++++++--------- 1 file changed, 57 insertions(+), 16 deletions(-) diff --git a/fixed_wide/src/fixed.rs b/fixed_wide/src/fixed.rs index 84667bc..bcee486 100644 --- a/fixed_wide/src/fixed.rs +++ b/fixed_wide/src/fixed.rs @@ -138,31 +138,72 @@ impl std::iter::Sum for Fixed{ } } +const fn signed_shift(lhs:u64,rhs:i32)->u64{ + if rhs.is_negative(){ + lhs>>-rhs + }else{ + lhs< { + ( $output: ty, $unsigned:ty, $exponent_bits:expr, $mantissa_bits:expr ) => { impl Into<$output> for Fixed{ #[inline] fn into(self)->$output{ - let mut total=0.0; - let bits=self.bits.to_bits(); - let digits=bits.digits(); - for (i,digit) in digits[0..N-1].iter().enumerate(){ - // (i*64-F) as i32 will interpret the highest order bit as a sign bit but whatever - total+=(*digit as $output)*(2.0 as $output).powi((i*64-F) as i32); + const DIGIT_SHIFT:u32=6;//Log2[64] + // SBBB BBBB + // 1001 1110 0000 0000 + let sign=if self.bits.is_negative(){(1 as $unsigned)<<(<$unsigned>::BITS-1)}else{0}; + println!("sign={sign}"); + let unsigned=self.bits.unsigned_abs(); + println!("unsigned={unsigned}"); + let most_significant_bit=unsigned.bits(); + println!("most_significant_bit={most_significant_bit}"); + let exp=if unsigned.is_zero(){ + 0 + }else{ + let msb=most_significant_bit as $unsigned; + println!("msb={msb}"); + let _127=((1 as $unsigned)<<($exponent_bits-1))-1; + println!("_127={_127}"); + let msb_offset=msb+_127-1-F as $unsigned; + println!("msb_offset={msb_offset}"); + msb_offset<<($mantissa_bits-1) + }; + println!("exp={exp:#034b}"); + let digits=unsigned.digits(); + println!("digits={digits:?}"); + let digit_index=most_significant_bit>>DIGIT_SHIFT; + println!("digit_index={digit_index}"); + let digit=digits[digit_index as usize]; + println!("digit={digit:#034b}"); + //How many bits does the mantissa take from this digit + let take_bits=most_significant_bit-(digit_index<::from_bits(bits) } } } } -impl_into_float!(f32); -impl_into_float!(f64); +impl_into_float!(f32,u32,8,24); +impl_into_float!(f64,u64,11,53); impl core::fmt::Display for Fixed{ #[inline] From 865d7a7886bbddebfada7fabbf5cf450d5b6dfe4 Mon Sep 17 00:00:00 2001 From: Quaternions Date: Tue, 17 Sep 2024 14:47:18 -0700 Subject: [PATCH 201/227] float tests --- fixed_wide/src/tests.rs | 34 ++++++++++++++++++++++++++++++++-- 1 file changed, 32 insertions(+), 2 deletions(-) diff --git a/fixed_wide/src/tests.rs b/fixed_wide/src/tests.rs index f7278ce..35795be 100644 --- a/fixed_wide/src/tests.rs +++ b/fixed_wide/src/tests.rs @@ -4,13 +4,43 @@ use crate::types::I256F256; #[test] fn you_can_add_numbers(){ let a=I256F256::from((3i128*2).pow(4)); - assert_eq!(a+a,I256F256::from((3i128*2).pow(4)*2)) + assert_eq!(a+a,I256F256::from((3i128*2).pow(4)*2)); +} + +#[test] +fn to_f32(){ + let a=I256F256::from(1)>>2; + let f:f32=a.into(); + assert_eq!(f,0.25f32); + let f:f32=(-a).into(); + assert_eq!(f,-0.25f32); + let a=I256F256::from(0); + let f:f32=(-a).into(); + assert_eq!(f,0f32); + let a=I256F256::from(237946589723468975i64)<<32; + let f:f32=a.into(); + assert_eq!(f,237946589723468975f32*2.0f32.powi(32)); +} + +#[test] +fn to_f64(){ + let a=I256F256::from(1)>>2; + let f:f64=a.into(); + assert_eq!(f,0.25f64); + let f:f64=(-a).into(); + assert_eq!(f,-0.25f64); + let a=I256F256::from(0); + let f:f64=(-a).into(); + assert_eq!(f,0f64); + let a=I256F256::from(237946589723468975i64)<<32; + let f:f64=a.into(); + assert_eq!(f,237946589723468975f64*2.0f64.powi(32)); } #[test] fn you_can_shr_numbers(){ let a=I32F32::from(4); - assert_eq!(a>>1,I32F32::from(2)) + assert_eq!(a>>1,I32F32::from(2)); } #[test] From 665d528b87c1b313ddd10f8291f24d994e9e4122 Mon Sep 17 00:00:00 2001 From: Quaternions Date: Tue, 17 Sep 2024 14:48:21 -0700 Subject: [PATCH 202/227] remove debug from float builder --- fixed_wide/src/fixed.rs | 16 ---------------- 1 file changed, 16 deletions(-) diff --git a/fixed_wide/src/fixed.rs b/fixed_wide/src/fixed.rs index bcee486..d88203b 100644 --- a/fixed_wide/src/fixed.rs +++ b/fixed_wide/src/fixed.rs @@ -154,49 +154,33 @@ macro_rules! impl_into_float { // SBBB BBBB // 1001 1110 0000 0000 let sign=if self.bits.is_negative(){(1 as $unsigned)<<(<$unsigned>::BITS-1)}else{0}; - println!("sign={sign}"); let unsigned=self.bits.unsigned_abs(); - println!("unsigned={unsigned}"); let most_significant_bit=unsigned.bits(); - println!("most_significant_bit={most_significant_bit}"); let exp=if unsigned.is_zero(){ 0 }else{ let msb=most_significant_bit as $unsigned; - println!("msb={msb}"); let _127=((1 as $unsigned)<<($exponent_bits-1))-1; - println!("_127={_127}"); let msb_offset=msb+_127-1-F as $unsigned; - println!("msb_offset={msb_offset}"); msb_offset<<($mantissa_bits-1) }; - println!("exp={exp:#034b}"); let digits=unsigned.digits(); - println!("digits={digits:?}"); let digit_index=most_significant_bit>>DIGIT_SHIFT; - println!("digit_index={digit_index}"); let digit=digits[digit_index as usize]; - println!("digit={digit:#034b}"); //How many bits does the mantissa take from this digit let take_bits=most_significant_bit-(digit_index<::from_bits(bits) } } From 934475b959dd89dcbfcd55890e6f4131805d10f9 Mon Sep 17 00:00:00 2001 From: Quaternions Date: Tue, 17 Sep 2024 15:10:07 -0700 Subject: [PATCH 203/227] fix fix --- fixed_wide/src/fixed.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fixed_wide/src/fixed.rs b/fixed_wide/src/fixed.rs index d88203b..a566151 100644 --- a/fixed_wide/src/fixed.rs +++ b/fixed_wide/src/fixed.rs @@ -536,7 +536,7 @@ macro_rules! impl_fix_rhs_lt_lhs_not_const_generic{ paste::item!{ #[inline] pub fn [](self)->Fixed<$rhs,{$rhs*32}>{ - Fixed::from_bits(bnum::cast::As::as_::>(self.bits).shr(($lhs-$rhs)*32)) + Fixed::from_bits(bnum::cast::As::as_::>(self.bits.shr(($lhs-$rhs)*32))) } } } From bc773f7d45f44a01613ba01393c1d21c16aecf6e Mon Sep 17 00:00:00 2001 From: Quaternions Date: Tue, 17 Sep 2024 15:10:11 -0700 Subject: [PATCH 204/227] test fix better --- fixed_wide/src/tests.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/fixed_wide/src/tests.rs b/fixed_wide/src/tests.rs index 35795be..17c1ce3 100644 --- a/fixed_wide/src/tests.rs +++ b/fixed_wide/src/tests.rs @@ -84,8 +84,8 @@ fn test_bint(){ #[test] fn test_fix(){ - let a=I32F32::ONE; - assert_eq!(a.fix_8(),I256F256::ONE); + assert_eq!(I32F32::ONE.fix_8(),I256F256::ONE); + assert_eq!(I32F32::ONE,I256F256::ONE.fix_1()); } #[test] fn test_sqrt(){ From 94cd23fe4b863b5cb87d68a25adf00731a67cf9d Mon Sep 17 00:00:00 2001 From: Quaternions Date: Wed, 18 Sep 2024 10:44:18 -0700 Subject: [PATCH 205/227] add ratio tests --- ratio_ops/src/lib.rs | 3 +++ ratio_ops/src/tests.rs | 58 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 61 insertions(+) create mode 100644 ratio_ops/src/tests.rs diff --git a/ratio_ops/src/lib.rs b/ratio_ops/src/lib.rs index 96b877a..6786c4f 100644 --- a/ratio_ops/src/lib.rs +++ b/ratio_ops/src/lib.rs @@ -1 +1,4 @@ pub mod ratio; + +#[cfg(test)] +mod tests; diff --git a/ratio_ops/src/tests.rs b/ratio_ops/src/tests.rs new file mode 100644 index 0000000..739313e --- /dev/null +++ b/ratio_ops/src/tests.rs @@ -0,0 +1,58 @@ +use crate::ratio::Ratio; + +macro_rules! test_op{ + ($ratio_op:ident,$op:ident,$a:expr,$b:expr,$c:expr,$d:expr)=>{ + assert_eq!( + Ratio::new($a,$b).$ratio_op(Ratio::new($c,$d)), + (($a as f32)/($b as f32)).$op(&(($c as f32)/($d as f32))) + ); + }; +} + +macro_rules! test_many_ops{ + ($ratio_op:ident,$op:ident)=>{ + test_op!($ratio_op,$op,1,2,3,4); + test_op!($ratio_op,$op,1,2,-3,4); + test_op!($ratio_op,$op,-1,2,-3,4); + test_op!($ratio_op,$op,-1,-2,-3,4); + test_op!($ratio_op,$op,2,1,6,3); + test_op!($ratio_op,$op,-2,1,6,3); + test_op!($ratio_op,$op,2,-1,-6,3); + test_op!($ratio_op,$op,2,1,6,-3); + }; +} + +#[test] +fn test_lt(){ + test_many_ops!(lt_ratio,lt); +} + +#[test] +fn test_gt(){ + test_many_ops!(gt_ratio,gt); +} + +#[test] +fn test_le(){ + test_many_ops!(le_ratio,le); +} + +#[test] +fn test_ge(){ + test_many_ops!(ge_ratio,ge); +} + +#[test] +fn test_eq(){ + test_many_ops!(eq_ratio,eq); +} + +#[test] +fn test_partial_cmp(){ + test_many_ops!(partial_cmp_ratio,partial_cmp); +} + +// #[test] +// fn test_cmp(){ +// test_many_ops!(cmp_ratio,cmp); +// } From 546a4aa8c72b46a390b24009dae4c0ba1b791605 Mon Sep 17 00:00:00 2001 From: Quaternions Date: Wed, 18 Sep 2024 11:50:34 -0700 Subject: [PATCH 206/227] test negative --- fixed_wide/src/tests.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/fixed_wide/src/tests.rs b/fixed_wide/src/tests.rs index 17c1ce3..8e4dd4e 100644 --- a/fixed_wide/src/tests.rs +++ b/fixed_wide/src/tests.rs @@ -86,6 +86,8 @@ fn test_bint(){ fn test_fix(){ assert_eq!(I32F32::ONE.fix_8(),I256F256::ONE); assert_eq!(I32F32::ONE,I256F256::ONE.fix_1()); + assert_eq!(I32F32::NEG_ONE.fix_8(),I256F256::NEG_ONE); + assert_eq!(I32F32::NEG_ONE,I256F256::NEG_ONE.fix_1()); } #[test] fn test_sqrt(){ From ba357ee99b48a5bcde8a5e061043058e4af344fb Mon Sep 17 00:00:00 2001 From: Quaternions Date: Sat, 21 Sep 2024 15:42:29 -0700 Subject: [PATCH 207/227] efficient fixed mul --- fixed_wide/src/fixed.rs | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/fixed_wide/src/fixed.rs b/fixed_wide/src/fixed.rs index a566151..05e8b26 100644 --- a/fixed_wide/src/fixed.rs +++ b/fixed_wide/src/fixed.rs @@ -295,10 +295,14 @@ macro_rules! impl_multiply_operator_not_const_generic { impl $struct<$width,F>{ paste::item!{ #[inline] - pub fn [](self, other: Self) -> Self { - let lhs=self.bits.as_::>(); - let rhs=other.bits.as_::>(); - Self::from_bits(lhs.mul(rhs).shr(F as u32).as_()) + pub fn [](self, rhs: Self) -> Self { + let (low,high)=self.bits.unsigned_abs().widening_mul(rhs.bits.unsigned_abs()); + let out:BInt::<{$width*2}>=unsafe{core::mem::transmute([low,high])}; + if self.is_negative()==rhs.is_negative(){ + Self::from_bits(out.shr(F as u32).as_()) + }else{ + -Self::from_bits(out.shr(F as u32).as_()) + } } } } From 102ea607abcde4ccc669e68d9849fb6217f00807 Mon Sep 17 00:00:00 2001 From: Quaternions Date: Mon, 23 Sep 2024 11:20:11 -0700 Subject: [PATCH 208/227] Ratio Parity trait --- fixed_wide/src/fixed.rs | 7 +++++- ratio_ops/src/ratio.rs | 56 +++++++++++++++++++++++++++++++++++++---- 2 files changed, 57 insertions(+), 6 deletions(-) diff --git a/fixed_wide/src/fixed.rs b/fixed_wide/src/fixed.rs index 05e8b26..7d592d5 100644 --- a/fixed_wide/src/fixed.rs +++ b/fixed_wide/src/fixed.rs @@ -408,7 +408,12 @@ impl co ratio_ops::ratio::Ratio::new(self,other) } } - +#[cfg(feature="deferred-division")] +impl ratio_ops::ratio::Parity for Fixed{ + fn parity(&self)->bool{ + self.is_negative() + } +} macro_rules! impl_shift_operator { ( $struct: ident, $trait: ident, $method: ident, $output: ty ) => { impl core::ops::$trait for $struct{ diff --git a/ratio_ops/src/ratio.rs b/ratio_ops/src/ratio.rs index 55732be..b41dc74 100644 --- a/ratio_ops/src/ratio.rs +++ b/ratio_ops/src/ratio.rs @@ -68,17 +68,63 @@ impl_ratio_method!(Add,add,add_ratio); impl_ratio_method!(Sub,sub,sub_ratio); impl_ratio_method!(Rem,rem,rem_ratio); -macro_rules! impl_ratio_ord_method { - ($method:ident, $ratio_method:ident, $output:ty) => { - impl Ratio{ +/// Comparing two ratios needs to know the parity of the denominators +/// For signed integers this can be implemented with is_negative() +pub trait Parity{ + fn parity(&self)->bool; +} +macro_rules! impl_parity_unsigned{ + ($($type:ty),*)=>{ + $( + impl Parity for $type{ + fn parity(&self)->bool{ + false + } + } + )* + }; +} +macro_rules! impl_parity_signed{ + ($($type:ty),*)=>{ + $( + impl Parity for $type{ + fn parity(&self)->bool{ + self.is_negative() + } + } + )* + }; +} +macro_rules! impl_parity_float{ + ($($type:ty),*)=>{ + $( + impl Parity for $type{ + fn parity(&self)->bool{ + self.is_sign_negative() + } + } + )* + }; +} + +impl_parity_unsigned!(u8,u16,u32,u64,u128,usize); +impl_parity_signed!(i8,i16,i32,i64,i128,isize); +impl_parity_float!(f32,f64); + +macro_rules! impl_ratio_ord_method{ + ($method:ident, $ratio_method:ident, $output:ty)=>{ + impl Ratio{ #[inline] - pub fn $ratio_method(self,rhs:Ratio)->$output + pub fn $ratio_method(self,rhs:Ratio)->$output where LhsNum:core::ops::Mul, LhsDen:core::ops::Mul, T:Ord, { - (self.num*rhs.den).$method(&(self.den*rhs.num)) + match self.den.parity()^rhs.den.parity(){ + true=>(self.den*rhs.num).$method(&(self.num*rhs.den)), + false=>(self.num*rhs.den).$method(&(self.den*rhs.num)), + } } } } From b91f061797d746c40ebe7cf0b702079dfb1fa142 Mon Sep 17 00:00:00 2001 From: Quaternions Date: Wed, 25 Sep 2024 09:46:44 -0700 Subject: [PATCH 209/227] implement same-size wide mul more efficiently --- fixed_wide/src/fixed.rs | 56 +++++++++++++++++++++++++++++++++++------ 1 file changed, 48 insertions(+), 8 deletions(-) diff --git a/fixed_wide/src/fixed.rs b/fixed_wide/src/fixed.rs index 7d592d5..446d957 100644 --- a/fixed_wide/src/fixed.rs +++ b/fixed_wide/src/fixed.rs @@ -510,18 +510,54 @@ macro_rules! impl_wide_not_const_generic{ impl_wide_operators!($lhs,$rhs); }; } +macro_rules! impl_wide_same_size_not_const_generic{ + ( + (), + $width:expr + )=>{ + impl Fixed<$width,{$width*32}> + { + paste::item!{ + #[inline] + pub fn [](self,rhs:Fixed<$width,{$width*32}>)->Fixed<{$width*2},{$width*2*32}>{ + let (low,high)=self.bits.unsigned_abs().widening_mul(rhs.bits.unsigned_abs()); + let out:BInt::<{$width*2}>=unsafe{core::mem::transmute([low,high])}; + if self.is_negative()==rhs.is_negative(){ + Fixed::from_bits(out) + }else{ + // Wrapping is the cheapest negation operation + // And the inputs cannot reach the point where it matters + Fixed::from_bits(out.wrapping_neg()) + } + } + /// This operation cannot represent the fraction exactly, + /// but it shapes the output to have precision for the + /// largest and smallest possible fractions. + #[inline] + pub fn [](self,rhs:Fixed<$width,{$width*32}>)->Fixed<{$width*2},{$width*2*32}>{ + // (lhs/2^LHS_FRAC)/(rhs/2^RHS_FRAC) + let lhs=self.bits.as_::>().shl($width*64); + let rhs=rhs.bits.as_::>(); + Fixed::from_bits(lhs/rhs) + } + } + } + #[cfg(feature="wide-mul")] + impl_wide_operators!($width,$width); + }; +} //const generics sidestepped wahoo macro_repeated!( impl_wide_not_const_generic,(), - (1,1),(2,1),(3,1),(4,1),(5,1),(6,1),(7,1),(8,1),(9,1),(10,1),(11,1),(12,1),(13,1),(14,1),(15,1), - (1,2),(2,2),(3,2),(4,2),(5,2),(6,2),(7,2),(8,2),(9,2),(10,2),(11,2),(12,2),(13,2),(14,2), - (1,3),(2,3),(3,3),(4,3),(5,3),(6,3),(7,3),(8,3),(9,3),(10,3),(11,3),(12,3),(13,3), - (1,4),(2,4),(3,4),(4,4),(5,4),(6,4),(7,4),(8,4),(9,4),(10,4),(11,4),(12,4), - (1,5),(2,5),(3,5),(4,5),(5,5),(6,5),(7,5),(8,5),(9,5),(10,5),(11,5), - (1,6),(2,6),(3,6),(4,6),(5,6),(6,6),(7,6),(8,6),(9,6),(10,6), - (1,7),(2,7),(3,7),(4,7),(5,7),(6,7),(7,7),(8,7),(9,7), - (1,8),(2,8),(3,8),(4,8),(5,8),(6,8),(7,8),(8,8),(9,8), + (2,1),(3,1),(4,1),(5,1),(6,1),(7,1),(8,1),(9,1),(10,1),(11,1),(12,1),(13,1),(14,1),(15,1), + (1,2), (3,2),(4,2),(5,2),(6,2),(7,2),(8,2),(9,2),(10,2),(11,2),(12,2),(13,2),(14,2), + (1,3),(2,3), (4,3),(5,3),(6,3),(7,3),(8,3),(9,3),(10,3),(11,3),(12,3),(13,3), + (1,4),(2,4),(3,4), (5,4),(6,4),(7,4),(8,4),(9,4),(10,4),(11,4),(12,4), + (1,5),(2,5),(3,5),(4,5), (6,5),(7,5),(8,5),(9,5),(10,5),(11,5), + (1,6),(2,6),(3,6),(4,6),(5,6), (7,6),(8,6),(9,6),(10,6), + (1,7),(2,7),(3,7),(4,7),(5,7),(6,7), (8,7),(9,7), + (1,8),(2,8),(3,8),(4,8),(5,8),(6,8),(7,8), (9,8), (1,9),(2,9),(3,9),(4,9),(5,9),(6,9),(7,9), (1,10),(2,10),(3,10),(4,10),(5,10),(6,10), (1,11),(2,11),(3,11),(4,11),(5,11), @@ -530,6 +566,10 @@ macro_repeated!( (1,14),(2,14), (1,15) ); +macro_repeated!( + impl_wide_same_size_not_const_generic,(), + 1,2,3,4,5,6,7,8 +); pub trait Fix{ fn fix(self)->Out; From 2b58204cb9a36376a71e9d30b5cdbc897b8df6ce Mon Sep 17 00:00:00 2001 From: Quaternions Date: Wed, 25 Sep 2024 10:03:09 -0700 Subject: [PATCH 210/227] update bnum --- fixed_wide/Cargo.lock | 4 ++-- fixed_wide/Cargo.toml | 2 +- linear_ops/Cargo.lock | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/fixed_wide/Cargo.lock b/fixed_wide/Cargo.lock index 1f6a13a..7a78ffb 100644 --- a/fixed_wide/Cargo.lock +++ b/fixed_wide/Cargo.lock @@ -10,9 +10,9 @@ checksum = "7c02d123df017efcdfbd739ef81735b36c5ba83ec3c59c80a9d7ecc718f92e50" [[package]] name = "bnum" -version = "0.11.0" +version = "0.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3e31ea183f6ee62ac8b8a8cf7feddd766317adfb13ff469de57ce033efd6a790" +checksum = "50202def95bf36cb7d1d7a7962cea1c36a3f8ad42425e5d2b71d7acb8041b5b8" [[package]] name = "fixed_wide" diff --git a/fixed_wide/Cargo.toml b/fixed_wide/Cargo.toml index 40d6321..45504f9 100644 --- a/fixed_wide/Cargo.toml +++ b/fixed_wide/Cargo.toml @@ -10,7 +10,7 @@ wide-mul=[] zeroes=["dep:arrayvec"] [dependencies] -bnum = "0.11.0" +bnum = "0.12.0" arrayvec = { version = "0.7.6", optional = true } paste = "1.0.15" ratio_ops = { path = "../ratio_ops", optional = true } diff --git a/linear_ops/Cargo.lock b/linear_ops/Cargo.lock index 917b30f..e83034a 100644 --- a/linear_ops/Cargo.lock +++ b/linear_ops/Cargo.lock @@ -4,9 +4,9 @@ version = 3 [[package]] name = "bnum" -version = "0.11.0" +version = "0.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3e31ea183f6ee62ac8b8a8cf7feddd766317adfb13ff469de57ce033efd6a790" +checksum = "50202def95bf36cb7d1d7a7962cea1c36a3f8ad42425e5d2b71d7acb8041b5b8" [[package]] name = "fixed_wide" From e46f4fb9001c79297e764f9c015454b208111d3f Mon Sep 17 00:00:00 2001 From: Quaternions Date: Wed, 25 Sep 2024 10:07:41 -0700 Subject: [PATCH 211/227] save a copy in sqrt using epic bnum 0.12 feature (pulled by yours truly) --- fixed_wide/src/fixed.rs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/fixed_wide/src/fixed.rs b/fixed_wide/src/fixed.rs index 446d957..a8bf944 100644 --- a/fixed_wide/src/fixed.rs +++ b/fixed_wide/src/fixed.rs @@ -708,7 +708,11 @@ macro_rules! impl_not_const_generic{ let wide_self=self.[](); //descend down the bits and check if flipping each bit would push the square over the input value for shift in (0..=max_shift).rev(){ - let new_result=result|Self::from_bits(BInt::from_bits(bnum::BUint::power_of_two(shift))); + let new_result={ + let mut bits=result.to_bits().to_bits(); + bits.set_bit(shift,true); + Self::from_bits(BInt::from_bits(bits)) + }; if new_result.[](new_result)<=wide_self{ result=new_result; } From 8d97ffba92a8538db5db84e28bf960098cf6ace0 Mon Sep 17 00:00:00 2001 From: Quaternions Date: Thu, 26 Sep 2024 15:06:01 -0700 Subject: [PATCH 212/227] column major --- linear_ops/src/macros/matrix.rs | 55 +++++++++++++++++------------- linear_ops/src/matrix.rs | 2 +- linear_ops/src/tests/fixed_wide.rs | 14 ++++---- linear_ops/src/tests/tests.rs | 20 +++++------ 4 files changed, 49 insertions(+), 42 deletions(-) diff --git a/linear_ops/src/macros/matrix.rs b/linear_ops/src/macros/matrix.rs index c04e965..69db874 100644 --- a/linear_ops/src/macros/matrix.rs +++ b/linear_ops/src/macros/matrix.rs @@ -4,18 +4,18 @@ macro_rules! impl_matrix { () => { impl Matrix{ #[inline(always)] - pub const fn new(array:[[T;X];Y])->Self{ + pub const fn new(array:[[T;Y];X])->Self{ Self{array} } #[inline(always)] - pub fn to_array(self)->[[T;X];Y]{ + pub fn to_array(self)->[[T;Y];X]{ self.array } #[inline] - pub fn from_rows(rows:[Vector;Y])->Self + pub fn from_cols(cols:[Vector;X])->Self { Matrix::new( - rows.map(|row|row.array), + cols.map(|col|col.array), ) } #[inline] @@ -40,38 +40,45 @@ macro_rules! impl_matrix { ) } #[inline] - // MatY.MatX = MatY + // old (list of rows) MatY.MatX = MatY + // new (list of columns) MatX.MatZ = MatZ pub fn dot(self,rhs:Matrix)->Matrix where T:core::ops::Mul+Copy, V:core::iter::Sum, U:Copy, { - let mut array_of_iterators=rhs.array.map(|axis|axis.into_iter().cycle()); - Matrix::new( - self.array.map(|axis| + let mut array_of_iterators=self.array.map(|axis|axis.into_iter().cycle()); + Matrix{ + array:rhs.array.map(|rhs_axis| core::array::from_fn(|_| - // axis dot product with transposed rhs array - axis.iter().zip( - array_of_iterators.iter_mut() - ).map(|(&lhs_value,rhs_iter)| - lhs_value*rhs_iter.next().unwrap() - ).sum() + array_of_iterators + .iter_mut() + .zip(rhs_axis.iter()) + .map(|(lhs_iter,&rhs_value)| + lhs_iter.next().unwrap()*rhs_value + ).sum() ) ) - ) + } } #[inline] - // MatY.VecX = VecY + // MatX.VecY = VecX pub fn transform_vector(self,rhs:Vector)->Vector where T:core::ops::Mul, V:core::iter::Sum, U:Copy, { + let mut array_of_iterators=self.array.map(|axis|axis.into_iter()); Vector::new( - self.array.map(|axis| - Vector::new(axis).dot(rhs) + core::array::from_fn(|_| + array_of_iterators + .iter_mut() + .zip(rhs.array.iter()) + .map(|(lhs_iter,&rhs_value)| + lhs_iter.next().unwrap()*rhs_value + ).sum() ) ) } @@ -82,7 +89,7 @@ macro_rules! impl_matrix { { #[inline(always)] pub const fn from_value(value:T)->Self{ - Self::new([[value;X];Y]) + Self::new([[value;Y];X]) } } @@ -98,13 +105,13 @@ macro_rules! impl_matrix { impl core::fmt::Display for Matrix{ #[inline] fn fmt(&self,f:&mut core::fmt::Formatter)->Result<(),core::fmt::Error>{ - for row in &self.array[0..Y]{ + for col in &self.array[0..X]{ core::write!(f,"\n")?; - for elem in &row[0..X-1]{ + for elem in &col[0..Y-1]{ core::write!(f,"{}, ",elem)?; } // assume we will be using matrices of size 1x1 or greater - core::write!(f,"{}",row.last().unwrap())?; + core::write!(f,"{}",col.last().unwrap())?; } Ok(()) } @@ -166,14 +173,14 @@ macro_rules! impl_matrix_extend { ( $x: expr, $y: expr ) => { impl Matrix<$x,$y,T>{ #[inline] - pub fn extend_row(self,value:Vector<$x,T>)->Matrix<$x,{$y+1},T>{ + pub fn extend_column(self,value:Vector<$y,T>)->Matrix<{$x+1},$y,T>{ let mut iter=self.array.into_iter().chain(core::iter::once(value.array)); Matrix::new( core::array::from_fn(|_|iter.next().unwrap()), ) } #[inline] - pub fn extend_column(self,value:Vector<$y,T>)->Matrix<{$x+1},$y,T>{ + pub fn extend_row(self,value:Vector<$x,T>)->Matrix<$x,{$y+1},T>{ let mut iter_rows=value.array.into_iter(); Matrix::new( self.array.map(|axis|{ diff --git a/linear_ops/src/matrix.rs b/linear_ops/src/matrix.rs index 2c7dfb5..200d176 100644 --- a/linear_ops/src/matrix.rs +++ b/linear_ops/src/matrix.rs @@ -2,7 +2,7 @@ use crate::vector::Vector; #[derive(Clone,Copy,Debug,Hash,Eq,PartialEq)] pub struct Matrix{ - pub(crate) array:[[T;X];Y], + pub(crate) array:[[T;Y];X], } crate::impl_matrix!(); diff --git a/linear_ops/src/tests/fixed_wide.rs b/linear_ops/src/tests/fixed_wide.rs index ae11c41..7032fd0 100644 --- a/linear_ops/src/tests/fixed_wide.rs +++ b/linear_ops/src/tests/fixed_wide.rs @@ -1,4 +1,4 @@ -use crate::types::{Matrix3,Matrix2x3,Matrix4x3,Matrix2x4,Vector3}; +use crate::types::{Matrix3,Matrix3x2,Matrix3x4,Matrix4x2,Vector3}; type Planar64=fixed_wide::types::I32F32; type Planar64Wide1=fixed_wide::types::I64F64; @@ -37,28 +37,28 @@ fn wide_vec3_length_squared(){ #[test] fn wide_matrix_dot(){ - let lhs=Matrix4x3::new([ + let lhs=Matrix3x4::new([ [Planar64::from(1),Planar64::from(2),Planar64::from(3),Planar64::from(4)], [Planar64::from(5),Planar64::from(6),Planar64::from(7),Planar64::from(8)], [Planar64::from(9),Planar64::from(10),Planar64::from(11),Planar64::from(12)], - ]); - let rhs=Matrix2x4::new([ + ]).transpose(); + let rhs=Matrix4x2::new([ [Planar64::from(1),Planar64::from(2)], [Planar64::from(3),Planar64::from(4)], [Planar64::from(5),Planar64::from(6)], [Planar64::from(7),Planar64::from(8)], - ]); + ]).transpose(); // Mat3.dot(Mat4) -> Mat3 let m_dot=lhs*rhs; //In[1]:= {{1, 2, 3, 4}, {5, 6, 7, 8}, {9, 10, 11, 12}} . {{1, 2}, {3, 4}, {5, 6}, {7, 8}} //Out[1]= {{50, 60}, {114, 140}, {178, 220}} assert_eq!( m_dot.array, - Matrix2x3::new([ + Matrix3x2::new([ [Planar64Wide1::from(50),Planar64Wide1::from(60)], [Planar64Wide1::from(114),Planar64Wide1::from(140)], [Planar64Wide1::from(178),Planar64Wide1::from(220)], - ]).array + ]).transpose().array ); } diff --git a/linear_ops/src/tests/tests.rs b/linear_ops/src/tests/tests.rs index 41233b2..573fe9a 100644 --- a/linear_ops/src/tests/tests.rs +++ b/linear_ops/src/tests/tests.rs @@ -1,4 +1,4 @@ -use crate::types::{Vector2,Vector3,Matrix4x3,Matrix2x4,Matrix2x3,Matrix3x2}; +use crate::types::{Vector2,Vector3,Matrix3x4,Matrix4x2,Matrix3x2,Matrix2x3}; #[test] fn test_bool(){ @@ -21,10 +21,10 @@ fn test_arithmetic(){ #[test] fn matrix_transform_vector(){ - let m=Matrix3x2::new([ + let m=Matrix2x3::new([ [1,2,3], [4,5,6], - ]); + ]).transpose(); let v=Vector3::new([1,2,3]); let transformed=m*v; assert_eq!(transformed.array,Vector2::new([14,32]).array); @@ -32,28 +32,28 @@ fn matrix_transform_vector(){ #[test] fn matrix_dot(){ - - let rhs=Matrix2x4::new([ + // All this code was written row major and I converted the lib to colum major + let rhs=Matrix4x2::new([ [ 1.0, 2.0], [ 3.0, 4.0], [ 5.0, 6.0], [ 7.0, 8.0], - ]); // | | | - let lhs=Matrix4x3::new([ // | | | + ]).transpose(); // | | | + let lhs=Matrix3x4::new([ // | | | [1.0, 2.0, 3.0, 4.0],// [ 50.0, 60.0], [5.0, 6.0, 7.0, 8.0],// [114.0,140.0], [9.0,10.0,11.0,12.0],// [178.0,220.0], - ]); + ]).transpose(); // Mat3.dot(Mat4) -> Mat3 let m_dot=lhs*rhs; //In[1]:= {{1, 2, 3, 4}, {5, 6, 7, 8}, {9, 10, 11, 12}} . {{1, 2}, {3, 4}, {5, 6}, {7, 8}} //Out[1]= {{50, 60}, {114, 140}, {178, 220}} assert_eq!( m_dot.array, - Matrix2x3::new([ + Matrix3x2::new([ [50.0,60.0], [114.0,140.0], [178.0,220.0], - ]).array + ]).transpose().array ); } From e6cd239dcbbc0addb2a785bf29c6a7eb668e9a3c Mon Sep 17 00:00:00 2001 From: Quaternions Date: Thu, 26 Sep 2024 15:26:18 -0700 Subject: [PATCH 213/227] fix zeroes --- fixed_wide/src/zeroes.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fixed_wide/src/zeroes.rs b/fixed_wide/src/zeroes.rs index 621e22e..7f1dbc9 100644 --- a/fixed_wide/src/zeroes.rs +++ b/fixed_wide/src/zeroes.rs @@ -10,7 +10,7 @@ macro_rules! impl_zeroes{ let a2pos=match a2.cmp(&Self::ZERO){ Ordering::Greater=>true, Ordering::Equal=>return ArrayVec::from_iter(Self::zeroes1(a0,a1).into_iter()), - Ordering::Less=>true, + Ordering::Less=>false, }; let radicand=a1*a1-a2*a0*4; match radicand.cmp(&::Output::ZERO){ From 94e23b7f0f1198456f5ec69d0b3aa052e48e6fd0 Mon Sep 17 00:00:00 2001 From: Quaternions Date: Thu, 26 Sep 2024 18:08:20 -0700 Subject: [PATCH 214/227] idk what I'm doing --- fixed_wide/src/fixed.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/fixed_wide/src/fixed.rs b/fixed_wide/src/fixed.rs index a8bf944..14c8245 100644 --- a/fixed_wide/src/fixed.rs +++ b/fixed_wide/src/fixed.rs @@ -525,9 +525,9 @@ macro_rules! impl_wide_same_size_not_const_generic{ if self.is_negative()==rhs.is_negative(){ Fixed::from_bits(out) }else{ - // Wrapping is the cheapest negation operation + // Normal neg is the cheapest negation operation // And the inputs cannot reach the point where it matters - Fixed::from_bits(out.wrapping_neg()) + Fixed::from_bits(out.neg()) } } /// This operation cannot represent the fraction exactly, From 438d0ec6ec4ae97d13d950ea317ce324dd205e10 Mon Sep 17 00:00:00 2001 From: Quaternions Date: Thu, 26 Sep 2024 18:08:33 -0700 Subject: [PATCH 215/227] test zeroes --- fixed_wide/src/tests.rs | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/fixed_wide/src/tests.rs b/fixed_wide/src/tests.rs index 8e4dd4e..22002a2 100644 --- a/fixed_wide/src/tests.rs +++ b/fixed_wide/src/tests.rs @@ -139,3 +139,27 @@ fn test_sqrt_max(){ let a=I32F32::MAX; test_exact(a); } +#[test] +#[cfg(all(feature="zeroes",not(feature="deferred-division")))] +fn test_zeroes_normal(){ + // (x-1)*(x+1) + // x^2-1 + let zeroes=I32F32::zeroes2(I32F32::NEG_ONE,I32F32::ZERO,I32F32::ONE); + assert_eq!(zeroes,arrayvec::ArrayVec::from_iter([I32F32::NEG_ONE,I32F32::ONE])); + let zeroes=I32F32::zeroes2(I32F32::NEG_ONE*3,I32F32::ONE*2,I32F32::ONE); + assert_eq!(zeroes,arrayvec::ArrayVec::from_iter([I32F32::NEG_ONE*3,I32F32::ONE])); +} +#[test] +#[cfg(all(feature="zeroes",feature="deferred-division"))] +fn test_zeroes_deferred_division(){ + // (x-1)*(x+1) + // x^2-1 + let zeroes=I32F32::zeroes2(I32F32::NEG_ONE,I32F32::ZERO,I32F32::ONE); + assert_eq!( + zeroes, + arrayvec::ArrayVec::from_iter([ + ratio_ops::ratio::Ratio::new(I32F32::ONE*2,I32F32::NEG_ONE*2), + ratio_ops::ratio::Ratio::new(I32F32::ONE*2,I32F32::ONE*2), + ]) + ); +} From 9a7ebb0f0a1b38bc42448a31e2197dd432423f8d Mon Sep 17 00:00:00 2001 From: Quaternions Date: Mon, 30 Sep 2024 10:18:25 -0700 Subject: [PATCH 216/227] licensing and registration --- fixed_wide/Cargo.toml | 4 + LICENSE-APACHE => fixed_wide/LICENSE-APACHE | 0 LICENSE-MIT => fixed_wide/LICENSE-MIT | 0 linear_ops/Cargo.toml | 4 + linear_ops/LICENSE-APACHE | 176 ++++++++++++++++++++ linear_ops/LICENSE-MIT | 23 +++ ratio_ops/Cargo.toml | 4 + ratio_ops/LICENSE-APACHE | 176 ++++++++++++++++++++ ratio_ops/LICENSE-MIT | 23 +++ 9 files changed, 410 insertions(+) rename LICENSE-APACHE => fixed_wide/LICENSE-APACHE (100%) rename LICENSE-MIT => fixed_wide/LICENSE-MIT (100%) create mode 100644 linear_ops/LICENSE-APACHE create mode 100644 linear_ops/LICENSE-MIT create mode 100644 ratio_ops/LICENSE-APACHE create mode 100644 ratio_ops/LICENSE-MIT diff --git a/fixed_wide/Cargo.toml b/fixed_wide/Cargo.toml index 45504f9..5dcf9b6 100644 --- a/fixed_wide/Cargo.toml +++ b/fixed_wide/Cargo.toml @@ -2,6 +2,10 @@ name = "fixed_wide" version = "0.1.0" edition = "2021" +repository = "https://git.itzana.me/StrafesNET/fixed_wide_vectors" +license = "MIT OR Apache-2.0" +description = "Fixed point numbers with optional widening Mul operator." +authors = ["Rhys Lloyd "] [features] default=[] diff --git a/LICENSE-APACHE b/fixed_wide/LICENSE-APACHE similarity index 100% rename from LICENSE-APACHE rename to fixed_wide/LICENSE-APACHE diff --git a/LICENSE-MIT b/fixed_wide/LICENSE-MIT similarity index 100% rename from LICENSE-MIT rename to fixed_wide/LICENSE-MIT diff --git a/linear_ops/Cargo.toml b/linear_ops/Cargo.toml index c1bc3ef..1284814 100644 --- a/linear_ops/Cargo.toml +++ b/linear_ops/Cargo.toml @@ -2,6 +2,10 @@ name = "linear_ops" version = "0.1.0" edition = "2021" +repository = "https://git.itzana.me/StrafesNET/fixed_wide_vectors" +license = "MIT OR Apache-2.0" +description = "Vector/Matrix operations using trait bounds." +authors = ["Rhys Lloyd "] [features] default=["named-fields","fixed-wide"] diff --git a/linear_ops/LICENSE-APACHE b/linear_ops/LICENSE-APACHE new file mode 100644 index 0000000..a7e77cb --- /dev/null +++ b/linear_ops/LICENSE-APACHE @@ -0,0 +1,176 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + +TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + +1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + +2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + +3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + +4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + +5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + +6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + +7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + +8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + +9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + +END OF TERMS AND CONDITIONS \ No newline at end of file diff --git a/linear_ops/LICENSE-MIT b/linear_ops/LICENSE-MIT new file mode 100644 index 0000000..468cd79 --- /dev/null +++ b/linear_ops/LICENSE-MIT @@ -0,0 +1,23 @@ +Permission is hereby granted, free of charge, to any +person obtaining a copy of this software and associated +documentation files (the "Software"), to deal in the +Software without restriction, including without +limitation the rights to use, copy, modify, merge, +publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software +is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice +shall be included in all copies or substantial portions +of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF +ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED +TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT +SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR +IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. \ No newline at end of file diff --git a/ratio_ops/Cargo.toml b/ratio_ops/Cargo.toml index d7e0e92..dc0a750 100644 --- a/ratio_ops/Cargo.toml +++ b/ratio_ops/Cargo.toml @@ -2,5 +2,9 @@ name = "ratio_ops" version = "0.1.0" edition = "2021" +repository = "https://git.itzana.me/StrafesNET/fixed_wide_vectors" +license = "MIT OR Apache-2.0" +description = "Ratio operations using trait bounds for avoiding division like the plague." +authors = ["Rhys Lloyd "] [dependencies] diff --git a/ratio_ops/LICENSE-APACHE b/ratio_ops/LICENSE-APACHE new file mode 100644 index 0000000..a7e77cb --- /dev/null +++ b/ratio_ops/LICENSE-APACHE @@ -0,0 +1,176 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + +TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + +1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + +2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + +3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + +4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + +5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + +6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + +7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + +8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + +9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + +END OF TERMS AND CONDITIONS \ No newline at end of file diff --git a/ratio_ops/LICENSE-MIT b/ratio_ops/LICENSE-MIT new file mode 100644 index 0000000..468cd79 --- /dev/null +++ b/ratio_ops/LICENSE-MIT @@ -0,0 +1,23 @@ +Permission is hereby granted, free of charge, to any +person obtaining a copy of this software and associated +documentation files (the "Software"), to deal in the +Software without restriction, including without +limitation the rights to use, copy, modify, merge, +publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software +is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice +shall be included in all copies or substantial portions +of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF +ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED +TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT +SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR +IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. \ No newline at end of file From c6b4cc29b8ae406ded6f5ddfc3ebc22f4e0a4e64 Mon Sep 17 00:00:00 2001 From: Quaternions Date: Mon, 30 Sep 2024 10:20:02 -0700 Subject: [PATCH 217/227] all dependencies must have a version specified --- fixed_wide/Cargo.toml | 2 +- linear_ops/Cargo.toml | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/fixed_wide/Cargo.toml b/fixed_wide/Cargo.toml index 5dcf9b6..035e42f 100644 --- a/fixed_wide/Cargo.toml +++ b/fixed_wide/Cargo.toml @@ -17,4 +17,4 @@ zeroes=["dep:arrayvec"] bnum = "0.12.0" arrayvec = { version = "0.7.6", optional = true } paste = "1.0.15" -ratio_ops = { path = "../ratio_ops", optional = true } +ratio_ops = { version = "0.1.0", path = "../ratio_ops", registry = "strafesnet", optional = true } diff --git a/linear_ops/Cargo.toml b/linear_ops/Cargo.toml index 1284814..e229c97 100644 --- a/linear_ops/Cargo.toml +++ b/linear_ops/Cargo.toml @@ -14,9 +14,9 @@ fixed-wide=["dep:fixed_wide","dep:paste"] deferred-division=["dep:ratio_ops"] [dependencies] -ratio_ops = { path = "../ratio_ops", optional = true } -fixed_wide = { path = "../fixed_wide", optional = true } +ratio_ops = { version = "0.1.0", path = "../ratio_ops", registry = "strafesnet", optional = true } +fixed_wide = { version = "0.1.0", path = "../fixed_wide", registry = "strafesnet", optional = true } paste = { version = "1.0.15", optional = true } [dev-dependencies] -fixed_wide = { path = "../fixed_wide", features = ["wide-mul"] } +fixed_wide = { version = "0.1.0", path = "../fixed_wide", registry = "strafesnet", features = ["wide-mul"] } From 46bb2bac4ec89946ea185eb7bc6c2f8166636535 Mon Sep 17 00:00:00 2001 From: Quaternions Date: Mon, 30 Sep 2024 17:08:12 -0700 Subject: [PATCH 218/227] deconstruct array instead of indexing --- fixed_wide/src/fixed.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/fixed_wide/src/fixed.rs b/fixed_wide/src/fixed.rs index 14c8245..852ccff 100644 --- a/fixed_wide/src/fixed.rs +++ b/fixed_wide/src/fixed.rs @@ -65,7 +65,8 @@ impl Fixed<1,F>{ } #[inline] pub const fn to_raw(self)->i64{ - self.to_bits().to_bits().digits()[0] as i64 + let &[digit]=self.to_bits().to_bits().digits(); + digit as i64 } } From c4a2778af1b13921aa47d96600e2a7c8c9eb8ac5 Mon Sep 17 00:00:00 2001 From: Quaternions Date: Mon, 30 Sep 2024 17:08:46 -0700 Subject: [PATCH 219/227] explicitly implement From for specific types --- fixed_wide/src/fixed.rs | 23 +++++++++++++++-------- 1 file changed, 15 insertions(+), 8 deletions(-) diff --git a/fixed_wide/src/fixed.rs b/fixed_wide/src/fixed.rs index 852ccff..985d530 100644 --- a/fixed_wide/src/fixed.rs +++ b/fixed_wide/src/fixed.rs @@ -70,15 +70,22 @@ impl Fixed<1,F>{ } } -impl From for Fixed - where - BInt:From -{ - #[inline] - fn from(value:T)->Self{ - Self::from_bits(BInt::<{N}>::from(value)<{ + $( + impl From<$from> for Fixed{ + #[inline] + fn from(value:$from)->Self{ + Self::from_bits(BInt::<{N}>::from(value)< PartialEq for Fixed{ #[inline] From a65eef36098638cdad87977d6f8c41be3af58022 Mon Sep 17 00:00:00 2001 From: Quaternions Date: Tue, 1 Oct 2024 14:59:33 -0700 Subject: [PATCH 220/227] fix to float --- fixed_wide/src/fixed.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fixed_wide/src/fixed.rs b/fixed_wide/src/fixed.rs index 985d530..ac972bb 100644 --- a/fixed_wide/src/fixed.rs +++ b/fixed_wide/src/fixed.rs @@ -173,7 +173,7 @@ macro_rules! impl_into_float { msb_offset<<($mantissa_bits-1) }; let digits=unsigned.digits(); - let digit_index=most_significant_bit>>DIGIT_SHIFT; + let digit_index=most_significant_bit.saturating_sub(1)>>DIGIT_SHIFT; let digit=digits[digit_index as usize]; //How many bits does the mantissa take from this digit let take_bits=most_significant_bit-(digit_index< Date: Tue, 1 Oct 2024 15:00:06 -0700 Subject: [PATCH 221/227] change to float tests --- fixed_wide/src/tests.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/fixed_wide/src/tests.rs b/fixed_wide/src/tests.rs index 22002a2..34afcc8 100644 --- a/fixed_wide/src/tests.rs +++ b/fixed_wide/src/tests.rs @@ -17,9 +17,9 @@ fn to_f32(){ let a=I256F256::from(0); let f:f32=(-a).into(); assert_eq!(f,0f32); - let a=I256F256::from(237946589723468975i64)<<32; + let a=I256F256::from(237946589723468975i64)<<16; let f:f32=a.into(); - assert_eq!(f,237946589723468975f32*2.0f32.powi(32)); + assert_eq!(f,237946589723468975f32*2.0f32.powi(16)); } #[test] @@ -32,9 +32,9 @@ fn to_f64(){ let a=I256F256::from(0); let f:f64=(-a).into(); assert_eq!(f,0f64); - let a=I256F256::from(237946589723468975i64)<<32; + let a=I256F256::from(237946589723468975i64)<<16; let f:f64=a.into(); - assert_eq!(f,237946589723468975f64*2.0f64.powi(32)); + assert_eq!(f,237946589723468975f64*2.0f64.powi(16)); } #[test] From 0d05540a6baf3c3081e69ffe9f7ea3a553338409 Mon Sep 17 00:00:00 2001 From: Quaternions Date: Tue, 1 Oct 2024 15:00:30 -0700 Subject: [PATCH 222/227] from float + tests --- fixed_wide/src/fixed.rs | 91 +++++++++++++++++++++++++++++++++++++++++ fixed_wide/src/tests.rs | 53 ++++++++++++++++++++++++ 2 files changed, 144 insertions(+) diff --git a/fixed_wide/src/fixed.rs b/fixed_wide/src/fixed.rs index ac972bb..d970585 100644 --- a/fixed_wide/src/fixed.rs +++ b/fixed_wide/src/fixed.rs @@ -197,6 +197,97 @@ macro_rules! impl_into_float { impl_into_float!(f32,u32,8,24); impl_into_float!(f64,u64,11,53); +#[inline] +fn integer_decode_f32(f: f32) -> (u64, i16, bool) { + let bits: u32 = f.to_bits(); + let sign: bool = bits & (1<<31) != 0; + let mut exponent: i16 = ((bits >> 23) & 0xff) as i16; + let mantissa = if exponent == 0 { + (bits & 0x7fffff) << 1 + } else { + (bits & 0x7fffff) | 0x800000 + }; + // Exponent bias + mantissa shift + exponent -= 127 + 23; + (mantissa as u64, exponent, sign) +} +#[inline] +fn integer_decode_f64(f: f64) -> (u64, i16, bool) { + let bits: u64 = f.to_bits(); + let sign: bool = bits & (1u64<<63) != 0; + let mut exponent: i16 = ((bits >> 52) & 0x7ff) as i16; + let mantissa = if exponent == 0 { + (bits & 0xfffffffffffff) << 1 + } else { + (bits & 0xfffffffffffff) | 0x10000000000000 + }; + // Exponent bias + mantissa shift + exponent -= 1023 + 52; + (mantissa, exponent, sign) +} +#[derive(Debug,Eq,PartialEq)] +pub enum FixedFromFloatError{ + Nan, + Infinite, + Overflow, + Underflow, +} +impl FixedFromFloatError{ + pub fn underflow_to_zero(self)->Result,Self>{ + match self{ + FixedFromFloatError::Underflow=>Ok(Fixed::ZERO), + _=>Err(self), + } + } +} +macro_rules! impl_from_float { + ( $decode:ident, $input: ty, $mantissa_bits:expr ) => { + impl TryFrom<$input> for Fixed{ + type Error=FixedFromFloatError; + #[inline] + fn try_from(value:$input)->Result{ + const DIGIT_SHIFT:u32=6; + match value.classify(){ + std::num::FpCategory::Nan=>Err(FixedFromFloatError::Nan), + std::num::FpCategory::Infinite=>Err(FixedFromFloatError::Infinite), + std::num::FpCategory::Zero=>Ok(Self::ZERO), + std::num::FpCategory::Subnormal + |std::num::FpCategory::Normal + =>{ + let (m,e,s)=$decode(value); + let mut digits=[0u64;N]; + let most_significant_bit=e as i32+$mantissa_bits as i32+F as i32; + if most_significant_bit<0{ + return Err(FixedFromFloatError::Underflow); + } + let digit_index=most_significant_bit>>DIGIT_SHIFT; + let digit=digits.get_mut(digit_index as usize).ok_or(FixedFromFloatError::Overflow)?; + let take_bits=most_significant_bit-(digit_index< core::fmt::Display for Fixed{ #[inline] fn fmt(&self,f:&mut core::fmt::Formatter)->Result<(),core::fmt::Error>{ diff --git a/fixed_wide/src/tests.rs b/fixed_wide/src/tests.rs index 34afcc8..c171c6b 100644 --- a/fixed_wide/src/tests.rs +++ b/fixed_wide/src/tests.rs @@ -37,6 +37,59 @@ fn to_f64(){ assert_eq!(f,237946589723468975f64*2.0f64.powi(16)); } +#[test] +fn from_f32(){ + let a=I256F256::from(1)>>2; + let b:Result=0.25f32.try_into(); + assert_eq!(b,Ok(a)); + let a=I256F256::from(-1)>>2; + let b:Result=(-0.25f32).try_into(); + assert_eq!(b,Ok(a)); + let a=I256F256::from(0); + let b:Result=0.try_into(); + assert_eq!(b,Ok(a)); + let a=I256F256::from(0b101011110101001010101010000000000000000000000000000i64)<<16; + let b:Result=(0b101011110101001010101010000000000000000000000000000u64 as f32*2.0f32.powi(16)).try_into(); + assert_eq!(b,Ok(a)); + //I32F32::MAX into f32 is truncated into this value + let a=I32F32::raw(0b111111111111111111111111000000000000000000000000000000000000000i64); + let b:Result=Into::::into(I32F32::MAX).try_into(); + assert_eq!(b,Ok(a)); + //I32F32::MIN hits a special case since it's not representable as a positive signed integer + //TODO: don't return an overflow because this is technically possible + let a=I32F32::MIN; + let b:Result=Into::::into(I32F32::MIN).try_into(); + assert_eq!(b,Err(crate::fixed::FixedFromFloatError::Overflow)); + //16 is within the 24 bits of float precision + let b:Result=Into::::into(-I32F32::MIN.fix_2()).try_into(); + assert_eq!(b,Err(crate::fixed::FixedFromFloatError::Overflow)); + let b:Result=f32::MIN_POSITIVE.try_into(); + assert_eq!(b,Err(crate::fixed::FixedFromFloatError::Underflow)); + //test many cases + for i in 0..64{ + let a=crate::fixed::Fixed::<2,64>::raw_digit(0b111111111111111111111111000000000000000000000000000000000000000i64)<,_>=f.try_into(); + assert_eq!(b,Ok(a)); + } +} + +#[test] +fn from_f64(){ + let a=I256F256::from(1)>>2; + let b:Result=0.25f64.try_into(); + assert_eq!(b,Ok(a)); + let a=I256F256::from(-1)>>2; + let b:Result=(-0.25f64).try_into(); + assert_eq!(b,Ok(a)); + let a=I256F256::from(0); + let b:Result=0.try_into(); + assert_eq!(b,Ok(a)); + let a=I256F256::from(0b101011110101001010101010000000000000000000000000000i64)<<16; + let b:Result=(0b101011110101001010101010000000000000000000000000000u64 as f64*2.0f64.powi(16)).try_into(); + assert_eq!(b,Ok(a)); +} + #[test] fn you_can_shr_numbers(){ let a=I32F32::from(4); From 64e44846aaee937c0fbf545324e181df5b1c279c Mon Sep 17 00:00:00 2001 From: Quaternions Date: Tue, 1 Oct 2024 15:02:15 -0700 Subject: [PATCH 223/227] v0.1.1 from float --- fixed_wide/Cargo.lock | 2 +- fixed_wide/Cargo.toml | 2 +- linear_ops/Cargo.lock | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/fixed_wide/Cargo.lock b/fixed_wide/Cargo.lock index 7a78ffb..695e4f8 100644 --- a/fixed_wide/Cargo.lock +++ b/fixed_wide/Cargo.lock @@ -16,7 +16,7 @@ checksum = "50202def95bf36cb7d1d7a7962cea1c36a3f8ad42425e5d2b71d7acb8041b5b8" [[package]] name = "fixed_wide" -version = "0.1.0" +version = "0.1.1" dependencies = [ "arrayvec", "bnum", diff --git a/fixed_wide/Cargo.toml b/fixed_wide/Cargo.toml index 035e42f..619d592 100644 --- a/fixed_wide/Cargo.toml +++ b/fixed_wide/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "fixed_wide" -version = "0.1.0" +version = "0.1.1" edition = "2021" repository = "https://git.itzana.me/StrafesNET/fixed_wide_vectors" license = "MIT OR Apache-2.0" diff --git a/linear_ops/Cargo.lock b/linear_ops/Cargo.lock index e83034a..649a61c 100644 --- a/linear_ops/Cargo.lock +++ b/linear_ops/Cargo.lock @@ -10,7 +10,7 @@ checksum = "50202def95bf36cb7d1d7a7962cea1c36a3f8ad42425e5d2b71d7acb8041b5b8" [[package]] name = "fixed_wide" -version = "0.1.0" +version = "0.1.1" dependencies = [ "bnum", "paste", From 218a7fbf0f0f2d77615f8b88d519e9811cd347d9 Mon Sep 17 00:00:00 2001 From: Quaternions Date: Thu, 3 Oct 2024 12:25:39 -0700 Subject: [PATCH 224/227] more general PartialEq + PartialOrd --- ratio_ops/src/ratio.rs | 30 ++++++++++++++++++------------ 1 file changed, 18 insertions(+), 12 deletions(-) diff --git a/ratio_ops/src/ratio.rs b/ratio_ops/src/ratio.rs index b41dc74..a525b71 100644 --- a/ratio_ops/src/ratio.rs +++ b/ratio_ops/src/ratio.rs @@ -251,15 +251,18 @@ impl_ratio_assign_operator!(RemAssign,rem_assign); // Only implement PartialEq // Rust's operators aren't actually that good -impl PartialEq for Ratio +impl PartialEq> for Ratio where - Num:Copy, - Den:Copy, - Num:core::ops::Mul, - T:PartialEq, + LhsNum:Copy, + LhsDen:Copy, + RhsNum:Copy, + RhsDen:Copy, + LhsNum:core::ops::Mul, + RhsNum:core::ops::Mul, + T:PartialEq, { #[inline] - fn eq(&self,&other:&Self)->bool{ + fn eq(&self,other:&Ratio)->bool{ (self.num*other.den).eq(&(other.num*self.den)) } } @@ -268,15 +271,18 @@ impl Eq for Ratio Ratio:PartialEq, {} -impl PartialOrd for Ratio +impl PartialOrd> for Ratio where - Num:Copy, - Den:Copy, - Num:core::ops::Mul, - T:PartialOrd, + LhsNum:Copy, + LhsDen:Copy, + RhsNum:Copy, + RhsDen:Copy, + LhsNum:core::ops::Mul, + RhsNum:core::ops::Mul, + T:PartialOrd, { #[inline] - fn partial_cmp(&self,&other:&Self)->Option{ + fn partial_cmp(&self,other:&Ratio)->Option{ (self.num*other.den).partial_cmp(&(other.num*self.den)) } } From a274b6d232bbfb9953ab7e387951638206925b6a Mon Sep 17 00:00:00 2001 From: Quaternions Date: Thu, 3 Oct 2024 12:31:41 -0700 Subject: [PATCH 225/227] not that important --- ratio_ops/src/ratio.rs | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/ratio_ops/src/ratio.rs b/ratio_ops/src/ratio.rs index a525b71..00ad27c 100644 --- a/ratio_ops/src/ratio.rs +++ b/ratio_ops/src/ratio.rs @@ -266,10 +266,7 @@ impl PartialEq> for Ratio< (self.num*other.den).eq(&(other.num*self.den)) } } -impl Eq for Ratio - where - Ratio:PartialEq, -{} +impl Eq for Ratio where Self:PartialEq{} impl PartialOrd> for Ratio where From c5fb915a6d9e149d79f801423d800415aeef6e36 Mon Sep 17 00:00:00 2001 From: Quaternions Date: Sat, 12 Oct 2024 10:01:06 -0700 Subject: [PATCH 226/227] div_euclid --- fixed_wide/src/fixed.rs | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/fixed_wide/src/fixed.rs b/fixed_wide/src/fixed.rs index d970585..58aae16 100644 --- a/fixed_wide/src/fixed.rs +++ b/fixed_wide/src/fixed.rs @@ -412,7 +412,7 @@ macro_rules! impl_multiply_operator_not_const_generic { type Output=Self; #[inline] fn divide(self, other: i64)->Self::Output{ - Self::from_bits(self.bits/BInt::from(other)) + Self::from_bits(self.bits.div_euclid(BInt::from(other))) } } } @@ -422,11 +422,11 @@ macro_rules! impl_divide_operator_not_const_generic { impl $struct<$width,F>{ paste::item!{ #[inline] - pub fn [](self, other: Self) -> Self { + pub fn [](self,other:Self)->Self{ //this only needs to be $width+F as u32/64+1 but MUH CONST GENERICS!!!!! let lhs=self.bits.as_::>().shl(F as u32); let rhs=other.bits.as_::>(); - Self::from_bits(lhs.div(rhs).as_()) + Self::from_bits(lhs.div_euclid(rhs).as_()) } } } @@ -446,28 +446,28 @@ macro_rules! impl_divide_operator_not_const_generic { } macro_rules! impl_multiplicative_operator { - ( $struct: ident, $trait: ident, $method: ident, $output: ty ) => { + ( $struct: ident, $trait: ident, $method: ident, $inner_method: ident, $output: ty ) => { impl core::ops::$trait for $struct where BInt:::From+core::ops::$trait, { type Output = $output; #[inline] - fn $method(self, other: U) -> Self::Output { - Self::from_bits(self.bits.$method(BInt::::from(other))) + fn $method(self,other:U)->Self::Output{ + Self::from_bits(self.bits.$inner_method(BInt::::from(other))) } } }; } macro_rules! impl_multiplicative_assign_operator { - ( $struct: ident, $trait: ident, $method: ident ) => { + ( $struct: ident, $trait: ident, $method: ident, $not_assign_method: ident ) => { impl core::ops::$trait for $struct where BInt:::From+core::ops::$trait, { #[inline] - fn $method(&mut self, other: U) { - self.bits.$method(BInt::::from(other)); + fn $method(&mut self,other:U){ + self.bits=self.bits.$not_assign_method(BInt::::from(other)); } } }; @@ -495,10 +495,10 @@ macro_16!( impl_multiplicative_assign_operator_not_const_generic, (Fixed, MulAss macro_16!( impl_multiply_operator_not_const_generic, (Fixed, Mul, mul, Self) ); macro_16!( impl_multiplicative_assign_operator_not_const_generic, (Fixed, DivAssign, div_assign, div) ); macro_16!( impl_divide_operator_not_const_generic, (Fixed, Div, div, Self) ); -impl_multiplicative_assign_operator!( Fixed, MulAssign, mul_assign ); -impl_multiplicative_operator!( Fixed, Mul, mul, Self ); -impl_multiplicative_assign_operator!( Fixed, DivAssign, div_assign ); -impl_multiplicative_operator!( Fixed, Div, div, Self ); +impl_multiplicative_assign_operator!( Fixed, MulAssign, mul_assign, mul ); +impl_multiplicative_operator!( Fixed, Mul, mul, mul, Self ); +impl_multiplicative_assign_operator!( Fixed, DivAssign, div_assign, div_euclid ); +impl_multiplicative_operator!( Fixed, Div, div, div_euclid, Self ); #[cfg(feature="deferred-division")] impl core::ops::Div> for Fixed{ type Output=ratio_ops::ratio::Ratio,Fixed>; From 19bb5c021e310df56f3fc281cae966c74945a034 Mon Sep 17 00:00:00 2001 From: Quaternions Date: Thu, 2 Jan 2025 19:53:50 -0800 Subject: [PATCH 227/227] fixed_wide_vectors: move into folder --- README.md => lib/README.md | 0 {fixed_wide => lib/fixed_wide}/.gitignore | 0 {fixed_wide => lib/fixed_wide}/Cargo.lock | 0 {fixed_wide => lib/fixed_wide}/Cargo.toml | 0 {fixed_wide => lib/fixed_wide}/LICENSE-APACHE | 0 {fixed_wide => lib/fixed_wide}/LICENSE-MIT | 0 {fixed_wide => lib/fixed_wide}/src/fixed.rs | 0 {fixed_wide => lib/fixed_wide}/src/lib.rs | 0 {fixed_wide => lib/fixed_wide}/src/tests.rs | 0 {fixed_wide => lib/fixed_wide}/src/types.rs | 0 {fixed_wide => lib/fixed_wide}/src/zeroes.rs | 0 {linear_ops => lib/linear_ops}/.gitignore | 0 {linear_ops => lib/linear_ops}/Cargo.lock | 0 {linear_ops => lib/linear_ops}/Cargo.toml | 0 {linear_ops => lib/linear_ops}/LICENSE-APACHE | 0 {linear_ops => lib/linear_ops}/LICENSE-MIT | 0 {linear_ops => lib/linear_ops}/src/lib.rs | 0 {linear_ops => lib/linear_ops}/src/macros/common.rs | 0 {linear_ops => lib/linear_ops}/src/macros/fixed_wide.rs | 0 {linear_ops => lib/linear_ops}/src/macros/matrix.rs | 0 {linear_ops => lib/linear_ops}/src/macros/mod.rs | 0 {linear_ops => lib/linear_ops}/src/macros/vector.rs | 0 {linear_ops => lib/linear_ops}/src/matrix.rs | 0 {linear_ops => lib/linear_ops}/src/named.rs | 0 {linear_ops => lib/linear_ops}/src/tests/fixed_wide.rs | 0 {linear_ops => lib/linear_ops}/src/tests/mod.rs | 0 {linear_ops => lib/linear_ops}/src/tests/named.rs | 0 {linear_ops => lib/linear_ops}/src/tests/tests.rs | 0 {linear_ops => lib/linear_ops}/src/types.rs | 0 {linear_ops => lib/linear_ops}/src/vector.rs | 0 {ratio_ops => lib/ratio_ops}/.gitignore | 0 {ratio_ops => lib/ratio_ops}/Cargo.lock | 0 {ratio_ops => lib/ratio_ops}/Cargo.toml | 0 {ratio_ops => lib/ratio_ops}/LICENSE-APACHE | 0 {ratio_ops => lib/ratio_ops}/LICENSE-MIT | 0 {ratio_ops => lib/ratio_ops}/src/lib.rs | 0 {ratio_ops => lib/ratio_ops}/src/ratio.rs | 0 {ratio_ops => lib/ratio_ops}/src/tests.rs | 0 38 files changed, 0 insertions(+), 0 deletions(-) rename README.md => lib/README.md (100%) rename {fixed_wide => lib/fixed_wide}/.gitignore (100%) rename {fixed_wide => lib/fixed_wide}/Cargo.lock (100%) rename {fixed_wide => lib/fixed_wide}/Cargo.toml (100%) rename {fixed_wide => lib/fixed_wide}/LICENSE-APACHE (100%) rename {fixed_wide => lib/fixed_wide}/LICENSE-MIT (100%) rename {fixed_wide => lib/fixed_wide}/src/fixed.rs (100%) rename {fixed_wide => lib/fixed_wide}/src/lib.rs (100%) rename {fixed_wide => lib/fixed_wide}/src/tests.rs (100%) rename {fixed_wide => lib/fixed_wide}/src/types.rs (100%) rename {fixed_wide => lib/fixed_wide}/src/zeroes.rs (100%) rename {linear_ops => lib/linear_ops}/.gitignore (100%) rename {linear_ops => lib/linear_ops}/Cargo.lock (100%) rename {linear_ops => lib/linear_ops}/Cargo.toml (100%) rename {linear_ops => lib/linear_ops}/LICENSE-APACHE (100%) rename {linear_ops => lib/linear_ops}/LICENSE-MIT (100%) rename {linear_ops => lib/linear_ops}/src/lib.rs (100%) rename {linear_ops => lib/linear_ops}/src/macros/common.rs (100%) rename {linear_ops => lib/linear_ops}/src/macros/fixed_wide.rs (100%) rename {linear_ops => lib/linear_ops}/src/macros/matrix.rs (100%) rename {linear_ops => lib/linear_ops}/src/macros/mod.rs (100%) rename {linear_ops => lib/linear_ops}/src/macros/vector.rs (100%) rename {linear_ops => lib/linear_ops}/src/matrix.rs (100%) rename {linear_ops => lib/linear_ops}/src/named.rs (100%) rename {linear_ops => lib/linear_ops}/src/tests/fixed_wide.rs (100%) rename {linear_ops => lib/linear_ops}/src/tests/mod.rs (100%) rename {linear_ops => lib/linear_ops}/src/tests/named.rs (100%) rename {linear_ops => lib/linear_ops}/src/tests/tests.rs (100%) rename {linear_ops => lib/linear_ops}/src/types.rs (100%) rename {linear_ops => lib/linear_ops}/src/vector.rs (100%) rename {ratio_ops => lib/ratio_ops}/.gitignore (100%) rename {ratio_ops => lib/ratio_ops}/Cargo.lock (100%) rename {ratio_ops => lib/ratio_ops}/Cargo.toml (100%) rename {ratio_ops => lib/ratio_ops}/LICENSE-APACHE (100%) rename {ratio_ops => lib/ratio_ops}/LICENSE-MIT (100%) rename {ratio_ops => lib/ratio_ops}/src/lib.rs (100%) rename {ratio_ops => lib/ratio_ops}/src/ratio.rs (100%) rename {ratio_ops => lib/ratio_ops}/src/tests.rs (100%) diff --git a/README.md b/lib/README.md similarity index 100% rename from README.md rename to lib/README.md diff --git a/fixed_wide/.gitignore b/lib/fixed_wide/.gitignore similarity index 100% rename from fixed_wide/.gitignore rename to lib/fixed_wide/.gitignore diff --git a/fixed_wide/Cargo.lock b/lib/fixed_wide/Cargo.lock similarity index 100% rename from fixed_wide/Cargo.lock rename to lib/fixed_wide/Cargo.lock diff --git a/fixed_wide/Cargo.toml b/lib/fixed_wide/Cargo.toml similarity index 100% rename from fixed_wide/Cargo.toml rename to lib/fixed_wide/Cargo.toml diff --git a/fixed_wide/LICENSE-APACHE b/lib/fixed_wide/LICENSE-APACHE similarity index 100% rename from fixed_wide/LICENSE-APACHE rename to lib/fixed_wide/LICENSE-APACHE diff --git a/fixed_wide/LICENSE-MIT b/lib/fixed_wide/LICENSE-MIT similarity index 100% rename from fixed_wide/LICENSE-MIT rename to lib/fixed_wide/LICENSE-MIT diff --git a/fixed_wide/src/fixed.rs b/lib/fixed_wide/src/fixed.rs similarity index 100% rename from fixed_wide/src/fixed.rs rename to lib/fixed_wide/src/fixed.rs diff --git a/fixed_wide/src/lib.rs b/lib/fixed_wide/src/lib.rs similarity index 100% rename from fixed_wide/src/lib.rs rename to lib/fixed_wide/src/lib.rs diff --git a/fixed_wide/src/tests.rs b/lib/fixed_wide/src/tests.rs similarity index 100% rename from fixed_wide/src/tests.rs rename to lib/fixed_wide/src/tests.rs diff --git a/fixed_wide/src/types.rs b/lib/fixed_wide/src/types.rs similarity index 100% rename from fixed_wide/src/types.rs rename to lib/fixed_wide/src/types.rs diff --git a/fixed_wide/src/zeroes.rs b/lib/fixed_wide/src/zeroes.rs similarity index 100% rename from fixed_wide/src/zeroes.rs rename to lib/fixed_wide/src/zeroes.rs diff --git a/linear_ops/.gitignore b/lib/linear_ops/.gitignore similarity index 100% rename from linear_ops/.gitignore rename to lib/linear_ops/.gitignore diff --git a/linear_ops/Cargo.lock b/lib/linear_ops/Cargo.lock similarity index 100% rename from linear_ops/Cargo.lock rename to lib/linear_ops/Cargo.lock diff --git a/linear_ops/Cargo.toml b/lib/linear_ops/Cargo.toml similarity index 100% rename from linear_ops/Cargo.toml rename to lib/linear_ops/Cargo.toml diff --git a/linear_ops/LICENSE-APACHE b/lib/linear_ops/LICENSE-APACHE similarity index 100% rename from linear_ops/LICENSE-APACHE rename to lib/linear_ops/LICENSE-APACHE diff --git a/linear_ops/LICENSE-MIT b/lib/linear_ops/LICENSE-MIT similarity index 100% rename from linear_ops/LICENSE-MIT rename to lib/linear_ops/LICENSE-MIT diff --git a/linear_ops/src/lib.rs b/lib/linear_ops/src/lib.rs similarity index 100% rename from linear_ops/src/lib.rs rename to lib/linear_ops/src/lib.rs diff --git a/linear_ops/src/macros/common.rs b/lib/linear_ops/src/macros/common.rs similarity index 100% rename from linear_ops/src/macros/common.rs rename to lib/linear_ops/src/macros/common.rs diff --git a/linear_ops/src/macros/fixed_wide.rs b/lib/linear_ops/src/macros/fixed_wide.rs similarity index 100% rename from linear_ops/src/macros/fixed_wide.rs rename to lib/linear_ops/src/macros/fixed_wide.rs diff --git a/linear_ops/src/macros/matrix.rs b/lib/linear_ops/src/macros/matrix.rs similarity index 100% rename from linear_ops/src/macros/matrix.rs rename to lib/linear_ops/src/macros/matrix.rs diff --git a/linear_ops/src/macros/mod.rs b/lib/linear_ops/src/macros/mod.rs similarity index 100% rename from linear_ops/src/macros/mod.rs rename to lib/linear_ops/src/macros/mod.rs diff --git a/linear_ops/src/macros/vector.rs b/lib/linear_ops/src/macros/vector.rs similarity index 100% rename from linear_ops/src/macros/vector.rs rename to lib/linear_ops/src/macros/vector.rs diff --git a/linear_ops/src/matrix.rs b/lib/linear_ops/src/matrix.rs similarity index 100% rename from linear_ops/src/matrix.rs rename to lib/linear_ops/src/matrix.rs diff --git a/linear_ops/src/named.rs b/lib/linear_ops/src/named.rs similarity index 100% rename from linear_ops/src/named.rs rename to lib/linear_ops/src/named.rs diff --git a/linear_ops/src/tests/fixed_wide.rs b/lib/linear_ops/src/tests/fixed_wide.rs similarity index 100% rename from linear_ops/src/tests/fixed_wide.rs rename to lib/linear_ops/src/tests/fixed_wide.rs diff --git a/linear_ops/src/tests/mod.rs b/lib/linear_ops/src/tests/mod.rs similarity index 100% rename from linear_ops/src/tests/mod.rs rename to lib/linear_ops/src/tests/mod.rs diff --git a/linear_ops/src/tests/named.rs b/lib/linear_ops/src/tests/named.rs similarity index 100% rename from linear_ops/src/tests/named.rs rename to lib/linear_ops/src/tests/named.rs diff --git a/linear_ops/src/tests/tests.rs b/lib/linear_ops/src/tests/tests.rs similarity index 100% rename from linear_ops/src/tests/tests.rs rename to lib/linear_ops/src/tests/tests.rs diff --git a/linear_ops/src/types.rs b/lib/linear_ops/src/types.rs similarity index 100% rename from linear_ops/src/types.rs rename to lib/linear_ops/src/types.rs diff --git a/linear_ops/src/vector.rs b/lib/linear_ops/src/vector.rs similarity index 100% rename from linear_ops/src/vector.rs rename to lib/linear_ops/src/vector.rs diff --git a/ratio_ops/.gitignore b/lib/ratio_ops/.gitignore similarity index 100% rename from ratio_ops/.gitignore rename to lib/ratio_ops/.gitignore diff --git a/ratio_ops/Cargo.lock b/lib/ratio_ops/Cargo.lock similarity index 100% rename from ratio_ops/Cargo.lock rename to lib/ratio_ops/Cargo.lock diff --git a/ratio_ops/Cargo.toml b/lib/ratio_ops/Cargo.toml similarity index 100% rename from ratio_ops/Cargo.toml rename to lib/ratio_ops/Cargo.toml diff --git a/ratio_ops/LICENSE-APACHE b/lib/ratio_ops/LICENSE-APACHE similarity index 100% rename from ratio_ops/LICENSE-APACHE rename to lib/ratio_ops/LICENSE-APACHE diff --git a/ratio_ops/LICENSE-MIT b/lib/ratio_ops/LICENSE-MIT similarity index 100% rename from ratio_ops/LICENSE-MIT rename to lib/ratio_ops/LICENSE-MIT diff --git a/ratio_ops/src/lib.rs b/lib/ratio_ops/src/lib.rs similarity index 100% rename from ratio_ops/src/lib.rs rename to lib/ratio_ops/src/lib.rs diff --git a/ratio_ops/src/ratio.rs b/lib/ratio_ops/src/ratio.rs similarity index 100% rename from ratio_ops/src/ratio.rs rename to lib/ratio_ops/src/ratio.rs diff --git a/ratio_ops/src/tests.rs b/lib/ratio_ops/src/tests.rs similarity index 100% rename from ratio_ops/src/tests.rs rename to lib/ratio_ops/src/tests.rs