見出し画像

高校数学をプログラミングで解く(数学II編)「1-1 複素数」


はじめに

今回は、数学IIで学ぶ「複素数」について、2つの複素数の四則演算を行う関数を作成し、それを用いて複素数の計算を行うプログラムを作成します。

複素数

まず、複素数について解説しておきます。

$${a, b, c, d}$$は実数とし、$${i^2=-1}$$とします。

定義 $${a+bi}$$ $${b=0}$$のとき実数、$${b \neq 0}$$のとき虚数。
相等 $${a+bi = c+di \Leftrightarrow a=c, b=d }$$ 特に$${a+bi = 0 \Leftrightarrow a=0, b=0}$$
四則演算
和:$${(a+bi)+(c+di) = (a+c)+(b+d)i}$$
差:$${(a+bi)-(c+di) = (a-c)+(b-d)i}$$
積:$${(a+bi) \cdot (c+di) = (ac-bd)+(ad+bc)i}$$
商:$${(a+bi) / (c+di) = \frac{ac+bd}{c^2+d^2}+\frac{-ad+bc}{c^2+d^2}i}$$
負の数の平方根 $${a>0}$$のとき、$${-a}$$の平方根は$${\sqrt{a}i}$$と$${-\sqrt{a}i}$$

複素数の四則演算を行うプログラム

今回は、2つの複素数$${c_1 = 3+4i}$$と$${c_2 = 1+2i}$$との四則演算を行うプログラムを作成します。

課題:複素数を扱う変数をどうするか?

複素数を扱うプログラムを作成したいのですが、プログラミング言語「Processing」では、残念ながら複素数を扱うための変数などは準備されていません。そこで、今回は複素数を扱う変数としてPVectorクラスを利用することにしました。つまり、複素数$${c=a+bi}$$を

PVector c = new PVector(a,b); 

として利用することにします。

アルゴリズム設計

2つの複素数の四則演算は上記で説明した式を用いると、比較的簡単に計算することができます。今回は、これらの2つの複素数の四則演算(和、差、積、商)をそれぞれ関数化して利用することにします。

プログラム

では、2つの複素数の四則演算を行うプログラムを作成します。

// 複素数の計算
void setup(){
  
  // c1 = 3 + 4i
  PVector c1 = new PVector(3.0, 4.0);
  // c2 = 1 + 2i
  PVector c2 = new PVector(1.0, 2.0);
  
  // 複素数の和 c1 + c2
  PVector sum = c_sum(c1, c2);
  println("和:"+ sum.x + "+" + sum.y + "i" );
 
  // 複素数の差 c1 - c2
  PVector sub = c_sub(c1, c2);
  println("差:"+ sub.x + "+" + sub.y + "i" );

  // 複素数の積 c1 * c2
  PVector prod = c_prod(c1, c2);
  println("積:"+ prod.x + "+" + prod.y + "i" );
  
  // 複素数の商 c1 / c2
  PVector div = c_div(c1, c2);
  println("商:"+ div.x + "+" + div.y + "i" );
}

// 2つの複素数の和を計算する関数
PVector c_sum(
  PVector c1,
  PVector c2
){
  PVector sum = c1.copy().add(c2);
  return sum;
}
  
// 2つの複素数の差を計算する関数
PVector c_sub(
  PVector c1,
  PVector c2
){
  PVector sub = c1.copy().sub(c2);
  return sub;
}
  
// 2つの複素数の積を計算する関数
PVector c_prod(
  PVector c1,
  PVector c2
){
  PVector prod = new PVector();
  prod.x = c1.x * c2.x - c1.y * c2.y;
  prod.y = c1.x * c2.y + c1.y * c2.x;
  return prod;
}

// 2つの複素数の商を計算する関数
PVector c_div(
  PVector c1,
  PVector c2
){
  PVector div = new PVector();
  div.x = (c1.x * c2.x + c1.y * c2.y)/(c2.x*c2.x+c2.y*c2.y);
  div.y = (-c1.x * c2.y + c1.y * c2.x)/(c2.x*c2.x+c2.y*c2.y);
  return div;
}

ソースコード1 2つの複素数の四則演算を行うプログラム

このソースコード1を、Processingの開発環境ウィンドウを開いて(スケッチ名を「complex_number」としています)、テキストエディタ部分に書いて実行すると、図1のように、

和:4.0+6.0i
差:2.0+2.0i
積:-5.0+10.0i
商:2.2+-0.4i

とコンソールに出力されます。

図1 スケッチ「complex_number」の実行結果

プログラムの解説

今回は2つの複素数の四則演算について、和、差、積、商のそれぞれに関数を準備しました。関数は4つ共に、引数として複素数を表すPVectorクラスの変数を2つ与え、そして返り値として演算結果の複素数を表すPVectorクラスの値を返すようにしました。

