Complex.cpp

#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;
}

1人评论了“Complex.cpp”

  1. Pingback: Complex手册 – lightning BLOG

发表评论

您的邮箱地址不会被公开。 必填项已用 * 标注

滚动至顶部