电竞比分网-中国电竞赛事及体育赛事平台

分享

從一維到二維,C 復(fù)數(shù)運(yùn)算總結(jié)

 菌心說(shuō) 2021-08-06

復(fù)數(shù)稱(chēng)Complex Number,從英文上來(lái)看似乎它是“復(fù)雜的數(shù)”。其實(shí)并不然,它實(shí)際上指的是復(fù)合數(shù),即由實(shí)部虛部復(fù)合而成的數(shù)。它可以用下面的公式表示:

從一維到二維,C++復(fù)數(shù)運(yùn)算總結(jié)

這里,純實(shí)數(shù)a是實(shí)部,ib是虛部,其中,a b都是實(shí)數(shù),i是虛數(shù)。

如果我們將實(shí)部作為x軸,虛部作為y軸,復(fù)數(shù)就可以在坐標(biāo)軸上表示了,這樣的坐標(biāo)系我們稱(chēng)作復(fù)數(shù)坐標(biāo)系。它和復(fù)平面上原點(diǎn)的連線(xiàn)可以表示一個(gè)向量,向量和x軸的夾角為復(fù)數(shù)的輻角theta。

從一維到二維,C++復(fù)數(shù)運(yùn)算總結(jié)

實(shí)數(shù)我們大家都很熟悉,在平時(shí)生活中,常用的也都是一些實(shí)數(shù)。那么,虛數(shù)是什么呢?

虛數(shù)并不是單純的數(shù)字,如果x^2=-1,我們就將它們的解定義為+/-i,這里的i就是虛數(shù),很顯然虛數(shù)似乎并不是我們平時(shí)所使用的數(shù),因?yàn)樵谖覀兯斫獾膶?shí)數(shù)領(lǐng)里任何一個(gè)數(shù)進(jìn)行平方之后都不可能是小于0的,但這并代表它沒(méi)有意義,我們可以換一個(gè)角度來(lái)理解虛數(shù),我們通過(guò)它可將實(shí)數(shù)擴(kuò)展到復(fù)數(shù)域。

要理解虛數(shù)我們就需要先復(fù)習(xí)一下之前學(xué)習(xí)的歐拉公式

如果,

則,

相信這里大家應(yīng)該有了發(fā)現(xiàn):

在復(fù)數(shù)域中,

復(fù)數(shù)與復(fù)指數(shù)相乘,相當(dāng)于復(fù)數(shù)對(duì)應(yīng)的向量旋轉(zhuǎn)對(duì)應(yīng)的角度。

這里就相當(dāng)于我們把1逆時(shí)針旋轉(zhuǎn)90度,就可以得到i,如果我們?cè)倌鏁r(shí)針旋轉(zhuǎn)90度就是-1,也就是i*i。

所以,大家也就明白了i的含義,以及為什么i的平方等于-1了。

從一維到二維,C++復(fù)數(shù)運(yùn)算總結(jié)

因此,虛數(shù)i的幾何意義上是一個(gè)旋轉(zhuǎn)量。

數(shù)學(xué)是一個(gè)偉大的工具,從實(shí)數(shù)到復(fù)數(shù)的擴(kuò)展是一個(gè)里程碑的進(jìn)步。數(shù)學(xué)家雅克·阿達(dá)馬說(shuō),在實(shí)數(shù)域中,連接兩個(gè)真理的最短的路徑是通過(guò)復(fù)數(shù)域。

從一維到二維,C++復(fù)數(shù)運(yùn)算總結(jié)

程序中如何定義復(fù)數(shù)?

在C++中,complex頭文件中定義了一個(gè)complex模板類(lèi)型,用來(lái)處理復(fù)數(shù)。格式如下:

template <class T> class complex;template<> class complex<float>; template<> class complex<double>;template<> class complex<long double>;

T是實(shí)部和虛部的數(shù)字的數(shù)據(jù)類(lèi)型,它可以支持floatdouble、long double這幾種類(lèi)型。

復(fù)數(shù)這個(gè)類(lèi)模板有多個(gè)構(gòu)造函數(shù):

complex( const T& re = T(), const T& im = T() );complex( const complex& other );template<class X > complex( const complex<X>& other);

