C++中有限環接口的聲明與實現

D:\MathTool\gaptool>cl /c IRing.cpp
用於 x86 的 Microsoft (R) C/C++ 優化編譯器 17.00.50727.1 版版權所有(C) Microsoft Corporation。保留所有權利。

IRing.cpp
C:\Program Files (x86)\Microsoft Visual Studio 11.0\VC\INCLUDE\xlocale(336) : warning C4530: 使用了 C++ 異常處理程序,但未啓用展開語義。請指
定 /EHsc

D:\MathTool\gaptool>link /OUT:IRing.exe IRing.obj
Microsoft (R) Incremental Linker Version 11.00.50727.1
Copyright (C) Microsoft Corporation.  All rights reserved.

D:\MathTool\gaptool>IRing
R2_1:N0n0bAbOn1n2n4n5n6n7n8S1N2=[1,1],2,1,0,2,1,1,1,4,1,2,[1,1],[]
R2_2:N0n0bAbOn1n2n4n5n6n7n8S1N2=[1,1],2,1,1,1,2,0,0,3,0,2,[1,1],[[2,2,1]]
R4_2:N0n0bAbOn1n2n4n5n6n7n8S1N2=[1,1,2],4,1,0,4,1,1,3,12,3,4,[1,1,2],[[4,4,4]]
R4_3:N0n0bAbOn1n2n4n5n6n7n8S1N2=[1,1,2],4,1,1,2,2,1,1,8,1,4,[1,1,2],[[2,4,2],[4,2,2],[4,4,4]]
R256_-1:N0n0bAbOn1n2n4n5n6n7n8S1N2=[1,15,240,0,0,0,0,0,0],4,0,0,256,1,63,255,14848,255,32,[1,15,160,80,0,0,0,0,0],[[4,4,50688]]
環的階太大,不在控制檯打印
R256_-1:N0n0bAbOn1n2n4n5n6n7n8S1N2=[1,15,240,0,0,0,0,0,0],4,0,1,160,26,27,39,2464,159,4,[1,15,74,86,80,0,0,0,0],[[2,4,3168],[4,2,3168],[4,4,
56736]]
環的階太大,不在控制檯打印
R2_1:
[R2Add]
1 2
2 1
[R2Mul]
1 1
1 1
cnt=16
R16_301:N0n0bAbOn1n2n4n5n6n7n8S1N2=[1,15,0,0,0],2,1,0,16,1,15,15,256,15,16,[1,15,0,0,0],[]
cnt=512
R512_-1:N0n0bAbOn1n2n4n5n6n7n8S1N2=[1,511,0,0,0,0,0,0,0,0],2,1,0,512,1,511,511,262144,511,512,[1,511,0,0,0,0,0,0,0,0],[]
環的階太大,不在控制檯打印
cnt=16
R16_300:N0n0bAbOn1n2n4n5n6n7n8S1N2=[1,15,0,0,0],2,0,1,10,8,3,3,58,9,2,[1,10,5,0,0],[[2,2,198]]
cnt=512
R512_-1:N0n0bAbOn1n2n4n5n6n7n8S1N2=[1,511,0,0,0,0,0,0,0,0],2,0,1,344,58,21,63,6168,343,2,[1,78,287,146,0,0,0,0,0,0],[[2,2,255976]]
環的階太大,不在控制檯打印
源碼:

#ifndef IRING_H
#define IRING_H

#include<stdio.h>
#include<string.h>
#include<sstream>
#include<vector>
#include<map>
#include<tuple>
#include<iterator>
#include<algorithm>
#include<functional>
using namespace std;

struct IRing
{
    virtual void printTable() = 0;
    virtual int add(int a,int b) = 0;
    virtual int mul(int a,int b) = 0;
    virtual int size() = 0;        
};

void printRing(IRing* r){
   int n=r->size();
   printf("[R%dAdd]\n",n);   
   for(int i=0;i<n;i++){
       for(int j=0;j<n;j++){
          int ij=r->add(i,j);
          printf("%d ",ij+1);
       } 
       printf("\n");   
   }
   printf("[R%dMul]\n",n);   
   for(int i=0;i<n;i++){
       for(int j=0;j<n;j++){
          int ij=r->mul(i,j);
          printf("%d ",ij+1); 
       } 
       printf("\n");       
   }
}

// 一個環r的子環s
struct Subring:public IRing
{
public:
    // 靜態函數
public:
    // 實現抽象基類的方法
    virtual void printTable();
    virtual int add(int a,int b);
    virtual int mul(int a,int b);
    virtual int size(); 
    // 構造函數
    Subring(IRing* r,const vector<int>& gens);
    // 成員函數    
    // 成員變量
    vector<int> m_Set;
    IRing* m_r;
};

