bugfixes in contfrac and polynomial
This commit is contained in:
1 parent
63b9e8c92e
commit
4bc7be4265
4 files changed
+14
-9
No files matched your search
+10
-5
@@ -144,13 +144,14 @@ void ContFrac<T>::canonicalize()
|
||||
{
|
||||
int n=this->length();
|
||||
if(n==0) return;
|
||||
this->copyonwrite();
|
||||
if(n>0 && (*this)[1]<0) //handle negative a_i i>0
|
||||
{
|
||||
for(int i=0; i<=n; ++i) (*this[i]) = -(*this[i]);
|
||||
for(int i=0; i<=n; ++i) (*this)[i] = -(*this)[i];
|
||||
*this = -(*this);
|
||||
n=this->length(); //unary minus changes the length
|
||||
}
|
||||
this->copyonwrite();
|
||||
if((*this)[n]==1) {(*this)[n]=0; ++(*this)[n-1];} //avoid deepest 1/1
|
||||
if(n>0 && (*this)[n]==1) {(*this)[n]=0; ++(*this)[n-1];} //avoid deepest 1/1
|
||||
for(int i=1; i<=n; ++i) //truncate if possible
|
||||
{
|
||||
if((*this)[i]==0) //convention for infinity
|
||||
@@ -393,6 +394,7 @@ if(den<0)
|
||||
den= -den;
|
||||
}
|
||||
T g=gcd(num,den);
|
||||
if(g<0) g= -g; //gcd may be negative for negative num
|
||||
if(g>1)
|
||||
{
|
||||
num/=g;
|
||||
@@ -405,7 +407,8 @@ Rational<T> & Rational<T>::operator*=(const T &rhs)
|
||||
{
|
||||
T r=rhs;
|
||||
T g=gcd(r,den);
|
||||
if(MYABS(g)>1)
|
||||
if(g<0) g= -g; //keep den positive
|
||||
if(g>1)
|
||||
{
|
||||
r/=g;
|
||||
den/=g;
|
||||
@@ -420,12 +423,14 @@ Rational<T> & Rational<T>::operator/=(const T &rhs)
|
||||
{
|
||||
T r=rhs;
|
||||
T g=gcd(r,num);
|
||||
if(MYABS(g)>1)
|
||||
if(g<0) g= -g;
|
||||
if(g>1)
|
||||
{
|
||||
r/=g;
|
||||
num/=g;
|
||||
}
|
||||
den*=r;
|
||||
if(den<0) {num= -num; den= -den;} //keep den positive
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -124,7 +124,7 @@ public:
|
||||
ContFrac(T p, T q); //should yield a canonical form
|
||||
explicit ContFrac(const Rational<T> &r) : ContFrac(r.num,r.den) {};
|
||||
|
||||
void canonicalize();
|
||||
void canonicalize(); //requires a_1..a_n of the same sign (works on the terms, no overflow for fixed-size T)
|
||||
void convergent(T *p, T*q, const int trunc= -1) const;
|
||||
Rational<T> rational(const int trunc= -1) const {T p,q; convergent(&p,&q,trunc); return Rational<T>(p,q);};
|
||||
double value(const int trunc= -1) const; //we could make also a template usable with an arbitrary-precision type
|
||||
|
||||
+2
-2
@@ -177,7 +177,7 @@ Polynomial<T> poly_gcd(const Polynomial<T> &p, const Polynomial<T> &q, const typ
|
||||
Polynomial<T> big,small;
|
||||
if(p.degree() < q.degree()) {big=q; small=p;} else {big=p; small=q;}
|
||||
small.simplify(thr);
|
||||
if(small.degree()==0) return small;
|
||||
if(small.degree()==0) return MYABS(small[0])<=thr ? big : small; //gcd(p,0)=p, gcd(p,const)=const
|
||||
Polynomial<T> help;
|
||||
do {
|
||||
help=small;
|
||||
@@ -185,7 +185,7 @@ do {
|
||||
big=help;
|
||||
small.simplify(thr);
|
||||
}
|
||||
while((d<0 && small.degree() != 0) || (d>=0 && small.degree()>=d));
|
||||
while(!(small.degree()==0 && MYABS(small[0])<=thr) && (d<0 || small.degree()>=d)); //stop at zero remainder or below the expected degree
|
||||
return big;
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -213,7 +213,7 @@ for(int i=d; i>2; i-=2)
|
||||
sum= sum*x2; //not *= for matrices
|
||||
}
|
||||
sum += p[1];
|
||||
sum *= x;
|
||||
sum= sum*x; //not *= for matrices
|
||||
return sum;
|
||||
}
|
||||
|
||||
|
||||
Reference in new issue
Block a user