抽象代数的代码实现(5)分裂域

不可约多项式

先来纠正上篇文章一处不严谨的地方,给定一个多项式f(x),做出有理数域K的扩域K(α),使得f(α) = 0.,这里必须要规定f(x)是不可约多项式才保证能做出扩域,不可约多项式指的是f(x)不能表示成两个次数小于f(x)的多项式之积。

如果f(x)是可约多项式,那么并不能按照之前讲的方法扩域,举个例子,假如f(x)=x ^3-1,那么f(x)可约,因为f(x)=x ^3-1 = (x-1)(x ^2 +x+ 1),设α使得f(α) = 0,那么α-1 是没有逆元的,因为假如存在某个元X(α)=x0+x1α+x2α ^2使得(α-1)X(α)=1,则两边都乘以(α ^2 +α+1),得(α-1)(α ^2 +α+1)X(α) = α ^2+α+1,注意到(α-1)(α ^2 +α+1)=0,这说明α ^2 +α+1=0,但α ^2 +α+1除以α ^3-1的余式仍然是α ^2 +α+1并不为0,矛盾。

在代码中可以把pPoly设为x ^3-1,取一个向量元(-1 1 0)对应α-1,输入到PolyMultInv函数求逆时,最后在解线性方程时,SolveLinearEqu函数会返回0说明该线性方程无解。

如果f(x)是不可约多项式,上面的扩域是成立的,对于任一个给定的元g(α)都会有逆元存在,即存在X(α)使得g(α)X(α) = 1 (mod f(α)),对于X(α) 的系数x0,x1,…xn将会产生一个n元的线性方程,如果这个方程对应的齐次方程g(α)X(α)=0不存在非零解,那么这个方程是有解的,又g(α)X(α)=0说明f(α)整除g(α)X(α),可以通过下面的引理证明X(α)只可能是0。

引理,如果f(x)是不可约多项式,不存在两个次数小于f(x)的多项式其积被f(x)整除。可以用反证法证明,假设存在,那么选一个次数最小的,不妨设为g(x),则g(x)h(x)=k(x)f(x),令f(x)=g(x)q(x)+r(x),r(x)的次数小于g(x),因为 f(x)不可约,所以r(x)不等于0,把两边都乘以h(x),f(x)h(x)=g(x)q(x)h(x)+r(x)h(x)=k(x)f(x) +r(x)h(x),这说明r(x)h(x)被f(x)整除,这与g(x)是最小的矛盾。

所以g(α)X(α)=0只有零解,这说明化简后得到的向量方程x0A+x1B+x2B…=0只有零解,所以A、B、C…这n个向量是线性无关的,n维向量的最大线性无关组是n,所以上述n个向量可以表示向量空间中的任何向量,特别的可以表示(1 0 0…0),所以g(α)X(α) = 1 (mod f(α))的解一定存在。

关于这种存在性的问题现在只能用文字说明,还没有什么好的办法用代码做出比较有说服力的证明。

分裂域

对于有理数域K和K上多项式p(x),如果存在K的扩域E,使得E中可以选出s个元素满足等式p(x) = a(x-α1)(x-α2)…(x-αs),a为p(x)最高次项系数,E是满足等式的最小的扩域,则称E为K上的分裂域,显然分裂域E中的元α1,α2…,αs是方程p(x)的根

从代码的角度看,扩域后上述方程的系数都在新域中,用向量表示,但是p(x)的系数仍然是有理数,与K中的元素是相对应的,但却是用向量表示的,也就是向量的第1个元素是属于K的,后面都是0。

接着来说明这样的域是存在的:

首先如果p(x)在有理数域K上是不可约多项式,那么按照前面讲的方法用向量空间的表示来扩域。否则将p(x)分解成2个小于p(x)最高次数的多项式f(x)和g(x)的乘积,如果这两个多项式还不是不可约多项式那么继续分解,直到全部都是不可约多项式为止,因为一次多项式是不可约的,所以上面的步骤总可以结束的,这样p(x)就分解成有限个不可约多项式之积,不妨设为p(x)=p1(x)p2(x)…pn(x),从这些不可约多项式因子中选择一个进行扩域,不妨选择p1(x),并且使新的域E1(如果p1(x)是一次的,那么新的域和原来的域相等)有元α1使得p1(α1)=0,所以p(α1)=0, 设p(x)=(x-α1)p’(x)+r,r为常量,p '(x)的为域E1上的多项式,把α1代入上式得r=0, 所以p(x)=(x-α1)p '(x),按照同样的方法对E1添加元α2扩充成新的域E2,使得p '(α2)=0,得到p(x)=(x-α1)(x-α2)p"(x),依次类推可以得到一个扩域链K=E0⊂E1⊂E2…Es=E,E中有元α1,α2,…,αs满足p(x) = a(x-α1)(x-α2)…(x-αs)

扫描二维码关注公众号,回复: 12497553 查看本文章

