Code Search for Developers
 
 
  

Aff_polynomial.C from Magnus at Krugle


Show Aff_polynomial.C syntax highlighted


#include "Affine.h"
//#include "OutMessages.h"

void polynomial::set(int coeff, const vector<int> &pow){
	entries.clear();
	polynomial_term a = polynomial_term(degree, pow);
	a.set_powersum();
	if(coeff!=0){
		entries.push_back(monomial(coeff,a));
	}
}

monomial::monomial(int c,polynomial_term t) : term(t){
	coefficient = c;
}

monomial::monomial(int a) : term(a){
}

polynomial::polynomial(int deg){
	degree = deg;
}

void polynomial::reset_head_coeff(){
	list<monomial>::iterator p;
	p = entries.begin();
	if(p!=entries.end()){
		p->coefficient = 1;
	}
}

polynomial::polynomial(int deg, int coeff, const vector<int> &pow){
	degree = deg;
	polynomial_term a = polynomial_term(deg, pow);
	a.set_powersum();
	if(coeff!=0){
		entries.push_back(monomial(coeff,a));
	}
}

polynomial operator+(const polynomial &a, const polynomial &b){
	list<monomial>::const_iterator p = a.entries.begin();
	list<monomial>::const_iterator q = b.entries.begin();
	int sum;
	polynomial c = polynomial(a.degree);
	while(p!=a.entries.end() && q!=b.entries.end()){
		if(p->term < q->term){
			c.entries.push_back(monomial(p->coefficient,p->term));
			p++;
		}else if (q->term < p->term){
			c.entries.push_back(monomial(q->coefficient,q->term));
			q++;
		}else{
			sum = q->coefficient+p->coefficient;
			if(sum!=0){
				c.entries.push_back(monomial(sum,p->term));
			}
			p++;
			q++;
		}	
	}
	while(p!=a.entries.end()){
		c.entries.push_back(monomial(p->coefficient,p->term));
		p++;
	}
	while(q!=b.entries.end()){
		c.entries.push_back(monomial(q->coefficient,q->term));
		q++;
	}
	return c;
}

polynomial& operator-=(polynomial &a,const polynomial &b){
	list<monomial>::iterator p= a.entries.begin();
	list<monomial>::const_iterator q = b.entries.begin();
	int diff;
	while(p!=a.entries.end() && q!=b.entries.end()){
		if(p->term < q->term){
			p++;
		}else if (q->term < p->term){
			a.entries.insert(p,monomial(-1*q->coefficient,q->term));
			q++;
		}else {
			diff = p->coefficient - q->coefficient;
			if(diff==0){
				p = a.entries.erase(p);
			}else {
				p->coefficient = diff;
			}
			q++;
		}
	}
	while(q!=b.entries.end()){
		a.entries.push_back(monomial(-1*q->coefficient,q->term));
		q++;
	}
	return a;
}

polynomial operator-(const polynomial &a,const polynomial &b){
	return a + ((-1)*b);
}

//The following routine should only be called while constructing the matrices.
//It could probably be optimized.
polynomial operator*(const polynomial &a,const polynomial &b){
	polynomial c = polynomial(a.degree);
	list<monomial>::const_iterator p =a.entries.begin();
	list<monomial>::const_iterator q;
	while(p!=a.entries.end()){
		q=b.entries.begin();
		while(q!=b.entries.end()){
			c += monomial(p->coefficient*q->coefficient,p->term*q->term);
			q++;
		}
		p++;
	}
	return c;
}

polynomial& operator+=(polynomial &a, const monomial &b){
	list<monomial>::iterator p =a.entries.begin();
	while(p->term<b.term && p!=a.entries.end()){
		p++;
	}
	if(p == a.entries.end()){
		a.entries.push_back(b);
	}else if(p->term == b.term){
		p->coefficient = p->coefficient + b.coefficient;
	}else{
		a.entries.insert(p,b);
	}
	return a;
}

bool operator!(const polynomial &a){
	if(a.entries.begin() == a.entries.end()){
		return 1;
	}
	return 0;
}

int polynomial::head_coeff() const{
	return entries.front().coefficient;
}

int agcd(int a, int b) {
  if (b == 0)
    return a;

  return agcd(b, a % b);
}

int alcm(int a,int b){
        return (a*b)/agcd(a,b);
}


void polynomial::reduce_coeff(){
	list<monomial>::iterator p = entries.begin();
	int tgcd = p->coefficient;
	p++;
	while(p!=entries.end()){
		if(tgcd==1){return;}
		tgcd = agcd(tgcd,p->coefficient);
		p++;
	}
	for(p=entries.begin();p!=entries.end();p++){
		p->coefficient /= tgcd;
	}
}

void reduce(polynomial &h, const vector<polynomial> &grob){
	while(single_reduce(h, grob));
}

bool full_reduce(polynomial &h,const vector<polynomial> &grob1,const vector<polynomial> &grob2){
	int changed = 0;
	while(single_full_reduce(h, grob1) || single_full_reduce(h,grob2)) {changed = 1;}
	return changed;
}