從上面復(fù)數(shù)的構(gòu)造函數(shù)可以看出,我們可以用下面的幾種方法來(lái)定義一個(gè)復(fù)數(shù):

  • 根據(jù)實(shí)部和虛部的值來(lái)構(gòu)造一個(gè)復(fù)數(shù);
  • 根據(jù)一個(gè)復(fù)數(shù)的值來(lái)構(gòu)造一個(gè)復(fù)數(shù);
  • 從不同類(lèi)型的復(fù)數(shù)構(gòu)造一個(gè)復(fù)數(shù)。
#include <iostream>#include <complex>int main (){ std::complex<float> z1(1.2, 2.3); std::complex<float> z2(z1); std::complex<double> z3(z2); std::cout << z3 << '\n'; return 0;}

結(jié)果輸出:

(1.2,2.3)

復(fù)數(shù)的運(yùn)算

復(fù)數(shù)和實(shí)數(shù)一樣是可以進(jìn)行+ - × /等算術(shù)運(yùn)算的。假如有兩個(gè)復(fù)數(shù)z1z2,如下:

復(fù)數(shù)的加法是將兩個(gè)復(fù)數(shù)的實(shí)部和實(shí)部相加,虛部和虛部相加:

同樣的,復(fù)數(shù)的減法是將兩個(gè)復(fù)數(shù)的實(shí)部和實(shí)部相減,虛部和虛部相減:

復(fù)數(shù)的乘法呢?因?yàn)閺?fù)數(shù)也是滿(mǎn)足實(shí)數(shù)域的交換律、結(jié)合律以及分配律這些定理,因此,我們可以對(duì)乘法進(jìn)行分解。

除法就會(huì)復(fù)雜一些,我們需要考慮將分母的復(fù)數(shù)轉(zhuǎn)成實(shí)數(shù)。該怎么進(jìn)行轉(zhuǎn)換呢?在這之前,我們需要先了解共軛復(fù)數(shù),如果有兩個(gè)復(fù)數(shù)z2=c+diz3=c-di,他們實(shí)部相同,虛部互為相反數(shù),我們稱(chēng)它們互為共軛,z2是z3的共軛復(fù)數(shù),z3也是z2的共軛復(fù)數(shù)。

從一維到二維,C++復(fù)數(shù)運(yùn)算總結(jié)

共軛

共軛復(fù)數(shù)有這樣的一個(gè)特性,如果兩個(gè)共軛復(fù)數(shù)相乘,它們的結(jié)果是一個(gè)實(shí)數(shù)。

因此,我們可以利用共軛復(fù)數(shù)的這個(gè)特性進(jìn)行復(fù)數(shù)的除法運(yùn)算。

實(shí)際上,我們?cè)谑褂肅++寫(xiě)程序時(shí)不需要這么復(fù)雜的公式計(jì)算,complex類(lèi)實(shí)際上已經(jīng)進(jìn)行重載了這些操作。

complex& operator= (const T& val);template<class X> complex& operator= (const complex<X>& rhs);template<class T> complex<T> operator+(const complex<T>& lhs, const complex<T>& rhs);template<class T> complex<T> operator+(const complex<T>& lhs, const T& val);template<class T> complex<T> operator+(const T& val, const complex<T>& rhs);template<class T> complex<T> operator-(const complex<T>& lhs, const complex<T>& rhs);template<class T> complex<T> operator-(const complex<T>& lhs, const T& val);template<class T> complex<T> operator-(const T& val, const complex<T>& rhs);template<class T> complex<T> operator*(const complex<T>& lhs, const complex<T>& rhs);template<class T> complex<T> operator*(const complex<T>& lhs, const T& val);template<class T> complex<T> operator*(const T& val, const complex<T>& rhs);template<class T> complex<T> operator/(const complex<T>& lhs, const complex<T>& rhs);template<class T> complex<T> operator/(const complex<T>& lhs, const T& val);template<class T> complex<T> operator/(const T& val, const complex<T>& rhs);template<class T> complex<T> operator+(const complex<T>& rhs);template<class T> complex<T> operator-(const complex<T>& rhs);

complex頭文件中已經(jīng)包含了常見(jiàn)的運(yùn)算操作,我們通過(guò)下面的的例子來(lái)加深了解。

