zeroes: branch instead of heap allocation
This commit is contained in:
parent
9563290454
commit
62e9397c98
@ -1,8 +1,64 @@
|
||||
//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<Self::Item>{
|
||||
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<Planar64>{
|
||||
pub fn zeroes2(a0:Planar64,a1:Planar64,a2:Planar64)->Zeroes{
|
||||
if a2==Planar64::ZERO{
|
||||
return zeroes1(a0,a1);
|
||||
}
|
||||
@ -14,27 +70,27 @@ pub fn zeroes2(a0:Planar64,a1:Planar64,a2:Planar64) -> Vec<Planar64>{
|
||||
//TODO: one or two newtons
|
||||
//sort roots ascending and avoid taking the difference of large numbers
|
||||
match (Planar64::ZERO<a2,Planar64::ZERO<a1){
|
||||
(true, true )=>vec![(-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)];
|
||||
return [a1/(a2*-2)].into();
|
||||
}else{
|
||||
return vec![];
|
||||
return [].into();
|
||||
}
|
||||
}
|
||||
#[inline]
|
||||
pub fn zeroes1(a0:Planar64,a1:Planar64) -> Vec<Planar64> {
|
||||
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();
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user