void Subring::printTable()
{
    int IdRing(IRing*);
    int ID=IdRing(this);
    printf("R%d_%d:\n",size(),ID);
    printRing(this);    
}

int Subring::add(int a,int b)
{
    int ij=m_r->add(m_Set[a],m_Set[b]);
    vector<int>::iterator p=std::find(m_Set.begin(),m_Set.end(),ij);
    int IJ=-1;
    if(p!=m_Set.end()){
        IJ=p-m_Set.begin();
    }
    return IJ;
}

int Subring::mul(int a,int b)
{
    int ij=m_r->mul(m_Set[a],m_Set[b]);
    vector<int>::iterator p=std::find(m_Set.begin(),m_Set.end(),ij);
    int IJ=-1;
    if(p!=m_Set.end()){
        IJ=p-m_Set.begin();
    }
    return IJ;
}

int Subring::size()
{
    return m_Set.size();
}

Subring::Subring(IRing* r,const vector<int>& gens)
{
    m_r=r;
    int E=0;
    m_Set.push_back(E);
    for(int i=0;i<gens.size();i++)
    {
        if(gens[i]!=E)
            m_Set.push_back(gens[i]);
    }
    int R=m_Set.size();
    int cnt=R;
    int cnt1=R;
    do{
        cnt=m_Set.size();
        for(int i=0;i<cnt;i++)
        {
            for(int j=0;j<cnt;j++)
            {
                int IJ=m_r->mul(m_Set[i],m_Set[j]);
                vector<int>::iterator p=std::find(m_Set.begin(),m_Set.end(),IJ);
                if(p==m_Set.end()){
                    m_Set.push_back(IJ);
                }
                int IJ1=m_r->add(m_Set[i],m_Set[j]);
                p=std::find(m_Set.begin(),m_Set.end(),IJ1);
                if(p==m_Set.end()){
                    m_Set.push_back(IJ1);
                }
            }
        }
        cnt1=m_Set.size();
    }while(cnt1>cnt);
}
string itos(int i)
{
  stringstream s;
  s << i;
  return s.str();
}

vector<int>  DivisorsInt(int n){
    vector<int> ret;
    if(n<1)
        return ret;
    for(int i=1;i<=n;i++){
        if(n%i==0){
            ret.push_back(i);
        }
    }
    return ret;
}

string simplyS1(vector<int>& S1){
    int n=S1.size();
    vector<int> vOrders=DivisorsInt(n);
    vector<int> vCounts(n+1);
     for(int i=0;i<n;i++)
    {
        int ord=S1[i];
        vCounts[ord]=vCounts[ord]+1;
    }
    string str="[";
    for(int i=0;i<vOrders.size();i++)
    {
        char sz[200]={0};
        sprintf(sz,"%d,",vCounts[vOrders[i]]);
        str+=sz;
    }
    if(str.size()>2)
    {
        str=str.substr(0,str.size()-1);
    }
    str+="]";
    return str;
}

string calS1(IRing* r,bool bDone){

   int n=r->size();
   vector<int> S1;
   for(int i=0;i<n;i++){
       vector<int> v;
       v.push_back(i);
       Subring si(r,v);
       S1.push_back(si.size());
   }
   if(bDone)
   {
       string str=simplyS1(S1);
       return str;
   }    
   string str="[";
   for(int i=0;i<n;i++)
   {
       str+=itos(S1[i]);
       if(i<n-1)
           str+=",";   
   }       
   str+="]";
   return str;
}

vector<int> Order(IRing* r,int m){
    vector<int> ret;
    int mi=m;
    int m0=0;
    ret.push_back(m0);
    while(mi!=m0){
        ret.push_back(mi);
        mi=r->add(mi,m);
    }
    return ret;
}

string calcN0(IRing* r){
    int n=r->size();
    vector<int> vOrders=DivisorsInt(n);
    vector<int> vCounts(n+1);
     for(int i=0;i<n;i++){
        vector<int> S1=Order(r,i);
        int ord=S1.size();
        vCounts[ord]=vCounts[ord]+1;
    }
    string strN0="[";
    for(int i=0;i<vOrders.size();i++){
        char sz[200]={0};
        sprintf(sz,"%d,",vCounts[vOrders[i]]);
        strN0+=sz;
    }
    if(strN0.size()>2){
        strN0=strN0.substr(0,strN0.size()-1);
    }
    strN0+="]";
    return strN0;
}

