g_R3_2R3_2Add={
{0,1,2,3,4,5,6,7,8},
{1,2,0,4,5,3,7,8,6},
{2,0,1,5,3,4,8,6,7},
{3,4,5,6,7,8,0,1,2},
{4,5,3,7,8,6,1,2,0},
{5,3,4,8,6,7,2,0,1},
{6,7,8,0,1,2,3,4,5},
{7,8,6,1,2,0,4,5,3},
{8,6,7,2,0,1,5,3,4}
}
g_R3_2R3_2Mul={
{0,0,0,0,0,0,0,0,0},
{0,1,2,0,1,2,0,1,2},
{0,2,1,0,2,1,0,2,1},
{0,0,0,3,3,3,6,6,6},
{0,1,2,3,4,5,6,7,8},
{0,2,1,3,5,4,6,8,7},
{0,0,0,6,6,6,3,3,3},
{0,1,2,6,7,8,3,4,5},
{0,2,1,6,8,7,3,5,4}
}
local calF3F3=calring("g_R3_2R3_2Add","g_R3_2R3_2Mul","R9_10")
print(calF3F3)
g_R8_10Add={
{0,1,2,3,4,5,6,7},
{1,3,6,4,0,7,5,2},
{2,6,0,5,7,3,1,4},
{3,4,5,0,1,2,7,6},
{4,0,7,1,3,6,2,5},
{5,7,3,2,6,0,4,1},
{6,5,1,7,2,4,3,0},
{7,2,4,6,5,1,0,3}
}
g_R8_10Mul={
{0,0,0,0,0,0,0,0},
{0,3,3,0,3,3,0,0},
{0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0},
{0,3,3,0,3,3,0,0},
{0,0,0,0,0,0,0,0},
{0,3,3,0,3,3,0,0},
{0,3,3,0,3,3,0,0}
}
local calR8_10=calring("g_R8_10Add","g_R8_10Mul","R8_10")
print(calR8_10)
D:\hxh\bin\LUA資料\LUA\luatest\luatest>math test1.lua
環R9_10的結構不變量N0,N2,bA,bO,n1,n2,n4,n5,n6,n7=[1,8,0],[[3,3,56]],1,1,5,4,0,0,25,4
環R8_10的結構不變量N0,N2,bA,bO,n1,n2,n4,n5,n6,n7=[1,3,4,0],[[4,2,8],[4,4,8]],0,0,8,1,5,7,48,7
G8ElementToOrder(0)=1
G8ElementToOrder(1)=2
G8ElementToOrder(2)=4
G8ElementToOrder(3)=4
G8ElementToOrder(4)=2
G8ElementToOrder(5)=2
G8ElementToOrder(6)=4
G8ElementToOrder(7)=4
環R8_8的結構不變量N0,N2,bA,bO,n1,n2,n4,n5,n6,n7=[1,3,4,0],[[2,4,8],[4,4,8]],0,0,8,1,5,7,48,7
G8ElementToOrder(0)=1
G8ElementToOrder(1)=2
G8ElementToOrder(2)=4
G8ElementToOrder(3)=4
G8ElementToOrder(4)=2
G8ElementToOrder(5)=2
G8ElementToOrder(6)=4
G8ElementToOrder(7)=4
環R8_10的結構不變量N0,N2,bA,bO,n1,n2,n4,n5,n6,n7=[1,3,4,0],[[4,2,8],[4,4,8]],0,0,8,1,5,7,48,7
#include"stdafx.h"
#include<stdio.h>
#include<stdlib.h>
#include<tuple>
#include<vector>
#include<algorithm>
using namespace std;
void printMtx(int* a,int m,int n)
{
printf("The original array is:\n");
for (int i=0; i<m; i++)
{
for (int j=0; j<n; j++)
printf("%4d", *(a+n*i+j));
printf("\n");
}
}
// 矩陣轉置
void printTranMtx(int* a,int m,int n)
{
printf("The result array is:\n");
for (int j=0; j<n; j++)
{
for (int i=0; i<m; i++)
printf("%4d", *(a+n*i+j));
printf("\n");
}
}
int ZeroNum(int* a,int m,int n)
{
int iRet=0;
for(int i=0;i<m;i++)for(int j=0;j<n;j++){if(*(a+n*i+j)==0)iRet++;}
//printf("零乘個數n6=%d,",iRet);
return iRet;
}
int ZeroFactorNum(int* a,int n)
{
int iRet=0;
for(int i=1;i<n;i++)
{
for(int j=1;j<n;j++)
{
if(*(a+n*i+j)==0)
{
iRet++;
break;
}
}
}
//printf("零因子個數n7=%d,",iRet);
return iRet;
}
bool IsIdempotent(int* a,int n,int i2){
if(i2<0||i2>=n)
return false;
if(*(a+n*i2+i2)==i2)
return true;
return false;
}
int IdempotentNum(int* a,int n)
{
int iRet=0;
for(int i2=0;i2<n;i2++){if(IsIdempotent(a,n,i2))iRet++;}
//printf("冪等元個數n2=%d,",iRet);
return iRet;
}
int Nil2Num(int* a,int n)
{
int iRet=0;
for(int i4=1;i4<n;i4++){if(*(a+n*i4+i4)==0)iRet++;}
//printf("2次冪零元個數n4=%d,",iRet);
return iRet;
}
int Nil3Num(int* a,int n)
{
int iRet=0;
for(int i5=1;i5<n;i5++){int j=*(a+n*i5+i5);if(*(a+n*j+i5)==0)iRet++;}
//printf("2~3次冪零元個數n5=%d,",iRet);
return iRet;
}
bool IsAbelian(int* a,int n)
{
for (int i=0; i<n; i++)for (int j=0; j<n; j++){if(*(a+n*i+j)!=*(a+n*j+i))return false;}
return true;
}
bool IsOne(int* a,int n,int i3)
{
if(i3<0||i3>=n)
return false;
for (int i=0; i<n; i++)
{
if(*(a+n*i3+i)!=i || *(a+n*i+i3)!=i)
return false;
}
return true;
}
int One(int* a,int n)
{
for (int i3=0; i3<n; i3++){if(IsOne(a,n,i3))return i3;}
return -1;
}
// 是否有可逆元,-1表示沒有
int Inv(int* a,int n,int i1,int iOne)
{
for (int i=0; i<n; i++){if(*(a+n*i1+i)==iOne && *(a+n*i+i1)==iOne)return i;}
return -1;
}
// 不可逆元個數n1
int NoInvNum(int* a,int n)
{
int iRet=0;
int iOne=One(a,n);
if(iOne==-1)
return n;
for(int i1=0;i1<n;i1++){if(Inv(a,n,i1,iOne)==-1)iRet++;}
return iRet;
}
int g_R8_8Mul[8][8]={
{0,0,0,0,0,0,0,0},
{0,0,4,4,0,0,4,4},
{0,0,0,0,0,0,0,0},
{0,0,4,4,0,0,4,4},
{0,0,0,0,0,0,0,0},
{0,0,4,4,0,0,4,4},
{0,0,0,0,0,0,0,0},
{0,0,4,4,0,0,4,4}
};
int g_R8_10Mul[8][8]={
{0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0},
{0,4,0,4,0,4,0,4},
{0,4,0,4,0,4,0,4},
{0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0},
{0,4,0,4,0,4,0,4},
{0,4,0,4,0,4,0,4}
};
int g_R8_24Add[8][8]={
{0,1,2,3,4,5,6,7},
{1,0,3,2,5,4,7,6},
{2,3,4,5,6,7,0,1},
{3,2,5,4,7,6,1,0},
{4,5,6,7,0,1,2,3},
{5,4,7,6,1,0,3,2},
{6,7,0,1,2,3,4,5},
{7,6,1,0,3,2,5,4}
};
struct IdxArr2
{
int n;
int Id;
int *RAdd;
int *RMul;
char name[100];
};
IdxArr2 g_ring_arr2_data[]={ \
{8,8,&g_R8_24Add[0][0],&g_R8_8Mul[0][0],"R8_8"}, \
{8,10,&g_R8_24Add[0][0],&g_R8_10Mul[0][0],"R8_10"}, \
};
int g_ring_arr2_data_count=sizeof(g_ring_arr2_data)/sizeof(IdxArr2);
vector<vector<int> > Arr2ToVec2(int *R,int N,int delt)
{
vector<vector<int> > vv(N);
for(int i=0;i<N;i++)
{
vector<int> v(N);
vv[i]=v;
}
for (int i=0; i<N; i++)
for (int j=0; j<N; j++)
{
vv[i][j]=*(R+i*N+j)+delt;
}
return vv;
}
vector<int> Factors(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;
}
vector<int> IsLegalMtx(const vector<vector<int>> &mtx)
{
vector<int> ret(3);
int illegal=-1;
ret[1]=mtx.size();
if(ret[1]==0)
{
ret[0]=illegal;//不是合法矩陣
return ret;
}
ret[2]=mtx[0].size();
if(ret[2]==0)
{
ret[0]=illegal;//不是合法矩陣
return ret;
}
for(int i=1;i<ret[1];i++)
{
if(mtx[i].size()!=ret[2])
{
ret[0]=illegal;//不是合法矩陣
return ret;
}
}
ret[0]=0;//是合法矩陣
return ret;
}
// 未知n階羣的羣元的階
int getGnEOrder(const vector<vector<int>> &A,int a)
{
vector<int> AFlag=IsLegalMtx(A);
if(AFlag[0]==-1)
return -1;
int n=AFlag[1];
if(a<0||a>=n)
return -1;
int t=0;
for(int i=1;i<=n;i++)
{
t=A[t][a]-1;
if(t==0)
return i;
}
return -1;
}
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 calN2(vector<vector<int> >& A,vector<vector<int> >& M)
{
int n=A.size();
vector<pair<int,int> > v;
for(int i=1;i<n;i++)
{
for(int j=1;j<n;j++)
{
if(M[i][j]!=1)
{
int oi=getGnEOrder(A,i);
int oj=getGnEOrder(A,j);
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;
}
void printRingStruct(char *szName,int* a,int* m,int n,int delt)
{
vector<vector<int> > A=Arr2ToVec2(a,n,delt);
vector<vector<int> > M=Arr2ToVec2(m,n,delt);
vector<int> AFlag=IsLegalMtx(A);
if(AFlag[0]==-1||AFlag[1]!=AFlag[2])
return;
vector<int> vOrders=Factors(AFlag[1]);
vector<int> vCounts(AFlag[1]+1);
for(int i=0;i<AFlag[1];i++)
{
int ord=getGnEOrder(A,i);
printf("G%dElementToOrder(%d)=%d\n",AFlag[1],i,ord);
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+="]";
bool bA=IsAbelian(m,n);
int n3=One(m,n);
bool bO=(n3>-1);
int n1=NoInvNum(m,n);
int n2=IdempotentNum(m,n);
int n4=Nil2Num(m,n);
int n5=Nil3Num(m,n);
int n6=ZeroNum(m,n,n);
int n7=ZeroFactorNum(m,n);
string strN2=calN2(A,M);
printf("環%s的結構不變量N0,N2,bA,bO,n1,n2,n4,n5,n6,n7=%s,%s,%d,%d,%d,%d,%d,%d,%d,%d\n",szName,strN0.c_str(),strN2.c_str(),bA,bO,n1,n2,n4,n5,n6,n7);
}
int main()
{
for(int i=0;i<g_ring_arr2_data_count;i++)
{
printRingStruct(g_ring_arr2_data[i].name,g_ring_arr2_data[i].RAdd,g_ring_arr2_data[i].RMul,g_ring_arr2_data[i].n,1);
}
system("pause");
return 0;
}