基本的な環#

行列やベクトル,あるいは多項式を定義する際,定義の土台となる「環」を指定することが有利に働くだけではなく,不可欠ですらある場合がある. (ring)とは,和と積が質よくふるまうことが保証されている数学的構造物のことだ. これまで聞いたことがなかったとしても,以下にあげる四つの広く使われている環についてだけは知っておくべきだろう:

  • 整数 \(\{..., -1, 0, 1, 2, ...\}\), Sageでは ZZ で呼ぶ.

  • 有理数 -- つまり整数による分数あるいは比 -- QQ で呼ぶ.

  • 実数, RR で呼ぶ.

  • 複素数, CC で呼ぶ.

これらの環の違いについて意識しておきたいのは,例えば同じ多項式であってもそれがどの環の上で定義されるかによって異なった扱いがなされることがあるからだ. 具体例をあげると,多項式 \(x^2-2\) は二つの根 \(\pm \sqrt{2}\) を持つ. 両方とも有理数ではないから,もし有理係数の多項式として扱うのならばこの多項式は因数分解できない. しかし,実係数の多項式として扱うのなら分解可能だ. とすれば,求める情報を確実に得られる環を指定しておきたくなるのも当然だろう. 以下の二つのコマンドは,有理係数と実係数の多項式の集合を定義する. 集合はそれぞれ ratpolyrealpoly と命名されているが,大切なのはその名前ではない. むしろ注意すべきは,各々の集合で使われる 変数名 を定義しているのが文字列 .<t>.<z> であることである.

sage: ratpoly.<t> = PolynomialRing(QQ)
sage: realpoly.<z> = PolynomialRing(RR)
>>> from sage.all import *
>>> ratpoly = PolynomialRing(QQ, names=('t',)); (t,) = ratpoly._first_ngens(1)
>>> realpoly = PolynomialRing(RR, names=('z',)); (z,) = realpoly._first_ngens(1)

ここで \(x^2-2\) の因数分解の様子を見てみよう:

sage: factor(t^2-2)
t^2 - 2
sage: factor(z^2-2)
(z - 1.41421356237310) * (z + 1.41421356237310)
>>> from sage.all import *
>>> factor(t**Integer(2)-Integer(2))
t^2 - 2
>>> factor(z**Integer(2)-Integer(2))
(z - 1.41421356237310) * (z + 1.41421356237310)

以上と同様の注意点は,行列に対しても通用する. 既約行階段形式は元の行列がどんな環の上で定義されているかに依存するし,固有値と固有ベクトルも同様である. 多項式の構成法については 多項式 節に,行列に関しては 線形代数 節にもっと詳しい解説がある.

記号 I\(-1\) の平方根を表わし, iI と同義である. 言うまでもなく,これは有理数ではない.

sage: i  # -1の平方根
I
sage: i in QQ
False
>>> from sage.all import *
>>> i  # -1の平方根
I
>>> i in QQ
False

上のコードは,変数 i が反復制御に使われるなどして,違った値が割り当てられていたら予期した結果にならないことがある. そんな場合には,次のように入力すると元の虚数単位 i として復活する:

sage: reset('i')
>>> from sage.all import *
>>> reset('i')

複素数の定義には一つ微妙な点がある. すでに述べたように記号 i\(-1\) の平方根を表わすが,これはあくまでも代数的な数字で \(-1\)形式的 な平方根である. 一方, CC(i) または CC.0 を実行すると戻ってくるのは \(-1\)複素 平方根である. 異なる種類の数同士の演算は,いわゆる「型強制」(coercion)によって可能になる. これについては ペアレント,型変換および型強制 節を参照.

sage: i = CC(i)       # 複素浮動小数点数
sage: i == CC.0
True
sage: a, b = 4/3, 2/3
sage: z = a + b*i
sage: z
1.33333333333333 + 0.666666666666667*I
sage: z.imag()        # 虚部
0.666666666666667
sage: z.real() == a   # 比較の前に自動的に型変換される
True
sage: a + b
2
sage: 2*b == a
True
sage: parent(2/3)
Rational Field
sage: parent(4/2)
Rational Field
sage: 2/3 + 0.1       # 加算の前に自動型変換
0.766666666666667
sage: 0.1 + 2/3       # Sageの型変換規則は対称的である
0.766666666666667
>>> from sage.all import *
>>> i = CC(i)       # 複素浮動小数点数
>>> i == CC.gen(0)
True
>>> a, b = Integer(4)/Integer(3), Integer(2)/Integer(3)
>>> z = a + b*i
>>> z
1.33333333333333 + 0.666666666666667*I
>>> z.imag()        # 虚部
0.666666666666667
>>> z.real() == a   # 比較の前に自動的に型変換される
True
>>> a + b
2
>>> Integer(2)*b == a
True
>>> parent(Integer(2)/Integer(3))
Rational Field
>>> parent(Integer(4)/Integer(2))
Rational Field
>>> Integer(2)/Integer(3) + RealNumber('0.1')       # 加算の前に自動型変換
0.766666666666667
>>> RealNumber('0.1') + Integer(2)/Integer(3)       # Sageの型変換規則は対称的である
0.766666666666667

もう少しSageで基本となる環の実例をあげておこう. 先に示したように,有理数の環は QQ あるいは RationalField() で参照することができる(体(field) とは積演算が可換で,非零元が常に逆元をもつ環のことである. したがって有理数は体を構成するが整数は体にならない).

sage: RationalField()
Rational Field
sage: QQ
Rational Field
sage: 1/2 in QQ
True
>>> from sage.all import *
>>> RationalField()
Rational Field
>>> QQ
Rational Field
>>> Integer(1)/Integer(2) in QQ
True

有理数でもある小数は有理数に「型強制」することができるから, 例えば小数 1.2QQ に属すると見なされる( ペアレント,型変換および型強制 節を参照). しかし, \(\pi\)\(\sqrt{2}\) は有理数にはならない:

sage: 1.2 in QQ
True
sage: pi in QQ
False
sage: pi in RR
True
sage: sqrt(2) in QQ
False
sage: sqrt(2) in CC
True
>>> from sage.all import *
>>> RealNumber('1.2') in QQ
True
>>> pi in QQ
False
>>> pi in RR
True
>>> sqrt(Integer(2)) in QQ
False
>>> sqrt(Integer(2)) in CC
True

より高度な数学で利用するため,Sageには有限体,p-進整数,代数環,多項式環,そして行列環などが用意されている. 以下ではその中のいくつかを構成してみよう.

sage: GF(3)
Finite Field of size 3
sage: GF(27, 'a')  # 素数体でなければ生成元の命名が必要
Finite Field in a of size 3^3
sage: Zp(5)
5-adic Ring with capped relative precision 20
sage: sqrt(3) in QQbar # QQの代数的閉包(拡大)
True
>>> from sage.all import *
>>> GF(Integer(3))
Finite Field of size 3
>>> GF(Integer(27), 'a')  # 素数体でなければ生成元の命名が必要
Finite Field in a of size 3^3
>>> Zp(Integer(5))
5-adic Ring with capped relative precision 20
>>> sqrt(Integer(3)) in QQbar # QQの代数的閉包(拡大)
True