有限環子環個數的計算

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])    
    }    
}

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