[VBA] ユーザー定義型変数(構造体)による複素数の計算

 VBA には複数のデータ型を1つにまとめる ユーザー定義型 という変数を使うことができます (C言語における構造体と同じ概念です)。この記事では、このユーザー定義型変数によって複素数を処理する方法を解説します(以下のマクロは全て 数値計算用最新コード からまとめて素早くコピーできます)。

宣言セクションにユーザー定義型変数を記述します

 宣言セクション(モジュールの冒頭部分)に、Typeステートメントを用いて「複素数型変数」を定義しておきます。

 '複素数型変数の定義

 Type Complex
  re As Double
  im As Double
 End Type

 この記述によって、以降のマクロで Complex 型であると宣言された変数は、実部 (re) と虚部 (im) の2つの値をもつことになります。
 

複素数を定義します

 複素数 $z=a+bi$ を定義するマクロは次のようになります。

 '複素数の定義

 Function CPX(a As Double, b As Double) As Complex

 CPX.re = a
 CPX.im = b

 End Function

 極形式 $z=ae^{ix}=a(\cos x+i\sin x)$ で定義する場合は以下のように記述します。

 '極形式による複素数の定義

 Function CPX2(x As Double, Optional a As Double = 1) As Complex

 CPX2.re = a * Cos(x)
 CPX2.im = a * Sin(x)

 End Function

 以下に CPX関数と CPX2関数を呼びだして $2+3i$ と $2e^{3\pi i}$ を定義するマクロを載せておきます。

 '2 + 3i と 2exp(iπ/3) の定義

 Sub CPXtest()

 Dim z1 As Complex, z2 As Complex
 Dim p As Double

 p = 4 * Atn(1)

 'z = 2 + 3iを定義
 z1 = CPX(2, 3)

 'z = 2exp(iπ/3)を定義
 z2 = CPX2(p / 3, 2)

 '2 + 3i の実部と虚部を表示
 Debug.Print z1.re, z1.im

 '2exp(iπ/3) の実部と虚部を表示
 Debug.Print z2.re, z2.im

 End Sub

 マクロを実行するとイミディエイトウィンドウに $2+3i$ の実部と虚部「 2 3 」および、$2e^{3\pi i}$ の実部と虚部「 1 1.732 ... 」が表示されます。
 

共役複素数と絶対値(大きさ)

 $z=a+bi$ の共役複素数 (conjugate number) $\bar{z}=a-bi$ を返すマクロです。

 '共役複素数

 Function CJG(z As Complex) As Complex

 CJG.re = z.re
 CJG.im = -z.im

 End Function

 $z\bar{z}$ および $|z|=\sqrt{z\bar{z}}$(絶対値)を計算させるマクロは次のようになります。

 '複素数の絶対値

 Function CPXABS(z As Complex, _
 Optional s As Boolean = True) As Double

 CPXABS = z.re ^ 2 + z.im ^ 2

 If s = True Then
  CPXABS = Sqr(CPXABS)
 End If

 End Function

 CPXABS関数を呼びだすときには

CPXABS(z[,演算の種類])

のように記述します。[演算の種類] はオプション引数で、True あるいは 1 を指定する(または省略する)と絶対値を計算します。False あるいは 0 を指定すると平方根をとらずに $z\bar{z}$ の値を返します。CJG関数と CPXABS関数をテストしてみます。

 '共役複素数と絶対値の計算例

 Sub CJGABStest()
 Dim z1 As Complex
 Dim cjgz1 As Complex
 Dim absz1 As Double

 'z1 = 3 + 5i
 z1 = CPX(3, 5)

 'z1 の共役複素数
 cjgz1 = CJG(z1)

 'z1 の絶対値
 absz1 = CPXABS(z1)

 Debug.Print cjgz1.re, cjgz1.im
 Debug.Print absz1

 End Sub

 実行すると $3+5i$ の共役複素数 $3-5i$ の実部と虚部「 3, -5 」と絶対値「 5.83 ... 」が表示されます。

 ≫ [Amazon 数学書籍] 公理と証明(証明論への招待)
 ≫ [Amazon 数学書籍] 新版複素解析(基礎数学シリーズ)

