#include // require sqrt(), sin(), cos(), atan2() #include // streaming Cmplx value using namespace std; // complex arithmetic C++ class Cmplx // by Dick Kostelnicek 05/12/2021 // operations with (double)d, (double)c, (Cmplx)z, and (Cmplx)w // yields Cmplx: w=z, w=d, +z, -z, // w+z, W+=z, w+d, w+=d, d+z, // w-z, w-=z, w-d, w-=d, d-z, // w*z, w*=z, w*d, w*=d, d*z, // w/z, w/=z, w/d, w/=d, d/z, // conj(z), exp(z); log(z), polar(d, c) // yields double: Re(z), Im(z), mag(z), arg(z) class Cmplx { private: double x = 0; // real part double y = 0; // Imaginary part public: // constructor Cmplx(double re = 0.0, double im = 0.0) { x = re; y = im; } // Cmplx = Cmplx Cmplx& operator = (const Cmplx& z) { x = z.x; y = z.y; return *this; } // Cmplx = double Cmplx& operator = (const double& d) { x = d; y = 0; return *this; } // +Cmplx Cmplx operator + () { return Cmplx(x, y); } // - Cmplx Cmplx operator - () { return Cmplx(-x, -y); } // Cmplx + Cmplx Cmplx operator + (Cmplx const& z) { return Cmplx(x + z.x, y + z.y); } // Cmplx += Cmplx Cmplx& operator += (Cmplx const& z) { x += z.x; y += z.y; return *this; } // Cmplx + double Cmplx operator + (double const& d) { return Cmplx(x + d, y); } // Cmplx += double Cmplx& operator += (double const& d) { x += d; return *this; } // double + Cmplx friend Cmplx operator + (const double& d, const Cmplx& z); // Cmplx - Cmplx Cmplx operator - (Cmplx const& z) { return Cmplx(x - z.x, y - z.y); } // Cmplx -= Cmplx Cmplx& operator -= (Cmplx const& z) { x -= z.x; y -= z.y; return *this; } // Cmplx - double Cmplx operator - (double const& d) { return Cmplx(x - d, y); } // Cmplx -= double Cmplx& operator -= (double const& d) { x -= d; return *this; } // double - Cmplx friend Cmplx operator - (const double& d, const Cmplx& z); // Cmplx * Cmplx Cmplx operator * (Cmplx const& z) { return Cmplx(x * z.x - y * z.y, x * z.y + y * z.x); } // Cmplx *= Cmplx Cmplx& operator *= (Cmplx const& z) { double temp = x; x = x * z.x - y * z.y; y = temp * z.y + y * z.x; return *this; } // Cmplx * double Cmplx operator * (double const& d) { return Cmplx(x * d, y * d); } // Cmplx *= double Cmplx& operator *= (double const& d) { x *= d; y *= d; return *this; } // double * Cmplx friend Cmplx operator * (const double& d, const Cmplx& z); // Cmplx / Cmplx Cmplx operator / (Cmplx const& z) { double d = z.x * z.x + z.y * z.y; return Cmplx((x * z.x + y * z.y) / d, (-x * z.y + y * z.x) / d); } // Cmplx /= Cmplx Cmplx& operator /= (Cmplx const& z) { double d = z.x * z.x + z.y * z.y; double temp = x; x = (x * z.x + y * z.y) / d; y = (-temp * z.y + y * z.x) / d; return *this; } // Cmplx / double Cmplx operator / (double const& d) { return Cmplx(x / d, y / d); } // Cmplx /= double Cmplx& operator /= (double const& d) { x /= d; y /= d; return *this; } // double / Cmplx friend Cmplx operator / (const double& d, const Cmplx& z); // real part friend double Re(Cmplx const& z); // imaginary part friend double Im(Cmplx const& z); // conjugate friend Cmplx conj(Cmplx const& z); // magnitude friend double mag(Cmplx const& z); // argument (radians) friend double arg(Cmplx const& z); // exponentiate friend Cmplx exp(Cmplx const& z); // natural log friend Cmplx log(Cmplx const& z); // output as: cout << Cmplx << endl friend ostream& operator << (ostream& os, const Cmplx& z); }; // friend functions of Cmplx class // real part double Re(Cmplx const& z) { return z.x; } // imaginary part double Im(Cmplx const& z) { return z.y; } // conjugate Cmplx conj(Cmplx const& z) { return Cmplx(z.x, -z.y); } // magnitude double mag(Cmplx const& z) { return sqrt(z.x * z.x + z.y * z.y); } // argument (radians) double arg(Cmplx const& z) { return atan2(z.y, z.x); } // exponentiate Cmplx exp(Cmplx const& z) { double d = exp(z.x); return Cmplx(d * cos(z.y), d * sin(z.y)); } // natural log Cmplx log(Cmplx const& z) { return Cmplx(log(mag(z)), arg(z)); } // double + Cmplx Cmplx operator + (const double& d, const Cmplx& z) { return Cmplx(d + z.x, z.y); } // double - cmplx Cmplx operator - (const double& d, const Cmplx& z) { return Cmplx(d - z.x, -z.y); } // double * Cmplx Cmplx operator * (const double& d, const Cmplx& z) { return Cmplx(d * z.x, d * z.y); } // double / Cmplx Cmplx operator / (const double& d, const Cmplx& z) { double f = d / (z.x * z.x + z.y * z.y); return Cmplx(f * z.x, -f * z.y); } ostream& operator << (ostream& os, const Cmplx& z) { os << '(' << z.x << ", " << z.y << ')'; return os; } // polar to Cmplx Cmplx polar(const double& rho, const double& theta) { return Cmplx(rho * cos(theta), rho * sin(theta)); } //------------------------------------------------------- // Test Complex operations #include int main() { Cmplx a, b = 5.1, c(2.7,-1.7), d; Cmplx p[2] = {Cmplx(1.1,2.2), Cmplx(4.5,6.7)}; cout << "test Cmplx C++ Class" << endl; cout << "by Dick Kostelnicek 05/12/2021" << endl << endl; cout << "complex variables" << endl; cout << "a = " << a << endl; cout << "b = " << b << endl; cout << "c = " << c << endl << endl; cout << "complex array" << endl; cout << "p[0] = " << p[0] << endl; cout << "p[1] = " << p[1] << endl << endl; cout << "complex functions" << endl; cout << "Re(c) = " << Re(c) << endl; cout << "Im(c) = " << Im(c) << endl; cout << "mag(c) = " << mag(c) << endl; cout << "arg(c) = " << arg(c) << endl; cout << "polar(mag(c), arg(c)) = " << polar(mag(c), arg(c)) << endl; cout << "conj(c) = " << conj(c) << endl << endl; cout << "copy" << endl; cout << "d = " << d << endl; cout << "d = c " << endl; cout << "d = " << (d=c) << endl << endl; cout << "sign assigment" << endl; cout << "+d = " << +d << endl; cout << "-d = " << -d << endl << endl; cout << "Cmplx + Cmplx" << endl; cout << "p[0] = " << p[0] << endl; cout << "p[0] + Cmplx(2.0, 0) = " << p[0] + Cmplx(2.0, 0) << endl; cout << "p[0] += Cmplx(1.0, 1.0) = " << (p[0] += Cmplx(1.0, 1.0)) << endl; cout <<"Cmplx + double" << endl; cout << "p[0] + 2.0 = " << p[0] + 2.0 << endl; cout << "p[0] = " << p[0] << endl; cout << "p[0] += 2.0 = " << (p[0] += 2.0) << endl; cout <<"double + Cmplx" << endl; cout << "2.0 + p[0] = " << 2.0 + p[0] << endl << endl; cout << "Cmplx - Cmplx" << endl; cout << "p[0] = " << p[0] << endl; cout << "p[0] - Cmplx(2, 0) = " << p[0] - Cmplx(2, 0) << endl; cout << "p[0] -= Cmplx(1.0, 1.0) = " << (p[0] -= Cmplx(1.0, 1.0)) << endl; cout << "Cmplx - double" << endl; cout << "p[0] - 2.0 = " << p[0] - 2.0 << endl; cout << "p[0] = " << p[0] << endl; cout << "p[0] -= 2.0 = " << (p[0] -= 2.0) << endl; cout <<"double - Cmplx" << endl; cout << "2.0 - p[0] = " << 2.0 - p[0] << endl << endl; cout << "Cmplx * Cmplx" << endl; cout << "p[0] = " << p[0] << endl; cout << "p[0] * Cmplx(2, 0.0) = " << p[0] * Cmplx(2, 0.0) << endl; p[0] *= Cmplx(2.0, 2.0); cout << "p[0] *= Cmplx(2.0, 2.0) = " << p[0] << endl; cout << "Cmplx * double" << endl; cout << "p[0] * 2.0 = " << p[0] * 2.0 << endl; cout << "p[0] = " << p[0] << endl; cout << "p[0] *= 2.0 = " << (p[0] *= 2.0) << endl; cout <<"double * Cmplx" << endl; cout << "2.0 * p[0] = " << 2.0 * p[0] << endl << endl; cout << "Cmplx / Cmplx" << endl; cout << "p[0] = " << p[0] << endl; cout << "p[0] / Cmplx(2.0, 0.0) = " << p[0] / Cmplx(2.0, 0.0) << endl; p[0] /= Cmplx(2.0, 2.0); cout << "p[0] /= Cmplx(2.0, 2.0) = " << p[0] << endl; cout << "Cmplx / double" << endl; cout << "p[0] / 2.0 = " << p[0] / 2.0 << endl; cout << "p[0] = " << p[0] << endl; cout << "p[0] /= 2.0 = " << (p[0] /= 2.0) << endl; cout << "double / Cmplx" << endl; cout << "2.0 / p[0] = " << 2.0 / p[0] << endl << endl; cout <<"exponentiate and log" << endl; cout << "c = " << c << endl; cout << "exp(c = " << c << endl; cout << "log(c) = " << log(c) << endl; cout << "log(exp(c)) = " << log(exp(c)) << endl; cout << "-1.0**0.5 = " << exp(0.5*log(Cmplx(-1.0, 0))) << endl; cout << "sqrt(Cmplx(0, 1)) = " << exp(0.5*log(Cmplx(0.0, 1.0))) << endl << endl; return 0; }