Complex Number  0.1.2
src/ComplexNumber.cpp
Go to the documentation of this file.
00001 // Copyright (c) 2010 Matthew Krupcale
00002 
00003 // Permission is hereby granted, free of charge, to any person
00004 // obtaining a copy of this software and associated documentation
00005 // files (the "Software"), to deal in the Software without
00006 // restriction, including without limitation the rights to use,
00007 // copy, modify, merge, publish, distribute, sublicense, and/or sell
00008 // copies of the Software, and to permit persons to whom the
00009 // Software is furnished to do so, subject to the following
00010 // conditions:
00011 
00012 // The above copyright notice and this permission notice shall be
00013 // included in all copies or substantial portions of the Software.
00014 
00015 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
00016 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
00017 // OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
00018 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
00019 // HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
00020 // WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
00021 // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
00022 // OTHER DEALINGS IN THE SOFTWARE.
00023 
00024 #ifndef COMPLEX_NUMBER_CPP
00025 #define COMPLEX_NUMBER_CPP
00026 
00027 //============================================================================
00028 // Name        : ComplexNumber.cpp
00029 // Author      : Matthew Krupcale
00030 // Version     : 0.1.2
00031 // Copyright   : Copyright (C) 2010 Matthew Krupcale
00032 // Description : A class that deals with complex numbers
00033 //============================================================================
00034 
00047 #include "ComplexNumber.h"
00048 #include "MathExceptions.h"
00049 #include "Namespace.h"
00050 #include <iostream>
00051 #include <cmath>
00052 
00060 BEGIN_NAMESPACE(math)
00061 
00062 
00069 BEGIN_NAMESPACE(complex)
00070 
00071 template<> const ComplexNumber<double> ComplexNumber<double>::i(0, 1);
00072 
00073 template <class T>
00074 ComplexNumber<T>::ComplexNumber() {
00075     real = 0.;
00076     imaginary = 0.;
00077 }
00078 
00079 template <class T>
00080 ComplexNumber<T>::ComplexNumber(const T& real, const T& imaginary) {
00081     this->real = real;
00082     this->imaginary = imaginary;
00083 }
00084 
00085 template <class T>
00086 ComplexNumber<T>::ComplexNumber(const ComplexNumber<T>& z) {
00087     real = z.getReal();
00088     imaginary = z.getImaginary();
00089 }
00090 
00091 template <class T>
00092 ComplexNumber<T>::~ComplexNumber() {
00093 
00094 }
00095 
00096 template <class T>
00097 ComplexNumber<T>
00098 ComplexNumber<T>::polar(const T& r, const T& theta) {
00099     return ComplexNumber<T>(r * std::cos(theta), r * std::sin(theta));
00100 }
00101 
00102 template <class T>
00103 ComplexNumber<T>
00104 ComplexNumber<T>::operator+() const {
00105     return ComplexNumber<T>(real, imaginary);
00106 }
00107 
00108 template <class T>
00109 ComplexNumber<T>
00110 ComplexNumber<T>::operator-() const {
00111     return ComplexNumber<T>(-real, -imaginary);
00112 }
00113 
00114 template <class T>
00115 template <class U>
00116 ComplexNumber<T>::operator ComplexNumber<U>() const {
00117     return ComplexNumber<U>((U)(real), (U)(imaginary));
00118 }
00119 
00120 template <class T>
00121 template <class U>
00122 ComplexNumber<T>&
00123 ComplexNumber<T>::operator=(const ComplexNumber<U>& z) {
00124     if (this == &z) {
00125         return *this;
00126     }
00127     real = z.getReal();
00128     imaginary = z.getImaginary();
00129     return *this;
00130 }
00131 
00132 template <class T>
00133 template <class U>
00134 ComplexNumber<T>&
00135 ComplexNumber<T>::operator=(const U& real) {
00136     this->real = real;
00137     imaginary = 0;
00138     return *this;
00139 }
00140 
00141 template <class T>
00142 template <class U>
00143 ComplexNumber<T>&
00144 ComplexNumber<T>::operator+=(const ComplexNumber<U>& z) {
00145     real += z.getReal();
00146     imaginary += z.getImaginary();
00147     return *this;
00148 }
00149 
00150 template <class T>
00151 template <class U>
00152 ComplexNumber<T>&
00153 ComplexNumber<T>::operator+=(const U& real) {
00154     this->real += real;
00155     return *this;
00156 }
00157 
00158 template <class T>
00159 template <class U>
00160 ComplexNumber<T>&
00161 ComplexNumber<T>::operator-=(const ComplexNumber<U>& z) {
00162     real -= z.getReal();
00163     imaginary -= z.getImaginary();
00164     return *this;
00165 }
00166 
00167 template <class T>
00168 template <class U>
00169 ComplexNumber<T>&
00170 ComplexNumber<T>::operator-=(const U& real) {
00171     this->real -= real;
00172     return *this;
00173 }
00174 
00175 template <class T>
00176 template <class U>
00177 ComplexNumber<T>&
00178 ComplexNumber<T>::operator*=(const ComplexNumber<U>& z) {
00179     real = real * z.getReal() - imaginary * z.getImaginary();
00180     imaginary = real * z.getImaginary() + imaginary * z.getReal();
00181     return *this;
00182 }
00183 
00184 template <class T>
00185 template <class U>
00186 ComplexNumber<T>&
00187 ComplexNumber<T>::operator*=(const U& real) {
00188     this->real *= real;
00189     imaginary *= real;
00190     return *this;
00191 }
00192 
00193 template <class T>
00194 template <class U>
00195 ComplexNumber<T>&
00196 ComplexNumber<T>::operator/=(const ComplexNumber<U>& z) {
00197     // prevent division by zero
00198     if (z == 0) {
00199         throw DivisionByZeroException();
00200     }
00201     real = (real * z.getReal() + imaginary * z.getImaginary()) /
00202         (std::pow(z.getReal(), 2) + std::pow(z.getImaginary(), 2));
00203     imaginary = (imaginary * z.getReal() - real * z.getImaginary()) /
00204         (std::pow(z.getReal(), 2) + std::pow(z.getImaginary(), 2));
00205     return *this;
00206 }
00207 
00208 template <class T>
00209 template <class U>
00210 ComplexNumber<T>&
00211 ComplexNumber<T>::operator/=(const U& real) {
00212     // prevent division by zero
00213     if (real == 0) {
00214         throw DivisionByZeroException();
00215     }
00216     this->real /= real;
00217     imaginary /= real;
00218     return *this;
00219 }
00220 
00221 template <class T>
00222 T
00223 ComplexNumber<T>::getReal() const {
00224     return real;
00225 }
00226 
00227 template <class T>
00228 T
00229 ComplexNumber<T>::getImaginary() const {
00230     return imaginary;
00231 }
00232 
00233 template <class T>
00234 void
00235 ComplexNumber<T>::setReal(const T& real) {
00236     this->real = real;
00237 }
00238 
00239 template <class T>
00240 void
00241 ComplexNumber<T>::setImaginary(const T& imaginary) {
00242     this->imaginary = imaginary;
00243 }
00244 
00245 template <class T>
00246 ComplexNumber<T> operator+(const ComplexNumber<T>& lhs,
00247                            const ComplexNumber<T>& rhs) {
00248     return ComplexNumber<T>(lhs.getReal() + rhs.getReal(),
00249                             lhs.getImaginary() + rhs.getImaginary());
00250 }
00251 
00252 template <class T>
00253 ComplexNumber<T> operator+(const ComplexNumber<T>& lhs, const T& rhs) {
00254     return ComplexNumber<T>(lhs.getReal() + rhs, lhs.getImaginary());
00255 }
00256 
00257 template <class T>
00258 ComplexNumber<T> operator+(const T& lhs, const ComplexNumber<T>& rhs) {
00259     return ComplexNumber<T>(lhs + rhs.getReal(), rhs.getImaginary());
00260 }
00261 
00262 template <class T>
00263 ComplexNumber<T> operator-(const ComplexNumber<T>& lhs,
00264                            const ComplexNumber<T>& rhs) {
00265     return ComplexNumber<T>(lhs.getReal() - rhs.getReal(),
00266                             lhs.getImaginary() - rhs.getImaginary());
00267 }
00268 
00269 template <class T>
00270 ComplexNumber<T> operator-(const ComplexNumber<T>& lhs, const T& rhs) {
00271     return ComplexNumber<T>(lhs.getReal() - rhs, lhs.getImaginary());
00272 }
00273 
00274 template <class T>
00275 ComplexNumber<T> operator-(const T& lhs, const ComplexNumber<T>& rhs) {
00276     return ComplexNumber<T>(lhs - rhs.getReal(), rhs.getImaginary());
00277 }
00278 
00279 template <class T>
00280 ComplexNumber<T> operator*(const ComplexNumber<T>& lhs,
00281                            const ComplexNumber<T>& rhs) {
00282     return ComplexNumber<T>(lhs.getReal() * rhs.getReal() -
00283                             lhs.getImaginary() * rhs.getImaginary(),
00284                             lhs.getReal() * rhs.getImaginary() +
00285                             lhs.getImaginary() * rhs.getReal());
00286 }
00287 
00288 template <class T>
00289 ComplexNumber<T> operator*(const ComplexNumber<T>& lhs, const T& rhs) {
00290     return ComplexNumber<T>(lhs.getReal() * rhs, lhs.getImaginary() * rhs);
00291 }
00292 
00293 template <class T>
00294 ComplexNumber<T> operator*(const T& lhs, const ComplexNumber<T>& rhs) {
00295     return ComplexNumber<T>(lhs * rhs.getReal(), lhs * rhs.getImaginary());
00296 }
00297 
00298 template <class T>
00299 ComplexNumber<T> operator/(const ComplexNumber<T>& lhs,
00300                            const ComplexNumber<T>& rhs) {
00301     // prevent division by zero
00302     if (rhs == 0) {
00303         throw DivisionByZeroException();
00304     }
00305     return ComplexNumber<T>((lhs.getReal() * rhs.getReal() +
00306                              lhs.getImaginary() * rhs.getImaginary()) /
00307                             (std::pow(rhs.getReal(), 2) +
00308                              std::pow(rhs.getImaginary(), 2)),
00309                             (lhs.getImaginary() * rhs.getReal() -
00310                              lhs.getReal() * rhs.getImaginary()) /
00311                             (std::pow(rhs.getReal(), 2) +
00312                              std::pow(rhs.getImaginary(), 2)));
00313 }
00314 
00315 template <class T>
00316 ComplexNumber<T> operator/(const ComplexNumber<T>& lhs, const T& rhs) {
00317     // prevent division by zero
00318     if (rhs == 0) {
00319         throw DivisionByZeroException();
00320     }
00321     return ComplexNumber<T>(lhs.getReal() / rhs, lhs.getImaginary() / rhs);
00322 }
00323 
00324 template <class T>
00325 ComplexNumber<T> operator/(const T& lhs, const ComplexNumber<T>& rhs) {
00326     // prevent division by zero
00327     if (rhs == 0) {
00328         throw DivisionByZeroException();
00329     }
00330     return ComplexNumber<T>((lhs * rhs.getReal()) /
00331                             (std::pow(rhs.getReal(), 2) +
00332                              std::pow(rhs.getImaginary(), 2)),
00333                             (lhs * rhs.getImaginary()) /
00334                             (std::pow(rhs.getReal(), 2) +
00335                              std::pow(rhs.getImaginary(), 2)));
00336 }
00337 
00338 template <class T, class U>
00339 bool operator==(const ComplexNumber<T>& lhs, const ComplexNumber<U>& rhs) {
00340     return (lhs.getReal() == rhs.getReal() &&
00341             lhs.getImaginary() == rhs.getImaginary());
00342 }
00343 
00344 template <class T, class U>
00345 bool operator==(const ComplexNumber<T>& lhs, const U& rhs) {
00346     return (lhs.getReal() == rhs && lhs.getImaginary() == 0);
00347 }
00348 
00349 template <class T, class U>
00350 bool operator==(const T& lhs, const ComplexNumber<U>& rhs) {
00351     return (lhs == rhs.getReal() && rhs.getImaginary() == 0);
00352 }
00353 
00354 template <class T, class U>
00355 bool operator!=(const ComplexNumber<T>& lhs, const ComplexNumber<U>& rhs) {
00356     return (lhs.getReal() != rhs.getReal() ||
00357             lhs.getImaginary() != rhs.getImaginary());
00358 }
00359 
00360 template <class T, class U>
00361 bool operator!=(const ComplexNumber<T>& lhs, const U& rhs) {
00362     return (lhs.getReal() != rhs || lhs.getImaginary() != 0);
00363 }
00364 
00365 template <class T, class U>
00366 bool operator!=(const T& lhs, const ComplexNumber<U>& rhs) {
00367     return (lhs != rhs.getReal() || rhs.getImaginary() == 0);
00368 }
00369 
00370 template <class U>
00371 std::ostream& operator<<(std::ostream& out, const ComplexNumber<U>& z) {
00372     if (z.getImaginary() > 0) {
00373         out << z.getReal() << "+" << z.getImaginary() << "i";
00374     } else if (z.getImaginary() < 0) {
00375         out << z.getReal() << "-" << -z.getImaginary() << "i";
00376     } else {
00377         out << z.getReal();
00378     }
00379     return out;
00380 }
00381 
00382 template <class U>
00383 std::istream& operator>>(std::istream& in, ComplexNumber<U>& z) {
00384     U real, imaginary;
00385     in >> real >> imaginary;
00386     z.setReal(real);
00387     z.setImaginary(imaginary);
00388     return in;
00389 }
00390 
00391 END_NAMESPACE(complex)
00392 END_NAMESPACE(math)
00393 
00394 #endif /* COMPLEX_NUMBER_CPP */