上面证明了p(x)的分裂域E是存在的,但是要求得分裂域E和方程p(x)=0的根,必须要先完成下面2个步骤:

  1. 怎么判定一个给定的多项式p(x)是否是不可约的
  2. 如果p(x)是可约的,怎么将p(x)分解成2个次数小于p(x)的多项式之积

针对上面两个问题的方法有很多,但是对于不同形式的p(x)需要不同的方法来判定,如艾森斯坦判别法等,方法灵活多变,目前并没有一种适用于任何多项式的通用方法。关于不可约多项式的判定问题内容还有很多,但是这不在当前内容的主线范围内,所以不再深入研究。

代码实现

本篇内容讲的都是一些存在性问题,没有具体的操作步骤,似乎不好用代码来表达,但是人的自然语言却能将这些描述出来做到逻辑自洽,那么也应该存在一种代码的表达方式把这些问题给说清楚。当然有人用形式化的方法去做了,但我觉得形式化方法并没有将问题的本质提取出来,只不过为了证明而证明,没什么意思,而人证明了一些东西后是可以用证明的结论来提升做其他事情效率的。

因为缺了上面2个步骤,所以没法求出具体的分裂域E,但是还是可以写一些有价值的代码,现在不考虑多项式p(x)是否可约,都按照不可约多项式来处理,对域K按照上面提到的域链不断扩充,得到一个向量空间E,这中间过程中如果p(x),p '(x);p"(x)…出现可约多项式,那么最后得到的E并不是一个域。但这无关紧要,实现过程中的代码还是有价值的,首先是有理数域K通过向量空间的方式扩充成E1后,E1的元素是向量,向量的元素是K中的元素,E1扩充成E2后,E2的元素是一个向量,这个向量中元素是E1中的元素竟然也是一个向量,这似乎不符合我们的直觉,因为通常的认知中向量的元素是一个数。同理E3中的向量元素为E2中的向量,依次类推,就得到了一个迭代的向量表示。学了抽象后我觉得要转变的一个思维是不要认为一个概念就表示一种特定的东西,更应关注的是各种概念之间的内在联系,以及这些概念在不断的运算和变换中的结构特点。

现在来看代码的实现,代码不是很多,但是已经抽象无比了,而且不仅是抽象,在多次扩域后计算量变得非常大。首先原多项式要写成新域的形式,比如现在对p(x)=x ^5 + x ^4 +x ^3 +x ^2 + x + 3进行扩充,新扩充的域E1通过添加α得到,其中p(α)=0,域E1中的元为x0+x1α+x2α ^2 + x3 α ^3+ x4 α ^4的形式,此时要把α从x分裂出来表示为p(x) = (x-α)(x ^4 +(1+α)x ^3 +(1+α+α ^2)x ^2 + (1+α+α ^2+α ^3)x + (1+α+α ^2+α ^3+α ^4)),原来的p(x)在有理数域中用向量[3 1 1 1 1 1]表示,在新域中用列向量组表示,其中每一列代表新域中的元,上一级域中的元素放在新域向量的第1个元素

3 1 1 1 1 1
0 0 0 0 0 0
0 0 0 0 0 0
0 0 0 0 0 0
0 0 0 0 0 0

//把多项式系数写成扩充的新域的形式
VectorEle *GetNewFieldPoly(FieldSys *pField,VectorEle *pPoly)
{
    
    
    
    ... ...
    assert( pBase->eType==pPoly->eType );

    p = NewVector(pPoly->nEle);
    p->pSubField = pField;
    p->eType = pPoly->eType+1;
    p->pPoly = NULL;

    for(i=0; i<pPoly->nEle; i++)
    {
    
    
        p->aVecEle[i] = NewVector1(pPoly,pBase->nEle);
        pVec =  p->aVecEle[i];
        //原多项式中的元素放在对应向量的第一个
        pVec->aVecEle[0] = pPlus->xOperat(pZero,pPoly->aVecEle[i]);
        //其他设为0
        for(j=1; j<pBase->nEle; j++)
        {
    
    
            pVec->aVecEle[j] = pPlus->xOperat(pZero,pZero);
        }
    }

    return p;
}

然后我们要获得x-α在新域中的形式

0 1 0 0 0
-1 0 0 0 0
0 0 0 0 0
0 0 0 0 0
0 0 0 0 0

代码如下

//x-α
VectorEle *NewLinerPoly(FieldSys *pField,VectorEle *pPoly)
{
    
    
   ...  ...
    assert( pPoly->nEle>2 );
    p = NewVector(pPoly->nEle-1);
    p->pSubField = pField;
    p->eType = pPoly->eType;
    p->pPoly = pPoly;

    p->aVecEle[0] = NewVector1(pBase,pBase->nEle);
    pVec = p->aVecEle[0];
    for(j=0;j<pBase->nEle;j++)
    {
    
    
        if( j==1 )
        {
    
    
            // 第1列的第2个元素取-1,即单位元取逆
            pVec->aVecEle[j] = pPlus->xInvEle(pMult->pBaseEle);
        }
        else
        {
    
    
            pVec->aVecEle[j] = pPlus->xOperat(pPlus->pBaseEle,pPlus->pBaseEle);
        }
    }
    //第2列取单位元
    p->aVecEle[1] = pField->pGroup1->xOperat(pBase,pIdentity);
    //其余取0
    for(i=2; i<pPoly->nEle-1; i++)
    {
    
    
        p->aVecEle[i] = pField->pGroup1->xOperat(pBase,pBase);
    }

    return p;
}

然后p(x)除以x-α就可以得到分裂后的多项式p '(x),其表示形式如下

1 1 1 1 1
1 1 1 1 0
1 1 1 0 0
1 1 0 0 0
1 0 0 0 0

最后分裂域的完整代码如下

FieldSys *SplittingField(FieldSys *pField)
{
    
    
    OperateSys *pPlus = pField->pGroup1;
    FieldSys *pExtend;
    VectorEle *pPoly;
    VectorEle *pDiv;
    VectorEle *pTemp;

    pExtend = (FieldSys *)malloc(sizeof(FieldSys));

    pTemp = pPlus->pBaseEle;
    //改写原来域中的多项式
    pPoly = GetNewFieldPoly(pField,pTemp->pPoly);
    PrintVec(pField,pPoly);
    //获得新域的线性因子x-α
    pDiv = NewLinerPoly(pField,pPoly);
    PrintVec(pField,pDiv);
    pTemp = pPoly;
    //相除后的商为一个分裂后的多项式,在此基础上继续扩域
    pPoly = VectorMod(pField,pPoly,pDiv,1);
    FreeVector(pTemp);
    PrintVec(pField,pPoly);
    //用新的多项式扩域
    pExtend->pGroup1 = PolyPlusObj(pField,pPoly->nEle-1,pPoly);
    pExtend->pGroup2 = PolyMultObj(pField,pPoly->nEle-1,pPoly);
    pField->pParent = pExtend;
    loga("Extend %d",pPoly->nEle);
    IsField(pExtend);

    return pExtend;
}

测试代码如下,现在假如pField是有理数域经过一个5次多项式扩域后得到的新域

    pExtend = SplittingField(pField);//分裂后得到4次多项式上的扩域
    pExtend = SplittingField(pExtend);//分裂后得到3次多项式上的扩域
    pExtend = SplittingField(pExtend);//分裂后得到2次多项式上的扩域

一般来说,要在不可约多项式的基础上扩张才能组成一个新域,否则的话扩张后在证明域的过程中会触发断言。在分裂域扩张的过程中,基本上会失去所有的直观性,最后域中运算的步骤人已经无法直观感知,例如在5次多项式扩张后的域E1中,对分裂后的4次多项式p '(x)=x ^4 +(1+α)x ^3 +(1+α+α ^2)x ^2 + (1+α+α ^2+α ^3)x + (1+α+α ^2+α ^3+α ^4)通过添加β继续扩张得到E2,其中p '(β)=0,其在新域中的表示为如下矩阵组,每个矩阵表示原来的域E1中的元素
1 0 0 0
1 0 0 0
1 0 0 0
1 0 0 0
1 0 0 0

1 0 0 0
1 0 0 0
1 0 0 0
1 0 0 0
0 0 0 0

1 0 0 0
1 0 0 0
1 0 0 0
0 0 0 0
0 0 0 0

1 0 0 0
1 0 0 0
0 0 0 0
0 0 0 0
0 0 0 0

1 0 0 0
0 0 0 0
0 0 0 0
0 0 0 0
0 0 0 0

x-β表示为
0 -1 0 0
0 -0 0 0
0 -0 0 0
0 -0 0 0
0 -0 0 0

1 0 0 0
0 0 0 0
0 0 0 0
0 0 0 0
0 0 0 0

0 0 0 0
0 0 0 0
0 0 0 0
0 0 0 0
0 0 0 0

0 0 0 0
0 0 0 0
0 0 0 0
0 0 0 0
0 0 0 0
p '(x)除以 x-β后得到分裂后的3次多项式p"(x),用下面的矩阵组表示,基本上看不出什么直观上的意义了
1 1 1 1
1 1 1 0
1 1 0 0
1 0 0 0
0 0 0 0

1 1 1 0
1 1 0 0
1 0 0 0
0 0 0 0
0 0 0 0

1 1 0 0
1 0 0 0
0 0 0 0
0 0 0 0
0 0 0 0

1 0 0 0
0 0 0 0
0 0 0 0
0 0 0 0
0 0 0 0

当然这个域中的元素进行乘除运算,里面步骤的复杂性会更加无法想象,可以把矩阵组想象成一个立方体,解这个立方体组成的线性方程,这里就不再展示了,当然再继续扩张下去一个元素将会是一组立方体组成…

参考代码

https://github.com/pfysw/CMath/tree/master/Algebra

猜你喜欢

转载自blog.csdn.net/pfysw/article/details/89764060