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;
}