//利用歐幾里得算法計算兩個數的最大公約數
int gcd(int a, int b)
{
    int temp;
    if(b == 0) return a;
    if(a == 0) return b;
    if(a%b == 0) return b;
    else return gcd(b, a%b);
}

int lcm(const vector<int>& v){
 int n=v.size();
 if(n<1)
  return 0;
 if(n==1)
  return v[0];
 int ret=v[0];
 for(int i=1;i<n;i++) {
  ret=(ret*v[i]/gcd(ret,v[i]));
 }
 return ret;
}

int calcn0(IRing* r){
    vector<int> v;
    int n=r->size();
    vector<int> vOrders=DivisorsInt(n);
    vector<int> vCounts(n+1);
    for(int i=0;i<n;i++){
        vector<int> S1=Order(r,i);
        int ord=S1.size();
        vCounts[ord]=vCounts[ord]+1;
    }
    for(int i=0;i<vOrders.size();i++){
    if(vCounts[vOrders[i]]!=0)
      v.push_back(vOrders[i]);
    }
    int n0=lcm(v);
    return n0;
}

vector<tuple<int,int,int> > doN2Vec(vector<pair<int,int> >& v){
    vector<tuple<int,int,int> > ret;
    int n=v.size();
    for(int i=0;i<n;i++){
        pair<int,int> vi=v[i];
        vector<tuple<int,int,int> >::const_iterator it=std::find_if(ret.begin(),ret.end(),[vi](tuple<int,int,int>& obj)->bool{if(get<0>(obj)==vi.first && get<1>(obj)==vi.second)return true;return false;});
        if(it==ret.end()){
            ret.push_back(make_tuple(vi.first,vi.second,1));
        }else{
            int cnt=get<2>(*it);
            ret[it-ret.begin()]=make_tuple(vi.first,vi.second,cnt+1);
        }
    }
    return ret;
}

string calcN2(IRing* r){
    int n=r->size();
    vector<pair<int,int> > v;
    for(int i=1;i<n;i++){
        for(int j=1;j<n;j++){
            if(r->mul(i,j)!=0){
                vector<int> S1i=Order(r,i);            
                int oi=S1i.size();
                vector<int> S1j=Order(r,j);            
                int oj=S1j.size();
                v.push_back(make_pair(oi,oj));
            }
        }
    }
    std::sort(v.begin(),v.end());
    vector<tuple<int,int,int> > v1=doN2Vec(v);
    string strN2="[";
    for(int i=0;i<v1.size();i++)
    {
        char sz[200]={0};
        sprintf(sz,"[%d,%d,%d],",get<0>(v1[i]),get<1>(v1[i]),get<2>(v1[i]));
        strN2+=sz;
    }
    if(strN2.size()>2)
    {
        strN2=strN2.substr(0,strN2.size()-1);
    }
    strN2+="]";
    return strN2;
}

int ZeroNum(IRing* r){
    int n=r->size();
    int iRet=0;
    for(int i=0;i<n;i++)for(int j=0;j<n;j++){if(r->mul(i,j)==0)iRet++;}
    //printf("零乘個數n6=%d,",iRet);
    return iRet;
}

int ZeroFactorNum(IRing* r){
    int n=r->size();
    int iRet=0;
    for(int i=1;i<n;i++){
        for(int j=1;j<n;j++){
            if(r->mul(i,j)==0){
                iRet++;
                break;
            }
        }
    }
    //printf("零因子個數n7=%d,",iRet);
    return iRet;
}

bool IsIdempotent(IRing* r,int i2){
    int n=r->size();    
    if(i2<0||i2>=n)
        return false;
    if(r->mul(i2,i2)==i2)
        return true;
    return false;
}

int IdempotentNum(IRing* r){
    int n=r->size();
    int iRet=0;
    for(int i2=0;i2<n;i2++){if(IsIdempotent(r,i2))iRet++;}
    //printf("冪等元個數n2=%d,",iRet);
    return iRet;
}

int Nil2Num(IRing* r){
    int n=r->size();
    int iRet=0;
    for(int i4=1;i4<n;i4++){if(r->mul(i4,i4)==0)iRet++;}
    //printf("2次冪零元個數n4=%d,",iRet);
    return iRet;
}

int Nil3Num(IRing* r){
    int n=r->size();
    int iRet=0;
    for(int i5=1;i5<n;i5++){int j=r->mul(i5,i5);if(r->mul(j,i5)==0)iRet++;}
    //printf("2~3次冪零元個數n5=%d,",iRet);
    return iRet;
}

bool IsAbelian(IRing* r){
    int n=r->size();
    for (int i=0; i<n; i++)for (int j=0; j<n; j++){if(r->mul(i,j)!=r->mul(j,i))return false;}
    return true;
}

