|
| 1 | +// bigcomplex.h: complex class built on NTL's RR |
| 2 | +////////////////////////////////////////////////////////////////////////// |
| 3 | +// |
| 4 | +// Copyright 1990-2023 John Cremona |
| 5 | +// |
| 6 | +// This file is part of the eclib package. |
| 7 | +// |
| 8 | +// eclib is free software; you can redistribute it and/or modify it |
| 9 | +// under the terms of the GNU General Public License as published by the |
| 10 | +// Free Software Foundation; either version 2 of the License, or (at your |
| 11 | +// option) any later version. |
| 12 | +// |
| 13 | +// eclib is distributed in the hope that it will be useful, but WITHOUT |
| 14 | +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
| 15 | +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License |
| 16 | +// for more details. |
| 17 | +// |
| 18 | +// You should have received a copy of the GNU General Public License |
| 19 | +// along with eclib; if not, write to the Free Software Foundation, |
| 20 | +// Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA |
| 21 | +// |
| 22 | +////////////////////////////////////////////////////////////////////////// |
| 23 | + |
| 24 | +#ifndef _ECLIB_BIGCOMPLEX_H_ |
| 25 | +#define _ECLIB_BIGCOMPLEX_H_ |
| 26 | + |
| 27 | +class bigcomplex{ |
| 28 | +public: |
| 29 | + explicit bigcomplex() : re(RR()), im(RR()) {;} |
| 30 | + explicit bigcomplex(const RR& r) : re(r), im(RR()) {;} |
| 31 | + explicit bigcomplex(const RR& r, const RR& i) : re(r), im(i) {;} |
| 32 | + bigcomplex(const bigcomplex&) = default; |
| 33 | + |
| 34 | + // standard class methods |
| 35 | + RR real() const {return re;}; |
| 36 | + RR imag() const {return im;}; |
| 37 | + RR norm() const {return sqr(re)+sqr(im);}; |
| 38 | + RR arg() const { return atan2(im, re);}; |
| 39 | + RR abs() const {return ::NTL::sqrt(norm());}; |
| 40 | + bigcomplex conj() const {return bigcomplex(re,-im);}; |
| 41 | + bigcomplex timesI() const {return bigcomplex(-im,re);}; |
| 42 | + int IsReal() const {return ::NTL::IsZero(im);} |
| 43 | + int IsImaginary() const {return ::NTL::IsZero(re);} |
| 44 | + int IsZero() const {return ::NTL::IsZero(re) && ::NTL::IsZero(im);} |
| 45 | + |
| 46 | + |
| 47 | + bigcomplex operator= (const RR& r) {re=r; im=RR(); return *this;} |
| 48 | + bigcomplex operator+=(const RR& r) {re+=r; return *this;}; |
| 49 | + bigcomplex operator+(const RR& r) const {bigcomplex z(*this); z.re+=r; return z;}; |
| 50 | + bigcomplex operator-=(const RR& r) {re -= r; return *this;}; |
| 51 | + bigcomplex operator-(const RR& r) const {bigcomplex z(*this); z.re-=r; return z;}; |
| 52 | + bigcomplex operator*=(const RR& r) {re*=r; im*=r; return *this;}; |
| 53 | + bigcomplex operator*(const RR& r) const {bigcomplex z(*this); z.re*=r; z.im*=r; return z;}; |
| 54 | + bigcomplex operator/=(const RR& r) {re/=r; im/=r; return *this;}; |
| 55 | + bigcomplex operator/(const RR& r) const {bigcomplex z(*this); z.re/=r; z.im/=r; return z;}; |
| 56 | + |
| 57 | + bigcomplex operator=(const bigcomplex& z) {re=z.re; im=z.im; return *this;}; |
| 58 | + bigcomplex operator+=(const bigcomplex& z) {re+=z.re; im+=z.im; return *this;}; |
| 59 | + bigcomplex operator+(const bigcomplex& z) const {return bigcomplex(re+z.re, im+z.im);}; |
| 60 | + bigcomplex operator+() {return *this;}; |
| 61 | + bigcomplex operator-=(const bigcomplex& z) {re-=z.re; im-=z.im; return *this;}; |
| 62 | + bigcomplex operator-(const bigcomplex& z) const {return bigcomplex(re-z.re, im-z.im);}; |
| 63 | + bigcomplex operator-() const {return bigcomplex(-re,-im);}; |
| 64 | + bigcomplex operator*=(const bigcomplex& z) {RR x = re; re=x*z.re-im*z.im; im = x*z.im+im*z.re; return *this;}; |
| 65 | + bigcomplex operator*(const bigcomplex& z) const {bigcomplex w(*this); w*=z; return w;}; |
| 66 | + bigcomplex operator/=(const bigcomplex& z) {RR r=z.norm(), x = re; re=(x*z.re+im*z.im)/r; im = (-x*z.im+im*z.re)/r; return *this;}; |
| 67 | + bigcomplex operator/(const bigcomplex& z) const {bigcomplex w(*this); w/=z; return w;}; |
| 68 | + |
| 69 | + // standard functions as class methods: |
| 70 | + bigcomplex sqrt() const {RR r = abs(); RR u = ::NTL::sqrt((r+re)/2), v=::NTL::sqrt((r-re)/2); if (im<0) v=-v; return bigcomplex(u,v);}; |
| 71 | + bigcomplex cos() const {bigcomplex z(this->timesI()); return (z+z.conj())/to_RR(2);}; |
| 72 | + bigcomplex sin() const {bigcomplex z(this->timesI()); return (z-z.conj())/bigcomplex(RR(),to_RR(2));}; |
| 73 | + bigcomplex exp() const {RR e = ::NTL::exp(re); return bigcomplex(e * ::NTL::cos(im), e * ::NTL::sin(im));}; |
| 74 | + bigcomplex log() const {return bigcomplex(::NTL::log(abs()), arg());} |
| 75 | + |
| 76 | + |
| 77 | + operator string() const |
| 78 | + { |
| 79 | + ostringstream s; |
| 80 | + s << "(" << re << "," << im << ")"; |
| 81 | + return s.str(); |
| 82 | + } |
| 83 | + |
| 84 | + string pretty_string() const |
| 85 | + { |
| 86 | + ostringstream s; |
| 87 | + if (IsReal()) |
| 88 | + { |
| 89 | + s<<re; |
| 90 | + return s.str(); |
| 91 | + } |
| 92 | + if (IsImaginary()) |
| 93 | + { |
| 94 | + if (IsOne(im)) |
| 95 | + s << ""; |
| 96 | + else |
| 97 | + if (IsOne(-im)) |
| 98 | + s << "-"; |
| 99 | + else s << im; |
| 100 | + } |
| 101 | + else |
| 102 | + { |
| 103 | + s<<re; |
| 104 | + if(im>0) |
| 105 | + s<<"+"; |
| 106 | + else |
| 107 | + s<<"-"; |
| 108 | + RR abs_im(::NTL::abs(im)); |
| 109 | + if (abs_im>1) |
| 110 | + s<<abs_im; |
| 111 | + } |
| 112 | + s<<"i"; |
| 113 | + return s.str(); |
| 114 | + } |
| 115 | + |
| 116 | + friend ostream& operator<<(ostream& s, const bigcomplex& z) |
| 117 | + { |
| 118 | + s << string(z); |
| 119 | + return s; |
| 120 | + } |
| 121 | + |
| 122 | + // Implementation |
| 123 | +private: |
| 124 | + RR re, im; |
| 125 | +}; |
| 126 | + |
| 127 | + |
| 128 | +// inline functions |
| 129 | +inline RR real(const bigcomplex& z) {return z.real();}; |
| 130 | +inline RR imag(const bigcomplex& z) {return z.imag();}; |
| 131 | +inline RR norm(const bigcomplex& z) {return z.norm();}; |
| 132 | +inline RR arg(const bigcomplex& z) { return z.arg();}; |
| 133 | +inline RR abs(const bigcomplex& z) {return z.abs();}; |
| 134 | +inline bigcomplex conj(const bigcomplex& z) {return z.conj();}; |
| 135 | +inline int IsReal(const bigcomplex& z) {return z.IsReal();} |
| 136 | +inline int IsImaginary(const bigcomplex& z) {return z.IsImaginary();} |
| 137 | +inline int IsZero(const bigcomplex& z) {return z.IsZero();} |
| 138 | + |
| 139 | +// operators with left operand RR |
| 140 | +inline bigcomplex operator+(const RR& r, const bigcomplex& z) {return bigcomplex(r)+z;}; |
| 141 | +inline bigcomplex operator-(const RR& r, const bigcomplex& z) {return bigcomplex(r)-z;}; |
| 142 | +inline bigcomplex operator*(const RR& r, const bigcomplex& z) {return bigcomplex(r)*z;}; |
| 143 | +inline bigcomplex operator/(const RR& r, const bigcomplex& z) {return bigcomplex(r)/z;}; |
| 144 | + |
| 145 | +// standard method functions as functions: |
| 146 | +inline bigcomplex sqrt(const bigcomplex& z) {bigcomplex w(z); return w.sqrt();}; |
| 147 | +inline bigcomplex cos(const bigcomplex& z) {bigcomplex w(z); return w.cos();}; |
| 148 | +inline bigcomplex sin(const bigcomplex& z) {bigcomplex w(z); return w.sin();}; |
| 149 | +inline bigcomplex exp(const bigcomplex& z) {bigcomplex w(z); return w.exp();}; |
| 150 | +inline bigcomplex log(const bigcomplex& z) {bigcomplex w(z); return w.log();}; |
| 151 | + |
| 152 | + |
| 153 | +inline void swap(bigcomplex& z1, bigcomplex& z2) {bigcomplex z3(z1); z1=z2; z2=z3;} |
| 154 | + |
| 155 | +#endif |
0 commit comments