此头文件是数值库的一部分。本篇介绍complex的基本用法。
常用的API如下:
运算 | |
real | 返回实部 (函数模板) |
imag | 返回虚部 (函数模板) |
abs(std::complex) | 返回复数的模 (函数模板) |
arg | 返回辐角 (函数模板) |
norm | 返回模(范数)的平方 (函数模板) |
conj | 返回复共轭 (函数模板) |
proj (C++11) | 返回到黎曼球上的投影 (函数模板) |
polar | 从模和辐角构造复数 (函数模板) |
指数函数 | |
exp(std::complex) | 以 e 为底复数的指数 (函数模板) |
log(std::complex) | 沿负实轴切割的复自然对数 (函数模板) |
log10(std::complex) | 沿负实轴分割的复常用对数 (函数模板) |
幂函数 | |
pow(std::complex) | 复数幂,一或两个实参可为复数 (函数模板) |
sqrt(std::complex) | 右半平面范围中的复平方根 (函数模板) |
三角函数 | |
sin(std::complex) | 计算复数的正弦(sinz) |
(函数模板) | |
cos(std::complex) | 计算复数的余弦(cosz) |
(函数模板) | |
tan(std::complex) | 计算复数的正切(tanz) |
(函数模板) | |
asin(std::complex) (C++11) | 计算复数的反正弦(arcsinz) |
(函数模板) | |
acos(std::complex) (C++11) | 计算复数的反余弦(arccosz) |
(函数模板) | |
atan(std::complex) (C++11) | 计算复数的反正切(arctanz) |
(函数模板) | |
双曲函数 | |
sinh(std::complex) | 计算复数的双曲正弦(sinhz) |
(函数模板) | |
cosh(std::complex) | 计算复数的双曲余弦(coshz) |
(函数模板) | |
tanh(std::complex) | 计算复数的双曲正切(tanhz) |
(函数模板) | |
asinh(std::complex) (C++11) | 计算复数的反双曲正弦(arsinhz) |
(函数模板) | |
acosh(std::complex) (C++11) | 计算复数的反双曲余弦(arcoshz) |
(函数模板) | |
atanh(std::complex) (C++11) | 计算复数的反双曲正切(artanhz) |
示例代码:
#include <iostream> // std::wcout, std::wcout
#include <complex>
#include <limits>
#include <string> // std::wstring
#include <cmath>
int main()
{
// complex operators
std::complex<double> mycomplex;
mycomplex = 10.0; // 10
mycomplex += 2.0; // 12
std::cout << "mycomplex is " << mycomplex << '\n';
mycomplex = std::complex<double>(10.0, 3.0); // 10+i
std::cout << "mycomplex is " << mycomplex << '\n';
mycomplex = mycomplex + 10.0; // 20+i
if (mycomplex == std::complex<double>(20.0, 3.0))
std::cout << "mycomplex is " << mycomplex << '\n';
// std::real example
std::cout << "Real part:" << std::real(mycomplex) << '\n';
// std::imag example
std::cout << "Imaginary part:" << std::imag(mycomplex) << '\n';
// abs complex example
std::complex<double> mycomplex2(3.0, 4.0);
std::cout << "The absolute value of " << mycomplex2 << " is " << std::abs(mycomplex2) << '\n';
// arg complex example
std::cout << "The polar form of " << mycomplex2;
std::cout << " is " << std::abs(mycomplex2) << "*e^i*" << std::arg(mycomplex2) << "rad\n";
// norm example
std::cout << "The norm of " << mycomplex2 << " is " << std::norm(mycomplex2) << '\n';
// conj example
std::complex<double> mycomplex3(10.0, 2.0);
std::cout << "The conjugate of " << mycomplex3 << " is " << std::conj(mycomplex3) << '\n';
// polar example
std::cout << "The complex whose magnitude is " << 2.0;
std::cout << " and phase angle is " << 0.5;
std::cout << " is " << std::polar(2.0, 0.5) << '\n';
// proj example
std::complex<double> mycomplex4(std::numeric_limits<double>::infinity(), 2.0);
std::cout << "The projection of " << mycomplex4 << " is " << std::proj(mycomplex4) << '\n';
// sin example
std::cout << std::fixed;
std::complex<double> z(1, 0); // 表现同沿着实轴的实正弦
std::cout << "sin" << z << " = " << std::sin(z)
<< " (sin(1) = " << std::sin(1) << ")\n";
// sinh example
std::complex<double> z2(0, 1); // 表现同沿着虚轴的 sinh
std::cout << "sin" << z2 << " = " << std::sin(z2)
<< " (sinh(1) = " << std::sinh(1) << ")\n";
// cos example
std::complex<double> z3(1.0, 0.0); // 表现为沿实轴的实余弦
std::cout << "cos" << z3 << " = " << std::cos(z3)
<< " (cos(1) = " << std::cos(1) << ")\n";
// cosh example
std::complex<double> z4(0.0, 1.0); // 表现为沿虚轴的实 cosh
std::cout << "cos" << z4 << " = " << std::cos(z4)
<< " (cosh(1) = " << std::cosh(1) << ")\n";
// tan example
std::complex<double> z5(1, 0); // 表现类似沿实轴的实正切
std::cout << "tan" << z5 << " = " << std::tan(z5)
<< " (tan(1) = " << std::tan(1) << ")\n";
// tanh example
std::complex<double> z6(0, 1); // 表现类似沿虚轴的 tanh
std::cout << "tan" << z6 << " = " << std::tan(z6)
<< " (tanh(1) = " << std::tanh(1) << ")\n";
// asin example
std::complex<double> z7(-2.0, 0.0);
std::cout << "asin" << z7 << " = " << std::asin(z7) << '\n';
std::complex<double> z8(-2.0, -0.0);
std::cout << "asin" << z8 << " (the other side of the cut) = "
<< std::asin(z8) << '\n';
// acos example
// for any z, asin(z) = acos(−z) − pi / 2
const double pi = std::acos(-1);
std::complex<double> z9 = std::acos(z8) - pi / 2;
std::cout << "sin(acos" << z8 << " - pi / 2) = " << std::sin(z9) << '\n';
// atan example
std::complex<double> z10(0.0, 2.0);
std::cout << "atan" << z10 << " = " << std::atan(z10) << '\n';
std::complex<double> z11(-0.0, 2.0);
std::cout << "atan" << z11 << " (the other side of the cut) = "
<< std::atan(z11) << '\n';
// atan example
std::complex<double> z12(0.0, INFINITY);
std::cout << "2 * atan" << z12 << " = " << 2.0 * std::atan(z12) << '\n';
// asinh example
std::complex<double> z13(0.0, -2.0);
std::cout << "asinh" << z13 << " = " << std::asinh(z13) << '\n';
std::complex<double> z14(-0.0, -2);
std::cout << "asinh" << z14 << " (the other side of the cut) = "
<< std::asinh(z14) << '\n';
// for any z, asinh(z) = asin(iz) / i
std::complex<double> z15(1.0, 2.0);
std::complex<double> i(0.0, 1.0);
std::cout << "asinh" << z15 << " = " << std::asinh(z15) << '\n'
<< "asin" << z15 * i << " / i = " << std::asin(z15 * i) / i << '\n';
// acosh example
std::complex<double> z16(0.5, 0);
std::cout << "acosh" << z16 << " = " << std::acosh(z16) << '\n';
std::complex<double> z17(0.5, -0.0);
std::cout << "acosh" << z17 << " (the other side of the cut) = "
<< std::acosh(z17) << '\n';
// 在上半平面,acosh = i acos
std::complex<double> z18(1, 1), i2(0, 1);
std::cout << "acosh" << z18 << " = " << std::acosh(z18) << '\n'
<< "i*acos" << z18 << " = " << i2 * std::acos(z18) << '\n';
// atanh example
std::complex<double> z19(2.0, 0.0);
std::cout << "atanh" << z19 << " = " << std::atanh(z19) << '\n';
std::complex<double> z20(2.0, -0.0);
std::cout << "atanh" << z20 << " (the other side of the cut) = "
<< std::atanh(z20) << '\n';
// for any z, atanh(z) = atanh(iz) / i
std::complex<double> z21(1.0, 2.0);
std::complex<double> i3(0.0, 1.0);
std::cout << "atanh" << z21 << " = " << std::atanh(z21) << '\n'
<< "atan" << z21 * i3 << " / i = " << std::atan(z21 * i3) / i3 << '\n';
// exp example
const double pi4 = std::acos(-1);
const std::complex<double> i4(0, 1);
std::cout << std::fixed << "exp(i4*pi4) = " << std::exp(i4 * pi4) << '\n';
// log example
std::complex<double> z22{ 0.0, 1.0 }; // r = 1, θ = pi / 2
std::cout << "2 * log" << z22 << " = " << 2.0 * std::log(z22) << '\n';
std::complex<double> z23{ sqrt(2.0) / 2, sqrt(2.0) / 2 }; // r = 1, θ = pi / 4
std::cout << "4 * log" << z23 << " = " << 4.0 * std::log(z23) << '\n';
std::complex<double> z24{ -1.0, 0.0 }; // r = 1, θ = pi
std::cout << "log" << z24 << " = " << std::log(z24) << '\n';
std::complex<double> z25(-1, -0.0); // 分支的另一侧
std::cout << "log" << z25 << " (the other side of the cut) = " << std::log(z25) << '\n';
// log10 example
std::complex<double> z26(0.0, 1.0); // r = 0, θ = pi / 2
std::cout << "2 * log10" << z26 << " = " << 2.0 * std::log10(z26) << '\n';
std::complex<double> z27(sqrt(2.0) / 2, sqrt(2.0) / 2); // r = 1, θ = pi / 4
std::cout << "4 * log10" << z27 << " = " << 4.0 * std::log10(z27) << '\n';
std::complex<double> z28(-100.0, 0.0); // r = 100, θ = pi
std::cout << "log10" << z28 << " = " << std::log10(z28) << '\n';
std::complex<double> z29(-100.0, -0.0); // 切割的另一侧
std::cout << "log10" << z29 << " = " << std::log10(z29) << " "
"(the other side of the cut)\n"
"(note: pi / log(10) = " << std::acos(-1.0) / std::log(10.0) << ")\n";
// pow example
std::complex<double> z30(1.0, 2.0);
std::cout << "(1,2)^2 = " << std::pow(z30, 2) << '\n';
std::complex<double> z31(-1.0, 0.0); // -1 的平方根
std::cout << "-1^0.5 = " << std::pow(z31, 0.5) << '\n';
std::complex<double> z32(-1.0, -0.0); // 切割的另一侧
std::cout << "(-1,-0)^0.5 = " << std::pow(z32, 0.5) << '\n';
std::complex<double> i5(0.0, 1.0); // i^i = exp(-pi/2)
std::cout << "i^i = " << std::pow(i5, i5) << '\n';
// sqrt example
std::cout << "-4 的平方根是 "
<< std::sqrt(std::complex<double>(-4.0, 0.0)) << '\n'
<< "(-4,-0) 的平方根是 "
<< std::sqrt(std::complex<double>(-4.0, -0.0))
<< "(切割的另一侧)\n";
return 0;
}
运行结果:
参考:
https://cplusplus.com/reference/complex/
https://zh.cppreference.com/w/cpp/header/complex