bool IsOne(IRing* r,int i3){
    int n=r->size();
    if(i3<0||i3>=n)
        return false;
    for (int i=0; i<n; i++){
        if(r->mul(i3,i)!=i || r->mul(i,i3)!=i)
            return false;
    }
    return true;
}

int One(IRing* r){
    int n=r->size();
    for (int i3=0; i3<n; i3++){if(IsOne(r,i3))return i3;}
    return -1;
}

// 是否有可逆元,-1表示沒有
int Inv(IRing* r,int i1,int iOne){
    int n=r->size();
    for (int i=0; i<n; i++){if(r->mul(i1,i)==iOne && r->mul(i,i1)==iOne)return i;}
    return -1;
}

// 不可逆元個數n1
int NoInvNum(IRing* r){
    int n=r->size();
    int iRet=0;
    int iOne=One(r);
    if(iOne==-1)
       return n;
    for(int i1=0;i1<n;i1++){if(Inv(r,i1,iOne)==-1)iRet++;}
    return iRet;
}

bool IsInCenter(IRing* r,int j){
    int N=r->size();
    for(int i=0;i<N;i++){
        int ij=r->mul(i,j);
        int ji=r->mul(j,i);
        if(ij==ji)
            continue;
        else
            return false;
    }
    return true;
}

vector<int> Center(IRing* r){
    vector<int> ret;
    int N=r->size();
    for(int i=0;i<N;i++){
        if(IsInCenter(r,i))
            ret.push_back(i);
        else
            continue;
    }
    return ret;
}

//-----------------------------Begin of IdRing---------------------------------
class RIDHelper
{
public:
    RIDHelper();
    ~RIDHelper();
private:
    multimap<string,int> m_RingInvariant;//根據環的結構不變量N0n0bAbOn1n2n4n5n6n7n8S1N2返回ID編號列表    
public:
    vector<int> IDFromRingInvariant(string& RingInvariant);        
};

