#include <iostream>
#include <cmath>
#include <string>
#include <sstream>
#include <vector>
#include <variant>
using namespace std;
template<typename T=double>
class Complex
{
public:
Complex():real(0),imag(0),phi(0),r(0){}
Complex(T real){this->real=real;this->imag=0;this->phi=0;this->r=real;}
Complex(T real, T imag){this->real=real;this->imag=imag;this->phi=atan2(imag,real);this->r=Magnitude();}
Complex(T real, T imag, double phi, double r){this->phi=phi;this->r=r;this->real=r*cos(phi);this->imag=r*sin(phi);}
T & operator[](int idx) {
if (idx < 0 || idx >= 4) {
throw std::out_of_range("Index out of range");
}
if (idx == 0) {return real;}
if (idx == 1) {return imag;}
if (idx == 2) {return phi;}
if (idx == 3) {return r;}
}
Complex operator[](char idx){return (* this).conjugate();}
Complex<T> operator()(double phi,double r){this->phi=phi;this->r=r;this->real=r*cos(phi);this->imag=r*sin(phi);return *this;}
Complex<T> operator()(Complex c){this->real=real * c.real-imag * c.imag;this->imag=real * c.imag + imag * c.real;return *this;}
bool friend operator==(const Complex& c ,const Complex<T>& a) {
return (a.real == c.real) && (a.imag == c.imag);
}
bool operator!=(const Complex& other) const {
// 通过对==运算符结果取反来判断是否不相等(前提是==运算符已正确定义)
return!((*this)==other);
}
template<typename U>
friend Complex<U> operator+(const Complex<U>& ,const Complex<U>& );
template<typename U>
friend Complex<U> operator-(const Complex<U>&, const Complex<U>&);
template<typename U>
friend Complex<U> operator*(const Complex<U>& ,const Complex<U>& );
template<typename U>
friend Complex<U> operator/(const Complex<U>& c, const Complex<U>& a);
template<typename U>
friend Complex<U> operator%(const Complex<U>& c, const Complex<U>& a);
template<typename U>
friend Complex<U> operator||(const Complex<U>&, const Complex<U>&);
template<typename U>
friend Complex<U> operator^( Complex<U>& , double );
template<typename U>
friend Complex<U> operator^( Complex<U>& , Complex<U>& );
template<typename U>
friend ostream & operator<<(ostream &, const Complex<U> &c);
template<typename U>
friend istream & operator>>(istream &, Complex<U> &c);
double Magnitude(){return sqrt(real*real + imag*imag);}
void showMagnitude(){ cout << '|' << (*this) << "|" << "=sqt(" << (*this) << "*" << (*this).conjugate() << ")" << "=sqt(" << (*this) * (*this).conjugate() << ")=" << r << endl; }
Complex conjugate()const {return Complex<T>(real,-imag);}
void showconjugate()const{ cout << "Conjugate:" << (*this)['-'] << endl; }
void info(){cout<<(*this)<<" info:"<<endl<<"real:"<<real<<" "<<"imag:"<<imag<<' '<<"phi:"<<phi<<" "<<"r:"<<r<<endl;}
void show(){cout<<*this<<endl;info();}
double norm() const {
return (*this*(*this).conjugate()).real;
}
Complex unit()const {
return Complex<T>(0,0,phi,1);
}
void show_unit()const{ cout << "unitvector:" << (*this).unit() << endl; }
friend Complex gcd_gaussian(const Complex &a, const Complex &b) {
Complex zero;
if (b == zero) {
return a;
}
Complex remainder = a % b;
return gcd_gaussian(b, remainder);
}
friend Complex* extended_gcd_gaussian(const Complex& a, const Complex& b,
std::vector<Complex<T>>& qList, std::vector<Complex<T>>& rList) {
Complex<T> u1(1, 0), v1(0, 0);
Complex<T> u2(0, 0), v2(1, 0);
Complex<T> temp;
Complex<T> currentA = a;
Complex<T> currentB = b;
cout <<"start"<<endl;
while (currentB != Complex(0,0)) {
cout << u2 << " " << v2 << endl;
Complex<T> quotient = currentA / currentB;
qList.push_back(quotient);
rList.push_back(currentA%currentB);
temp = u2;
u2 = u1 - quotient * u2;
u1 = temp;
temp = v2;
v2 = v1 - quotient * v2;
v1 = temp;
temp = currentA;
currentA = currentB;
currentB = temp % currentB;
}
Complex* result = new Complex<T>[2];
result[0] = u1;
result[1] = v1;
return result;
}
friend void printExtendedGcdSteps(const Complex<T>& a, const Complex<T>& b,
const std::vector<Complex<T>>& q, const std::vector<Complex<T>>& r) {
std::vector<Complex<T>> tempA = { a };
std::vector<Complex<T>> tempB = { b };
for (size_t i = 0; i < r.size(); ++i) {
std::cout << tempA[i] << " = " << tempB[i] << " * " << q[i] << " + " << r[i] << std::endl;
if (i < r.size()-1 ) {
tempA.push_back(tempB[i]);
tempB.push_back(r[i]);
}
}
}
private:
T real, imag;
T phi,r;
};
template<typename T>
Complex<T> operator+(const Complex<T> &c,const Complex<T> &a) { return Complex<T>(a.real + c.real, a.imag + c.imag); }
template<typename T>
Complex<T> operator-(const Complex<T> &c, const Complex<T> &a) {
return Complex<T>(c.real - a.real, c.imag - a.imag);
}
template<typename T>
Complex<T> operator*(const Complex<T> &c,const Complex<T> &a) { return Complex<T>(a.real * c.real-a.imag * c.imag, a.real * c.imag + a.imag * c.real); }
template<typename T>
Complex<T> operator/(const Complex<T>& c, const Complex<T>& a) {
if (std::is_same<T, int>::value) {
// 计算中间值
T u = c.real * a.real + c.imag * a.imag;
T v = c.imag * a.real - c.real * a.imag;
T w = a.norm();
// 四舍五入计算商的实部和虚部
T newReal = static_cast<T>(std::round(static_cast<double>(u) / w));
T newImag = static_cast<T>(std::round(static_cast<double>(v) / w));
return Complex<T>(newReal, newImag);
}
else {
T newReal = (c.real * a.real + c.imag * a.imag) / (a.real * a.real + a.imag * a.imag);
T newImag = (c.imag * a.real - c.real * a.imag) / (a.real * a.real + a.imag * a.imag);
return Complex<T>(newReal, newImag);
}
}
template<typename T>
ostream & operator<<(ostream &out, const Complex<T> & c) {
if (c.real == 0) {
if (c.imag== 1) {
out << "i";
}
else if (c.imag == -1) {
out << "-i";
}
else {
out << c.imag << "i";
}
}
else {
if (c.imag > 0) {
out << c.real << "+" ;
if (c.imag== 1) {
out << "i";
}
else if (c.imag == -1) {
out << "-i";
}
else {
out << c.imag << "i";
}
}
else if (c.imag < 0) {
out << c.real ;
if (c.imag== 1) {
out << "i";
}
else if (c.imag == -1) {
out << "-i";
}
else {
out << c.imag << "i";
}
}
else {
out << c.real;
}
}
return out;
}
template<typename T>
istream & operator>>(istream &in,Complex<T> & c) {
cout << "Enter real: ";
in >> c.real;
cout << "Enter imag: ";
in >>c.imag;
return in;
}
template<typename T>
Complex<T> operator^( Complex<T>& c , double n) {
return Complex<T>(0,0,c.phi*n,pow(c.r,n));
}
template<typename T>
Complex<T> operator^( Complex<T>& c , Complex<T>& b) {
return Complex<T>(0,0,c.phi*b[0]+b[1]*log(c.r),exp(b[0]*log(c.r)-b[1]*c.phi));
}
template<typename T>
Complex<T> operator%(const Complex<T>& c, const Complex<T>& a){
Complex<T> quotient = c/a;
Complex<T> product = a * quotient;
return c - product;
}
template<typename U>
Complex<U> operator||(const Complex<U>& c1, const Complex<U>& c2) {
return gcd_gaussian(c1, c2);
}
// 展示加法运算过程的函数
template<class T>
void showAddition(T c, T a) {
T result = c + a;
std::cout << c << " + " << a << " = " << result << std::endl;
}
// 展示减法运算过程的函数
template<class T>
void showSubtraction(T c, T a) {
T result = c - a;
std::cout << c << " - " << a << " = " << result << std::endl;
}
// 展示乘法运算过程的函数
template<class T>
void showMultiplication(T c, T a) {
std::cout << c << " * " << a << " = " << c * a << std::endl;
}
// 展示除法运算过程的函数
template<class T>
void showDivision(T c, T a) {
T conjugate_a = a.conjugate();
std::cout << c << " / " << a << " = " << c << " * " << conjugate_a << " / " << a << " * " << conjugate_a << " = " << c * conjugate_a << " / " << a * conjugate_a << " = " << c / a << std::endl;
}
// 展示求模运算过程的函数
template<class T>
void showModulo(T c, T a) {
std::cout << c << " = " << c / a << " * " << a << " ~~~ " << (c % a) << std::endl;
}
// 展示次方(幂运算)运算过程的函数,针对复数次幂情况
template<class T>
void showPower(T c, T b) {
std::cout << c << " ^ " << b << " = " << (c ^ b) << std::endl;
}
// 展示次方(幂运算)运算过程的函数,针对实数次幂情况
template<class T>
void showPower(T c, double n) {
std::cout << c << " ^ " << n << " = " << (c ^ n) << std::endl;
}
template<class T>
bool showBazout(T a, T b, T u, T v) {
showMultiplication(a, u);
showMultiplication(b, v);
showAddition(a * u, b * v);
cout << a * u + b * v << " =?= " << (a || b) << endl;
return a * u + b * v == (a || b);
}
template<class T>
void test(T z1, T z2) {
z1.info();
z2.info();
showAddition(z1, z2);
showSubtraction(z1, z2);
showMultiplication(z1, z2);
showDivision(z1, z2);
showModulo(z1, z2);
showPower(z1, 0.5);
showPower(z1, z2);
cout<<z1<<" || "<<z2 << " = " << (z1 || z2) << endl;
std::vector<T> q;
std::vector<T> r;
T* uv=extended_gcd_gaussian(z1,z2, q, r);
cout << "uv" << endl;
T u = uv[0], v = uv[1];
cout << "u:"<<u << " " << "v:" << v << "" << endl;
showBazout(z1, z2, u, v);
printExtendedGcdSteps(z1, z2, q, r);
}
int main()
{
Complex<double> z1(1,1), z2(1,-1);
/*cin >> z1 >> z2;*/
test(z1, z2);
cout<<z1<<endl<<z1[1]<<endl;
Complex<int> z3(23,-13), z4(7,3);
test(z3, z4);
return 0;
}
Post Views: 8
Pingback: Complex手册 – lightning BLOG