D:\MathTool\gaptool>PolynomialRing
R8_3/([[0,2],[2]],[1,0,1])=R16_118:N0n0bAbOn1n2n4n5n6n7n8S1N2=[1,3,12,0,0],4,1,0,16,1,7,15,128,15,16,[1,3,8,4,0],[[4,4,128]]
I1I2=[[1,1,1],[2,1,3],[4,1,4],[4,2,4],[8,23,4]],[[2,1,3],[4,1,10],[4,2,10],[4,4,3],[8,5,12],[8,16,12],[8,23,22]]
R8_3/([[4,6],[4,7]],[0,0,1])=R16_16:N0n0bAbOn1n2n4n5n6n7n8S1N2=[1,3,4,8,0],8,1,0,16,1,15,15,160,15,16,[1,3,4,8,0],
[[2,8,16],[4,8,16],[8,2,16],[8,4,16],[8,8,32]]
I1I2=[[1,1,1],[2,1,3],[4,1,4],[8,1,8]],[[2,1,3],[4,1,10],[4,4,3],[8,1,44],[8,5,12]]
R8_3/([[6,1],[6,3]],[0,0,1])=R16_17:N0n0bAbOn1n2n4n5n6n7n8S1N2=[1,3,4,8,0],8,1,0,16,1,7,7,128,15,16,[1,3,4,0,8],[[2,8,16],
[4,8,16],[8,2,16],[8,4,16],[8,8,64]]
I1I2=[[1,1,1],[2,1,3],[4,1,4]],[[2,1,3],[4,1,10],[4,4,3],[8,5,12]]
cnt=4
R2_2/([1,0,1])=R4_9:N0n0bAbOn1n2n4n5n6n7n8S1N2=[1,3,0],2,1,1,2,2,1,1,8,1,4,[1,2,1],[[2,2,8]]
cnt=4
R2_2/([1,1,1])=R4_11:N0n0bAbOn1n2n4n5n6n7n8S1N2=[1,3,0],2,1,1,1,2,0,0,7,0,4,[1,1,2],[[2,2,9]]
cnt=4
R2_2/([0,0,1])=R4_9:N0n0bAbOn1n2n4n5n6n7n8S1N2=[1,3,0],2,1,1,2,2,1,1,8,1,4,[1,2,1],[[2,2,8]]
cnt=4
R2_2/([0,1,1])=R4_10:N0n0bAbOn1n2n4n5n6n7n8S1N2=[1,3,0],2,1,1,3,4,0,0,9,2,4,[1,3,0],[[2,2,7]]
cnt=8
R2_2/([1,0,0,1])=R8_51:N0n0bAbOn1n2n4n5n6n7n8S1N2=[1,7,0,0],2,1,1,5,4,0,0,21,4,8,[1,3,2,2],[[2,2,43]]
cnt=9
R3_2/([1,0,1])=R9_11:N0n0bAbOn1n2n4n5n6n7n8S1N2=[1,8,0],3,1,1,1,2,0,0,17,0,9,[1,2,6],[[3,3,64]]
cnt=9
R3_2/([1,1,1])=R9_9:N0n0bAbOn1n2n4n5n6n7n8S1N2=[1,8,0],3,1,1,3,2,2,2,21,2,9,[1,4,4],[[3,3,60]]
cnt=9
R3_2/([0,0,1])=R9_9:N0n0bAbOn1n2n4n5n6n7n8S1N2=[1,8,0],3,1,1,3,2,2,2,21,2,9,[1,4,4],[[3,3,60]]
cnt=9
R3_2/([0,1,1])=R9_10:N0n0bAbOn1n2n4n5n6n7n8S1N2=[1,8,0],3,1,1,5,4,0,0,25,4,9,[1,6,2],[[3,3,56]]
cnt=16
R4_3/([1,0,1])=R16_105:N0n0bAbOn1n2n4n5n6n7n8S1N2=[1,3,12,0,0],4,1,1,8,2,3,3,48,7,16,[1,3,2,6,4],[[2,4,32],[4,2,32],[4,4,144]]
cnt=16
R4_3/([1,1,1])=R16_106:N0n0bAbOn1n2n4n5n6n7n8S1N2=[1,3,12,0,0],4,1,1,4,2,3,3,40,3,16,[1,3,2,2,8],[[2,4,36],[4,2,36],[4,4,144]]
cnt=16
R4_3/([0,0,1])=R16_110:N0n0bAbOn1n2n4n5n6n7n8S1N2=[1,3,12,0,0],4,1,1,8,2,7,7,56,7,16,[1,3,6,2,4],[[2,4,32],[4,2,32],[4,4,136]]
cnt=16
R4_3/([0,1,1])=R16_104:N0n0bAbOn1n2n4n5n6n7n8S1N2=[1,3,12,0,0],4,1,1,12,4,3,3,64,11,16,[1,3,6,6,0],[[2,4,28],[4,2,28],[4,4,136]]
R4_3/([[1,0,1]],[1,0,0,1])=R32_-1:N0n0bAbOn1n2n4n5n6n7n8S1N2=[1,7,24,0,0,0],4,1,0,32,2,7,7,160,31,32,[1,7,2,4,10,8],[[2,4,144],[4,2,144],[4,
4,576]]
I1I2=[[1,1,1],[2,1,7],[4,3,2],[8,13,2],[8,21,2],[16,106,8],[16,251,2]],[[2,1,7],[4,3,5],[4,4,21],[8,13,17],[8,21,17],[16,106,92],[16,251,53]
]
cnt=64
R4_3/([1,0,0,1])=R64_-1:N0n0bAbOn1n2n4n5n6n7n8S1N2=[1,7,56,0,0,0,0],4,1,1,40,4,7,7,320,39,64,[1,7,6,16,10,8,16],[[2,4,344],[4,2,344],[4,4,30
88]]
I1I2=[[1,1,1],[2,1,7],[4,3,6],[8,13,8],[8,21,8],[16,106,8],[16,251,2],[32,-1,8]],[[2,1,7],[4,3,15],[4,4,21],[8,13,68],[8,21,68],[16,104,48],
[16,106,92],[16,205,36],[16,219,36],[16,251,53],[32,-1,428]]
#include"ZmodnZ.h"
#include<vector>
#include<iostream>
#include<fstream>
#include<string>
using namespace std;
typedef vector<int> Polynomial;// 用向量表示多項式
// r[x]/(a)、(m)r[x]/(n)r[x]
struct PolynomialRing:public IRing
{
public:
// 靜態函數
static bool IsEqual(Polynomial& a,Polynomial& b);// 是否相等
static Polynomial add(Polynomial& a,Polynomial& b,int ord);// 加法
static Polynomial mul(Polynomial& a,Polynomial& b,int ord);// 乘法
static Polynomial mod(Polynomial& a,Polynomial& b,int ord);// 取餘
static bool is_zero(Polynomial& a);// 是否爲零多項式
static bool is_irr(Polynomial& a,int ord);// 是否不可約,Error測試不通過
static bool is_pri(Polynomial& a,int ord);// 是否本原,Error測試不通過
static Polynomial pow(Polynomial& a,unsigned int b,int ord);// 快速指數算法
static Polynomial gcd(Polynomial& a,Polynomial& b,int ord);
static vector<int> FactorsInt(int n);
static bool nextV1(int m,vector<int>& v);
static string Itos(int Num);
static string sPoly(Polynomial& a);
static vector<Polynomial> FR(Polynomial &a,vector<Polynomial> &v,int ord);
public:
// 實現抽象基類的方法
virtual void printTable();
virtual int add(int a,int b);
virtual int mul(int a,int b);
virtual int size();
// 構造函數
PolynomialRing(){};
PolynomialRing(IRing *r,Polynomial& a);
// 成員函數
void initFR(IRing *r,Polynomial &m,Polynomial &n);
int visitVnRm(int n,int m);
// 成員變量
vector<Polynomial> m_Set;
Polynomial m_a;// 運算爲模a加法和模a乘法
vector<Polynomial> m_gen;
IRing* m_r;
};
void PolynomialRing::initFR(IRing *r,Polynomial &m,Polynomial &n)
{
m_r=r;
m_a=n;
vector<Polynomial> v;
v.push_back(m);
m_Set=FR(n,v,r->size());
m_gen=v;
}
vector<Polynomial> PolynomialRing::FR(Polynomial &a,vector<Polynomial> &v,int ord)
{
vector<Polynomial> S;
Polynomial p0;
p0.push_back(0);
S.push_back(p0);
for(int i=0;i<v.size();i++)
{
Polynomial r1=mod(v[i],a,ord);
S.push_back(r1);
}
int cnt=0;
int cnt1=S.size();
while(cnt1>cnt){
cnt=S.size();
for(int i=0;i<S.size();i++){
for(int j=0;j<S.size();j++){
Polynomial ij=mod(mul(S[i],S[j],ord),a,ord);
vector<Polynomial>::iterator p=std::find(S.begin(),S.end(),ij);
if(p==S.end()){
S.push_back(ij);
}
Polynomial ij1=mod(add(S[i],S[j],ord),a,ord);
vector<Polynomial>::iterator p1=std::find(S.begin(),S.end(),ij1);
if(p1==S.end()){
S.push_back(ij1);
}
}
}
cnt1=S.size();
}
return S;
}
// 將一個數字轉換成字符串
string PolynomialRing::Itos(int Num)
{
char buffer[100]={0};
sprintf(buffer,"%d",Num);
string strBuf=buffer;
return strBuf;
}
string PolynomialRing::sPoly(Polynomial& a)
{
string str="[";
int n=a.size();
for(int i=0;i<n;i++)
{
str+=Itos(a[i]);
if(i<n-1)
{
str+=",";
}
}
str+="]";
return str;
}
bool PolynomialRing::nextV1(int m,vector<int>& v){
int n=v.size();
for(int i=n-1;i>=0;i--){
if(v[i]<m-1){
v[i]+=1;
return true;
}
else if(v[i]==m-1 && i>0){
if(v[i-1]<m-1){
v[i-1]+=1;
for(int j=i;j<n;j++)
v[j]=0;
return true;
}
}
}
return false;
}
// 調用m^n次visit
int PolynomialRing::visitVnRm(int n,int m){
vector<int> v(n,0);
int cnt=0;
do {
++cnt;
Polynomial p=v;
while( !p.empty() && !p.back() )
p.pop_back();
if (p.empty()) {// 補零
p.push_back(0);
}
m_Set.push_back(p);
}while(nextV1(m,v));
return cnt;
}
void PolynomialRing::printTable()
{
int ID1=IdRing(m_r);
int ID=IdRing(this);
string str1=sPoly(m_a);
string str2="";
if(m_gen.size()>0){
str2+="[";
for(int i=0;i<m_gen.size();i++){
str2+=sPoly(m_gen[i]);
if(i<m_gen.size()-1)
str2+=",";
}
str2+="],";
}
string str=calcRingInvariant(this);
printf("R%d_%d/(%s%s)=R%d_%d:N0n0bAbOn1n2n4n5n6n7n8S1N2=%s\n",m_r->size(),ID1,str2.c_str(),str1.c_str(),size(),ID,str.c_str());
string I1=calcI1(this);
string I2=calcI2(this);
printf("I1I2=%s,%s\n",I1.c_str(),I2.c_str());
//printRing(this);
}
int PolynomialRing::add(int a,int b)
{
Polynomial C=add(m_Set[a],m_Set[b],m_r->size());
int c=-1;
vector<Polynomial>::iterator p=std::find(m_Set.begin(),m_Set.end(),C);
if(p!=m_Set.end()){
c=p-m_Set.begin();
}
return c;
}
int PolynomialRing::mul(int a,int b)
{
Polynomial C1=mul(m_Set[a],m_Set[b],m_r->size());
Polynomial C=mod(C1,m_a,m_r->size());
int c=-1;
vector<Polynomial>::iterator p=std::find(m_Set.begin(),m_Set.end(),C);
if(p!=m_Set.end()){
c=p-m_Set.begin();
}
return c;
}
int PolynomialRing::size()
{
return m_Set.size();
}
PolynomialRing::PolynomialRing(IRing *r,Polynomial& a)
{
m_a=a;
m_r=r;
int N=r->size();
unsigned int pOrd = a.size()-1;/*多項式最高次項次數*/
int cnt=visitVnRm(pOrd,N);
printf("cnt=%d\n",cnt);
}
vector<int> PolynomialRing::FactorsInt(int n )
{
vector<int> a;
for( int i = 2 , sign ; i < n / 2 + 1 ; i++ )
{
sign=0;
if( n % i == 0 )
{
if( a.empty() )
{
a.push_back( i );
continue;
}
for( unsigned int j = 0 ; j < a.size() ; j++ )
{
if( i % a[j] == 0 )
{
sign=1;
break;
}
}
if( sign == 0 )
a.push_back( i );
}
}
/*對階n進行唯一分解,結果存儲於向量a*/
if( a.empty() )
a.push_back( n );
return a;
}
Polynomial PolynomialRing::gcd(Polynomial& a,Polynomial& b,int ord)
{
Polynomial pa = a;
Polynomial pb = b;
Polynomial pc;
while(!is_zero(pb))
{
pc = mod(pa,pb,ord);
pa = pb;
pb = pc;
}
return pa;
}
Polynomial PolynomialRing::pow(Polynomial& a,unsigned int b,int ord)
{
unsigned int sum =ord;/*sum用於計算p^n-1*/
vector<short> vBin;/*vBin用於存儲p^n-1的二進制位*/
Polynomial Q1;
Q1.push_back(1);
Polynomial Qx;
Qx.push_back(0);
Qx.push_back(1);
Polynomial qm = Q1;
for( unsigned int i = b ; i > 1 ; i-- )
sum *= ord;
sum -= 1;
for( ; sum != 0 ; )
{
vBin.push_back( sum % 2 );
sum /= 2;
}
/*將p^n-1化爲二進制表示,存入向量vBin,向量下標小的元素存儲二進制的低位*/
for( int i = vBin.size()-1 ; i >= 0 ; i-- )
{
qm=mod(mul(qm,qm,ord),a,ord);
if( vBin[i] )
{
qm=mod(mul(qm,Qx,ord),a,ord);
}
if( is_zero(qm)) break;
}/*此處用到快速指數算法*/
return qm;
}
bool PolynomialRing::is_irr(Polynomial& a,int ord)
{
Polynomial p=a;
unsigned int pOrd = a.size()-1;/*多項式最高次項次數*/
if(pOrd==1)
return true;
Polynomial Q1;
Q1.push_back(1);
//step 1判斷f(x)是否是以n的因子爲次數的不可約多項式之積------------
if(!IsEqual(pow(p,pOrd,ord),Q1))
return false; //step 1結束---------------------------------------------------------
//step 2判斷f(x)是否有一次因式-------------------------------------
for(int i = 0,n,sum ; i < ord; i++ )
{
n = i ;
sum = a[0] ;
for(unsigned int j = 1 ; j<a.size() ; j++ )
{
sum = (( sum + a[j] * n ) % ord + ord ) % ord;
n = n * i % ord;
}
if(sum == 0)
return false;
}
//step 2結束---------------------------------------------------------
//step 3判斷f(x)中是否含有次數小於n的不可約因式--------------------
vector<int> vFac = FactorsInt( a.size()-1 );
for( unsigned int i = 0 ; i < vFac.size() ; i++ )
{
if( !IsEqual(gcd(p,pow(p,(a.size()-1)/vFac[i],ord),ord),Q1))
return false;
}
//step 3結束---------------------------------------------------------
return true;
}
/*該函數中對快速指數算法進行了一定的改進,因此沒有直接調用快速指數算法而直接重寫了函數*/
bool PolynomialRing::is_pri(Polynomial& a,int ord)
{
Polynomial p=a;
unsigned int sum = ord;/*sum用於計算p^n-1*/
vector<short> vBin;/*vBin用於存儲(p^n-1)/t的二進制位*/
Polynomial Q1;
Q1.push_back(1);
Polynomial Qx;
Qx.push_back(0);
Qx.push_back(1);
Polynomial qm = Q1;
for( unsigned int i = a.size()-1 ; i > 1 ; i-- )
sum *= ord;
sum -= 1;
for( unsigned int i = 2 , j ; i < sum / 2 + 1 ; i++ )
{
if( sum % i == 0 )
{
j = sum / i;
for( ; j != 0 ; )
{
vBin.push_back( j % 2 );
j /= 2;
}
/*將(p^n-1)/t化爲二進制表示,存入向量vBin,向量下標小的元素存儲二進制的低位*/
for( int k = vBin.size()-1 ; k >= 0 ; k-- )
{
qm=mod(mul(qm,qm,ord),p,ord);
if( vBin[k] )
{
qm=mod(mul(qm,Qx,ord),p,ord);
}
}
if( IsEqual(qm,Q1))
return false;
vBin.clear();
}
}
return true;
}
bool PolynomialRing::IsEqual(Polynomial& a,Polynomial& b)
{
int na=a.size();
int nb=b.size();
if(na!=nb)
return false;
for(int i=0;i<na;i++)
if(a[i]!=b[i])
return false;
return true;
}
bool PolynomialRing::is_zero(Polynomial& a)
{
if(a.size()==0||(a.size()==1&&a[0]==0))
return true;
return false;
}
Polynomial PolynomialRing::add(Polynomial& a,Polynomial& b,int ord)
{
int m=a.size();
int n=b.size();
int k=(m>n?m:n);
int ki=(m>n?n:m);
vector<int> c(k);
for(int i=0;i<ki;i++)
{
c[i]=(a[i]+b[i])%ord;
}
if(m>n)
{
memcpy(&c[n],&a[n],(m-n)*sizeof(int));
}
else if(m<n)
{
memcpy(&c[m],&b[m],(n-m)*sizeof(int));
}
while (c.size() && *(c.rbegin())==0) {// 清除高位無效零
c.pop_back();
}
if (c.empty()) {// 補零
c.push_back(0);
}
return c;
}
Polynomial PolynomialRing::mul(Polynomial& a,Polynomial& b,int ord)
{
vector<int> ma = a;
vector<int> mb = b;
vector<int> mc;
mc.assign(ma.size()+mb.size()- 1,0);
for(unsigned int i=0;i<ma.size();i++)
for(unsigned int j=0;j<mb.size();j++)
mc[i+j]=((mc[i+j]+ma[i]*mb[j])%ord+ord)%ord;
while(!mc.empty() && !mc.back())
mc.pop_back();
if (mc.empty()) {// 補零
mc.push_back(0);
}
return mc;
}
Polynomial PolynomialRing::mod(Polynomial& a,Polynomial& b,int ord)
{
vector<int> m=a;/*被除數*/
vector<int> n=b;/*除數*/
int coe;/*商係數*/
if( m.size() < n.size() )
return a;
else for( unsigned int i = 0 ; i < m.size() - n.size() + 1 ; i++ )
{
for( int ma = m[m.size()-1-i] ; ; )
{
if( !( ma % n[n.size()-1] ))
{
coe = ma / n[n.size()-1];
break;
}
ma += ord;
}
for( unsigned int j=0;j<n.size();j++)
m[m.size()-1-i-j] = ( m[m.size()-1-i-j] - coe*n[n.size()-1-j] % ord + ord ) % ord;
}
while( !m.empty() && !m.back() )
m.pop_back();
if (m.empty()) {// 補零
m.push_back(0);
}
return m;
}
int main(){
int f1[] = {1,0,1};
Polynomial vf1(f1,f1+sizeof(f1)/sizeof(f1[0]));
int f2[] = {1,1,1};
Polynomial vf2(f2,f2+sizeof(f2)/sizeof(f2[0]));
int f3[] = {0,0,1};
Polynomial vf3(f3,f3+sizeof(f3)/sizeof(f3[0]));
int f4[] = {0,1,1};
Polynomial vf4(f4,f4+sizeof(f4)/sizeof(f4[0]));
int f5[] = {1,0,0,1};
Polynomial vf5(f5,f5+sizeof(f5)/sizeof(f5[0]));
ZmodnZ r2_2(1,2);
ZmodnZ r3_2(1,3);
ZmodnZ r4_3(1,4);
ZmodnZ r8_3(1,8);
PolynomialRing r4_9(&r2_2,vf1);
r4_9.printTable();
PolynomialRing r4_11(&r2_2,vf2);
r4_11.printTable();
PolynomialRing r4_9a(&r2_2,vf3);
r4_9a.printTable();
PolynomialRing r4_10(&r2_2,vf4);
r4_10.printTable();
PolynomialRing r8_51(&r2_2,vf5);
r8_51.printTable();
PolynomialRing r9_11(&r3_2,vf1);
r9_11.printTable();
PolynomialRing r9_9(&r3_2,vf2);
r9_9.printTable();
PolynomialRing r9_9a(&r3_2,vf3);
r9_9a.printTable();
PolynomialRing r9_10(&r3_2,vf4);
r9_10.printTable();
PolynomialRing r16_105(&r4_3,vf1);
r16_105.printTable();
PolynomialRing r16_106(&r4_3,vf2);
r16_106.printTable();
PolynomialRing r16_110(&r4_3,vf3);
r16_110.printTable();
PolynomialRing r16_104(&r4_3,vf4);
r16_104.printTable();
PolynomialRing r32;
r32.initFR(&r4_3,vf1,vf5);
r32.printTable();
PolynomialRing r64(&r4_3,vf5);
r64.printTable();
return 0;
}