Location : Home > Languages > Perl > Package
Title : Math::Polynomial::Solve
Toolbox Logo

名称

 Math::Polynomial::Solve - 多項方程式の解の探索


概要

use Math::Complex;  # 解は複素数かもしれない
use Math::Polynomial::Solve qw(poly_roots);

my @x = poly_roots(@coefficients);

または

use Math::Complex;  # 解は複素数かもしれない
use Math::Polynomial::Solve qw(poly_roots get_hessenberg set_hessenberg);

# マトリックスメソッドを利用
set_hessenberg(1);
my @x = poly_roots(@coefficients);

または

use Math::Complex;  # 解は複素数かもしれない
use Math::Polynomial::Solve
   qw(linear_roots quadratic_roots cubic_roots quartic_roots);

# ax + b の解を探索
my @x1 = linear_roots($a, $b);

# ax**2 + bx +c の解を探索
my @x2 = quadratic_roots($a, $b, $c);

# ax**3 + bx**2 +cx + d の解を探索
my @x3 = cubic_roots($a, $b, $c, $d);

# ax**4 + bx**3 +cx**2 + dx + e の解を探索
my @x4 = quartic_roots($a, $b, $c, $d, $e);

説明

 本パッケージは多項方程式の解の探索を行う関数の集合を提供する。4次までの方程式は直接解析的に解くことができるが、5次以上の方程式は 解の公式がなく、繰り返し法で解く。
 linear, quadratic, cubic, quartic *_roots() 関数は $a 項が0でないことを想定している。
 全ての関数について、定数項が0であれば常に解の最初の値として0を返す。

set_hessenberg()

 方程式の次数にかかわらずヘッセンベルク行列(Hessenberg matrix)を使って条件を設定または解除する。引数が0でなければ条件を設定し、0であれば解除する。

get_hessenberg()

 ヘッセンベルク行列が使用中か否かよって 1 または 0 を返す。

poly_roots()

 方程式の次数に従い解探索の関数を呼び出すか、ヘッセンベルク行列を用いて方程式を解く。set_hessenberg(1) を呼び出すことで次数にかかわらず行列法で解くこともできる。さもなければ次数にしたがってそれぞれの解の公式を用いて解くことになる。
 他の解探索関数と異なり、最高次数の係数が0でないかを確認し、適切なケースに当てはまるまで次数を下げてくる。また最低次数の係数が0であるかを確認し、0であればまず解のリストに0を加えてから解の探索関数を呼び出す。このようにして、特殊な条件に出くわさない限り、できるだけ行列法を用いないで解の探索を行おうとする。

linear_roots()

 他の関数との整合性のためにだけ存在する。

ax + b = 0

に対し -b/a を返す。スカラコンテキストでも配列コンテキストでもよい。

quadratic_roots()

 2次方程式の解を返す。

ax**2 + bx + c = 0

に対しよく知られた解の公式を用いて解く。2要素のリストを返す。

cubic_roots()

 3次方程式の解を返す。

ax**3 + bx**2 + cx + d = 0

 R. W. D. Nickalls の方法を用いる(下記、謝辞セクションを見よ)。3要素のリストを返す。最初の要素は常に実数である。次の2つの解は、ともに実数であるかともに複素数であるかである。

quartic_roots()

 4次方程式の解を返す。

ax**4 + bx**3 + cx**2 + dx + e = 0

 Ferrari の公式を用いる(下記、謝辞セクションを見よ)。3要素のリストを返す。最初の2つの要素はともに実数であるかともに複素数であるかである。次の要素はタイプによる。

EXPORT

 デフォルトでは何もエクスポートしない。関数はエクスポートリストで命名される。


謝辞

3次方程式

 3次方程式は R. W. D. Nickalls, の著した "A New Approach to solving the cubic: Cardan's solution revealed," The Mathematical Gazette, 77, 354-359, 1993. に記述された方法で解いている。この論文は http://www.2dcurves.com/cubic/http://www.m-a.org.uk/resources/periodicals/online_articles_keyword_index/ を含むいくつかのサイトで入手できる。http://www.sosmath.com/algebra/factor/fac111/fac111.html ではこの論文に関するよい議論がなされている。
 Nickalls 博士は親切にも私に注釈や改定つきで論文を送ってくれ、ベルギーのルーベン大学工学部の Herman Bruyninckx によってこの論文に基づき書かれた Matlab スクリプトを送ってもらうようにしてくれた。この関数は Matlabスクリプトの変換であり、最初に作成した Herman Bruyninckx に感謝する。
 Dick Nickalls, dicknickalls@compuserve.com
 Herman Bruyninckx, Herman.Bruyninckx@mech.kuleuven.ac.be はウェブページ http://www.mech.kuleuven.ac.be/~bruyninc を持っており、Matlab 3次のソルバは http://people.mech.kuleuven.ac.be/~bruyninc/matlab/cubic.m にある。

4次方程式

 Karl's Calculus Tutor のページ http://www.karlscalculus.org/quartic.html に記されているフェラーリの解の公式を用いている。
 Ask Dr. Math FAQ, http://forum.swarthmore.edu/dr.math/faq/faq.cubic.equations.html に書かれているショートカットを利用している。
 

5次以上の方程式

  Back when 本モジュールは1次から4次までの多項式のみを解くことができるが、Math::Polynomial の著者である Matz Kindahl は poly_roots() 関数を示唆した。後に、GNU Scientific Library に Perl をバインディングした Nick Ing-Simmons は村上寛の QR ヘッセンベルクアルゴリズムのフォートラン実装を Perl に変換したものを送った。これは poly_roots() 関数によく適合したこれで5次以上の方程式でも数値解析的に解くことができる。
 村上寛のフォートランのルーチンは http://netlib.bell-labs.com/netlib/search.html で "companion" と検索すれば見つかる。
 村上は以下の論文を参照している。

 とっかかりとしては以下を読むとよいだろう。


参考資料

 Forsythe, George E., Michael A. Malcolm, and Cleve B. Moler (1977), Computer Methods for Mathematical Computations, Prentice-Hall.


著者

 John M. Gamble, <jgamble@ripco.com>


【訳注と解説】

  1. 上記文章で「方程式」と訳した言葉の原語はほとんど polynomial である。直訳はもちろん「多項式」なんだけれども、数学的に言えば、多項式は単に「項が多い式(=単項式でない式)」であって、その「解」なんてものは存在しない。「多項式=0」という形状の式があって、これを満たす項の値を求めることが「解を求める」ということであり、そういう式のことは普通「方程式」と言うので、そう訳すことにした。
Toolbox Logo
Updated : 2006/10/09