RIDHelper::RIDHelper(){
    // N0,【n0,bA,bO,n1,n2,n4,n5,n6,n7】,n8,S1,N2
    //R2
    m_RingInvariant.insert(make_pair("2,1,0,2,1,1,1,4,1",1));
    m_RingInvariant.insert(make_pair("2,1,1,1,2,0,0,3,0",2));    
    //R3
    m_RingInvariant.insert(make_pair("3,1,0,3,1,2,2,9,2",1));
    m_RingInvariant.insert(make_pair("3,1,1,1,2,0,0,5,0",2));        
    //R4
    m_RingInvariant.insert(make_pair("4,1,0,4,1,3,3,16,3",1));
    m_RingInvariant.insert(make_pair("4,1,0,4,1,1,3,12,3",2));
    m_RingInvariant.insert(make_pair("4,1,1,2,2,1,1,8,1",3));
    m_RingInvariant.insert(make_pair("2,1,0,4,1,3,3,16,3",4));    
    m_RingInvariant.insert(make_pair("2,1,0,4,1,1,3,12,3",5));
    m_RingInvariant.insert(make_pair("2,1,0,4,2,1,1,12,3",6));
    m_RingInvariant.insert(make_pair("2,0,0,4,3,1,1,10,1",7));
    m_RingInvariant.insert(make_pair("2,0,0,4,3,1,1,10,3",8));    
    m_RingInvariant.insert(make_pair("2,1,1,2,2,1,1,8,1",9));
    m_RingInvariant.insert(make_pair("2,1,1,3,4,0,0,9,2",10));
    m_RingInvariant.insert(make_pair("2,1,1,1,2,0,0,7,0",11));    
    //R5
    m_RingInvariant.insert(make_pair("5,1,0,5,1,4,4,25,4",1));
    m_RingInvariant.insert(make_pair("5,1,1,1,2,0,0,9,0",2));
    //R6
    m_RingInvariant.insert(make_pair("6,1,0,6,1,5,5,36,5",1));
    m_RingInvariant.insert(make_pair("6,1,0,6,2,1,1,20,5",2));
    m_RingInvariant.insert(make_pair("6,1,0,6,2,2,2,27,5",3));
    m_RingInvariant.insert(make_pair("6,1,1,4,4,0,0,15,3",4));
    //R8
    m_RingInvariant.insert(make_pair("8,1,0,8,1,7,7,64,7",1));
    m_RingInvariant.insert(make_pair("8,1,0,8,1,3,3,32,7",2));    
    m_RingInvariant.insert(make_pair("8,1,1,4,2,1,3,20,3",3));
    m_RingInvariant.insert(make_pair("8,1,0,8,1,3,7,48,7",4));    
    m_RingInvariant.insert(make_pair("4,1,0,8,1,7,7,64,7",5));
    m_RingInvariant.insert(make_pair("[1,3,4,0],4,1,0,8,1,3,7,48,7,8,[1,1,6,0]",6));    
    m_RingInvariant.insert(make_pair("4,1,0,8,2,3,3,48,7",7));
    m_RingInvariant.insert(make_pair("[1,3,4,0],4,0,0,8,1,5,7,48,7,2,[1,3,4,0]",8));    
    m_RingInvariant.insert(make_pair("[1,3,4,0],4,0,0,8,1,5,7,48,7,2,[1,1,6,0]",9));
    m_RingInvariant.insert(make_pair("[1,3,4,0],4,0,0,8,1,5,7,48,7,2,[1,3,4,0]",10));
    m_RingInvariant.insert(make_pair("4,1,0,8,1,7,7,40,7",11));
    m_RingInvariant.insert(make_pair("4,1,0,8,1,3,7,40,7",12));    
    m_RingInvariant.insert(make_pair("4,1,0,8,2,3,3,32,7",13));
    m_RingInvariant.insert(make_pair("4,1,1,6,4,1,1,24,5",14));    
    m_RingInvariant.insert(make_pair("4,0,0,8,3,3,3,28,7",15));    
    m_RingInvariant.insert(make_pair("[1,3,4,0],4,1,0,8,1,3,7,48,7,8,[1,3,4,0]",16));    
    m_RingInvariant.insert(make_pair("4,1,0,8,2,1,3,36,7",17));
    m_RingInvariant.insert(make_pair("4,0,0,8,1,1,7,40,7",18));    
    m_RingInvariant.insert(make_pair("4,1,0,8,1,3,7,40,7",19));
    m_RingInvariant.insert(make_pair("4,0,0,8,3,3,3,28,3",20));
    m_RingInvariant.insert(make_pair("4,1,1,4,2,3,3,24,3",21));
    m_RingInvariant.insert(make_pair("4,1,1,4,2,1,3,20,3",22));    
    m_RingInvariant.insert(make_pair("[1,3,4,0],4,1,0,8,1,3,7,48,7,8,[1,3,0,4]",23));
    m_RingInvariant.insert(make_pair("4,1,0,8,1,3,3,32,7",24));    
    m_RingInvariant.insert(make_pair("2,1,0,8,1,7,7,64,7",25));
    m_RingInvariant.insert(make_pair("2,1,0,8,1,3,7,48,7",26));    
    m_RingInvariant.insert(make_pair("2,1,0,8,2,3,3,48,7",27));
    m_RingInvariant.insert(make_pair("2,0,0,8,1,5,7,48,7",28));    
    m_RingInvariant.insert(make_pair("2,0,0,8,3,3,3,40,7",29));
    m_RingInvariant.insert(make_pair("2,0,0,8,5,3,3,36,3",30));
    m_RingInvariant.insert(make_pair("2,1,0,8,1,7,7,40,7",31));
    m_RingInvariant.insert(make_pair("2,1,0,8,1,3,7,40,7",32));    
    m_RingInvariant.insert(make_pair("2,1,0,8,1,3,3,32,7",33));
    m_RingInvariant.insert(make_pair("2,0,0,8,3,3,3,40,7",34));    
    m_RingInvariant.insert(make_pair("2,1,0,8,2,3,3,32,7",35));    
    m_RingInvariant.insert(make_pair("2,0,0,8,5,3,3,32,7",36));    
    m_RingInvariant.insert(make_pair("2,0,0,8,3,3,3,28,3",37));
    m_RingInvariant.insert(make_pair("2,1,0,8,2,1,3,36,7",38));    
    m_RingInvariant.insert(make_pair("2,0,0,8,1,1,7,40,7",39));
    m_RingInvariant.insert(make_pair("2,1,0,8,4,1,1,36,7",40));
    m_RingInvariant.insert(make_pair("2,0,0,8,6,1,1,30,5",41));
    m_RingInvariant.insert(make_pair("2,0,0,8,6,1,1,30,5",42));    
    m_RingInvariant.insert(make_pair("2,0,0,8,5,3,3,36,7",43));
    m_RingInvariant.insert(make_pair("2,0,0,8,3,3,3,28,7",44));    
    m_RingInvariant.insert(make_pair("2,1,1,4,2,3,3,24,3",45));    
    m_RingInvariant.insert(make_pair("2,1,1,4,2,1,3,20,3",46));    
    m_RingInvariant.insert(make_pair("2,0,0,8,6,1,1,30,7",47));
    m_RingInvariant.insert(make_pair("2,1,1,6,4,1,1,24,5",48));    
    m_RingInvariant.insert(make_pair("2,0,1,6,6,1,1,26,5",49));
    m_RingInvariant.insert(make_pair("2,1,1,7,8,0,0,27,6",50));
    m_RingInvariant.insert(make_pair("2,1,1,5,4,0,0,21,4",51));
    m_RingInvariant.insert(make_pair("2,1,1,1,2,0,0,15,0",52));
    //R9
    m_RingInvariant.insert(make_pair("9,1,0,9,1,8,8,81,8,9",1));
    m_RingInvariant.insert(make_pair("9,1,1,3,2,2,2,21,2,9",2));
    m_RingInvariant.insert(make_pair("9,1,0,9,1,2,8,45,8,9",3));
    m_RingInvariant.insert(make_pair("3,1,0,9,1,8,8,81,8,9",4));    
    m_RingInvariant.insert(make_pair("3,1,0,9,1,2,8,45,8,9",5));
    m_RingInvariant.insert(make_pair("3,1,0,9,2,2,2,45,8,9",6));
    m_RingInvariant.insert(make_pair("3,0,0,9,4,2,2,33,2,1",7));
    m_RingInvariant.insert(make_pair("3,0,0,9,4,2,2,33,8,1",8));    
    m_RingInvariant.insert(make_pair("3,1,1,3,2,2,2,21,2,9",9));
    m_RingInvariant.insert(make_pair("3,1,1,5,4,0,0,25,4,9",10));
    m_RingInvariant.insert(make_pair("3,1,1,1,2,0,0,17,0,9",11));    
}

