// Author: Courtesy of Wayne Rowcliffe // Date : 9/28/09 #include "complexx.h" #include #include using namespace std; complex::complex (double x, double y) : real(x), imag(y) {} // return real part double complex::realPart() const { return real; } // return imaginary part double complex::imagPart() const { return imag; } // return magnitude double complex::magnitude() const { return ::sqrt(::pow(real,2) + ::pow(imag,2)); } // return phase double complex::phase() const { return ::atan2(imag,real); } // square root with nonnegative real part complex complex::sqrt() const { // using formula given in assignment double squaredV = (::sqrt(::pow(real,2) + ::pow(imag,2)) - real)/2; double squaredU= squaredV + real; double v = (imag < 0) ? (-::sqrt(squaredV)) : (::sqrt(squaredV)); double u = ::sqrt(squaredU); return complex(u,v); } // nth power, more efficiently implemented using magnitude and phase angle complex complex::pow(int n) const { double mag = ::pow(complex::magnitude(),n); double phase = n * complex::phase(); return complex(mag * ::cos(phase), mag * sin(phase)); } // complex addition complex complex::operator+ (const complex& rhs) { return complex(real + rhs.real, imag + rhs.imag); } // complex subtraction complex complex::operator- (const complex& rhs) { return complex(real - rhs.real, imag - rhs.imag); } // complex multiplication complex complex::operator* (const complex& rhs) { return complex((real * rhs.real) - (imag * rhs.imag), (real* rhs.imag) + (imag * rhs.real)); } // complex division complex complex::operator/ (const complex& rhs) { double bottom = (::pow(rhs.real,2) + ::pow(rhs.imag,2)); double rl = ((real*rhs.real) + (imag * rhs.imag))/bottom; double img = ((imag * rhs.real) - (real * rhs.imag))/bottom; return complex(rl,img); } // equality bool complex::operator== (const complex& rhs) { return (real == rhs.real) && (imag == rhs.imag); } // negation of a complex number complex complex::operator-() const { return complex(-real,-imag); } // print a complex to a ostream ostream& operator<< (ostream& ostr, const complex& x) { double real = x.real; double imag = x.imag; if(abs(real) < 0.000001) {real = 0;} if(abs(imag) < 0.000001) {imag = 0;} int swVal = ((real != 0) << 2 | (imag > 0) << 1 | (imag < 0)); switch(swVal) { case 0 : ostr << '0'; break; // Both real and imaginary are zero : 0 case 1 : case 2 : ostr << imag << 'i'; break; // Real is zero : bi case 4 : ostr << real; break; // Imaginary is zero : a case 5 : ostr << real << " - " << -imag << 'i'; break; // Real is non-zero and Imaginary is negative : a - bi case 6 : ostr << real << " + " << imag << 'i'; break; // Real is non-zero and Imaginary is positive : a + bi } return ostr; } // read a complex from an istream istream& operator>> (istream& istr, complex& x) { double r(0), i(0); char c; istr >> r; // real part if(istr.peek() == 'i') { // If i is the next character, this is the imaginary part. i = r; r = 0; istr.get(c); } else if(istr.peek() == ' ' || istr.peek() == '\t' || istr.peek() == '\n') { // whitespace means the number is over i = 0; } else { if(istr.peek() == '+') { // get rid of the plus sign, leave the negative sign. istr.get(c); if(istr.peek() == 'i') { i = 1; } else { istr >> i; } } else { istr.get(c); if(istr.peek() == 'i') { i = -1; } else { istr >> i; i = -i; } } istr.get(c); } // save the components as values for x x.real = r; x.imag = i; return istr; } // evaluate the polynomial f(z) = z^3 - 3 z^2 + 4 z - 2 complex f(const complex& z) { return z.pow(3) - complex(3,0) * z.pow(2) + complex(4,0) * z - complex(2,0); }