C言語で複素数を扱った行列計算を行う場合、実部と虚部を管理するための構造体を作成し、複素数同士の掛け算や行列演算を自分で実装する必要があります。この記事では、複素数2×2行列とベクトルの積を計算するプログラムを例に、コードの構造や処理の流れ、注意すべきポイントについて分かりやすく解説します。
C言語で複素数を扱う基本的な考え方
C言語には標準で複素数型が用意されていますが、学習用や独自処理を行う場合は構造体を使って複素数を表現する方法がよく利用されます。
今回のプログラムでは、以下のような構造体を定義しています。
typedef struct { double re; double im; } Complex;
reには実部(real)、imには虚部(imaginary)を保存します。例えば複素数3+2jの場合、reには3.0、imには2.0を格納します。
このように実部と虚部を別々の変数として管理すると、行列計算や信号処理などの数学的な処理をC言語で実装しやすくなります。
複素数の掛け算処理の仕組み
複素数同士の掛け算は、通常の数値計算とは少し異なります。
2つの複素数(a+bi)(c+di)の積は以下の式になります。
(ac-bd)+(ad+bc)i
プログラム内では、この計算を以下の部分で行っています。
real = H[i][j].re * B[j].re - H[i][j].im * B[j].im;
imag = H[i][j].re * B[j].im + H[i][j].im * B[j].re;
realが結果の実部、imagが結果の虚部になります。この計算を行列の各要素について繰り返すことで、複素数行列の積を求めています。
行列HとベクトルBの積を求める処理
このプログラムでは、2×2の複素数行列Hと2要素の複素数ベクトルBを掛け合わせ、結果Cを求めています。
一般的な行列計算では、以下のような式になります。
C[i] = H[i][0] × B[0] + H[i][1] × B[1]
プログラムでは二重for文を使って、この計算を自動化しています。
for(i = 0; i < 2; i++) { for(j = 0; j < 2; j++) { ... } }
外側のループで結果ベクトルCの行を指定し、内側のループで行列Hの各列との積を計算しています。
例えば2行目の結果を求める場合、H[1][0]とB[0]の積、H[1][1]とB[1]の積を加算してC[1]を求めます。
テキストファイルから複素数データを読み込む方法
このプログラムでは、複素数行列とベクトルの値をファイルから読み込んでいます。
fopen関数でファイルを開き、fgets関数で1行ずつ読み込みます。
fp = fopen("hw1101-data.txt", "r");
読み込んだ文字列はstrtok関数で空白ごとに分割し、sscanf関数で複素数へ変換しています。
sscanf(column,"%lf%lfj",&H[row][0].re,&H[row][0].im);
例えばファイル内に以下のような記述がある場合、
1.0+2.0j 3.0+4.0j
5.0+6.0j 7.0+8.0j
1.0+1.0j
2.0+2.0j
最初の2行が行列H、後半2行がベクトルBとして読み込まれます。
プログラム作成時に注意したいポイント
複素数計算プログラムでは、入力形式とデータ読み込み処理の一致が重要です。
例えばsscanfで「%lf%lfj」という形式を使用する場合、入力データが実部と虚部を正しく分離できる形式になっている必要があります。入力ファイルの表記が異なる場合、正常に値を取得できない可能性があります。
また、ファイル読み込み時にはNULLチェックを行い、ファイルが存在しない場合に異常終了しないようにすることも重要です。
if(fp == NULL) { printf("ファイルを開けません。\n"); return 1; }
このようなエラー処理を入れることで、原因不明の動作を防ぐことができます。
計算結果の表示方法
最後にprintf関数を使って計算結果を表示します。
printf("C[%d] = %.1f%+.1fj\n", i, C[i].re, C[i].im);
%+.1fを使うことで、虚部の符号を含めて表示できます。
例えば結果が実部2.0、虚部-3.0の場合は、以下のように表示されます。
C[0] = 2.0-3.0j
この表示形式は数学で一般的な複素数表記に近いため、計算結果を確認しやすくなります。
まとめ
C言語で複素数行列計算を行うには、複素数を構造体で表現し、実部と虚部を分けて計算する方法が基本になります。
今回のような行列とベクトルの積では、複素数の掛け算処理と行列計算の仕組みを組み合わせることで実装できます。
また、ファイル入力を利用する場合はデータ形式を正しく設計し、エラー処理を入れることで安定したプログラムになります。複素数計算は通信処理や画像処理、信号解析など幅広い分野で利用されるため、基本的な仕組みを理解しておくと応用にも役立ちます。

コメント