RIDHelper::~RIDHelper(){
    m_RingInvariant.clear();    
}

vector<int>  RIDHelper::IDFromRingInvariant(string& RingInvariant){
    std::multimap<string,int>::iterator it;
    std::pair<std::multimap<string,int>::iterator, std::multimap<string,int>::iterator> pa;
    vector<int> v;
#if 1
    for( it = m_RingInvariant.begin(); it != m_RingInvariant.end(); ++it){
        string::size_type idx=RingInvariant.find(it->first);
        if(idx!=string::npos)
            v.push_back(it->second);
    }
#else
    pa = m_RingInvariant.equal_range(RingInvariant);    
    for( it = pa.first; it != m_RingInvariant.end() && it != pa.second; ++it){
        v.push_back(it->second);
    }
#endif
    return v;
}

string calcRingInvariant(IRing* r){
    string strN0=calcN0(r);
    int n0=calcn0(r); 
    bool bA=IsAbelian(r);
    int n3=One(r);
    bool bO=(n3>-1);
    int n1=NoInvNum(r);
    int n2=IdempotentNum(r);
    int n4=Nil2Num(r);
    int n5=Nil3Num(r);
    int n6=ZeroNum(r);
    int n7=ZeroFactorNum(r);
    vector<int> ZA=Center(r);
    int n8=ZA.size();
    string strS1=calS1(r,true);
    string strN2=calcN2(r);
    // N0n0bAbOn1n2n4n5n6n7n8S1N2
    char sz[1024]={0};
    sprintf(sz,"%s,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%s,%s",strN0.c_str(),n0,bA,bO,n1,n2,n4,n5,n6,n7,n8,strS1.c_str(),strN2.c_str());    
    return sz;
}

int IdRing(IRing* r){    
   string strRingInvariant=calcRingInvariant(r);
   RIDHelper idHelper;
   vector<int> vID=idHelper.IDFromRingInvariant(strRingInvariant);
   if(vID.size()<=0)       
       return -1;//沒有RingInvariant數據
   if(vID.size()>1){
        #if 1
             printf("[");
             for(int i=0;i<vID.size();i++){
                 printf("%d,",vID[i]);
             }
             printf("]\n");
        #endif       
       return 0;//ID不確定,還需要新的環不變量確定編號
   }   
   return vID[0];
}

//-----------------------------End of IdRing-------------------------------

#endif

#include"IRing.h"

// 有限循環環mZ/nZ,這裏限制m|n
struct ZmodnZ:public IRing
{
public:
    // 靜態函數
public:
    // 實現抽象基類的方法
    virtual void printTable();
    virtual int add(int a,int b);
    virtual int mul(int a,int b);
    virtual int size(); 
    // 構造函數
    ZmodnZ(int m,int n);
    // 成員函數    
    // 成員變量
    int m_m;
    int m_n;// 運算爲模n加法和模n乘法    
};

