倭算数理研究所

科学・数学・学習関連の記事を、「倭マン日記」とは別に書いていくのだ!

spire で多項式 Polynomial を使ってみる (3) : 代数としてのメソッド

spire を使ってみるシリーズ(目次)。 今回は Polynomial 型に定義されている代数としてのメソッドを見ていきます。 多項式ユークリッド環をなすので、加減乗法と余りのある除算が定義されています。

この記事中のサンプルコードでは以下の import 文が書かれているものとします:

import spire.math._
import spire.implicits._

符号

マイナス符号 (unary_-) は加法に関する逆元を返します。 まぁ、単に全ての係数の符号を変えた多項式ですけど。

  val p = Polynomial("x^3 + 2x^2 + 3")

  // -, unary_-
  assert( -p == Polynomial("-x^3 - 2x^2 - 3") )

加減乗法

多項式は環 (Ring) をなすので、和・差・積が定義されています。 計算方法は、説明の必要はないでしょう:

  val p1 = Polynomial("x^3 + 2x^2 + 3")
  val p2 = Polynomial("4x^2 + 5")

  // 加算 +
  assert( p1 + p2 == Polynomial("x^3 + 6x^2 + 8") )

  // 減算 -
  assert( p1 - p2 == Polynomial("x^3 - 2x^2 - 2") )

  // 乗法 *
  assert( p1 * p2 == Polynomial("4x^5 + 8x^4 + 5x^3 + 22x^2 + 15") )
  assert( (p1 * p2).degree == p1.degree + p2.degree )
    // 多項式の積では、次数はそれぞれの次数の和になります。

  // 自然数冪 **, pow() メソッド
  assert( p2**2 == Polynomial("16x^4 + 40x^2 + 25") )
  assert( (p2**2).degree == p2.degree * 2 )

積が計算できるので、自然数冪も計算できます。 この冪は係数の型に依らず Int 値で指定します。

除法

多項式ユークリッド環をなすので、余りのある除法も定義されています。 spire ではこの除法による商を(Scala での「/」ではなく)「/~」で計算します。 余り(剰余)は Scala と同じく「%」で計算します。 商と余りを同時に得たい場合は「/%」を使います。 結果はタプルで返されます:

  val p1 = Polynomial("x^3 + 2x^2 + 3")
  val p2 = Polynomial("4x^2 + 5")

  // 商 /~
  assert( p1 /~ p2 == Polynomial("1/4x + 1/2") )
  assert( (p1 /~ p2).degree == p1.degree - p2.degree )

  // 剰余 %
  assert( p1 % p2 == Polynomial("-5/4x + 1/2") )
  assert( (p1 % p2).degree < p2.degree)

  // (商, 剰余) /%
  assert( p1 /% p2 == (p1 /~ p2, p1 % p2) )  // 結果はタプル
  assert( p1 == p2 * (p1 /~ p2) + (p1 % p2) )
    // (割られる多項式) = (割る多項式) × (商) + (剰余)

上記の商や剰余の結果を見ると分かるように、元の多項式の係数が整数でも商や剰余の多項式の係数は分数になりうるので、これらの演算は係数の型が体 (Field) でなければ計算できません。 そうでなければコンパイルエラーが出ます。

定数倍

単なる定数も多項式なので多項式の定数倍は多項式の積として計算できますが、定数倍を簡単に行えるメソッドが定義されています。 定数倍にはレシーバとなる Polynomial オブジェクトを左に置くか右に置くかで「:*」「*:」の2つがあります。 コロン (:) がある側に Polynomial オブジェクトを置きます。 定数分の1(定数で割る)には多項式を左に置く「:/」のみがあります:

  val p = Polynomial("x^3 + 2x^2 + 3")

  // 定数倍 その1 :*
  assert( p :* 2 == Polynomial("2x^3 + 4x^2 + 6") )

  // 定数倍 その2 *:
  assert( 2 *: p == Polynomial("2x^3 + 4x^2 + 6") )

  // 定数分の1 :/
  assert( p :/ 2 == Polynomial("1/2x^3 + x^2 + 3/2") )

これらの演算子(メソッド)は spire で VectorSpace として扱える型全てに使えます。

今回見てきたメソッドは、多項式の計算としてはなんてことないものばかりですが、コードとして書くのも大したことありませんね。 余りのある除算の /~ や 定数倍の *: など、少し Scala コードと違うところがありますが、これらは spire の中では統一して使われているので慣れてしまえば便利です。

次回は Polynomial 型に定義されている残りのメソッド、主に係数をコレクションのように扱うメソッド群を見ていきます。

Scalaスケーラブルプログラミング第3版

Scalaスケーラブルプログラミング第3版