2011 / 11 / 25

都沒注意到這篇人氣已到 2500,筆者於另一份 blog 有發二篇較為詳細之文章,

有興趣之網友可參考。

[C語言數值分析] 複數運算 - 推導與程式碼

[C語言數值分析] 複數運算 - 完整程式碼參考

請將換 ie 以外瀏覽器 (如 FireFox),用 IE 開 IE 會當。


 

這個程式主要包含複數的下列運算,
至於公式怎麼來的不知道..
請翻翻課本吧 ...

1. 四則運算 - 簡單的加減乘除
    (1) 乘法 -> c = a * b, 
         c.real = a.real * b. real - a.img * b.img
         c.img  = a.img * b.real  + a.real * b.img

     (2) 除法  -> c = a/b,
          c = product(a, b) / (b.real^2 + b.img^2)
 
2. pow 幕次運算
    c = a^n,  其中 n 為整數
    令 A = sqrt(a.real^2 + a.img^2), sita = arctan(a.img/a.real),
    c.real = A^n * cos(n*sita)
    c.img  = A^n * sin(n*sita)


3. pow(1/n) n次方根運算
    c = a^(1/n) , 其中 n 為整數
    令 A = sqrt(a.real^2 + a.img^2), sita = arctan(a.img/a.real),
    c.real = A^(1/n) * cos( (2k*PI + sita)/n ), 
    c.img = A^(1/n) * sin( (2k*PI + sita)/n ),
    k = 0, 1, 2, ....., n-1

4. exp 指數運算
    c = exp(a)
    c.real = exp(a.real) * cos(a.real)
    c.img = exp(a.real) * sin(a.img)

5. ln 對數運算
    c = ln(a)
    令 A = sqrt(a.real^2 + a.img^2), sita = arctan(a.img/a.real), 
   c.real = ln(A),
   c.img  = sita

6. sin 正弦運算
   c = sin(a)
   c.real = 0.5 * sin(a.real) * ( exp(a.img) + exp(-a.img) )
   c.img  = 0.5 * cos(a.real) * ( exp(a.img) - exp(-a.img) )

7. cos 餘弦運算
   c = cos(a)
   c.real = 0.5 * cos(a.real) * ( exp(a.img) + exp(-a.img) )
   c.img  = 0.5 * sin(a.real) * ( exp(a.img) - exp(-a.img) )

以下程式碼參考, 有問題請回覆 blog 進行討論

// ====================================
// Filename: ecomplex.h
// Author  : Edison.Shih.
// mail    : crowyao@hotmail.com
// Date    : 2010.3.18
// ====================================

#ifndef __ECOMPLEX__
#define __ECOMPLEX__


// ===================================
#ifndef PI
#define PI (double)(3.14159265358979323846264338327950288419716939937510)
#endif

typedef struct{
      double real;
      double img;
}ecomplex;

// ===================================
// 四則運算

int complex_add(ecomplex a,
                        ecomplex b,
                        ecomplex *result);


int complex_sub(ecomplex a,
                        ecomplex b,
                        ecomplex *result);

int complex_mul(ecomplex a,
                        ecomplex b,
                        ecomplex *result);

int complex_div(ecomplex a,
                        ecomplex b,
                        ecomplex *result);

////////////////////////////////////////////////////////////
// ===================================
// 指對數問題

/*===================================
// 函數名稱:complex_pow
// 功能描述:求複數乘冪
// 參數說明:a(底數)
//           n(指數)
//           c(計算結果)
// 返回值: 0(失敗), 1(成功)
=================================== */
int complex_pow(ecomplex a,
                        int n,
                        ecomplex *c);

/*===================================
// 函數名稱:complex_nroot
// 功能描述:求複數 n 次方根
// 參數說明:a(已知數)
//           n(n次方根)
//           c(計算結果)
// 返回值: 0(失敗), 1(成功)
=================================== */
int complex_nroot(ecomplex a,
                          int n,
                          ecomplex *c);

/*===================================
// 函數名稱:complex_exp
// 功能描述:求複數指數
// 參數說明:a(已知數)
//           c(計算結果), c=exp^a
// 返回值: 0(失敗), 1(成功)
=================================== */
int complex_exp(ecomplex a,
                        ecomplex *c);

/*===================================
// 函數名稱:complex_ln
// 功能描述:求複數對數
// 參數說明:a(已知數)
//           c(計算結果), c=ln(a)
// 返回值: 0(失敗), 1(成功)
=================================== */
int complex_ln(ecomplex a,
                     ecomplex *c);

/*===================================
// 函數名稱:complex_sin
// 功能描述:求複數正弦
// 參數說明:a(輸入角度)
//           c(計算結果), c=sin(a)
// 返回值: 0(失敗), 1(成功)
=================================== */
int complex_sin(ecomplex a,
                        ecomplex *c);

/*===================================
// 函數名稱:complex_cos
// 功能描述:求複數餘弦
// 參數說明:a(輸入角度)
//           c(計算結果), c=cos(a)
// 返回值: 0(失敗), 1(成功)
=================================== */
// c = cos(a)
int complex_cos(ecomplex a,
                        ecomplex *c);

#endif

// ====================================
// Filename: ecomplex.cpp
// Author  : Edison.Shih.
// mail    : crowyao@hotmail.com
// Date    : 2010.3.18
// ====================================

