第6回 ベクトル・複素数の演算(2)


本日の課題

実際の計算には上記の全てがあると便利だが,今回の実習ではフーリエ変換に必要な複素数の

  1. 実数2つを,複素数に変換
  2. 四則演算(和,差,積,商)
  3. 共役
  4. 絶対値,偏角
  5. 指数関数

を求める関数をつくろう.
特に,指数関数に使われるオイラーの式は制御工学や伝熱工学,電磁気学などにおいて頻繁に現れる.

複素数計算関数群が出来たら,以下のような動作確認用のmain 関数を作り,作成した各関数を呼び出して,計算が正しく行われるか確認せよ.

関数を含めたソースファイルを提出せよ.ファイル名は 153R000000-06-1.cpp とする.000000の部分は学生番号.

動作確認が済んだら,main 関数以外は別ファイル(ヘッダファイル complex.h および 実装ファイル complex.cpp)にすると良い.
後半のヒントを参照すること.
分割ができたら,全てのソースファイルを提出せよ. ファイル名は 153R000000-06-1.cpp, complex.h, complex.cpp とする.Makefile も作成したら,あわせて提出.


#include <stdio.h>
#include <math.h>
#include "complex.h"   /* 分割コンパイルを行う場合 */

/* 複素数型構造体の定義 */
/* ヘッダファイルに書くと良い. */
struct Complex
{
    double re;
    double im;
};

/* ここに関数を記述.確認ができたら別ファイル(.h および .cpp)に実装すると良い. */


int main()
{
    Complex z1 = {1.0, -1.0};
    Complex z2 = {-3.0, 2.0};
    Complex z3;
    /*  int ???;         */  /*  必要に応じて */
    /*  double ???;      */  /*  必要に応じて */

    /*
    このようにキーボード入力させるのも良い.

    printf("z1を入力:");
    z1 = Cinp();
    
    printf("z2を入力:");
    z2 = Cinp();
    */

    /* いろいろ計算 */
    z3 = Cadd(z1, z2);
    
    /* 表示関数を使って,結果を確認 */
    Cdisp(z3);

    return 0;
}



ヒント:ヘッダファイル,実装ファイルの例

一般的には,汎用性のある関数群は別ファイル(ヘッダファイルおよび実装ファイル)に分割する.
例えば

  1. 複素数の「構造体定義」および,複素数の演算関数一式の「宣言」が記載されているヘッダファイル(例えば complex.h)
  2. 複素数の演算関数一式の「実際の処理」を記述した実装ファイル(例えば complex.cpp)
  3. それらを利用するmain関数の入ったソースファイル(例えば153R000000-06-main.cpp)

の3つのファイルを生成し,コンパイルは

z:¥.windows2000> bcc32 153R000000-06-main.cpp complex.cpp

などとする.ファイル名は各自の学生番号に応じて適宜変更すること.
さらに可能であれば,Makefileを使用して自動化すると良い.(必須では無いが,できると効率Up!)

ヘッダファイル complex.h の例


struct Complex
{
    double re;
    double im;
};

Complex ToComplex(double x, double y);    /* 実数2つから複素数を生成 */

void Cdisp(Complex z);                    /* 複素数を画面に表示 */
Complex Cinp(void);                       /* キーボードから実部,虚部を入力して複素数を返す */

Complex Cadd(Complex a, Complex b);       /* 複素数 a, b の和を返す */
Complex Csub(Complex a, Complex b);       /* 差 */
Complex Cmul(Complex a, Complex b);       /* 積 */
Complex Cdiv(Complex a, Complex b);       /* 商 */

Complex Conj(Complex z);                  /* 共役な複素数を返す */

double Cabs(Complex z);                   /* 絶対値 */
double Carg(Complex z);                   /* 偏角 */

Complex Cexp(Complex z);                /* 指数関数 */

実装ファイル complex.cpp の例


#include <stdio.h>
#include <math.h>
#include "complex.h"   /* ファイル名は各自で変更 */

Complex ToComplex(double x, double y)   //  実数x,yから複素数を作り,戻り値として返す関数
{
    Complex z;

    z.re = x;
    z.im = y;
    return z;
}

void Cdisp(Complex z)   //  実部と虚部を画面に表示
{
    //  ここに処理を記述
}

Complex Cinp(void)      // キーボードから実部,虚部を入力して返す
{
    //  ここに処理を記述
}


Complex Cadd(Complex a, Complex b)      //      複素数の和の例.
{
    Complex z;

    z.re = a.re + b.re;
    z.im = a.im + b.im;
    return z;
}

Complex Csub(Complex a, Complex b)
{
    //  ここに処理を記述
}

Complex Cmul(Complex a, Complex b)
{
    //  ここに処理を記述
}

Complex Cdiv(Complex a, Complex b)
{
    //  ここに処理を記述
}


Complex Conj(Complex z)
{
    //  ここに処理を記述
}



double Cabs(Complex z)
{
    //  ここに処理を記述
}
    
double Carg(Complex z)
{
    //  ここに処理を記述.関数はatan2を使うと良い
}

Complex Cexp(Complex z)   // 指数関数
{
    //  ここに処理を記述
}