From 62e9397c984265c2c572a3a9a1df3933c673e50f Mon Sep 17 00:00:00 2001 From: Quaternions Date: Wed, 7 Aug 2024 11:26:25 -0700 Subject: [PATCH] zeroes: branch instead of heap allocation --- src/zeroes.rs | 88 +++++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 72 insertions(+), 16 deletions(-) diff --git a/src/zeroes.rs b/src/zeroes.rs index d302456..8414ab9 100644 --- a/src/zeroes.rs +++ b/src/zeroes.rs @@ -1,40 +1,96 @@ //find roots of polynomials use crate::integer::Planar64; +pub enum Zeroes{ + Two([Planar64;2]), + One([Planar64;1]), + Zero, +} +impl Zeroes{ + pub fn len(&self)->usize{ + match self{ + Zeroes::Two(z)=>z.len(), + Zeroes::One(z)=>z.len(), + Zeroes::Zero=>0, + } + } +} +impl From<[Planar64;0]> for Zeroes{ + fn from(_value:[Planar64;0])->Self{ + Zeroes::Zero + } +} +impl From<[Planar64;1]> for Zeroes{ + fn from(value:[Planar64;1])->Self{ + Zeroes::One(value) + } +} +impl From<[Planar64;2]> for Zeroes{ + fn from(value:[Planar64;2])->Self{ + Zeroes::Two(value) + } +} +pub struct ZeroesIter{ + zeroes:Zeroes, + index:usize, +} +impl Iterator for ZeroesIter{ + type Item=Planar64; + fn next(&mut self)->Option{ + let ret=match self.zeroes{ + Zeroes::Two(z)=>z.get(self.index).copied(), + Zeroes::One(z)=>z.get(self.index).copied(), + Zeroes::Zero=>None, + }; + self.index+=1; + ret + } +} +impl IntoIterator for Zeroes{ + type Item=Planar64; + type IntoIter=ZeroesIter; + fn into_iter(self)->Self::IntoIter{ + ZeroesIter{ + zeroes:self, + index:0, + } + } +} + #[inline] -pub fn zeroes2(a0:Planar64,a1:Planar64,a2:Planar64) -> Vec{ +pub fn zeroes2(a0:Planar64,a1:Planar64,a2:Planar64)->Zeroes{ if a2==Planar64::ZERO{ - return zeroes1(a0, a1); + return zeroes1(a0,a1); } let radicand=a1.get() as i128*a1.get() as i128-a2.get() as i128*a0.get() as i128*4; - if 0vec![(-a1-planar_radicand)/(a2*2),(a0*2)/(-a1-planar_radicand)], - (true, false)=>vec![(a0*2)/(-a1+planar_radicand),(-a1+planar_radicand)/(a2*2)], - (false,true )=>vec![(a0*2)/(-a1-planar_radicand),(-a1-planar_radicand)/(a2*2)], - (false,false)=>vec![(-a1+planar_radicand)/(a2*2),(a0*2)/(-a1+planar_radicand)], + (true, true )=>[(-a1-planar_radicand)/(a2*2),(a0*2)/(-a1-planar_radicand)].into(), + (true, false)=>[(a0*2)/(-a1+planar_radicand),(-a1+planar_radicand)/(a2*2)].into(), + (false,true )=>[(a0*2)/(-a1-planar_radicand),(-a1-planar_radicand)/(a2*2)].into(), + (false,false)=>[(-a1+planar_radicand)/(a2*2),(a0*2)/(-a1+planar_radicand)].into(), } - } else if radicand==0 { - return vec![a1/(a2*-2)]; - } else { - return vec![]; + }else if radicand==0{ + return [a1/(a2*-2)].into(); + }else{ + return [].into(); } } #[inline] -pub fn zeroes1(a0:Planar64,a1:Planar64) -> Vec { +pub fn zeroes1(a0:Planar64,a1:Planar64)->Zeroes{ if a1==Planar64::ZERO{ - return vec![]; + return [].into(); }else{ let q=((-a0.get() as i128)<<32)/(a1.get() as i128); if i64::MIN as i128<=q&&q<=i64::MAX as i128{ - return vec![Planar64::raw(q as i64)]; + return [Planar64::raw(q as i64)].into(); }else{ - return vec![]; + return [].into(); } } -} \ No newline at end of file +}