#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include "ecomplex.h"

/*===================================
// 函數名稱:complex_add
// 功能描述:複數相加
// 返回值: 0(失敗), 1(成功)
=================================== */
int complex_add(ecomplex a,
                        ecomplex b,
                        ecomplex *result)
{
      if(result==NULL) return 0;

      result->img = a.img + b.img;
      result->real = a.real + b.real;
      return 1;
}

/*===================================
// 函數名稱:complex_sub
// 功能描述:複數相加
// 返回值: 0(失敗), 1(成功)
=================================== */
int complex_sub(ecomplex a,
                        ecomplex b,
                        ecomplex *result)
{
      if(result==NULL) return 0;
      result->img = a.img + b.img;
      result->real = a.real + b.real;
      return 1;
}

/*===================================
// 函數名稱:complex_mul
// 功能描述:複數相乘
// 返回值: 0(失敗), 1(成功)
=================================== */
int complex_mul(ecomplex a,
                        ecomplex b,
                        ecomplex *result)
{
      if(result==NULL) return 0;
      result->real = a.real * b.real - a.img * b.img;
      result->img  = a.img * b.real + a.real * b.img;
      return 1;
}

/*===================================
// 函數名稱:complex_div
// 功能描述:複數相除, a/b
// 返回值: 0(失敗), 1(成功)
=================================== */
int complex_div(ecomplex a,
                        ecomplex b,
                        ecomplex *result)
{
      if(result==NULL) return 0;
      double p = b.real*b.real + b.img*b.img;
      complex_mul(a, b, result);
      result->real = result->real / p;
      result->img  = result->img  / p;
      return 1;
}

////////////////////////////////////////////////////////////
// ===================================
// 指對數問題

/*===================================
// 函數名稱:complex_pow
// 功能描述:求複數乘冪
// 參數說明:a(底數)
//           n(指數)
//           c(計算結果)
// 返回值: 0(失敗), 1(成功)
=================================== */
int complex_pow(ecomplex a,
                        int n,
                        ecomplex *c)
{
      if(c==NULL) return 0;
      double An = pow(sqrt(a.real*a.real + a.img*a.img), n);
      double nsita = (double)n * atan(a.img/a.real);
      c->real = An * cos(nsita);
      c->img  = An * sin(nsita);
      return 1;
}

/*===================================
// 函數名稱:complex_nroot
// 功能描述:求複數 n 次方根
// 參數說明:a(已知數)
//           n(n次方根)
//           c(計算結果)
// 返回值: 0(失敗), 1(成功)
=================================== */
int complex_nroot(ecomplex a,
                          int n,
                          ecomplex *c)
{
      if(c==NULL) return 0;     
      double An1 = pow( sqrt(a.real* a.real + a.img* a.img), 1.0/n);
      double sita = atan(a.img / a.real);
      double nsita = 0.0;
      for(int i=0; i<n; i++){
            c[i].real = An1 * cos( (2.0*i*PI + sita)/(double)(n));
            c[i].img  = An1 * sin( (2.0*i*PI + sita)/(double)(n));
      }
      return 1;
}

/*===================================
// 函數名稱:complex_exp
// 功能描述:求複數指數
// 參數說明:a(已知數)
//           c(計算結果), c=exp^a
// 返回值: 0(失敗), 1(成功)
=================================== */
int complex_exp(ecomplex a,
                        ecomplex *c)
{
      if(c==NULL) return 0;
      double A = exp(a.real);
      c->real = A * cos(a.img);
      c->img  = A * sin(a.img);
      return 1;
}

/*===================================
// 函數名稱:complex_ln
// 功能描述:求複數對數
// 參數說明:a(已知數)
//           c(計算結果), c=ln(a)
// 返回值: 0(失敗), 1(成功)
=================================== */
int complex_ln(ecomplex a,
                     ecomplex *c)
{
      if(c==NULL) return 0;
      c->real = log( sqrt(a.real*a.real + a.img * a.img) );
      c->img  = atan(a.img / a.real);
      return 1;
}

/*===================================
// 函數名稱:complex_sin
// 功能描述:求複數對數
// 參數說明:a(輸入角度)
//           c(計算結果), c=sin(a)
// 返回值: 0(失敗), 1(成功)
=================================== */
int complex_sin(ecomplex a,
                        ecomplex *c)
{
      if(c==NULL) return 0;
      c->real = sin(a.real) * (exp(a.img) + exp(-a.img)) * 0.5;
      c->img  = cos(a.real) * (exp(a.img) - exp(-a.img)) * 0.5;
      return 1;
}

/*===================================
// 函數名稱:complex_cos
// 功能描述:求複數對數
// 參數說明:a(輸入角度)
//           c(計算結果), c=cos(a)
// 返回值: 0(失敗), 1(成功)
=================================== */
// c = cos(a)
int complex_cos(ecomplex a,
                        ecomplex *c)
{
      if(c==NULL) return 0;
      c->real = cos(a.real) * (exp(a.img) + exp(-a.img)) * 0.5;
      c->img  = sin(a.real) * (exp(a.img) - exp(-a.img)) * 0.5;
      return 1;
}

arrow
arrow
    全站熱搜

    Edison 發表在 痞客邦 留言(1) 人氣()