C言語で学ぶ大学の数学 「Laurent多項式の乗法」

この記事では、Laurent多項式の乗法をC言語で実行する方法を、前々回紹介した方法 A と方法 B それぞれの場合に説明します。

また前回の記事で計算結果を表示する方法に触れていなかったので、それについても説明します。



1.方法 Aで定義した1変数Laurent多項式の乗法


まずはLaurent多項式を方法Aで定義した場合の乗法を説明します。

例として


a(x) = x^(-3) - x^(-1) + 2 + x

b(x) = x^(-2) + x^(-1)


に対し、c(x)= a(x)b(x)を計算します。

まずは方法 A のやり方で次数を格納します。


int deg_a = 1;

int ldeg_a = 3;

int deg_b = 0;

int ldeg_b = 2;


そして係数を格納します。


float a[] = {1, 0, -1, 2, 1};

float b[] = {1, 1, 0};


次に c(x) の次数を考えます。手計算で c(x) = x^(-5) + … + 1 であると分かるので、deg_c = 0, ldeg_c = 5 としたいところですが、一般的な状況を考えて


int deg_c = deg_a + deg_b;

int ldeg_c = ldeg_a + ldeg_b;


とします。今の場合は deg_c = 1, ldeg_c = 5 となってしまいますが、仕方ありません。


float c[deg_c + ldeg_c + 1];


ここから乗法を計算します。

愚直に考えれば、「c(x) の n 次の項」は「a(x) の i 次の項」と「 b(x) の j 次の項」の組み合わせで計算できます。

しかしこれは「c[n + ldeg_c]」を「a[i + ldeg_a]」と「b[j + ldeg_b]」を使って計算することになります。

この方針でも計算できますが、条件が少しややこしいのでやめておきます。


ではどうするかというと、「正規化」した a(x) と b(x) の積を計算して「正規化」した c(x) を求めます。

これは「c[n]」を「a[i]」と「b[j]」を使って計算することになるので、以前紹介した通常の多項式の積を計算する方法がほぼそのまま使えます。

違ってくるのは、元々「deg_c」としていた箇所を「deg_c + ldeg_c」などと置き換えることです。


for(n=0; n<=deg_c + ldeg_c; n++){

 c[n] = 0;

 for(i=0; i<=deg_a + ldeg_a; i++){

  if(n-i>=0 && n-i<=deg_b + ldeg_b) c[n] += a[i]*b[n-i];

 }

}


次数のずれを気にすることなく計算できるので、加法より簡単に思えます。


計算結果を表示するには


for(n=-ldeg_c; n<=deg_c; n++){

 printf("%fx^%d + ", c[n + ldeg_c], n);

}


とするか


for(n=0; n<=deg_c + ldeg_c; n++){

 printf("%fx^%d + ", c[n], n -ldeg_c);

}


とします。



2.方法 Bで定義した1変数Laurent多項式の乗法


では、Laurent多項式を方法Bで定義した場合の乗法を説明します。

例として先程と同じ


a(x) = x^(-3) - x^(-1) + 2 + x

b(x) = x^(-2) + x^(-1)


を扱います。

まずは次数を格納します。


int deg_a = 1;

int ldeg_a = -3;

int deg_b = -1;

int ldeg_b = -2;


そして係数を格納します。


float a[] = {1, 0, -1, 2, 1};

float b[] = {1, 1};


次に c(x) の次数を考えます。方法 B でも方法 A と同じように一般に


int deg_c = deg_a + deg_b;

int ldeg_c = ldeg_a + ldeg_b;


と定めます。方法 B は次数を直接代入しているので、a(x) と b(x) のどちらかが 0 でない限りは deg_c = deg_a + deg_b, ldeg_c = ldeg_a + ldeg_b が成り立ちます。つまり無駄がありません。


float c[deg_c - ldeg_c + 1];


積の計算は方法 Aと同じように正規化した多項式の積を直接計算します。

ただし「ldeg_c」が「-ldeg_c」などに置き換わることに注意します。


for(n=0; n<=deg_c - ldeg_c; n++){

 c[n] = 0;

 for(i=0; i<=deg_a - ldeg_a; i++){

  if(n-i>=0 && n-i<=deg_b - ldeg_b) c[n] += a[i]*b[n-i];

 }

}


計算結果を表示するときも、符号に注意します。


for(n=ldeg_c; n<=deg_c; n++){

 printf("%fx^%d + ", c[n - ldeg_c], n);

}


とするか


for(n=0; n<=deg_c - ldeg_c; n++){

 printf("%fx^%d + ", c[n], n +ldeg_c);

}


とします。

  • Twitterで共有
  • Facebookで共有
  • はてなブックマークでブックマーク

作者を応援しよう!

ハートをクリックで、簡単に応援の気持ちを伝えられます。(ログインが必要です)

応援したユーザー

応援すると応援コメントも書けます

新規登録で充実の読書を

マイページ
読書の状況から作品を自動で分類して簡単に管理できる
小説の未読話数がひと目でわかり前回の続きから読める
フォローしたユーザーの活動を追える
通知
小説の更新や作者の新作の情報を受け取れる
閲覧履歴
以前読んだ小説が一覧で見つけやすい
新規ユーザー登録無料

アカウントをお持ちの方はログイン

カクヨムで可能な読書体験をくわしく知る