複素数の四則演算を利用するプログラム

今回は、複素数の四則演算を行う関数を用いて、次の問題を考えてみます。

問題
$${x=-2+3i}$$、$${y=-2-3i}$$のとき、次の式の値を求めよ。
(1) $${x^2+y^2}$$
(2) $${x^3+y^3}$$
(3) $${\frac{y}{x}+\frac{x}{y}}$$

問題の解法

この問題は次のように解析的に解くことが多いです。具体的には
$${x+y=-4, xy = 13}$$となるので、各問題の式を変形して
(1) $${x^2+y^2=(x+y)^2-2xy=(-4)^2-2\cdot13=-10}$$
(2) $${x^3+y^3=(x+y)^3-3xy(x+y)=(-4)^3-3\cdot13\cdot(-4)=92}$$
(3) $${\frac{y}{x}+\frac{x}{y}=\frac{x^2+y^2}{xy} = -\frac{10}{13} }$$
と解くことができます。

ただ、今回のプログラムはこのような解析的な方法ではなく、$${x}$$や$${y}$$の値を直接代入して計算する、少し泥臭い方法で作成していきます。

プログラム

では、複素数の四則演算を行う関数を用いて問題を解くプログラムを作成します。

// 複素数の計算2
void setup(){
  
  // x = -2 + 3i
  PVector x = new PVector(-2.0, 3.0);
  // y = -2 - 3i
  PVector y = new PVector(-2.0, -3.0);
  
  // a1 = x^2 + y^2
  PVector a1 = c_sum(c_prod(x,x), c_prod(y,y));
  println("(1)"+ a1.x + "+" + a1.y + "i" );
 
  // a2 = x^3 + y^3
  PVector a2 = c_sum(c_prod(c_prod(x,x),x), c_prod(c_prod(y,y),y));
  println("(2)"+ a2.x + "+" + a2.y + "i" );

  // a3 = y/x + x/y
  PVector a3 = c_sum(c_div(y,x), c_div(x,y));
  println("(3)"+ a3.x + "+" + a3.y + "i" );

}

// 2つの複素数の和を計算する関数
PVector c_sum(
  PVector c1,
  PVector c2
){
  PVector sum = c1.copy().add(c2);
  return sum;
}
  
// 2つの複素数の差を計算する関数
PVector c_sub(
  PVector c1,
  PVector c2
){
  PVector sub = c1.copy().sub(c2);
  return sub;
}
  
// 2つの複素数の積を計算する関数
PVector c_prod(
  PVector c1,
  PVector c2
){
  PVector prod = new PVector();
  prod.x = c1.x * c2.x - c1.y * c2.y;
  prod.y = c1.x * c2.y + c1.y * c2.x;
  return prod;
}

// 2つの複素数の商を計算する関数
PVector c_div(
  PVector c1,
  PVector c2
){
  PVector div = new PVector();
  div.x = (c1.x * c2.x + c1.y * c2.y)/(c2.x*c2.x+c2.y*c2.y);
  div.y = (-c1.x * c2.y + c1.y * c2.x)/(c2.x*c2.x+c2.y*c2.y);
  return div;
}

ソースコード2 複素数の四則演算を行う関数を用いたプログラム

このソースコード2を、Processingの開発環境ウィンドウを開いて(スケッチ名を「complex_number2」としています)、テキストエディタ部分に書いて実行すると、図2のように、

(1)-10.0+0.0i
(2)92.0+0.0i
(3)-0.7692308+0.0i

とコンソールに出力されます。

図2 スケッチ「complex_number2」の実行結果

なお、今回の問題の解は虚数部はすべて「0」になりますが、「0」であることを明示するために敢えて表示しました。

まとめ

今回は、数学IIで学ぶ「複素数」について、2つの複素数の四則演算を行う関数を作成し、それを用いて複素数の計算を行うプログラムを作成しました。

Processingには複素数を直接扱うような変数はありません。そのため、この記事では複素数をPVectorクラスで表すことにしました。そして、PVectorクラスの変数を利用して複素数の四則演算を行うための関数を準備しました。

複素数をプログラムで扱う方法は今回紹介した以外にもいろいろ考えることができます。特に、プログラミングをある程度経験している方は「複素数を扱うためのクラス」を自分で用意するのではないかと思います。クラスの作成についてはこの記事の範囲を越えるので割愛しますが、もし興味のある方は是非複素数を扱うクラスを作成してみてください。クラス作成については例えば、「Processingをはじめよう 第2版(オライリージャパン、ISBN9784873117737)」に解説されています。

参考文献

改訂版 教科書傍用 スタンダード 数学II(数研出版、ISBN9784410209369)

Processingをはじめよう 第2版(オライリージャパン、ISBN9784873117737)


この記事が気に入ったらサポートをしてみませんか?