void ZmodnZ::printTable()
{
    int ID=IdRing(this);
    string str=calcRingInvariant(this);
    printf("R%d_%d:N0n0bAbOn1n2n4n5n6n7n8S1N2=%s\n",size(),ID,str.c_str());    
    //string S1=calS1(this,true);
    //string undoS1=calS1(this,false);    
    //printf("R%d_%d:S1=%s,S1(未經處理)=%s\n",size(),ID,S1.c_str(),undoS1.c_str());
    //printRing(this);    
}

int ZmodnZ::add(int a,int b)
{
    return ((m_m*a+m_m*b)%m_n)/m_m;
}

int ZmodnZ::mul(int a,int b)
{
    return ((m_m*a*m_m*b)%m_n)/m_m;    
}

int ZmodnZ::size()
{
    return m_n/m_m;
}

ZmodnZ::ZmodnZ(int m,int n)
{
    m_m=m;
    m_n=n;
}

typedef vector<vector<int> > MATRIXi;

// 2階全矩陣環M2(r)
struct M2r:public IRing
{
public:
    // 靜態函數
   static int getidx(vector<MATRIXi> &Arr2,MATRIXi &Arr1);
   static bool IsEqual(const MATRIXi &t,const MATRIXi &m);    
public:
    // 實現抽象基類的方法
    virtual void printTable();
    virtual int add(int a,int b);
    virtual int mul(int a,int b);
    virtual int size(); 
    // 構造函數
    M2r(IRing* r);
    // 成員函數    
    // 成員變量
    vector<MATRIXi> m_Set;
    IRing* m_r;
};

int M2r::getidx(vector<MATRIXi> &Arr2,MATRIXi &Arr1){
    int N=Arr2.size();
    for(int i=0;i<N;i++){
        if(IsEqual(Arr2[i],Arr1))
            return i;
    }
    return -1;
}

bool M2r::IsEqual(const MATRIXi &t,const MATRIXi &m){
    int nt=t.size();
    int nm=m.size();
    if(nt!=nm)
        return false;
    for(int i=0;i<nt;i++){
        for(int j=0;j<nt;j++){
            if(t[i][j]!=m[i][j])
                return false;
        }
    }
    return true;
}

void M2r::printTable()
{
    int ID=IdRing(this);
    string str=calcRingInvariant(this);
    printf("R%d_%d:N0n0bAbOn1n2n4n5n6n7n8S1N2=%s\n",size(),ID,str.c_str());    
    //string S1=calS1(this,true);
    //string undoS1=calS1(this,false);    
    //printf("R%d_%d:S1=%s,S1(未經處理)=%s\n",size(),ID,S1.c_str(),undoS1.c_str());
    if(size()<100){
        //printRing(this);    
    }
    else{
       printf("環的階太大,不在控制檯打印\n");
    }
}

int M2r::add(int a,int b)
{
    MATRIXi A=m_Set[a];
    MATRIXi B=m_Set[b];    
    int n=2;
    MATRIXi C(n,vector<int>(n,0));
    for(int i=0;i<n;i++){
        for(int j=0;j<n;j++){
            C[i][j]=m_r->add(A[i][j],B[i][j]);
        }
    }
    int c=getidx(m_Set,C);
    return c;
}

int M2r::mul(int a,int b)
{
    MATRIXi A=m_Set[a];
    MATRIXi B=m_Set[b];    
    int n=2;
    MATRIXi C(n,vector<int>(n,0));
    for(int i=0;i<n;i++){
        for(int j=0;j<n;j++){
            int sum=0;
            for(int k=0;k<n;k++){
                sum=m_r->add(sum,m_r->mul(A[i][k],B[k][j]));
            }
            C[i][j]=sum;
        }
    }
    int c=getidx(m_Set,C);
    return c;
}

int M2r::size()
{
    return m_Set.size();
}

M2r::M2r(IRing* r)
{
    m_r=r;
    int N=r->size();
    int n=2;
    MATRIXi m(n,vector<int>(n,0));
    for(int i=0;i<N;i++){
        for(int j=0;j<N;j++){
            for(int k=0;k<N;k++){
                for(int l=0;l<N;l++){
                    m[0][0]=i;
                    m[0][1]=j;
                    m[1][0]=k;
                    m[1][1]=l;
                    m_Set.push_back(m);                    
                }
            }
        }
    }
}

typedef vector<vector<unsigned char> > MATRIXi8;