#include <iostream>#include <complex>int main (){  std::complex<double> z1(1, 2);  std::complex<double> z2 = std::complex<double>(3, 4);      std::cout << 'z1: ' << z1 << std::endl;  std::cout << 'z2: ' << z2 << std::endl;    std::cout << 'z1+z2: ' << z1+z2 << std::endl;  std::cout << 'z1-z2: ' << z1-z2 << std::endl;  std::cout << 'z1*z2: ' << z1*z2 << std::endl;  std::cout << 'z1/z2: ' << z1/z2 << std::endl;  std::cout << 'z1+2: ' <<z1 + 2.0<< std::endl;  return 0;}

上面的例子中,我們可以使用=直接對(duì)復(fù)數(shù)進(jìn)行賦值操作,還可以使用運(yùn)算符對(duì)復(fù)數(shù)進(jìn)行運(yùn)算,而且也支持實(shí)數(shù)和復(fù)數(shù)之間的運(yùn)算,其輸出結(jié)果如下:

z1: (1,2)z2: (3,4)z1+z2: (4,6)z1-z2: (-2,-2)z1*z2: (-5,10)z1/z2: (0.44,0.08)z1+2: (3,2)

當(dāng)然,除了上面的運(yùn)算,還支持+= -= *= /=等這些運(yùn)算。

complex& operator+= (const T& val);complex& operator-= (const T& val);complex& operator*= (const T& val);complex& operator/= (const T& val);template<class X> complex& operator+= (const complex<X>& rhs);template<class X> complex& operator-= (const complex<X>& rhs);template<class X> complex& operator*= (const complex<X>& rhs);template<class X> complex& operator/= (const complex<X>& rhs);

同樣的,我們看下面的代碼:

#include <iostream>#include <complex>int main (){ std::complex<double> z1(1, 2); std::complex<double> z2 = std::complex<double>(3, 4); z1 += 2.0; z2 -= z1; std::cout << 'z1: ' << z1 << std::endl; std::cout << 'z2: ' << z2 << std::endl; return 0;}

上面的代碼執(zhí)行結(jié)果:

z1: (3,2)z2: (0,2)

一些其他函數(shù)

除了上面的一些運(yùn)算,complex頭文件里還有一些函數(shù),我們選擇一些常見(jiàn)的函數(shù)來(lái)進(jìn)行介紹。

  • real和imag函數(shù)
  • abs函數(shù)
  • conj函數(shù)
  • arg和polar函數(shù)
  • norm函數(shù)
  • exp函數(shù)

real和imag函數(shù)

我們知道了復(fù)數(shù)有實(shí)部和虛部組成,當(dāng)我們需要分開(kāi)對(duì)實(shí)部和虛部處理的時(shí)候,如何取得實(shí)部和虛部的值呢?

complex頭文件定義了獲取實(shí)部(real函數(shù))和虛部(imag函數(shù))的函數(shù):

template<class T> T real (const complex<T>& x);template<class T> T imag (const complex<T>& x);

示例:

#include <iostream>#include <complex>int main (){  std::complex<double> z1 (1,2);  std::cout << 'real part: ' << std::real(z1) << '\n';  std::cout << 'imag part: ' << std::imag(z1) << '\n';  return 0;}

結(jié)果:

real part: 1imag part: 2

abs函數(shù)

復(fù)數(shù)的模也就是向量的長(zhǎng)度,它可以根據(jù)復(fù)數(shù)的實(shí)部與虛部數(shù)值的平方和的平方根的值求出。我們常利用abs函數(shù)計(jì)算信號(hào)的幅度大小。

complex頭文件中取模函數(shù)是abs,其定義:

template<class T> T abs (const complex<T>& x);

示例:

#include <iostream>#include <complex>int main (){ std::complex<double> z1 (3.0,4.0); std::cout << 'Absolute value: '<< std::abs(z1) << std::endl; return 0;}

結(jié)果:

Absolute value: 5

conj函數(shù)

在上面的除法運(yùn)算中,我們知道,如果實(shí)部相同,虛部互為相反數(shù),那么它們互為共軛復(fù)數(shù)。complex也提供了一個(gè)函數(shù)conj便于我們求解一個(gè)復(fù)數(shù)的共軛復(fù)數(shù)。

