gap> for i in [1..11] do R:=SmallRing(4,i);;M:=Ideals(R);;Print("N(R4_",i,")=",Size(M),",",List(M,Size),"\n");od;
N(R4_1)=3,[ 1, 2, 4 ]
N(R4_2)=3,[ 1, 2, 4 ]
N(R4_3)=3,[ 1, 2, 4 ]
N(R4_4)=5,[ 1, 2, 2, 2, 4 ]
N(R4_5)=3,[ 1, 2, 4 ]
N(R4_6)=4,[ 1, 2, 2, 4 ]
N(R4_7)=3,[ 1, 2, 4 ]
N(R4_8)=3,[ 1, 2, 4 ]
N(R4_9)=3,[ 1, 2, 4 ]
N(R4_10)=4,[ 1, 2, 2, 4 ]
N(R4_11)=2,[ 1, 4 ]
20200316結論:
S(R4_1)=3,[ 1, 2, 4 ]
S(R4_2)=3,[ 1, 2, 4 ]
S(R4_3)=3,[ 1, 2, 4 ]
S(R4_4)=5,[ 1, 2, 2, 2, 4 ]
S(R4_5)=4,[ 1, 2, 2, 4 ],R4_5有1個2階子環不是理想
S(R4_6)=4,[ 1, 2, 2, 4 ]
S(R4_7)=5,[ 1, 2, 2, 2, 4 ],R4_7有2個2階子環不是理想
S(R4_8)=5,[ 1, 2, 2, 2, 4 ],R4_8有2個2階子環不是理想
S(R4_9)=4,[ 1, 2, 2, 4 ],R4_9有1個2階子環不是理想
S(R4_10)=5,[ 1, 2, 2, 2, 4 ],R4_10有1個2階子環不是理想
S(R4_11)=3,[ 1, 2, 4 ],R4_11有1個2階子環不是理想
root@iZ14rcmneyrcltZ:~/cpptest/gotest# go build ZnElement.go
root@iZ14rcmneyrcltZ:~/cpptest/gotest# ./ZnElement
S(R4_1):
[1] => [1]
[2] => [1 2 3 4]
[3] => [1 3]
time consume: 182.66µs
S(R4_2):
[1] => [1]
[2] => [1 2 3 4]
[3] => [1 3]
time consume: 131.037µs
S(R4_3):
[1] => [1]
[2] => [1 2 3 4]
[3] => [1 3]
time consume: 137.214µs
S(R4_4):
[1] => [1]
[2] => [1 2]
[3] => [1 3]
[4] => [1 4]
[2 3] => [1 2 3 4]
time consume: 172.105µs
S(R4_5):
[1] => [1]
[2] => [1 2]
[3] => [1 2 3 4]
time consume: 118.751µs
S(R4_6):
[1] => [1]
[2] => [1 2]
[3] => [1 3]
[4] => [1 2 3 4]
time consume: 153.616µs
S(R4_7):
[1] => [1]
[2] => [1 2]
[3] => [1 3]
[4] => [1 4]
[2 3] => [1 2 3 4]
time consume: 200.43µs
S(R4_8):
[1] => [1]
[2] => [1 2]
[3] => [1 3]
[4] => [1 4]
[2 3] => [1 2 3 4]
time consume: 178.497µs
S(R4_9):
[1] => [1]
[2] => [1 2 3 4]
[3] => [1 3]
[4] => [1 4]
time consume: 164.448µs
S(R4_10):
[1] => [1]
[2] => [1 2]
[3] => [1 3]
[4] => [1 4]
[2 3] => [1 2 3 4]
time consume: 224.139µs
S(R4_11):
[1] => [1]
[2] => [1 2]
[3] => [1 2 3 4]
time consume: 111.436µs
package main
import (
"fmt"
"time"
"os"
)
type ZmodnZObj struct {
m_k,m_mod int
}
var g_Z4Add [][]int=[][]int{//GAP4中Z/4Z的加法表,0*a a 2*a -a對應0 1 2 3
{1,2,3,4},
{2,3,4,1},
{3,4,1,2},
{4,1,2,3},
}
var g_Z4Mul [][]int=[][]int{//GAP4中Z/4Z的乘法表,0*a a 2*a -a對應0 1 2 3
{1,1,1,1},
{1,2,3,4},
{1,3,1,3},
{1,4,3,2},
}
var g_R4_2Mul [][]int=[][]int{//GAP4中R4_2的乘法表,0*a a 2*a -a對應0 1 2 3
{1,1,1,1},
{1,3,1,3},
{1,1,1,1},
{1,3,1,3},
}
var g_R4_1Mul [][]int=[][]int{
{1,1,1,1},
{1,1,1,1},
{1,1,1,1},
{1,1,1,1},
}
var g_M4Mul [][]int=[][]int{
{0,0,0,0},
{0,0,0,0},
{0,0,0,0},
{0,0,0,0},
}
var g_F4Add [][]int=[][]int{
{0,1,2,3},
{1,0,3,2},
{2,3,0,1},
{3,2,1,0},
}
var g_F4Mul [][]int=[][]int{
{0,0,0,0},
{0,1,2,3},
{0,2,3,1},
{0,3,1,2},
}
var g_F2F2Mul [][]int=[][]int{//F_2×F_2的乘法表,0,1,v,1+v對應0,1,2,3
{0,0,0,0},
{0,1,2,3},
{0,2,2,0},
{0,3,0,3},
}
var g_R4_9Mul [][]int=[][]int{//GAP4中R4_9=F_2[x]/(x^2)的乘法表,0*a b a a+b對應0 1 2 3
{0,0,0,0},
{0,2,1,3},
{0,1,2,3},
{0,3,3,0},
}
var g_R4_8Mul [][]int=[][]int{//GAP4中R4_8的乘法表,0*a b a a+b對應0 1 2 3
{0,0,0,0},
{0,0,1,1},
{0,0,2,2},
{0,0,3,3},
}
var g_R4_7Mul [][]int=[][]int{//GAP4中R4_7的乘法表,0*a b a a+b對應0 1 2 3
{0,0,0,0},
{0,0,0,0},
{0,1,2,3},
{0,1,2,3},
}
var g_R4_6Mul [][]int=[][]int{//GAP4中M_2×F_2的乘法表,0*a b a a+b對應0 1 2 3
{0,0,0,0},
{0,0,0,0},
{0,0,2,2},
{0,0,2,2},
}
var g_R4_5Mul [][]int=[][]int{//GAP4中R4_5的乘法表,0*a b a a+b對應0 1 2 3
{0,0,0,0},
{0,0,0,0},
{0,0,1,1},
{0,0,1,1},
}
var g_Z4 []ZmodnZObj=[]ZmodnZObj{
ZmodnZObj{0,4},
ZmodnZObj{1,4},
ZmodnZObj{2,4},
ZmodnZObj{3,4}}
var g_Z5 []ZmodnZObj=[]ZmodnZObj{
ZmodnZObj{0,5},
ZmodnZObj{1,5},
ZmodnZObj{2,5},
ZmodnZObj{3,5},
ZmodnZObj{4,5}}
var g_Z6 []ZmodnZObj=[]ZmodnZObj{
ZmodnZObj{0,6},
ZmodnZObj{1,6},
ZmodnZObj{2,6},
ZmodnZObj{3,6},
ZmodnZObj{4,6}}
func (this *ZmodnZObj) isEqual(a ZmodnZObj) bool {
return (this.m_k==a.m_k && this.m_mod==a.m_mod)
}
func (this *ZmodnZObj) getName() string {
return fmt.Sprintf("ZmodnZObj(%d,%d)",this.m_k,this.m_mod)
}
func (this *ZmodnZObj) Add(a ZmodnZObj) ZmodnZObj {
var ret ZmodnZObj
ret.m_mod=this.m_mod
ret.m_k=(this.m_k+a.m_k)%this.m_mod
return ret
}
func (this *ZmodnZObj) InvAdd() ZmodnZObj {
var ret ZmodnZObj
ret.m_mod=this.m_mod
ret.m_k=(this.m_mod*2-this.m_k)%this.m_mod
return ret
}
func (this *ZmodnZObj) Mul(a ZmodnZObj) ZmodnZObj {
var ret ZmodnZObj
ret.m_mod=this.m_mod
ret.m_k=(this.m_k*a.m_k)%this.m_mod
return ret
}
//InverseMutable(a ZmodnZObj) bool {
func (this *ZmodnZObj) InvMul(a ZmodnZObj) ZmodnZObj {
var ret ZmodnZObj
ret.m_mod=this.m_mod
ret.m_k=(this.m_k*a.m_k)%this.m_mod
for i:=0;i<this.m_mod;i++ {
ret=ZmodnZObj{this.m_mod,i}
if(ret.Mul(a)==ZmodnZObj{this.m_mod,1}){
return ret
}
}
return ZmodnZObj{0,0}
}
func (this *ZmodnZObj) Idx(v *[]ZmodnZObj) int {
for i:=0;i<len(*v);i++ {
if(this.isEqual((*v)[i])){
return i
}
}
return -1
}
func IsInFR(v *[]int,m int)int {
for i:=0;i<len((*v));i++{
if((*v)[i]==m){
return i;
}
}
return -1;
}
func FR(A *[][]int,M *[][]int,v *[]int)[]int {
FR := []int{}
for i:=0;i<len((*v));i++{
FR=append(FR,(*v)[i])
}
var cnt,cnt1 int
cnt1=cnt
for {
cnt=len(FR)
for i:=0;i<cnt;i++{
for j:=0;j<cnt;j++{
IJ:=(*A)[FR[i]-1][FR[j]-1];
bIn := IsInFR(&FR,IJ)
if(bIn==-1){
FR=append(FR,IJ)
}
IJ1:=(*M)[FR[i]-1][FR[j]-1];
bIn1 := IsInFR(&FR,IJ1)
if(bIn1==-1){
FR=append(FR,IJ1)
}
}
}
cnt1=len(FR)
if cnt1==cnt {
break
}
}
BubbleSort(&FR)
return FR
}
func BubbleSort(arr *[]int){
//fmt.Println("排序前arr=",(*arr))
temp := 0
for i := 0;i < len(*arr) - 1;i++{
for j := 0 ;j<len(*arr) -1 - i;j++{
if((*arr)[j] > (*arr)[j+1]){
temp = (*arr)[j]
(*arr)[j] = (*arr)[j+1]
(*arr)[j+1] = temp
}
}
}
//fmt.Println("排序後arr=",(*arr))
}
func Order(n,m int)[]int {
ret := []int{}
var mi int=m
for {
if mi==0 {
break
}
ret=append(ret,mi)
mi=(mi+m)%n
}
ret=append(ret,mi)
BubbleSort(&ret)
return ret
}
func ToNormal(v *[]int,a int)int {
for i:=0;i<len(*v);i++ {
if((*v)[i]==a){
return i
}
}
return -1
}
//Zn=Z/nZ=1Z/nZ=ZnmTable(n,1)
func ZnTable(n int)([][]int,[][]int){
vZn := []ZmodnZObj{}
for i:=0;i<n;i++{
vZn=append(vZn,ZmodnZObj{i,n})
}
vvAdd:=[][]int{}
vvMul:=[][]int{}
for i:=0;i<n;i++{
I:=[]int{}
I1:=[]int{}
for j:=0;j<n;j++{
IJ:=vZn[i].Add(vZn[j])
ij:=IJ.Idx(&vZn)
I = append(I,ij+1)
IJ1:=vZn[i].Mul(vZn[j])
ij1:=IJ1.Idx(&vZn)
I1 = append(I1,ij1+1)
}
vvAdd = append(vvAdd,I)
vvMul = append(vvMul,I1)
}
return vvAdd,vvMul
}
//循環環mZ/nZ=RingByGenerators([ZmodnZObj(m,n)])
func ZnmTable(n,m int)([][]int,[][]int){
vZnm := Order(n,m)
s:=len(vZnm)
vZn := []ZmodnZObj{}
for i:=0;i<s;i++{
vZn=append(vZn,ZmodnZObj{vZnm[i],n})
}
vvAdd:=[][]int{}
vvMul:=[][]int{}
for i:=0;i<s;i++{
I:=[]int{}
I1:=[]int{}
for j:=0;j<s;j++{
IJ:=vZn[i].Add(vZn[j])
ij:=IJ.Idx(&vZn)
I = append(I,ij+1)
IJ1:=vZn[i].Mul(vZn[j])
ij1:=IJ1.Idx(&vZn)
I1 = append(I1,ij1+1)
}
vvAdd = append(vvAdd,I)
vvMul = append(vvMul,I1)
}
return vvAdd,vvMul
}
func PrintTable(vv [][]int){
for _, v := range vv {
for _, v2 := range v {
fmt.Printf("%d ",v2)
}
fmt.Println()
}
return
}
func WriteTable(vv,vv1 [][]int,fn string) {
f, err := os.OpenFile(fmt.Sprintf("%s.txt",fn), os.O_RDWR|os.O_CREATE, os.ModePerm)
if err != nil {
panic(err)
}
defer f.Close()
n:=len(vv)
var buf string
buf = fmt.Sprintf("[R%dAdd]\n",n)
f.WriteString(buf)
for i:=0;i<n;i++{
for j:=0;j<n;j++{
buf = fmt.Sprintf("%d ",vv[i][j])
f.WriteString(buf)
}
f.WriteString("\n");
}
buf = fmt.Sprintf("[R%dMul]\n",n)
f.WriteString(buf)
for i:=0;i<n;i++{
for j:=0;j<n;j++{
buf = fmt.Sprintf("%d ",vv1[i][j])
f.WriteString(buf)
}
f.WriteString("\n");
}
}
func Arr1_2(a *[]int,m,n int)[][]int{
res := [][]int{}
for i:=0;i<m;i++ {
t := []int{}
for j:=0;j<n;j++ {
r := (*a)[i*n+j]
t = append(t, r)
}
res = append(res,t)
}
return res
}
// n中取m的排列數
func mathPailie(n int, m int) int {
return jieCheng(n) / jieCheng(n-m)
}
// n中取m的組合數
func mathZuhe(n int, m int) int {
return jieCheng(n) / (jieCheng(n-m) * jieCheng(m))
}
// 階乘
func jieCheng(n int) int {
result := 1
for i := 2; i <= n; i++ {
result *= i
}
return result
}
// 根據索引號數組得到元素數組
func findNumsByIndexs(nums []int, indexs [][]int) [][]int {
if len(indexs) == 0 {
return [][]int{}
}
result := make([][]int, len(indexs))
for i, v := range indexs {
line := make([]int, 0)
for j, v2 := range v {
if v2 == 1 {
line = append(line, nums[j])
}
}
result[i] = line
}
return result
}
func moveOneToLeft(leftNums []int) {
//計算有幾個1
sum := 0
for i := 0; i < len(leftNums); i++ {
if leftNums[i] == 1 {
sum++
}
}
//將前sum個改爲1,之後的改爲0
for i := 0; i < len(leftNums); i++ {
if i < sum {
leftNums[i] = 1
} else {
leftNums[i] = 0
}
}
}
// 將ele複製後添加到arr中,返回新的數組
func addTo(arr [][]int, ele []int) [][]int {
newEle := make([]int, len(ele))
copy(newEle, ele)
arr = append(arr, newEle)
return arr
}
// n中取m
func zuheResult(n int, m int) [][]int {
if m < 1 || m > n {
fmt.Println("Illegal argument. Param m must between 1 and len(nums).")
return [][]int{}
}
//保存最終結果的數組,總數直接通過數學公式計算
result := make([][]int, 0, mathZuhe(n, m))
//保存每一個組合的索引的數組,1表示選中,0表示未選中
indexs := make([]int, n)
for i := 0; i < n; i++ {
if i < m {
indexs[i] = 1
} else {
indexs[i] = 0
}
}
//第一個結果
result = addTo(result, indexs)
for {
find := false
//每次循環將第一次出現的 1 0 改爲 0 1,同時將左側的1移動到最左側
for i := 0; i < n-1; i++ {
if indexs[i] == 1 && indexs[i+1] == 0 {
find = true
indexs[i], indexs[i+1] = 0, 1
if i > 1 {
moveOneToLeft(indexs[:i])
}
result = addTo(result, indexs)
break
}
}
//本次循環沒有找到 1 0 ,說明已經取到了最後一種情況
if !find {
break
}
}
return result
}
func IsEqual(a *[]int,b *[]int)bool {
n:=len((*a))
if(len((*b))!=n){
return false
}
for i:=0;i<n;i++{
if((*a)[i]!=(*b)[i]){
return false
}
}
return true
}
func IsInS(S *[][]int,v *[]int)int {
n:=len((*S))
for i:=0;i<n;i++{
bRet := IsEqual(&(*S)[i],v)
if(bRet){
return i
}
}
return -1
}
// 環R(A,M)的所有子環S(R)
func AllSubrings(A *[][]int,M *[][]int) {
S := [][]int{}
n:=len(*A)
nums := []int{}
for i:=1;i<=n;i++{
nums=append(nums,i)
}
timeStart := time.Now()
for m:=1;m<=n;m++{
indexs := zuheResult(n, m)
result := findNumsByIndexs(nums, indexs)
for _, v := range result {
vFR:=FR(A,M,&v)
if(IsInS(&S,&vFR)==-1){
S=append(S,vFR)
fmt.Println(v,"=>",vFR)
//}else{
// fmt.Println(v,"->",vFR)
}
}
}
timeEnd := time.Now()
fmt.Println("time consume:", timeEnd.Sub(timeStart))
}
func test1(){
I:=g_Z4[0]//零元
a:=g_Z4[1]//乘法幺元
aa:=g_Z4[2]
aaa:=g_Z4[3]
fmt.Println("I=",I.getName())
fmt.Println("a=",a.getName())
fmt.Println("aa=",aa)
fmt.Println("aaa=",aaa)
fmt.Println("I-I=",I.InvAdd())
fmt.Println("I-a=",a.InvAdd())
fmt.Println("I-aa=",aa.InvAdd())
fmt.Println("I-aaa=",aaa.InvAdd())
fmt.Println("aa*aaa=",aa.Mul(aaa))
fmt.Println("aaa*aa=",aaa.Mul(aa))
}
func test2() {
{
vv1,vv2:=ZnTable(4)
fmt.Println("ShowAdditionTable(R4_3)=",vv1)
PrintTable(vv1)
fmt.Println("ShowMultiplicationTable(R4_3)=",vv2)
PrintTable(vv2)
WriteTable(vv1,vv2,"R4_3")
}
{
vv1,vv2:=ZnmTable(8,2)
fmt.Println("ShowAdditionTable(R4_2)=",vv1)
PrintTable(vv1)
fmt.Println("ShowMultiplicationTable(R4_2)=",vv2)
PrintTable(vv2)
WriteTable(vv1,vv2,"R4_2")
}
}
func test3() {
var v1 []int=[]int{2,3}
var v2 []int=[]int{2}
var v3 []int=[]int{3}
var v4 []int=[]int{4}
{
fmt.Println("S(R4_3):")
var v1FR []int=FR(&g_Z4Add,&g_Z4Mul,&v1)
var v2FR []int=FR(&g_Z4Add,&g_Z4Mul,&v2)
var v3FR []int=FR(&g_Z4Add,&g_Z4Mul,&v3)
var v4FR []int=FR(&g_Z4Add,&g_Z4Mul,&v4)
fmt.Println("v1=",v1)
fmt.Println("v1FR=",v1FR)
fmt.Println("v2=",v2)
fmt.Println("v2FR=",v2FR)
fmt.Println("v3=",v3)
fmt.Println("v3FR=",v3FR)
fmt.Println("v4=",v4)
fmt.Println("v4FR=",v4FR)
}
{
fmt.Println("S(R4_2):")
var v1FR []int=FR(&g_Z4Add,&g_R4_2Mul,&v1)
var v2FR []int=FR(&g_Z4Add,&g_R4_2Mul,&v2)
var v3FR []int=FR(&g_Z4Add,&g_R4_2Mul,&v3)
var v4FR []int=FR(&g_Z4Add,&g_R4_2Mul,&v4)
fmt.Println("v1=",v1)
fmt.Println("v1FR=",v1FR)
fmt.Println("v2=",v2)
fmt.Println("v2FR=",v2FR)
fmt.Println("v3=",v3)
fmt.Println("v3FR=",v3FR)
fmt.Println("v4=",v4)
fmt.Println("v4FR=",v4FR)
}
}
func main() {
A:=[]*[][]int{&g_Z4Add,&g_Z4Add,&g_Z4Add,&g_F4Add,&g_F4Add,&g_F4Add,&g_F4Add,&g_F4Add,&g_F4Add,&g_F4Add,&g_F4Add}
M:=[]*[][]int{&g_R4_1Mul,&g_R4_2Mul,&g_Z4Mul,&g_M4Mul,&g_R4_5Mul,&g_R4_6Mul,&g_R4_7Mul,&g_R4_8Mul,&g_R4_9Mul,&g_F2F2Mul,&g_F4Mul}
delt:=[]int{0,0,0,1,1,1,1,1,1,1,1}
for i, v := range g_F4Add {
for j, _ := range v {
g_F4Add[i][j]+=1
}
}
for k:=0;k<len(M);k++{
for i, v := range *M[k] {
for j, _ := range v {
(*M[k])[i][j]+=delt[k]
}
}
fmt.Printf("S(R4_%d):\n",k+1)
AllSubrings(A[k],M[k])
}
}