複素数の演算

 複素数 $z_1=a+bi$ と $z_2=c+di$ の加減乗除を計算するマクロです。

 '複素数の演算

 Function CPXCLC(z1 As Complex, z2 As Complex, _
 Optional s As Integer = 1) As Complex

 Dim z As Complex
 Dim k As Double

 Select Case s

 Case 1
  z.re = z1.re + z2.re
  z.im = z1.im + z2.im

 Case 2
  z.re = z1.re - z2.re
  z.im = z1.im - z2.im

 Case 3
  z.re = z1.re * z2.re - z1.im * z2.im
  z.im = z1.re * z2.im + z1.im * z2.re

 Case Else

  k = z2.re ^ 2 + z2.im ^ 2

  z.re = (z1.re * z2.re + z1.im * z2.im) / k
  z.im = (z1.im * z2.re - z1.re * z2.im) / k

 End Select

 CPXCLC = z

 End Function

 CPXCLC関数を呼びだすときには

CPXCLC(z1,z2[,演算の種類])

と記述します。3 つめの引数である演算の種類は

1:加算 2:減算 3:乗算 その他の数値:除算

となっています。省略すると加算します。以下に使用例を載せておきます。

 '複素数の演算例

 Sub CLCtest()

 Dim z1 As Complex, z2 As Complex
 Dim zsum As Complex, zsub As Complex
 Dim zpdt As Complex, zdiv As Complex

 z1 = CPX(5, 3)
 z2 = CPX(2, 1)

 'z1 + z2
 zsum = CPXCLC(z1, z2)

 'z1 - z2
 zsub = CPXCLC(z1, z2, 2)

 'z1*z2
 zpdt = CPXCLC(z1, z2, 3)

 'z1/z2
 zdiv = CPXCLC(z1, z2, 4)

 Debug.Print zsum.re, zsum.im
 Debug.Print zsub.re, zsub.im
 Debug.Print zpdt.re, zpdt.im
 Debug.Print zdiv.re, zdiv.im

 End Sub

 マクロを実行すると $z_1=5+3i,\:z_2=2+i$ についての加減乗除を実行し、その実部と虚部を出力します。
 

複素数平面上の 2 点間の距離

 複素数 $z_1=a+bi$ と $z_2=c+di$ を複素数平面にプロットしたときの 2 点間の距離 $|z_1-z_2|=\sqrt{a^2+b^2}$ , あるいは距離の平方を計算するマクロです。

 '2 点間の距離

 Function CPXD(z1 As Complex, z2 As Complex, _
 Optional s As Boolean = True) As Double

 CPXD = (z1.re - z2.re) ^ 2 + (z1.im - z2.im) ^ 2

 If s = True Then

 CPXD = Sqr(CPXD)

 End If

 End Function

 CPXD 関数を使用するときは

CPXD(z1,z2[,演算の種類])

のように記述します。[演算の種類] はオプション引数で、True あるいは 1 を指定する(または省略する)と距離を計算します。False もしくは 0 を指定すると平方根をとらずに $|z_1-z_2|^2$ の値を返します。以下に CPXD関数の計算例を載せておきます。

 '複素数平面上の 2 点間距離の計算例

 Sub CPXDtest()

 Dim z1 As Complex
 Dim z2 As Complex
 Dim cpxdz1 As Double

 'z1 = 3 + 7i
 z1 = CPX(3, 7)

 'z2 = 1 + 2i
 z2 = CPX(1, 2)

 '|z1 - z2|
 cpxdz1 = CPXD(z1, z2)

 Debug.Print cpxdz1

 End Sub

 マクロを実行すると $z_1=3+7i$ と $z_2=1+2i$ の間の距離が計算されて「 5.385 ... 」という値が返ります。 ≫ VBA 数値計算の技術

スポンサーリンク
スポンサーリンク
末尾広告
末尾広告

コメントをどうぞ

メールアドレスが公開されることはありません。

このサイトはスパムを低減するために Akismet を使っています。コメントデータの処理方法の詳細はこちらをご覧ください