// n階全矩陣環Mn(r)
struct Mnr:public IRing
{
public:
    // 靜態函數
   static int getidx(vector<MATRIXi8> &Arr2,MATRIXi8 &Arr1);
   static bool IsEqual(const MATRIXi8 &t,const MATRIXi8 &m);    
   static bool nextV1(int m,vector<unsigned char>& v);
public:
    // 實現抽象基類的方法
    virtual void printTable();
    virtual int add(int a,int b);
    virtual int mul(int a,int b);
    virtual int size(); 
    // 構造函數
    Mnr(IRing* r,int n);
    // 成員函數    
    int visitMnRm(int n,int m);    
    // 成員變量
    vector<MATRIXi8> m_Set;
    IRing* m_r;
    int m_n;
};

bool Mnr::nextV1(int m,vector<unsigned char>& 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^2)次visit
int Mnr::visitMnRm(int n,int m){
    vector<unsigned char> v(n*n,0);
    int cnt=0;
    do {
        ++cnt;
        MATRIXi8 M(n,vector<unsigned char>(n,0));
        for(int k=0;k<n*n;k++){
            int i=k/n;
            int j=k%n;
            M[i][j]=v[k];
        }
        m_Set.push_back(M);
    }while(nextV1(m,v));
    return cnt;
}

int Mnr::getidx(vector<MATRIXi8> &Arr2,MATRIXi8 &Arr1){
    int N=Arr2.size();
    for(int i=0;i<N;i++){
        if(IsEqual(Arr2[i],Arr1))
            return i;
    }
    return -1;
}

bool Mnr::IsEqual(const MATRIXi8 &t,const MATRIXi8 &m){
    int nt=t.size();
    int nm=m.size();
    if(nt!=nm)
        return false;
    for(int i=0;i<nt;i++){
        for(int j=0;j<nt;j++){
            if(t[i][j]!=m[i][j])
                return false;
        }
    }
    return true;
}

void Mnr::printTable()
{
    int ID=IdRing(this);
    string str=calcRingInvariant(this);
    printf("R%d_%d:N0n0bAbOn1n2n4n5n6n7n8S1N2=%s\n",size(),ID,str.c_str());
    //string undoS1=calS1(this,false);    
    //printf("R%d_%d:S1=%s,S1(未經處理)=%s\n",size(),ID,S1.c_str(),undoS1.c_str());
    if(size()<100){
        //printRing(this);    
    }
    else{
       printf("環的階太大,不在控制檯打印\n");
    }
}

int Mnr::add(int a,int b)
{
    MATRIXi8 A=m_Set[a];
    MATRIXi8 B=m_Set[b];    
    int n=m_n;
    MATRIXi8 C(n,vector<unsigned char>(n,0));
    for(int i=0;i<n;i++){
        for(int j=0;j<n;j++){
            C[i][j]=m_r->add(A[i][j],B[i][j]);
        }
    }
    int c=getidx(m_Set,C);
    return c;
}

int Mnr::mul(int a,int b)
{
    MATRIXi8 A=m_Set[a];
    MATRIXi8 B=m_Set[b];    
    int n=m_n;
    MATRIXi8 C(n,vector<unsigned char>(n,0));
    for(int i=0;i<n;i++){
        for(int j=0;j<n;j++){
            int sum=0;
            for(int k=0;k<n;k++){
                sum=m_r->add(sum,m_r->mul(A[i][k],B[k][j]));
            }
            C[i][j]=sum;
        }
    }
    int c=getidx(m_Set,C);
    return c;
}

int Mnr::size()
{
    return m_Set.size();
}

Mnr::Mnr(IRing* r,int n)
{
    m_r=r;
    m_n=n;
    int N=r->size();
    int cnt=visitMnRm(m_n,N);
    printf("cnt=%d\n",cnt);
}

int main()
{
   ZmodnZ r2_1(2,4);
   r2_1.printTable();  

   ZmodnZ r2_2(1,2);  
   r2_2.printTable();

   ZmodnZ r4_2(2,8);
   r4_2.printTable();  

   ZmodnZ r4_3(1,4);  
   r4_3.printTable();
   
   M2r m2r4_2(&r4_2);
   m2r4_2.printTable(); 

   M2r m2r4_3(&r4_3);
   m2r4_3.printTable(); 
   
   vector<int> v;
   v.push_back(2);
   Subring r2_1a(&r4_3,v);
   r2_1a.printTable();
   
   Mnr m2r2_1(&r2_1,2);
   m2r2_1.printTable(); 

   Mnr m3r2_1(&r2_1,3);
   m3r2_1.printTable();   
   
   Mnr m2r2_2(&r2_2,2);
   m2r2_2.printTable(); 

   Mnr m3r2_2(&r2_2,3);
   m3r2_2.printTable();      
   
   return 0;
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章