bool single_full_reduce(polynomial &h, const vector<polynomial> &grob){
	int i,j;
	list<monomial>::iterator p;
	polynomial_term s(h.degree);
	if(!h){
		return 0;
	}
	for(i=0;i<grob.size();i++){
		for(p=h.entries.begin();p!=h.entries.end();p++){
			if(p->term >> grob[i].head_term() ){
				s = (p->term)/grob[i].head_term();
				if(grob[i].head_coeff() != 1){
					h *= alcm(grob[i].head_coeff(),p->coefficient)/p->coefficient;
				}
				h -= monomial(p->coefficient/grob[i].head_coeff(),s)*grob[i];
				return 1;
			}
		}
	}
	return 0;
}		

bool single_reduce(polynomial &h, const vector<polynomial> &grob){
	int i;
	polynomial_term s(h.degree);
	if(!h){
		return 0;
	}
	for(i=0;i<grob.size();i++){
		if(h.head_term() >> grob[i].head_term() ){
			s = h.head_term()/grob[i].head_term();
			if(grob[i].head_coeff() != 1){
				h *= alcm(grob[i].head_coeff(),h.head_coeff())/h.head_coeff();
			}
			h -= monomial(h.head_coeff()/grob[i].head_coeff(),s)*grob[i];
			return 1;
		}
	}
	return 0;
}

polynomial& operator*=(polynomial &a,int b){
	list<monomial>::iterator p;
	for(p=a.entries.begin();p!=a.entries.end();p++){
		p->coefficient *=b;
	}
	return a;
}

monomial operator*(const monomial &a,const monomial &b){
	return monomial(a.coefficient*b.coefficient,a.term*b.term);
}

polynomial operator*(const monomial &a, const polynomial &b){
	list<monomial>::const_iterator p =b.entries.begin();
	polynomial c(b.degree);
	while(p!=b.entries.end()){
		c.entries.push_back(a*monomial(p->coefficient,p->term));
		p++;
	}
	return c;
}

polynomial_term polynomial::head_term() const{
	return entries.front().term;
}

polynomial operator*(int a, const polynomial &b){
	if(a == 0){return 0;}
	polynomial c(b.degree);
	list<monomial>::const_iterator p= b.entries.begin();
	while(p!=b.entries.end()){
		c.entries.push_back(monomial(a * p->coefficient,p->term));
		p++;
	}
	return c;
}

polynomial::polynomial(const polynomial &a){
	degree = a.degree;
	entries = a.entries;
}

ostream& operator << (ostream& ostr, const polynomial &a){
	int i;
	list<monomial>::const_iterator p = a.entries.begin();
	while(p != a.entries.end()){
		ostr << "\t" << p->coefficient;
		ostr << p->term;
		p++;
	}
	return ostr;
}


bool operator<(const polynomial &a, const polynomial &b){
	list<monomial>::const_iterator p =a.entries.begin();
	list<monomial>::const_iterator q =b.entries.begin();
	while(p!=a.entries.end()){
		if(p->term<q->term || (p->term==q->term && p->coefficient < q->coefficient)){
			return 1;
		}
		if(q->term<p->term || (p->term==q->term && q->coefficient < p->coefficient) ||
			q==b.entries.end()){
			return 0;
		}
	}
	if(q!=b.entries.end()){
		return 0;
	}
	return 1;
}

polynomial operator-(const polynomial &a,int b){
	polynomial c = a;
	polynomial_term d(a.degree);
	c += monomial(-b,d);
	return c;
}




See more files for this project here

Magnus

Magnus is a special purpose mathematical package for Infinite Group Theory computations

Project homepage: http://sourceforge.net/projects/magnus
Programming language(s): C,C++
License: other

  AbelianEquations.C
  AbelianGroup.C
  AbelianGroupRep.C
  AbelianInfinitenessProblem.C
  AbelianSGPresentation.C
  Aff_poly_matrix.C
  Aff_poly_pair.C
  Aff_poly_term.C
  Aff_polynomial.C
  Affine.C
  EqSystemParser.C
  EquationParser.C
  FGGroup.C
  FGGroupRep.C
  FPGroup.C
  FPGroupRep.C
  FreeByCyclic.C
  FreeGroup.C
  FreeGroupRep.C
  GeneralWhitehead.C
  Group.C
  GroupFastChecks.C
  GroupRep.C
  Homology.C
  MSCGConjugacyProblem.C
  MSCGroup.C
  ORWordProblem.C
  PowerSeriesWP.C
  PresentationParser.C
  PrimeNumbers.C
  Products.C
  RandomAutomorphism.C
  RandomMSCGroup.C
  RandomPrimitiveElement.C
  RipsConstruction.C
  ShortenByRelators.C
  SmithNormalForm.C
  SmithNormalForm1.C
  SymmetricRelators.C
  TTP.C
  TietzeTrekker.C
  WordEnumerator.C