template<class T> complex<T> conj (const complex<T>& x);

示例:

#include <iostream>#include <complex>int main (){  std::complex<double> z1 (2.0,3.0);    std::cout << 'z1: ' << z1 << std::endl;  std::cout << 'z1 conjugate: ' << std::conj(z1) << std::endl;  return 0;}

結(jié)果:

z1: (2,3)z1 conjugate: (2,-3)

arg函數(shù)與polar函數(shù)

argpolar是兩個(gè)”相反“的函數(shù),這兩個(gè)函數(shù)可以進(jìn)行相互轉(zhuǎn)換。arg函數(shù)作用是根據(jù)一個(gè)復(fù)數(shù)返回一個(gè)角度,而polar函數(shù)可以根據(jù)角度返回一個(gè)復(fù)數(shù)。它們?cè)谟?jì)算相位或者根據(jù)相位計(jì)算其對(duì)應(yīng)的IQ時(shí)較為常用。

template<class T> T arg (const complex<T>& x);template<class T> complex<T> polar (const T& rho, const T& theta = 0);

示例:

#include <iostream> #include <complex>int main (){ std::complex<double> z1 (3,4); double theta = std::arg(z1); std::complex<double> z2 = std::polar(5.0, theta); std::cout << 'angle:' << theta << std::endl; std::cout << 'polar:' << z2 << std::endl; return 0;}

上面的示例先用arg函數(shù)求出對(duì)應(yīng)的theta角,然后,再用polar函數(shù)根據(jù)求出的theta角以及幅值r返回相應(yīng)的復(fù)數(shù),結(jié)果如下:

angle:0.927295polar:(3,4)

norm函數(shù)

norm函數(shù)可以計(jì)算復(fù)數(shù)的平方和,即實(shí)部和虛部平方的和,可用于計(jì)算IQ數(shù)據(jù)的功率大小。其定義如下:

template<class T> T norm (const complex<T>& x);

示例:

#include <iostream>#include <complex>int main (){  std::complex<double> z1 (3.0,4.0);  std::cout << 'z1 norm: ' << std::norm(z1) << std::endl;  return 0;}

結(jié)果:

z1 norm: 25

exp函數(shù)

complex也支持自然指數(shù),我們可以使用exp函數(shù)。通過(guò)這個(gè)函數(shù),我們就可以生成我們想要的復(fù)指數(shù)信號(hào)了。

template<class T> complex<T> exp (const complex<T>& x);

我們可以利用這個(gè)函數(shù)生成一個(gè)theta角為pi的復(fù)指數(shù)數(shù)據(jù),示例代碼:

#include <complex>#include <iostream> int main(){ double pi = std::acos(-1); std::complex<double> i(0, 1); std::cout << std::fixed << ' exp(i*pi) = ' << std::exp(i * pi) << '\n';}

運(yùn)行結(jié)果如下:

 exp(i*pi) = (-1.000000,0.000000)

最后

毋庸置疑,復(fù)數(shù)的提出對(duì)數(shù)學(xué)界來(lái)說(shuō)是一個(gè)全新的發(fā)展,復(fù)數(shù)擴(kuò)展了數(shù)的概念,讓數(shù)從一維變成了二維。復(fù)數(shù)也是現(xiàn)代數(shù)字通信行業(yè)發(fā)展的必要條件,它是數(shù)字信號(hào)處理的基礎(chǔ)。數(shù)字信號(hào)處理是一個(gè)極為抽象和復(fù)雜的學(xué)科,掌握復(fù)數(shù)的處理方法對(duì)數(shù)字信號(hào)處理應(yīng)用實(shí)為必要,因此大家一定要熟練掌握這些方法的應(yīng)用。

    本站是提供個(gè)人知識(shí)管理的網(wǎng)絡(luò)存儲(chǔ)空間,所有內(nèi)容均由用戶(hù)發(fā)布,不代表本站觀(guān)點(diǎn)。請(qǐng)注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購(gòu)買(mǎi)等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊一鍵舉報(bào)。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評(píng)論

    發(fā)表

    請(qǐng)遵守用戶(hù) 評(píng)論公約

    類(lèi)似文章 更多