📄 poly2.cpp
字号:
v3 = v;
zero = 0;
while(v3 != zero) {
q = u3/v3;
t1 = u1 - v1*q;
t2 = u2 - v2*q;
t3 = u3 - v3*q;
u1 = v1;
u2 = v2;
u3 = v3;
v1 = t1;
v2 = t2;
v3 = t3;
}
ptr=u3.start;
t=(GF2m)1/ptr->an;
u3.multerm(t,0);
u1.multerm(t,0);
u2.multerm(t,0);
result[0] = u3;
result[1] = u1;
result[2] = u2;
}
Poly2 pow(const Poly2& f,int k)
{
Poly2 u;
int w,e,b;
if (k==0)
{
u.addterm((GF2m)1,0);
return u;
}
u=f;
if (k==1) return u;
e=k;
b=0; while (k>1) {k>>=1; b++; }
w=(1<<b);
e-=w; w/=2;
while (w>0)
{
u=(u*u);
if (e>=w)
{
e-=w;
u=(u*f);
}
w/=2;
}
return u;
}
Poly2 pow(const Poly2& f,const Big& k,const Poly2& m)
{
Poly2 u,t;
Big w,e;
if (k==0)
{
u.addterm((GF2m)1,0);
return u;
}
u=(f%m);
if (k==1) return u;
e=k;
w=pow((Big)2,bits(e)-1);
e-=w; w/=2;
while (w>0)
{
u=(u*u)%m;
if (e>=w)
{
e-=w;
u=(u*f)%m;
}
w/=2;
}
return u;
}
int degree(const Poly2& p)
{
if (p.start==NULL) return 0;
else return p.start->n;
}
BOOL iszero(const Poly2& p)
{
if (degree(p)==0 && p.coeff(0)==0) return TRUE;
else return FALSE;
}
BOOL isone(const Poly2& p)
{
if (degree(p)==0 && p.coeff(0)==1) return TRUE;
else return FALSE;
}
void Poly2::clear()
{
term2 *ptr;
while (start!=NULL)
{
ptr=start->next;
delete start;
start=ptr;
}
}
Poly2& Poly2::operator=(int m)
{
clear();
if (m!=0) addterm((GF2m)m,0);
return *this;
}
Poly2 &Poly2::operator=(const Poly2& p)
{
term2 *ptr,*pos=NULL;
clear();
ptr=p.start;
while (ptr!=NULL)
{
pos=addterm(ptr->an,ptr->n,pos);
ptr=ptr->next;
}
return *this;
}
Poly2 operator+(const Poly2& a,const Poly2& b)
{
Poly2 sum;
sum=a;
sum+=b;
return sum;
}
Poly2 operator+(const Poly2& a,const GF2m& b)
{
Poly2 sum=a;
sum.addterm(b,0);
return sum;
}
Poly2& Poly2::operator+=(const Poly2& p)
{
term2 *ptr,*pos=NULL;
ptr=p.start;
while (ptr!=NULL)
{
pos=addterm(ptr->an,ptr->n,pos);
ptr=ptr->next;
}
return *this;
}
Poly2& Poly2::operator*=(const GF2m& x)
{
term2 *ptr=start;
while (ptr!=NULL)
{
ptr->an*=x;
ptr=ptr->next;
}
return *this;
}
BOOL operator==(const Poly2& a,const Poly2& b)
{
Poly2 diff=a+b;
if (iszero(diff)) return TRUE;
return FALSE;
}
BOOL operator!=(const Poly2& a,const Poly2& b)
{
Poly2 diff=a+b;
if (iszero(diff)) return FALSE;
return TRUE;
}
Poly2 operator*(const GF2m& z,const Poly2 &p)
{
Poly2 r=p;
r*=z;
return r;
}
Poly2 operator*(const Poly2 &p,const GF2m& z)
{
Poly2 r=p;
r*=z;
return r;
}
Poly2 operator/(const Poly2& a,const GF2m& b)
{
Poly2 quo;
quo=a;
quo/=(GF2m)b;
return quo;
}
Poly2& Poly2::operator/=(const GF2m& x)
{
GF2m t=(GF2m)1/x;
term2 *ptr=start;
while (ptr!=NULL)
{
ptr->an*=t;
ptr=ptr->next;
}
return *this;
}
void Poly2::multerm(const GF2m& a,int power)
{
term2 *ptr=start;
while (ptr!=NULL)
{
ptr->an*=a;
ptr->n+=power;
ptr=ptr->next;
}
}
Poly2 invmodxn(const Poly2& a,int n)
{ // Newton's method to find 1/a mod x^n
int i,k;
Poly2 b;
k=0; while ((1<<k)<n) k++;
b.addterm((GF2m)1/a.coeff(0),0); // important that a0 != 0
for (i=1;i<=k;i++)
b=modxn (a*(b*b),1<<i);
b=modxn(b,n);
return b;
}
Poly2 modxn(const Poly2& a,int n)
{ // reduce polynomial mod x^n
Poly2 b;
term2* ptr=a.start;
term2 *pos=NULL;
while (ptr!=NULL && ptr->n>=n) ptr=ptr->next;
while (ptr!=NULL)
{
pos=b.addterm(ptr->an,ptr->n,pos);
ptr=ptr->next;
}
return b;
}
Poly2 divxn(const Poly2& a,int n)
{ // divide polynomial by x^n
Poly2 b;
term2 *ptr=a.start;
term2 *pos=NULL;
while (ptr!=NULL)
{
if (ptr->n>=n)
pos=b.addterm(ptr->an,ptr->n-n,pos);
else break;
ptr=ptr->next;
}
return b;
}
Poly2 mulxn(const Poly2& a,int n)
{ // multiply polynomial by x^n
Poly2 b;
term2 *ptr=a.start;
term2 *pos=NULL;
while (ptr!=NULL)
{
pos=b.addterm(ptr->an,ptr->n+n,pos);
ptr=ptr->next;
}
return b;
}
Poly2 reverse(const Poly2& a)
{
term2 *ptr=a.start;
int deg=degree(a);
Poly2 b;
while (ptr!=NULL)
{
b.addterm(ptr->an,deg-ptr->n);
ptr=ptr->next;
}
return b;
}
// add term to polynomial. The pointer pos remembers the last
// accessed element - this is faster.
// Polynomial is stored with large powers first, down to low powers
// e.g. 9x^6 + x^4 + 3x^2 + 1
term2* Poly2::addterm(const GF2m& a,int power,term2 *pos)
{
term2* newone;
term2* ptr;
term2 *t,*iptr;
ptr=start;
iptr=NULL;
if (a.iszero()) return pos;
// quick scan through to detect if term exists already
// and to find insertion point
if (pos!=NULL) ptr=pos; // start looking from here
while (ptr!=NULL)
{
if (ptr->n==power)
{
ptr->an+=a;
if (ptr->an.iszero())
{ // delete term
if (ptr==start)
{ // delete first one
start=ptr->next;
delete ptr;
return start;
}
iptr=ptr;
ptr=start;
while (ptr->next!=iptr)ptr=ptr->next;
ptr->next=iptr->next;
delete iptr;
return ptr;
}
return ptr;
}
if (ptr->n>power) iptr=ptr;
else break;
ptr=ptr->next;
}
newone=new term2;
newone->next=NULL;
newone->an=a;
newone->n=power;
pos=newone;
if (start==NULL)
{
start=newone;
return pos;
}
// insert at the start
if (iptr==NULL)
{
t=start;
start=newone;
newone->next=t;
return pos;
}
// insert new term
t=iptr->next;
iptr->next=newone;
newone->next=t;
return pos;
}
ostream& operator<<(ostream& s,const Poly2& p)
{
BOOL first=TRUE;
GF2m a;
term2 *ptr=p.start;
if (ptr==NULL)
{
s << "0";
return s;
}
while (ptr!=NULL)
{
a=ptr->an;
if (!first) s << " + ";
if (ptr->n==0)
s << a;
else
{
if (a!=(GF2m)1) s << a << "*x";
else s << "x";
if (ptr->n!=1) s << "^" << ptr->n;
}
first=FALSE;
ptr=ptr->next;
}
return s;
}
Poly2 compose(const Poly2& q,const Poly2& p)
{ // compose polynomials
// assume P(x) = P3x^3 + P2x^2 + P1x^1 +P0
// Calculate P(Q(x)) = P3.(Q(x))^3 + P2.(Q(x))^2 ....
Poly2 poly;
Poly2 temp(p);
int qdegree;
term2 *qptr = q.start;
poly.start = NULL;
while(qptr != NULL) {
qdegree = qptr->n;
if(qdegree > 0) {
temp = p;
for(int i = 1; i < qdegree; i++)
temp = temp * p;
poly += temp;
} else {
poly = poly + qptr->an;
}
qptr = qptr->next;
}
return poly;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -