グレブナ基底

グレブナ基底について使い方のご質問がよくあります。ここではその使い方についてご紹介します。

Maple には Grobner というパッケージがあります。グレブナ基底に関する計算は数式処理の基幹をなすアルゴリズムです。

グレブナ基底とは?

グレブナ基底を理解するには高度な数学的理解が必要です。

しかしここでは難しい話はしないでmapleのGroebnerパッケージの使い方についてご紹介します。

>    restart:

次のような方程式を考えましょう。

x+y = 1

x^2+y^2 = 2

これを左辺=0の形に変形し左辺のみを設定します。

>    sys:={x^2+y^2-2,x+y-1};

sys := {x+y-1, x^2+y^2-2}

これはmapleでsolveにより簡単に解けます(ここで方程式はそれぞれ式=0(例:x+y-1=0)と想定されます)。

>    solve(sys,{x,y});

{y = RootOf(2*_Z^2-2*_Z-1,label = _L1), x = -RootOf(2*_Z^2-2*_Z-1,label = _L1)+1}

ここで RootOf(2*_Z^2-2*_Z-1,label = _L1) は根基(Radical)というもので代数方程式の根をあらわします。根は複数ありますので根基にはどの根であるかを示すためのラベルがつけられます。

ではこれらの多項式のグレブナ基底を求めてみましょう。

まずGrobnerパッケージを呼び出します(Maple 8 よりパッケージ名は大文字の Groebner となっています)

>    with(Groebner);

[MulMatrix, SetBasis, ToricIdealBasis, fglm_algo, gbasis, gsolve, hilbertdim, hilbertpoly, hilbertseries, inter_reduce, is_finite, is_solvable, leadcoeff, leadmon, leadterm, normalf, pretend_gbasis, re...
[MulMatrix, SetBasis, ToricIdealBasis, fglm_algo, gbasis, gsolve, hilbertdim, hilbertpoly, hilbertseries, inter_reduce, is_finite, is_solvable, leadcoeff, leadmon, leadterm, normalf, pretend_gbasis, re...

このようにグレブナ基底に関する多くの関数が用意されています。グレブナ基底を求める関数はgbasisです。

>    g:=gbasis(sys,plex(x,y));

g := [2*y^2-2*y-1, x+y-1]

ここで2番目の引数 plex(x, y) は項の順序を指定するパラメータで plex は辞書式順序 (pure lexical order) を指定します。この順序の指定は必ず必要です。項の順序により求められるグレブナ基底は異なります。tdeg はトータル次数 (total degree) による順番です。

>    gbasis(sys,tdeg(x,y));

[x+y-1, 2*y^2-2*y-1]

ではこの基底にはどのような意味があるのでしょう。

数学的にはイデアルという概念を理解しなければなりません。この二つの式(生成子)を使って構成(変形)できる式の集合がイデアルです。

方程式でいうと、もとの(連立)方程式系と求められたグレブナ基底の方程式系は同値になります。従って新しい連立方程式を解けば元の方程式の解となります。

元の式で生成されるイデアルとグレブナ基底で生成されるイデアルが同じとなるわけです。

>    sys2:={g[1]=0,g[2]=0};

sys2 := {x+y-1 = 0, 2*y^2-2*y-1 = 0}

 一方の方程式にはyだけ表れますので、yに関して解けます。これを解きもう一方の方程式に代入すれば解が求められます。

>    solve(sys2,{x,y});

{y = RootOf(2*_Z^2-2*_Z-1,label = _L3), x = -RootOf(2*_Z^2-2*_Z-1,label = _L3)+1}

最初にsolveで解いたように、Mapleでは内部的にグレブナ基底を使っていますので、Groebnerパッケージを使わなくてもsolveを使えば自動的に方程式は解かれます。

他の例をやってみましょう。

>    sys:={x^3+y^3-2,x+y-1};

sys := {x+y-1, x^3+y^3-2}

>    gbasis(sys,plex(x,y));

[-1+3*y^2-3*y, x+y-1]

>    solve(%[1]=0,y);

1/2+1/6*21^(1/2), 1/2-1/6*21^(1/2)

これでyが解けますのでこれを2番目の式に代入してxが求められます。もちろんMapleでは最初からsolveを使えば解は得られます。

>    solve(sys,{x,y});

{x = -RootOf(-1+3*_Z^2-3*_Z,label = _L5)+1, y = RootOf(-1+3*_Z^2-3*_Z,label = _L5)}

 もう一つの例を取り上げましょう。

>    sys:={x^2+y-3,x*y+y^2-1};

sys := {x^2+y-3, x*y+y^2-1}

>    gbasis(sys,plex(x,y));

[-5*y^2+1+y^3+y^4, y^2-4*y+x+y^3]

>    solve(sys,{x,y});

{x = RootOf(-_Z^3+3*_Z+_Z^4-6*_Z^2+8,label = _L7), y = -RootOf(-_Z^3+3*_Z+_Z^4-6*_Z^2+8,label = _L7)^2+3}

次は3変数の場合です。

>    sys:={x^2-2*x*z+5,x*y^2+y*z^3,3*y^2-8*z^3};

sys := {x^2-2*x*z+5, y^2*x+y*z^3, 3*y^2-8*z^3}

>    solve(sys,{x,y,z});

{y = 0, z = 0, x = RootOf(_Z^2+5,label = _L9)}, {x = -3/20*RootOf(-48*_Z^5+9*_Z^6+30*_Z^3+25,label = _L10)^2*(3*RootOf(-48*_Z^5+9*_Z^6+30*_Z^3+25,label = _L10)^3+5-16*RootOf(-48*_Z^5+9*_Z^6+30*_Z^3+25,...
{y = 0, z = 0, x = RootOf(_Z^2+5,label = _L9)}, {x = -3/20*RootOf(-48*_Z^5+9*_Z^6+30*_Z^3+25,label = _L10)^2*(3*RootOf(-48*_Z^5+9*_Z^6+30*_Z^3+25,label = _L10)^3+5-16*RootOf(-48*_Z^5+9*_Z^6+30*_Z^3+25,...
{y = 0, z = 0, x = RootOf(_Z^2+5,label = _L9)}, {x = -3/20*RootOf(-48*_Z^5+9*_Z^6+30*_Z^3+25,label = _L10)^2*(3*RootOf(-48*_Z^5+9*_Z^6+30*_Z^3+25,label = _L10)^3+5-16*RootOf(-48*_Z^5+9*_Z^6+30*_Z^3+25,...
{y = 0, z = 0, x = RootOf(_Z^2+5,label = _L9)}, {x = -3/20*RootOf(-48*_Z^5+9*_Z^6+30*_Z^3+25,label = _L10)^2*(3*RootOf(-48*_Z^5+9*_Z^6+30*_Z^3+25,label = _L10)^3+5-16*RootOf(-48*_Z^5+9*_Z^6+30*_Z^3+25,...
{y = 0, z = 0, x = RootOf(_Z^2+5,label = _L9)}, {x = -3/20*RootOf(-48*_Z^5+9*_Z^6+30*_Z^3+25,label = _L10)^2*(3*RootOf(-48*_Z^5+9*_Z^6+30*_Z^3+25,label = _L10)^3+5-16*RootOf(-48*_Z^5+9*_Z^6+30*_Z^3+25,...

>    gbasis(sys,plex(y,x,z));

[240*z^6+1600*z^3+9*z^9-96*z^8, 640*x*z^3+9*z^8+120*z^5-96*z^7, x^2-2*x*z+5, 80*y*z^3-3*z^8+32*z^7-40*z^5, 3*y^2-8*z^3]

>    solve(%[1]=0,z);

0, 0, 0, 2*RootOf(-48*_Z^5+9*_Z^6+30*_Z^3+25,index = 1), 2*RootOf(-48*_Z^5+9*_Z^6+30*_Z^3+25,index = 2), 2*RootOf(-48*_Z^5+9*_Z^6+30*_Z^3+25,index = 3), 2*RootOf(-48*_Z^5+9*_Z^6+30*_Z^3+25,index = 4), ...
0, 0, 0, 2*RootOf(-48*_Z^5+9*_Z^6+30*_Z^3+25,index = 1), 2*RootOf(-48*_Z^5+9*_Z^6+30*_Z^3+25,index = 2), 2*RootOf(-48*_Z^5+9*_Z^6+30*_Z^3+25,index = 3), 2*RootOf(-48*_Z^5+9*_Z^6+30*_Z^3+25,index = 4), ...
0, 0, 0, 2*RootOf(-48*_Z^5+9*_Z^6+30*_Z^3+25,index = 1), 2*RootOf(-48*_Z^5+9*_Z^6+30*_Z^3+25,index = 2), 2*RootOf(-48*_Z^5+9*_Z^6+30*_Z^3+25,index = 3), 2*RootOf(-48*_Z^5+9*_Z^6+30*_Z^3+25,index = 4), ...

他の変数が含まれている場合も同様です。

>    sys:={x^2+y^2-1,x+y-a};

sys := {x^2+y^2-1, x+y-a}

>    gbasis(sys,plex(x,y));

[2*y^2-1-2*y*a+a^2, x+y-a]

>    solve(sys,{x,y});

{y = RootOf(2*_Z^2-1-2*_Z*a+a^2), x = -RootOf(2*_Z^2-1-2*_Z*a+a^2)+a}

グレブナ基底の基礎

ここではグレブナ基底の基礎的なことについて紹介します。以下のような関係式の系が与えられています。

>    siderels := {x^3*y*z = x*z^2, x*y^2*z = x*y*z, x^2*y^2 = z^2};

siderels := {x^3*y*z = x*z^2, x^2*y^2 = z^2, x*y^2*z = x*y*z}

このときに次の多項式について考えましょう。

>    p := x*z^4 - x*y*z^3;

p := z^4*x-y*x*z^3

問題:   与えられた関係式 siderels  に関して多項式 p を標準形式に変換しなさい。

これは Maple でつぎのように行えます。

>    simplify(p, siderels);

0

すなわち0となってしまいます。とても想像ができないと思いますし、式の変形を試してみればその難しさが解ります。どのようにして式を簡潔にしますか?

数学的な枠組みは以下のようなものです。もとの多項式のドメイン   Q [ x, y, z ] に関してこのドメインにベクトル空間的な基底を指定することができます。選択できる単項式(monomials)の順序付けには様々なものがあります。 しばらくの間、順序付けはトータル次数( total degree ordering) で同じ次数では特定の辞書式順序を使用する以下のようなものに対応する基底を考えます。

>    tdegBasis := [1,z,y,x,z^2,y*z,x*z,y^2,x*y,x^2,z^3,y*z^2,x*z^2,y^2*z,x*y*z,x^2*z,y^3,x*y^2,x^2*y,x^3,z^4,` . . . `];

tdegBasis := [1, z, y, x, z^2, y*z, x*z, y^2, x*y, x^2, z^3, y*z^2, x*z^2, y^2*z, x*y*z, x^2*z, y^3, y^2*x, x^2*y, x^3, z^4, ` . . . `]

ドメイン Q [ x, y, z ](x、y、zを使った有理数の係数を持つ多項式全体)の与えられた式 p に対し、関係式 siderels  に関して p を簡潔にすることが必要であるとします。  数学的には、商環(quotient ring)   Q [ x, y, z ] / Id   の要素として標準形で p を表したいということです。商環では二つの式がある場合、式の差が関係式で割り切れる(正確にはイデアルに含まれる)ものは同じとみなします。ここで Id   は関係式で生成されるイデアルです。

[g1, g2, ..., g[m]]  が基底のとき二つの式h、kに対して多項式 a1, a2 ・・・ a[m] が存在して

h - k = a1g1 + a2g2 + ... + amgm

と書けるときhとkは同値です。g1,g2・・・ g[m] が0であれば h=k となるわけです。

 上で指定された関係式 siderels   に値して対応するイデアルはつぎのように表現します。

     Id   =  < x^3*y*z-x*z^2, x*y^2*z-x*y*z, x^2*y^2-z^2  >  

このイデアル要素はこれらの式で割れるので結果的に0(ゼロ)になるわけです。

目的:   商環   Q [ x, y, z ] / Id   の基底を定義し任意の特定の多項式 p  をその基底の項で表現するためのアルゴリズムを指定することです。

上で指定されたドメイン   Q [ x, y, z ] に対する基底 tdegBasis  は明らかに商環に対する基底ではありません。単項式は商環においてはすべて独立ではありません。

例えば、   x^2*y^2 = z^2  

質問:   商環の基底を得るためには、 どの単項式が tdegBasis   から消去されるべきか?

この質問に答えるために以下のように進めます。

ステップ 1:   イデアル Id に対するグレブナ基底を計算する。   

ステップ 2:     Q [ x, y, z ] / Id   の要素として、低い次元の単項式に既約(指定された単項式の順序に関して)(例として   x^2*y^2   は   z^2  に既約)できるかどうかを決定するためにIdに対するグレブナ基底に関して各単項式   1, z, y, x, z^2, y*z, ` . . . `  を調べる。   

注意:  上の概念はここでは少しあいまいです。また、ここでやろうとしていることは、実際に、簡約化したい多項式 p をステップ2で示した既約化を各特定の項に適用することだということを注意すべきです。

グレブナ基底に関するいくつかの注意

グレブナ基底で使われている基底という言葉はベクトル空間や多項式における基底の概念ではありません。特に基底の中の要素はベクトル空間の基底の意味での線形独立にはなりません。  むしろ、イデアルの生成子の集合の概念であるイデアルの基底の概念です。 実際イデアル Id   =  <   x^3*y*z-x*z^2, x*y^2*z-x*y*z, x^2*y^2-z^2  >  に対して対応するグレブナ基底は、もともと Id   の定義に指定された3個よりも多い要素(すなわちより多い生成子)を持ちます。 Mapleを使って、以下の例のように、 イデアル Id   に対するグレブナ基底 Gb  を決定することができます。

(イデアルは、Maple のリストで生成子を指定することで表現されることに注意してください。上で使用したアングル・ブラケット(<>)は共通の数学的記法ですが、Mapleではアングル・ブラケットは別の目的で使用されます。)

Example

>    with(Groebner):

>    Id := [x^3*y*z - x*z^2, x*y^2*z - x*y*z, x^2*y^2 - z^2];

Id := [x^3*y*z-x*z^2, x*y^2*z-x*y*z, x^2*y^2-z^2]

>    nops(Id);

3

順序付け (term ordering) をトータル次数 (tdeg) にします。

>    TermOrder := tdeg(x,y,z);

TermOrder := tdeg(x,y,z)

>    Gb := gbasis(Id, TermOrder);

Gb := [-z^3+y*z^3, -x*z^2+x*z^3, x*y*z^2-x*z^2, x^2*z^2-z^4, x*y^2*z-x*y*z, x^2*y*z-z^3, x^2*y^2-z^2, z^5-z^4]

>    nops(Gb);

8

イデアル Id   のもともとの指定では3つの生成子ですがグレブナ基底 Gb  は8個の生成子を持っていることに注意してください。

しかしながら異なる生成子の集合で同じイデアルが定義されています。

  Ideal(Id) = Ideal(Gb)  

いま、上で指定した多項式 p に対して行うべきことはグレブナ基底 Gb に関して多項式 pを簡約化することです。

Groebner パッケージの関数 normalf は、与えられた多項式を特定の指定したイデアルに関して標準形に規約化します

>    p;

z^4*x-y*x*z^3

>    normalf(p, Gb, TermOrder);

0

もし、もともとの Id の生成子Idがイデアルの指定に使われると、normalf 関数は p をイデアルの法 (modulo) において 0 (ゼロ) に規約化できません。

>    normalf(p, Id, TermOrder);

z^4*x-y*x*z^3

応用例

問題:次のような関係式が与えられています。

a+b+c = 3

a^2+b^2+c^2 = 9

a^3+b^3+c^3 = 24

この条件下で

a^4+b^4+c^4

はいくらになりますか?

まず次のように式を多項式に変換します。

>    P:=a+b+c-3;Q:=a^2+b^2+c^2-9;S:=a^3+b^3+c^3-24;

P := a+b+c-3

Q := a^2+b^2+c^2-9

S := a^3+b^3+c^3-24

a,b,cの値は3っの多項式が消去されるようになっています。

この多項式の集合で生成されるすべての多項式(イデアル)もこれらの値により消去されます。
このグレブナ基底を計算します。

>    GBasis:=gbasis({P,Q,S},plex(a,b,c));

GBasis := [c^3+1-3*c^2, b^2+c^2+b*c-3*b-3*c, a+b+c-3]

次にこれらの基底の項でこの項を表現します。すなわち多項式の割り算でのあまりを計算します。

次が求められます。

>    normalf(a^4+b^4+c^4,GBasis,plex(a,b,c));

69

すなわち   a^4+b^4+c^4  は64になります。

同じ計算をsimplifyコマンドで行うことができます。

ここで GBasis をsimplifyの条件式として指定します。

>    simplify(a^4+b^4+c^4,GBasis);

69

このようにsimplifyにもグレブナ基底が使われます。数式の簡約にはグレブナ基底が威力を発揮します。ちなみに条件の方程式を解くと次のようになります。

>    solve({P,Q,S},{a,b,c});

{c = RootOf(_Z^3+1-3*_Z^2), b = 2+2*RootOf(_Z^3+1-3*_Z^2)-RootOf(_Z^3+1-3*_Z^2)^2, a = 1-3*RootOf(_Z^3+1-3*_Z^2)+RootOf(_Z^3+1-3*_Z^2)^2}, {c = RootOf(_Z^3+1-3*_Z^2), a = 2+2*RootOf(_Z^3+1-3*_Z^2)-Root...
{c = RootOf(_Z^3+1-3*_Z^2), b = 2+2*RootOf(_Z^3+1-3*_Z^2)-RootOf(_Z^3+1-3*_Z^2)^2, a = 1-3*RootOf(_Z^3+1-3*_Z^2)+RootOf(_Z^3+1-3*_Z^2)^2}, {c = RootOf(_Z^3+1-3*_Z^2), a = 2+2*RootOf(_Z^3+1-3*_Z^2)-Root...
{c = RootOf(_Z^3+1-3*_Z^2), b = 2+2*RootOf(_Z^3+1-3*_Z^2)-RootOf(_Z^3+1-3*_Z^2)^2, a = 1-3*RootOf(_Z^3+1-3*_Z^2)+RootOf(_Z^3+1-3*_Z^2)^2}, {c = RootOf(_Z^3+1-3*_Z^2), a = 2+2*RootOf(_Z^3+1-3*_Z^2)-Root...

項順序 (Term Orderings)

Groebnerパッケージには二つのタイプの項の順序付け(term orderings)が許されます。:

有効な消去と一般的な目的のために行列で定義された項順序のために特別な順序付けが必要です。Groebner パッケージは両方 (lexdeg and matrix types) の順序付けと、より実際的な重み付け順序のための mdeg を用意しています。またユーザ定義順序付けも可能です

例: この例は lexdeg  を使うことにより plex  を使うよりも速く実行される計算の例です。次の最大値を計算するとします。

>    phi:=x^3+2*x*y*z-z^2;

phi := x^3+2*x*y*z-z^2

ただし条件として球面上とします。すなわち次の拘束条件のもとに最適化します。

>    const:=x^2+y^2+z^2-1;

const := x^2+y^2+z^2-1

ラグランジェの方法により次の計算をします。t はいわゆる未定定数 (Lagrange multiplier) です。

>    G:={seq(diff(phi,v)-diff(const,v)*t,v=[x,y,z]),const};

G := {2*x*z-2*y*t, 2*x*y-2*z-2*z*t, 3*x^2+2*y*z-2*x*t, x^2+y^2+z^2-1}

適切な項順序 (term order) を使用して t を消去します。

>    GB:=gbasis(G,lexdeg([t],[x,y,z]));

GB := [x^2+y^2+z^2-1, 17*y*z^2+17*x*z-13*z^3-x*y+13*z, 17*y^2*z+7*z^3-6*x*y-7*z, 17*y^3+11*z^3-7*x*y-17*x*z-17*y-11*z, -x*z^2+y^2*x-y*z, 48*z^4-34*x*z^2-34*y*z-48*z^2-63*x*y*z, 408*x*z^3+233*z^3+65*x*y...
GB := [x^2+y^2+z^2-1, 17*y*z^2+17*x*z-13*z^3-x*y+13*z, 17*y^2*z+7*z^3-6*x*y-7*z, 17*y^3+11*z^3-7*x*y-17*x*z-17*y-11*z, -x*z^2+y^2*x-y*z, 48*z^4-34*x*z^2-34*y*z-48*z^2-63*x*y*z, 408*x*z^3+233*z^3+65*x*y...
GB := [x^2+y^2+z^2-1, 17*y*z^2+17*x*z-13*z^3-x*y+13*z, 17*y^2*z+7*z^3-6*x*y-7*z, 17*y^3+11*z^3-7*x*y-17*x*z-17*y-11*z, -x*z^2+y^2*x-y*z, 48*z^4-34*x*z^2-34*y*z-48*z^2-63*x*y*z, 408*x*z^3+233*z^3+65*x*y...

t を持つ項を取り除きます。

>    remove(has,GB,t);

[x^2+y^2+z^2-1, 17*y*z^2+17*x*z-13*z^3-x*y+13*z, 17*y^2*z+7*z^3-6*x*y-7*z, 17*y^3+11*z^3-7*x*y-17*x*z-17*y-11*z, -x*z^2+y^2*x-y*z, 48*z^4-34*x*z^2-34*y*z-48*z^2-63*x*y*z, 408*x*z^3+233*z^3+65*x*y-408*x...
[x^2+y^2+z^2-1, 17*y*z^2+17*x*z-13*z^3-x*y+13*z, 17*y^2*z+7*z^3-6*x*y-7*z, 17*y^3+11*z^3-7*x*y-17*x*z-17*y-11*z, -x*z^2+y^2*x-y*z, 48*z^4-34*x*z^2-34*y*z-48*z^2-63*x*y*z, 408*x*z^3+233*z^3+65*x*y-408*x...

一般的には、数値的な評価をして phi  に代入しなければいけません。さらに進んで、xとyの消去によりzに対するすべての可能性のある値を計算します。

>    GB2:=gbasis(%,lexdeg([x,y],[z]));

GB2 := [1152*z^7-1763*z^5+655*z^3-44*z, 118*y*z^3-118*y*z-1152*z^6+1605*z^4-453*z^2, 3835*x*z+3835*y*z^2-1152*z^5-1404*z^3+2556*z, 3835*y^2*z-6912*z^5+10751*z^3-3839*z, 3835*x*y-19584*z^5+25987*z^3-640...
GB2 := [1152*z^7-1763*z^5+655*z^3-44*z, 118*y*z^3-118*y*z-1152*z^6+1605*z^4-453*z^2, 3835*x*z+3835*y*z^2-1152*z^5-1404*z^3+2556*z, 3835*y^2*z-6912*z^5+10751*z^3-3839*z, 3835*x*y-19584*z^5+25987*z^3-640...
GB2 := [1152*z^7-1763*z^5+655*z^3-44*z, 118*y*z^3-118*y*z-1152*z^6+1605*z^4-453*z^2, 3835*x*z+3835*y*z^2-1152*z^5-1404*z^3+2556*z, 3835*y^2*z-6912*z^5+10751*z^3-3839*z, 3835*x*y-19584*z^5+25987*z^3-640...

>    op(remove(has,GB2,{x,y}));

1152*z^7-1763*z^5+655*z^3-44*z

>    sol_z:=solve(%,z);

sol_z := 0, -1, 1, 2/3, -2/3, 1/16*22^(1/2), -1/16*22^(1/2)

系に代入することにより最適になる可能性のある x, y, z の値の組み合わせ (tuples) が見付かります。

>    map(op,[seq(map(`union`,[solve(convert(subs(z=i,GB2),set),{x,y})],{z=i}),i=sol_z)]);

[{x = 1, z = 0, y = 0}, {z = 0, y = 0, x = -1}, {z = 0, x = 0, y = 1}, {z = 0, x = 0, y = -1}, {z = -1, y = 0, x = 0}, {z = 1, y = 0, x = 0}, {y = 1/3, z = 2/3, x = -2/3}, {z = -2/3, y = -1/3, x = -2/3...
[{x = 1, z = 0, y = 0}, {z = 0, y = 0, x = -1}, {z = 0, x = 0, y = 1}, {z = 0, x = 0, y = -1}, {z = -1, y = 0, x = 0}, {z = 1, y = 0, x = 0}, {y = 1/3, z = 2/3, x = -2/3}, {z = -2/3, y = -1/3, x = -2/3...

そして最大値と最小値がみつかります。

>    min(op(map(subs,%,phi))),max(op(map(subs,%,phi)));

-28/27, 1

plex を使った同じ計算だと数時間かかってしまいます。

標準的基底に対する Groebner パッケージのもう一つの例です。

plex_min の項順序を使って多項式の頭の項を最大項の変わりに最小項として定義します。

>    L:=1+x+y+z+x^2+y^2+z^2;

L := 1+x+y+z+x^2+y^2+z^2

>    leadterm(L,plex(x,y,z));

x^2

>    leadterm(L,plex_min(x,y,z));

1

斉次 (homogeneous) イデアルに対してグレブナ基底が計算されます。これは Q*[x, y, z, w]  の例です。

>    G:=[y*w^2-z^3,x*w^3-z^4];

G := [y*w^2-z^3, x*w^3-z^4]

通常のグレブナ基底と比較します。

>    gbasis(G,plex(w,x,y,z));

[-y^3*z^5+x^2*z^6, -x*z^6+y^2*w*z^4, w*x*z^3-y*z^4, y*w^2-z^3, x*w^3-z^4]

これにより降順の冪での割り算ができます。

>    reduce(w^5*x^3*y^2*z,%,plex(w,x,y,z));

y^4*z^7

そして標準基底は

>    gbasis(G,plex_min(w,x,y,z));

[-y*w^2+z^3, z*y*w^2-x*w^3, -y^2*w^4+z^2*x*w^3, -w^4*x^2*z+y^3*w^4]

これは昇順の割り算ができます。

>    reduce(w^5*x^3*y^2*z,%,plex_min(w,x,y,z));

w^6*x^4*y

このように異なる式に簡約できます。