Complex Number 0.1.2 |
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 */