00001 /**** 00002 ***** Copyright 2010 Intel Corporation All Rights Reserved. 00003 ***** 00004 ***** The source code, information and material contained herein are owned by Intel Corporation or its suppliers ***** 00005 ***** or licensors, and title to such Material remains with Intel Corporation or its suppliers or licensors. ***** 00006 ***** The Material contains proprietary information of Intel or its suppliers and licensors. The Material is ***** 00007 ***** protected by worldwide copyright laws and treaty provisions. No part of the Material may be used, copied, ***** 00008 ***** reproduced, modified, published, uploaded, posted, transmitted, distributed or disclosed in any way without ***** 00009 ***** Intel's prior express written permission. 00010 ***** 00011 ***** No license under any patent, copyright or other intellectual property rights in the material is granted to ***** 00012 ***** or conferred upon you, either expressly, by implication, inducement, estoppel or otherwise. Any license ***** 00013 ***** under such intellectual property rights must be express and approved by Intel in writing. 00014 ****/ 00015 00016 /**** Copyright Ends ****/ 00017 00018 #ifndef ARBB_CPP_COMPLEX_HPP 00019 #define ARBB_CPP_COMPLEX_HPP 00020 00021 #include <cmath> 00022 #include <complex> 00023 00024 #include "scalar.hpp" 00025 #include "detail/container.hpp" 00026 #include "type_traits.hpp" 00027 00028 namespace std { 00029 00032 00034 template <arbb_scalar_type_t T> 00035 class complex<ARBB_CPP_NS::scalar<T> > { 00036 public: 00039 typedef ARBB_CPP_NS::scalar<T> value_type; 00040 00042 complex(); 00044 complex(const complex& other); 00046 complex(const value_type& real); 00049 complex(const value_type& real, const value_type& imag); 00052 complex(typename ARBB_CPP_NS::uncaptured<value_type>::type real, 00053 typename ARBB_CPP_NS::uncaptured<value_type>::type imag); 00054 00056 template <arbb_scalar_type_t U> 00057 explicit complex(const complex<ARBB_CPP_NS::scalar<U> >& other); 00058 00060 complex& operator=(const complex& other); 00062 complex& operator+=(const complex& other); 00064 complex& operator-=(const complex& other); 00066 complex& operator*=(const complex& other); 00068 complex& operator/=(const complex& other); 00069 00071 value_type real() const; 00073 value_type imag() const; 00074 00075 private: 00076 value_type m_real; 00077 value_type m_imag; 00078 }; 00079 00081 template <arbb_scalar_type_t T> 00082 complex<ARBB_CPP_NS::scalar<T> > polar(const ARBB_CPP_NS::scalar<T>& rho, const ARBB_CPP_NS::scalar<T>& theta = ARBB_CPP_NS::scalar<T>(0)); 00083 00085 template <arbb_scalar_type_t T> 00086 complex<ARBB_CPP_NS::scalar<T> > conj(const complex<ARBB_CPP_NS::scalar<T> >& c0); 00087 00089 template <arbb_scalar_type_t T> 00090 ARBB_CPP_NS::scalar<T> real(const complex<ARBB_CPP_NS::scalar<T> >& c0); 00091 00093 template <arbb_scalar_type_t T> 00094 ARBB_CPP_NS::scalar<T> imag(const complex<ARBB_CPP_NS::scalar<T> >& c0); 00095 00097 template <arbb_scalar_type_t T> 00098 ARBB_CPP_NS::scalar<T> abs(const complex<ARBB_CPP_NS::scalar<T> >& c0); 00099 00101 template <arbb_scalar_type_t T> 00102 ARBB_CPP_NS::scalar<T> norm(const complex<ARBB_CPP_NS::scalar<T> >& c0); 00103 00105 template <arbb_scalar_type_t T> 00106 ARBB_CPP_NS::scalar<T> arg(const complex<ARBB_CPP_NS::scalar<T> >& c0); 00107 00109 template <arbb_scalar_type_t T> 00110 complex<ARBB_CPP_NS::scalar<T> > operator+(const complex<ARBB_CPP_NS::scalar<T> >& c0); 00111 00113 template <arbb_scalar_type_t T> 00114 complex<ARBB_CPP_NS::scalar<T> > operator+(const complex<ARBB_CPP_NS::scalar<T> >& c0, const complex<ARBB_CPP_NS::scalar<T> >& c1); 00116 template <arbb_scalar_type_t T> 00117 complex<ARBB_CPP_NS::scalar<T> > operator+(const ARBB_CPP_NS::scalar<T>& c0, const complex<ARBB_CPP_NS::scalar<T> >& c1); 00119 template <arbb_scalar_type_t T> 00120 complex<ARBB_CPP_NS::scalar<T> > operator+(const complex<ARBB_CPP_NS::scalar<T> >& c0, const ARBB_CPP_NS::scalar<T>& c1); 00121 00123 template <arbb_scalar_type_t T> 00124 complex<ARBB_CPP_NS::scalar<T> > operator-(const complex<ARBB_CPP_NS::scalar<T> >& c0); 00125 00127 template <arbb_scalar_type_t T> 00128 complex<ARBB_CPP_NS::scalar<T> > operator-(const complex<ARBB_CPP_NS::scalar<T> >& c0, const complex<ARBB_CPP_NS::scalar<T> >& c1); 00130 template <arbb_scalar_type_t T> 00131 complex<ARBB_CPP_NS::scalar<T> > operator-(const ARBB_CPP_NS::scalar<T>& c0, const complex<ARBB_CPP_NS::scalar<T> >& c1); 00133 template <arbb_scalar_type_t T> 00134 complex<ARBB_CPP_NS::scalar<T> > operator-(const complex<ARBB_CPP_NS::scalar<T> >& c0, const ARBB_CPP_NS::scalar<T>& c1); 00135 00137 template <arbb_scalar_type_t T> 00138 complex<ARBB_CPP_NS::scalar<T> > operator*(const complex<ARBB_CPP_NS::scalar<T> >& c0, const complex<ARBB_CPP_NS::scalar<T> >& c1); 00140 template <arbb_scalar_type_t T> 00141 complex<ARBB_CPP_NS::scalar<T> > operator*(const ARBB_CPP_NS::scalar<T>& c0, const complex<ARBB_CPP_NS::scalar<T> >& c1); 00143 template <arbb_scalar_type_t T> 00144 complex<ARBB_CPP_NS::scalar<T> > operator*(const complex<ARBB_CPP_NS::scalar<T> >& c0, const ARBB_CPP_NS::scalar<T>& c1); 00145 00147 template <arbb_scalar_type_t T> 00148 complex<ARBB_CPP_NS::scalar<T> > operator/(const complex<ARBB_CPP_NS::scalar<T> >& c0, const complex<ARBB_CPP_NS::scalar<T> >& c1); 00150 template <arbb_scalar_type_t T> 00151 complex<ARBB_CPP_NS::scalar<T> > operator/(const ARBB_CPP_NS::scalar<T>& c0, const complex<ARBB_CPP_NS::scalar<T> >& c1); 00153 template <arbb_scalar_type_t T> 00154 complex<ARBB_CPP_NS::scalar<T> > operator/(const complex<ARBB_CPP_NS::scalar<T> >& c0, const ARBB_CPP_NS::scalar<T>& c1); 00155 00157 template <arbb_scalar_type_t T> 00158 ARBB_CPP_NS::boolean operator==(const complex<ARBB_CPP_NS::scalar<T> >& c0, const complex<ARBB_CPP_NS::scalar<T> >& c1); 00160 template <arbb_scalar_type_t T> 00161 ARBB_CPP_NS::boolean operator==(const ARBB_CPP_NS::scalar<T>& c0, const complex<ARBB_CPP_NS::scalar<T> >& c1); 00163 template <arbb_scalar_type_t T> 00164 ARBB_CPP_NS::boolean operator==(const complex<ARBB_CPP_NS::scalar<T> >& c0, const ARBB_CPP_NS::scalar<T>& c1); 00165 00167 template <arbb_scalar_type_t T> 00168 ARBB_CPP_NS::boolean operator!=(const complex<ARBB_CPP_NS::scalar<T> >& c0, const complex<ARBB_CPP_NS::scalar<T> >& c1); 00170 template <arbb_scalar_type_t T> 00171 ARBB_CPP_NS::boolean operator!=(const ARBB_CPP_NS::scalar<T>& c0, const complex<ARBB_CPP_NS::scalar<T> >& c1); 00173 template <arbb_scalar_type_t T> 00174 ARBB_CPP_NS::boolean operator!=(const complex<ARBB_CPP_NS::scalar<T> >& c0, const ARBB_CPP_NS::scalar<T>& c1); 00175 00176 // Returns the complex power of @p base by @p exp. 00177 template <arbb_scalar_type_t T> 00178 complex<ARBB_CPP_NS::scalar<T> > pow(const complex<ARBB_CPP_NS::scalar<T> >& base, int exp); 00179 // Returns the complex power of @p base by @p exp. 00180 template <arbb_scalar_type_t T> 00181 complex<ARBB_CPP_NS::scalar<T> > pow(const complex<ARBB_CPP_NS::scalar<T> >& base, const ARBB_CPP_NS::scalar<T>& exp); 00182 // Returns the complex power of @p base by @p exp. 00183 template <arbb_scalar_type_t T> 00184 complex<ARBB_CPP_NS::scalar<T> > pow(const complex<ARBB_CPP_NS::scalar<T> >& base, const complex<ARBB_CPP_NS::scalar<T> >& exp); 00185 // Returns the complex power of @p base by @p exp. 00186 template <arbb_scalar_type_t T> 00187 complex<ARBB_CPP_NS::scalar<T> > pow(const ARBB_CPP_NS::scalar<T>& base, const complex<ARBB_CPP_NS::scalar<T> >& exp); 00188 00189 // Returns the complex power of @p base by @p exp. 00190 template <arbb_scalar_type_t T> 00191 complex<ARBB_CPP_NS::scalar<T> > pow(const complex<ARBB_CPP_NS::scalar<T> >& base, const typename ARBB_CPP_NS::uncaptured<ARBB_CPP_NS::scalar<T> >::type& exp); 00192 00193 // Returns the complex natural exponent of @p c0. 00194 template <arbb_scalar_type_t T> 00195 complex<ARBB_CPP_NS::scalar<T> > exp(const complex<ARBB_CPP_NS::scalar<T> >& c0); 00196 00197 // Returns the complex square root of @p c0. 00198 template <arbb_scalar_type_t T> 00199 complex<ARBB_CPP_NS::scalar<T> > sqrt(const complex<ARBB_CPP_NS::scalar<T> >& c0); 00200 00201 // Returns the complex natural logarithm of @p c0. 00202 template <arbb_scalar_type_t T> 00203 complex<ARBB_CPP_NS::scalar<T> > log(const complex<ARBB_CPP_NS::scalar<T> >& c0); 00204 // Returns the complex base ten logarithm of @p c0. 00205 template <arbb_scalar_type_t T> 00206 complex<ARBB_CPP_NS::scalar<T> > log10(const complex<ARBB_CPP_NS::scalar<T> >& c0); 00207 00209 template <arbb_scalar_type_t T> 00210 complex<ARBB_CPP_NS::scalar<T> > sin(const complex<ARBB_CPP_NS::scalar<T> >& c0); 00212 template <arbb_scalar_type_t T> 00213 complex<ARBB_CPP_NS::scalar<T> > cos(const complex<ARBB_CPP_NS::scalar<T> >& c0); 00215 template <arbb_scalar_type_t T> 00216 complex<ARBB_CPP_NS::scalar<T> > tan(const complex<ARBB_CPP_NS::scalar<T> >& c0); 00218 template <arbb_scalar_type_t T> 00219 complex<ARBB_CPP_NS::scalar<T> > sinh(const complex<ARBB_CPP_NS::scalar<T> >& c0); 00221 template <arbb_scalar_type_t T> 00222 complex<ARBB_CPP_NS::scalar<T> > cosh(const complex<ARBB_CPP_NS::scalar<T> >& c0); 00224 template <arbb_scalar_type_t T> 00225 complex<ARBB_CPP_NS::scalar<T> > tanh(const complex<ARBB_CPP_NS::scalar<T> >& c0); 00226 00227 // @} 00228 00229 } // namespace std 00230 00231 namespace ARBB_CPP_NS { 00232 00235 00237 template <arbb_scalar_type_t T> 00238 std::complex<scalar<T> > select(const ARBB_CPP_NS::boolean& flag, const std::complex<scalar<T> >& src1, const std::complex<scalar<T> >& src2); 00239 00241 00243 00244 template <arbb_scalar_type_t S, std::size_t D> 00245 dense<scalar<S>, D> real(const dense<std::complex<scalar<S> >, D>& value); 00246 00247 template <arbb_scalar_type_t S, std::size_t D> 00248 dense<scalar<S>, D> imag(const dense<std::complex<scalar<S> >, D>& value); 00249 00250 template <arbb_scalar_type_t S, std::size_t D> 00251 dense<scalar<S>, D> norm(const dense<std::complex<scalar<S> >, D>& value); 00252 00253 template <arbb_scalar_type_t S, std::size_t D> 00254 dense<std::complex<scalar<S> >, D> polar(const dense<scalar<S>, D>& rho, const dense<scalar<S>, D>& theta); 00255 00263 template <typename T, std::size_t D> 00264 dense<T, D> 00265 abs(const dense<std::complex<T>, D>& value) 00266 { 00267 return sqrt(norm(value)); 00268 } 00269 00277 template <typename T, std::size_t D> 00278 dense<std::complex<T>, D> 00279 cos(const dense<std::complex<T>, D>& value) 00280 { 00281 dense<std::complex<T>, D> result; 00282 result.template set<0>(cos(real(value)) * cosh(imag(value))); 00283 result.template set<1>(-sin(real(value)) * sinh(imag(value))); 00284 return result; 00285 } 00286 00294 template <typename T, std::size_t D> 00295 dense<std::complex<T>, D> 00296 cosh(const dense<std::complex<T>, D>& value) 00297 { 00298 dense<std::complex<T>, D> result; 00299 result.template set<0>(cosh(real(value)) * cos(imag(value))); 00300 result.template set<1>(sinh(real(value)) * sin(imag(value))); 00301 return result; 00302 } 00303 00311 template <typename T, std::size_t D> 00312 dense<std::complex<T>, D> 00313 exp(const dense<std::complex<T>, D>& value) 00314 { 00315 return polar(exp(real(value)), imag(value)); 00316 } 00317 00325 template <typename T, std::size_t D> 00326 dense<std::complex<T>, D> 00327 log(const dense<std::complex<T>, D>& value) 00328 { 00329 dense<std::complex<T>, D> result; 00330 result.template set<0>(T(0.5) * log(norm(value))); 00331 result.template set<1>(arg(value)); 00332 return result; 00333 } 00334 00342 template <typename T, std::size_t D> 00343 dense<std::complex<T>, D> 00344 log10(const dense<std::complex<T>, D>& value) 00345 { 00346 return log(value) / log(std::complex<T>(10)); 00347 } 00348 00356 template <typename T, std::size_t D> 00357 dense<std::complex<T>, D> 00358 sin(const dense<std::complex<T>, D>& value) 00359 { 00360 dense<std::complex<T>, D> result; 00361 result.template set<0>(sin(real(value)) * cosh(imag(value))); 00362 result.template set<1>(cos(real(value)) * sinh(imag(value))); 00363 return result; 00364 } 00365 00373 template <typename T, std::size_t D> 00374 dense<std::complex<T>, D> 00375 sinh(const dense<std::complex<T>, D>& value) 00376 { 00377 dense<std::complex<T>, D> result; 00378 result.template set<0>(sinh(real(value)) * cos(imag(value))); 00379 result.template set<1>(cosh(real(value)) * sin(imag(value))); 00380 return result; 00381 } 00382 00390 template <typename T, std::size_t D> 00391 dense<std::complex<T>, D> 00392 sqrt(const dense<std::complex<T>, D>& value) 00393 { 00394 dense<T, D> scale = select(max(abs(real(value)), abs(imag(value))) > T(1), T(2), T(-2)); 00395 dense<T, D> t1 = abs(value / pow(T(2), scale)); 00396 dense<T, D> rmag = pow(T(2), -scale) * abs(real(value)); 00397 dense<T, D> t2 = pow(T(2), ((scale / T(2)) - T(1))) * sqrt(T(2) * (rmag + t1)); 00398 00399 dense<T, D> t3 = imag(value) / (T(2) * t2); 00400 00401 dense<boolean, D> mk = real(value) >= T(0); 00402 dense<T, D> tr = select(mk, t2 ,t3); 00403 dense<T, D> ti = select(mk, t3, t2); 00404 00405 dense<boolean, D> mks = real(value) < T(0) && imag(value) < T(0); 00406 dense<T, D> trs = select(mks, T(-1), T(1)); 00407 dense<T, D> tis = trs; 00408 00409 dense<T, D> r = tr * trs; 00410 dense<T, D> i = ti * tis; 00411 00412 dense<boolean, D> zeromk = real(value) == T(0) && imag(value) == T(0); 00413 r = select(zeromk, T(0), r); 00414 i = select(zeromk, T(0), i); 00415 00416 dense<std::complex<T>, D> result; 00417 result.template set<0>(r); 00418 result.template set<1>(i); 00419 return result; 00420 } 00421 00429 template <typename T, std::size_t D> 00430 dense<std::complex<T>, D> 00431 tan(const dense<std::complex<T>, D>& value) 00432 { 00433 dense<std::complex<T>, D> t; 00434 t.set<0>(-imag(value)); 00435 t.set<1>(real(value)); 00436 t = tanh(t); 00437 dense<std::complex<T>, D> result; 00438 result.template set<0>(imag(t)); 00439 result.template set<1>(-real(t)); 00440 return result; 00441 } 00442 00450 template <typename T, std::size_t D> 00451 dense<std::complex<T>, D> 00452 tanh(const dense<std::complex<T>, D>& value) 00453 { 00454 dense<T, D> t1 = tan(imag(value)); 00455 dense<T, D> t2 = sinh(real(value)); 00456 dense<T, D> t3 = t2 * (t1 * t1 + T(1)); 00457 dense<T, D> t4 = T(1) + t3 * t2; 00458 00459 dense<std::complex<T>, D> result; 00460 result.template set<0>(sqrt(T(1) + t2 * t2) * t3 / t4); 00461 result.template set<1>(t1 / t4); 00462 return result; 00463 } 00464 00473 template <typename T, std::size_t D> 00474 dense<std::complex<T>, D> 00475 operator-(const dense<std::complex<T>, D>& value) 00476 { 00477 dense<std::complex<T>, D> result; 00478 result.template set<0>(-real(value)); 00479 result.template set<1>(-imag(value)); 00480 return result; 00481 } 00482 00497 template <typename T, std::size_t D> 00498 dense<std::complex<T>, D> 00499 operator+(const typename uncaptured<std::complex<T> >::type& a, const dense<std::complex<T>, D>& b) 00500 { 00501 dense<std::complex<T>, D> result; 00502 result.template set<0>(std::real(a) + real(b)); 00503 result.template set<1>(std::imag(a) + imag(b)); 00504 return result; 00505 } 00506 00518 template <typename T, std::size_t D> 00519 dense<std::complex<T>, D> 00520 operator+(const dense<std::complex<T>, D>& a, const typename uncaptured<std::complex<T> >::type& b) 00521 { 00522 dense<std::complex<T>, D> result; 00523 result.template set<0>(real(a) + b.real()); 00524 result.template set<1>(imag(a) + b.imag()); 00525 return result; 00526 } 00527 00536 template <typename T, std::size_t D> 00537 dense<std::complex<T>, D> 00538 operator+(const dense<std::complex<T>, D>& a, const dense<std::complex<T>, D>& b) 00539 { 00540 dense<std::complex<T>, D> result; 00541 result.template set<0>(real(a) + real(b)); 00542 result.template set<1>(imag(a) + imag(b)); 00543 return result; 00544 } 00545 00560 template <typename T, std::size_t D> 00561 dense<std::complex<T>, D> 00562 operator+(const std::complex<T>& a, const dense<std::complex<T>, D>& b) 00563 { 00564 dense<std::complex<T>, D> result; 00565 result.template set<0>(a.real() + real(b)); 00566 result.template set<1>(a.imag() + imag(b)); 00567 return result; 00568 } 00569 00581 template <typename T, std::size_t D> 00582 dense<std::complex<T>, D> 00583 operator+(const dense<std::complex<T>, D>& a, const std::complex<T>& b) 00584 { 00585 dense<std::complex<T>, D> result; 00586 result.template set<0>(real(a) + b.real()); 00587 result.template set<1>(imag(a) + b.imag()); 00588 return result; 00589 } 00590 00602 template <typename T, std::size_t D> 00603 dense<std::complex<T>, D>& 00604 operator+=(dense<std::complex<T>, D>& value, const typename uncaptured<std::complex<T> >::type& increment) 00605 { 00606 value.template set<0>(real(value) + increment.real()); 00607 value.template set<1>(imag(value) + increment.imag()); 00608 return value; 00609 } 00610 00619 template <typename T, std::size_t D> 00620 dense<std::complex<T>, D>& 00621 operator+=(dense<std::complex<T>, D>& value, const dense<std::complex<T>, D>& increment) 00622 { 00623 value.template set<0>(real(value) + real(increment)); 00624 value.template set<1>(imag(value) + imag(increment)); 00625 return value; 00626 } 00627 00639 template <typename T, std::size_t D> 00640 dense<std::complex<T>, D>& 00641 operator+=(dense<std::complex<T>, D>& value, const std::complex<T>& increment) 00642 { 00643 value.template set<0>(real(value) + increment.real()); 00644 value.template set<1>(imag(value) + increment.imag()); 00645 return value; 00646 } 00647 00662 template <typename T, std::size_t D> 00663 dense<std::complex<T>, D> 00664 operator/(const typename uncaptured<std::complex<T> >::type& numerator, const dense<std::complex<T>, D>& denominator) 00665 { 00666 dense<T, D> d = norm(denominator); 00667 dense<std::complex<T>, D> result; 00668 result.template set<0>((real(numerator) * real(denominator) + imag(numerator) * imag(denominator)) / d); 00669 result.template set<1>((imag(numerator) * real(denominator) - real(numerator) * imag(denominator)) / d); 00670 return result; 00671 } 00672 00684 template <typename T, std::size_t D> 00685 dense<std::complex<T>, D> 00686 operator/(const dense<std::complex<T>, D>& numerator, const typename uncaptured<std::complex<T> >::type& denominator) 00687 { 00688 T d = std::norm(denominator); 00689 dense<std::complex<T>, D> result; 00690 result.template set<0>((real(numerator) * real(denominator) + imag(numerator) * imag(denominator)) / d); 00691 result.template set<1>((imag(numerator) * real(denominator) - real(numerator) * imag(denominator)) / d); 00692 return result; 00693 } 00694 00703 template <typename T, std::size_t D> 00704 dense<std::complex<T>, D> 00705 operator/(const dense<std::complex<T>, D>& numerator, const dense<std::complex<T>, D>& denominator) 00706 { 00707 dense<T, D> d = norm(denominator); 00708 dense<std::complex<T>, D> result; 00709 result.template set<0>((real(numerator) * real(denominator) + imag(numerator) * imag(denominator)) / d); 00710 result.template set<1>((imag(numerator) * real(denominator) - real(numerator) * imag(denominator)) / d); 00711 return result; 00712 } 00713 00728 template <typename T, std::size_t D> 00729 dense<std::complex<T>, D> 00730 operator/(const std::complex<T>& numerator, const dense<std::complex<T>, D>& denominator) 00731 { 00732 dense<T, D> d = norm(denominator); 00733 dense<std::complex<T>, D> result; 00734 result.template set<0>((numerator.real() * real(denominator) + numerator.imag() * imag(denominator)) / d); 00735 result.template set<1>((numerator.imag() * real(denominator) - numerator.real() * imag(denominator)) / d); 00736 return result; 00737 } 00738 00750 template <typename T, std::size_t D> 00751 dense<std::complex<T>, D> 00752 operator/(const dense<std::complex<T>, D>& numerator, const std::complex<T>& denominator) 00753 { 00754 T d = std::norm(denominator); 00755 dense<std::complex<T>, D> result; 00756 result.template set<0>((real(numerator) * denominator.real() + imag(numerator) * denominator.imag()) / d); 00757 result.template set<1>((imag(numerator) * denominator.real() - real(numerator) * denominator.imag()) / d); 00758 return result; 00759 } 00760 00761 template <typename T, std::size_t D> 00762 dense<std::complex<T>, D> 00763 operator/(const dense<std::complex<T>, D>& numerator, const T& denominator) 00764 { 00765 T d = denominator * denominator; 00766 dense<std::complex<T>, D> result; 00767 result.template set<0>((real(numerator) * real(denominator)) / d); 00768 result.template set<1>((imag(numerator) * real(denominator)) / d); 00769 return result; 00770 } 00771 00772 template <typename T, std::size_t D> 00773 dense<std::complex<T>, D> 00774 operator/(const dense<std::complex<T>, D>& numerator, const typename uncaptured<T>::type& denominator) 00775 { 00776 T d = denominator * denominator; 00777 dense<std::complex<T>, D> result; 00778 result.template set<0>((real(numerator) * real(denominator)) / d); 00779 result.template set<1>((imag(numerator) * real(denominator)) / d); 00780 return result; 00781 } 00782 00783 template <typename T, std::size_t D> 00784 dense<std::complex<T>, D> 00785 operator/(const T& numerator, const dense<std::complex<T>, D>& denominator) 00786 { 00787 T d = std::norm(denominator); 00788 dense<std::complex<T>, D> result; 00789 result.template set<0>((numerator * real(denominator)) / d); 00790 result.template set<1>((-numerator * imag(denominator)) / d); 00791 return result; 00792 } 00793 00794 template <typename T, std::size_t D> 00795 dense<std::complex<T>, D> 00796 operator/(const typename uncaptured<T>::type& numerator, const dense<std::complex<T>, D>& denominator) 00797 { 00798 T d = std::norm(denominator); 00799 dense<std::complex<T>, D> result; 00800 result.template set<0>((numerator * real(denominator)) / d); 00801 result.template set<1>((-numerator * imag(denominator)) / d); 00802 return result; 00803 } 00804 00805 template <typename T, std::size_t D> 00806 dense<std::complex<T>, D> 00807 operator/(const dense<std::complex<T>, D>& numerator, const dense<T, D>& denominator) 00808 { 00809 dense<T, D> d = denominator * denominator; 00810 dense<std::complex<T>, D> result; 00811 result.template set<0>((real(numerator) * denominator) / d); 00812 result.template set<1>((imag(numerator) * denominator) / d); 00813 return result; 00814 } 00815 00816 00828 template <typename T, std::size_t D> 00829 dense<std::complex<T>, D>& 00830 operator/=(dense<std::complex<T>, D>& value, const typename uncaptured<std::complex<T> >::type& denominator) 00831 { 00832 T d = std::norm(denominator); 00833 dense<std::complex<T>, D> result; 00834 result.template set<0>((real(value) * real(denominator) + imag(value) * imag(denominator)) / d); 00835 result.template set<1>((imag(value) * real(denominator) - real(value) * imag(denominator)) / d); 00836 value = result; 00837 return value; 00838 } 00839 00848 template <typename T, std::size_t D> 00849 dense<std::complex<T>, D>& 00850 operator/=(dense<std::complex<T>, D>& value, const dense<std::complex<T>, D>& denominator) 00851 { 00852 dense<T, D> d = norm(denominator); 00853 dense<std::complex<T>, D> result; 00854 result.template set<0>((real(value) * real(denominator) + imag(value) * imag(denominator)) / d); 00855 result.template set<1>((imag(value) * real(denominator) - real(value) * imag(denominator)) / d); 00856 value = result; 00857 return value; 00858 } 00859 00871 template <typename T, std::size_t D> 00872 dense<std::complex<T>, D>& 00873 operator/=(dense<std::complex<T>, D>& value, const std::complex<T>& denominator) 00874 { 00875 T d = std::norm(denominator); 00876 dense<std::complex<T>, D> result; 00877 result.template set<0>((real(value) * denominator.real() + imag(value) * denominator.imag()) / d); 00878 result.template set<1>((imag(value) * denominator.real() - real(value) * denominator.imag()) / d); 00879 value = result; 00880 return value; 00881 } 00882 00883 template <typename T, std::size_t D> 00884 dense<std::complex<T>, D>& 00885 operator/=(dense<std::complex<T>, D>& value, const T& denominator) 00886 { 00887 T d = denominator * denominator; 00888 dense<std::complex<T>, D> result; 00889 result.template set<0>((real(value) * real(denominator)) / d); 00890 result.template set<1>((imag(value) * real(denominator)) / d); 00891 value = result; 00892 return value; 00893 } 00894 00895 template <typename T, std::size_t D> 00896 dense<std::complex<T>, D>& 00897 operator/=(dense<std::complex<T>, D>& value, const typename uncaptured<T>::type& denominator) 00898 { 00899 T d = denominator * denominator; 00900 dense<std::complex<T>, D> result; 00901 value.template set<0>((real(value) * real(denominator)) / d); 00902 value.template set<1>((imag(value) * real(denominator)) / d); 00903 value = result; 00904 return value; 00905 } 00906 00907 template <typename T, std::size_t D> 00908 dense<std::complex<T>, D>& 00909 operator/=(dense<std::complex<T>, D>& value, const dense<T, D>& denominator) 00910 { 00911 dense<T, D> d = denominator * denominator; 00912 dense<std::complex<T>, D> result; 00913 result.template set<0>((real(value) * denominator) / d); 00914 result.template set<1>((imag(value) * denominator) / d); 00915 value = result; 00916 return value; 00917 } 00918 00932 template <typename T, std::size_t D> 00933 dense<boolean, D> 00934 operator==(const typename uncaptured<std::complex<T> >::type& a, const dense<std::complex<T>, D>& b) 00935 { 00936 return real(a) == real(b) && imag(a) == imag(b); 00937 } 00938 00949 template <typename T, std::size_t D> 00950 dense<boolean, D> 00951 operator==(const dense<std::complex<T>, D>& a, const typename uncaptured<std::complex<T> >::type& b) 00952 { 00953 return real(a) == real(b) && imag(a) == imag(b); 00954 } 00955 00963 template <typename T, std::size_t D> 00964 dense<boolean, D> 00965 operator==(const dense<std::complex<T>, D>& a, const dense<std::complex<T>, D>& b) 00966 { 00967 return real(a) == real(b) && imag(a) == imag(b); 00968 } 00969 00983 template <typename T, std::size_t D> 00984 dense<boolean, D> 00985 operator==(const std::complex<T>& a, const dense<std::complex<T>, D>& b) 00986 { 00987 return a.real() == real(b) && a.imag() == imag(b); 00988 } 00989 01000 template <typename T, std::size_t D> 01001 dense<boolean, D> 01002 operator==(const dense<std::complex<T>, D>& a, const std::complex<T>& b) 01003 { 01004 return real(a) == b.real() && imag(a) == b.imag(); 01005 } 01006 01021 template <typename T, std::size_t D> 01022 dense<std::complex<T>, D> 01023 operator*(const typename uncaptured<std::complex<T> >::type& a, const dense<std::complex<T>, D>& b) 01024 { 01025 dense<std::complex<T>, D> result; 01026 result.template set<0>(real(a) * real(b) - imag(a) * imag(b)); 01027 result.template set<1>(imag(a) * real(b) + real(a) * imag(b)); 01028 return result; 01029 } 01030 01042 template <typename T, std::size_t D> 01043 dense<std::complex<T>, D> 01044 operator*(const dense<std::complex<T>, D>& a, const typename uncaptured<std::complex<T> >::type& b) 01045 { 01046 dense<std::complex<T>, D> result; 01047 result.template set<0>(real(a) * real(b) - imag(a) * imag(b)); 01048 result.template set<1>(imag(a) * real(b) + real(a) * imag(b)); 01049 return result; 01050 } 01051 01060 template <typename T, std::size_t D> 01061 dense<std::complex<T>, D> 01062 operator*(const dense<std::complex<T>, D>& a, const dense<std::complex<T>, D>& b) 01063 { 01064 dense<std::complex<T>, D> result; 01065 result.template set<0>(real(a) * real(b) - imag(a) * imag(b)); 01066 result.template set<1>(imag(a) * real(b) + real(a) * imag(b)); 01067 return result; 01068 } 01069 01084 template <typename T, std::size_t D> 01085 dense<std::complex<T>, D> 01086 operator*(const std::complex<T>& a, const dense<std::complex<T>, D>& b) 01087 { 01088 dense<std::complex<T>, D> result; 01089 result.template set<0>(a.real() * real(b) - a.imag() * imag(b)); 01090 result.template set<1>(a.imag() * real(b) + a.real() * imag(b)); 01091 return result; 01092 } 01093 01105 template <typename T, std::size_t D> 01106 dense<std::complex<T>, D> 01107 operator*(const dense<std::complex<T>, D>& a, const std::complex<T>& b) 01108 { 01109 dense<std::complex<T>, D> result; 01110 result.template set<0>(real(a) * b.real() - imag(a) * b.imag()); 01111 result.template set<1>(imag(a) * b.real() + real(a) * b.imag()); 01112 return result; 01113 } 01114 01115 template <typename T, std::size_t D> 01116 dense<std::complex<T>, D> 01117 operator*(const dense<std::complex<T>, D>& a, const T& b) 01118 { 01119 dense<std::complex<T>, D> result; 01120 result.template set<0>(real(a) * b); 01121 result.template set<1>(imag(a) * b); 01122 return result; 01123 } 01124 01125 template <typename T, std::size_t D> 01126 dense<std::complex<T>, D> 01127 operator*(const dense<std::complex<T>, D>& a, const typename uncaptured<T>::type& b) 01128 { 01129 dense<std::complex<T>, D> result; 01130 result.template set<0>(real(a) * b); 01131 result.template set<1>(imag(a) * b); 01132 return result; 01133 } 01134 01135 template <typename T, std::size_t D> 01136 dense<std::complex<T>, D> 01137 operator*(const T& a, const dense<std::complex<T>, D>& b) 01138 { 01139 dense<std::complex<T>, D> result; 01140 result.template set<0>(a * real(b)); 01141 result.template set<1>(a * imag(b)); 01142 return result; 01143 } 01144 01145 template <typename T, std::size_t D> 01146 dense<std::complex<T>, D> 01147 operator*(const typename uncaptured<T>::type& a, const dense<std::complex<T>, D>& b) 01148 { 01149 dense<std::complex<T>, D> result; 01150 result.template set<0>(a * real(b)); 01151 result.template set<1>(a * imag(b)); 01152 return result; 01153 } 01154 01155 template <typename T, std::size_t D> 01156 dense<std::complex<T>, D> 01157 operator*(const dense<std::complex<T>, D>& a, const dense<T, D>& b) 01158 { 01159 dense<std::complex<T>, D> result; 01160 result.template set<0>(real(a) * b); 01161 result.template set<1>(imag(a) * b); 01162 return result; 01163 } 01164 01176 template <typename T, std::size_t D> 01177 dense<std::complex<T>, D>& 01178 operator*=(dense<std::complex<T>, D>& value, const typename uncaptured<std::complex<T> >::type& multiplicand) 01179 { 01180 dense<std::complex<T>, D> result; 01181 result.template set<0>(real(value) * real(multiplicand) - imag(value) * imag(multiplicand)); 01182 result.template set<1>(imag(value) * real(multiplicand) + real(value) * imag(multiplicand)); 01183 value = result; 01184 return value; 01185 } 01186 01195 template <typename T, std::size_t D> 01196 dense<std::complex<T>, D>& 01197 operator*=(dense<std::complex<T>, D>& value, const dense<std::complex<T>, D>& multiplicand) 01198 { 01199 dense<std::complex<T>, D> result; 01200 result.template set<0>(real(value) * real(multiplicand) - imag(value) * imag(multiplicand)); 01201 result.template set<1>(imag(value) * real(multiplicand) + real(value) * imag(multiplicand)); 01202 value = result; 01203 return value; 01204 } 01205 01217 template <typename T, std::size_t D> 01218 dense<std::complex<T>, D>& 01219 operator*=(dense<std::complex<T>, D>& value, const std::complex<T>& multiplicand) 01220 { 01221 dense<std::complex<T>, D> result; 01222 result.template set<0>(real(value) * multiplicand.real() - imag(value) * multiplicand.imag()); 01223 result.template set<1>(imag(value) * multiplicand.real() + real(value) * multiplicand.imag()); 01224 value = result; 01225 return value; 01226 } 01227 01228 template <typename T, std::size_t D> 01229 dense<std::complex<T>, D>& 01230 operator*=(dense<std::complex<T>, D>& value, const T& multiplicand) 01231 { 01232 dense<std::complex<T>, D> result; 01233 result.template set<0>(real(value) * multiplicand); 01234 result.template set<1>(imag(value) * multiplicand); 01235 value = result; 01236 return value; 01237 } 01238 01239 template <typename T, std::size_t D> 01240 dense<std::complex<T>, D>& 01241 operator*=(dense<std::complex<T>, D>& value, const typename uncaptured<T>::type& multiplicand) 01242 { 01243 dense<std::complex<T>, D> result; 01244 result.template set<0>(real(value) * multiplicand); 01245 result.template set<1>(imag(value) * multiplicand); 01246 value = result; 01247 return value; 01248 } 01249 01250 template <typename T, std::size_t D> 01251 dense<std::complex<T>, D>& 01252 operator*=(dense<std::complex<T>, D>& value, const dense<T, D>& multiplicand) 01253 { 01254 dense<std::complex<T>, D> result; 01255 result.template set<0>(real(value) * multiplicand); 01256 result.template set<1>(imag(value) * multiplicand); 01257 value = result; 01258 return value; 01259 } 01260 01274 template <typename T, std::size_t D> 01275 dense<boolean, D> 01276 operator!=(const typename uncaptured<std::complex<T> >::type& a, const dense<std::complex<T>, D>& b) 01277 { 01278 return real(a) != real(b) || imag(a) != imag(b); 01279 } 01280 01291 template <typename T, std::size_t D> 01292 dense<boolean, D> 01293 operator!=(const dense<std::complex<T>, D>& a, const typename uncaptured<std::complex<T> >::type& b) 01294 { 01295 return real(a) != real(b) || imag(a) != imag(b); 01296 } 01297 01305 template <typename T, std::size_t D> 01306 dense<boolean, D> 01307 operator!=(const dense<std::complex<T>, D>& a, const dense<std::complex<T>, D>& b) 01308 { 01309 return real(a) != real(b) || imag(a) != imag(b); 01310 } 01311 01325 template <typename T, std::size_t D> 01326 dense<boolean, D> 01327 operator!=(const std::complex<T>& a, const dense<std::complex<T>, D>& b) 01328 { 01329 return a.real() != real(b) || a.imag() != imag(b); 01330 } 01331 01342 template <typename T, std::size_t D> 01343 dense<boolean, D> 01344 operator!=(const dense<std::complex<T>, D>& a, const std::complex<T>& b) 01345 { 01346 return real(a) != b.real() || imag(a) != b.imag(); 01347 } 01348 01363 template <typename T, std::size_t D> 01364 dense<std::complex<T>, D> 01365 pow(const typename uncaptured<std::complex<T> >::type& base, const dense<std::complex<T>, D>& exponent) 01366 { 01367 return exp(exponent * log(base)); 01368 } 01369 01381 template <typename T, std::size_t D> 01382 dense<std::complex<T>, D> 01383 pow(const dense<std::complex<T>, D>& base, const typename uncaptured<std::complex<T> >::type& exponent) 01384 { 01385 return exp(exponent * log(base)); 01386 } 01387 01396 template <typename T, std::size_t D> 01397 dense<std::complex<T>, D> 01398 pow(const dense<std::complex<T>, D>& base, const dense<std::complex<T>, D>& exponent) 01399 { 01400 return exp(exponent * log(base)); 01401 } 01402 01417 template <typename T, std::size_t D> 01418 dense<std::complex<T>, D> 01419 pow(const std::complex<T>& base, const dense<std::complex<T>, D>& exponent) 01420 { 01421 return exp(exponent * log(base)); 01422 } 01423 01435 template <typename T, std::size_t D> 01436 dense<std::complex<T>, D> 01437 pow(const dense<std::complex<T>, D>& base, const std::complex<T>& exponent) 01438 { 01439 return exp(exponent * log(base)); 01440 } 01441 01456 template <typename T, std::size_t D> 01457 dense<std::complex<T>, D> 01458 operator-(const typename uncaptured<std::complex<T> >::type& value, const dense<std::complex<T>, D>& amount) 01459 { 01460 dense<std::complex<T>, D> result; 01461 result.template set<0>(value.real() - real(amount)); 01462 result.template set<1>(value.imag() - imag(amount)); 01463 return result; 01464 } 01465 01477 template <typename T, std::size_t D> 01478 dense<std::complex<T>, D> 01479 operator-(const dense<std::complex<T>, D>& value, const typename uncaptured<std::complex<T> >::type& amount) 01480 { 01481 dense<std::complex<T>, D> result; 01482 result.template set<0>(real(value) - amount.real()); 01483 result.template set<1>(imag(value) - amount.imag()); 01484 return result; 01485 } 01486 01495 template <typename T, std::size_t D> 01496 dense<std::complex<T>, D> 01497 operator-(const dense<std::complex<T>, D>& value, const dense<std::complex<T>, D>& amount) 01498 { 01499 dense<std::complex<T>, D> result; 01500 result.template set<0>(real(value) - real(amount)); 01501 result.template set<1>(imag(value) - imag(amount)); 01502 return result; 01503 } 01504 01519 template <typename T, std::size_t D> 01520 dense<std::complex<T>, D> 01521 operator-(const std::complex<T>& value, const dense<std::complex<T>, D>& amount) 01522 { 01523 dense<std::complex<T>, D> result; 01524 result.template set<0>(value.real() - real(amount)); 01525 result.template set<1>(value.imag() - imag(amount)); 01526 return result; 01527 } 01528 01540 template <typename T, std::size_t D> 01541 dense<std::complex<T>, D> 01542 operator-(const dense<std::complex<T>, D>& value, const std::complex<T>& amount) 01543 { 01544 dense<std::complex<T>, D> result; 01545 result.template set<0>(real(value) - amount.real()); 01546 result.template set<1>(imag(value) - amount.imag()); 01547 return result; 01548 } 01549 01561 template <typename T, std::size_t D> 01562 dense<std::complex<T>, D>& 01563 operator-=(dense<std::complex<T>, D>& value, const typename uncaptured<std::complex<T> >::type& amount) 01564 { 01565 value.template set<0>(real(value) - amount.real()); 01566 value.template set<1>(imag(value) - amount.imag()); 01567 return value; 01568 } 01569 01578 template <typename T, std::size_t D> 01579 dense<std::complex<T>, D>& 01580 operator-=(dense<std::complex<T>, D>& value, const dense<std::complex<T>, D>& amount) 01581 { 01582 value.template set<0>(real(value) - real(amount)); 01583 value.template set<1>(imag(value) - imag(amount)); 01584 return value; 01585 } 01586 01598 template <typename T, std::size_t D> 01599 dense<std::complex<T>, D>& 01600 operator-=(dense<std::complex<T>, D>& value, const std::complex<T>& amount) 01601 { 01602 value.template set<0>(real(value) - amount.real()); 01603 value.template set<1>(imag(value) - amount.imag()); 01604 return value; 01605 } 01606 01621 template <typename T, std::size_t D> 01622 dense<std::complex<T>, D> 01623 select(const typename uncaptured<boolean >::type& condition, const dense<std::complex<T>, D>& true_case, const dense<std::complex<T>, D>& false_case) 01624 { 01625 dense<std::complex<T>, D> result; 01626 result.template set<0>(select(condition, true_case.real(), real(false_case))); 01627 result.template set<1>(select(condition, true_case.imag(), imag(false_case))); 01628 return result; 01629 } 01630 01645 template <typename T, std::size_t D> 01646 dense<std::complex<T>, D> 01647 select(const dense<boolean, D>& condition, const typename uncaptured<std::complex<T> >::type& true_case, const dense<std::complex<T>, D>& false_case) 01648 { 01649 dense<std::complex<T>, D> result; 01650 result.template set<0>(select(condition, true_case.real(), real(false_case))); 01651 result.template set<1>(select(condition, true_case.imag(), imag(false_case))); 01652 return result; 01653 } 01654 01672 template <typename T, std::size_t D> 01673 dense<std::complex<T>, D> 01674 select(const typename uncaptured<boolean >::type& condition, const typename uncaptured<std::complex<T> >::type& true_case, const dense<std::complex<T>, D>& false_case) 01675 { 01676 dense<std::complex<T>, D> result; 01677 result.template set<0>(select(condition, true_case.real(), real(false_case))); 01678 result.template set<1>(select(condition, true_case.imag(), imag(false_case))); 01679 return result; 01680 } 01681 01693 template <typename T, std::size_t D> 01694 dense<std::complex<T>, D> 01695 select(const dense<boolean, D>& condition, const dense<std::complex<T>, D>& true_case, const typename uncaptured<std::complex<T> >::type& false_case) 01696 { 01697 dense<std::complex<T>, D> result; 01698 result.template set<0>(select(condition, real(true_case), false_case.real())); 01699 result.template set<1>(select(condition, imag(true_case), false_case.imag())); 01700 return result; 01701 } 01702 01717 template <typename T, std::size_t D> 01718 dense<std::complex<T>, D> 01719 select(const typename uncaptured<boolean >::type& condition, const dense<std::complex<T>, D>& true_case, const typename uncaptured<std::complex<T> >::type& false_case) 01720 { 01721 dense<std::complex<T>, D> result; 01722 result.template set<0>(select(condition, real(true_case), false_case.real())); 01723 result.template set<1>(select(condition, imag(true_case), false_case.imag())); 01724 return result; 01725 } 01726 01735 template <typename T, std::size_t D> 01736 dense<std::complex<T>, D> 01737 select(const dense<boolean, D>& condition, const dense<std::complex<T>, D>& true_case, const dense<std::complex<T>, D>& false_case) 01738 { 01739 dense<std::complex<T>, D> result; 01740 result.template set<0>(select(condition, real(true_case), real(false_case))); 01741 result.template set<1>(select(condition, imag(true_case), imag(false_case))); 01742 return result; 01743 } 01744 01759 template <typename T, std::size_t D> 01760 dense<std::complex<T>, D> 01761 select(const boolean& condition, const dense<std::complex<T>, D>& true_case, const dense<std::complex<T>, D>& false_case) 01762 { 01763 dense<std::complex<T>, D> result; 01764 result.template set<0>(select(condition, real(true_case), real(false_case))); 01765 result.template set<1>(select(condition, imag(true_case), imag(false_case))); 01766 return result; 01767 } 01768 01783 template <typename T, std::size_t D> 01784 dense<std::complex<T>, D> 01785 select(const dense<boolean, D>& condition, const std::complex<T>& true_case, const dense<std::complex<T>, D>& false_case) 01786 { 01787 dense<std::complex<T>, D> result; 01788 result.template set<0>(select(condition, true_case.real(), real(false_case))); 01789 result.template set<1>(select(condition, true_case.imag(), imag(false_case))); 01790 return result; 01791 } 01792 01810 template <typename T, std::size_t D> 01811 dense<std::complex<T>, D> 01812 select(const boolean& condition, const std::complex<T>& true_case, const dense<std::complex<T>, D>& false_case) 01813 { 01814 dense<std::complex<T>, D> result; 01815 result.template set<0>(select(condition, true_case.real(), real(false_case))); 01816 result.template set<1>(select(condition, true_case.imag(), imag(false_case))); 01817 return result; 01818 } 01819 01831 template <typename T, std::size_t D> 01832 dense<std::complex<T>, D> 01833 select(const dense<boolean, D>& condition, const dense<std::complex<T>, D>& true_case, const std::complex<T>& false_case) 01834 { 01835 dense<std::complex<T>, D> result; 01836 result.template set<0>(select(condition, real(true_case), false_case.real())); 01837 result.template set<1>(select(condition, imag(true_case), false_case.imag())); 01838 return result; 01839 } 01840 01855 template <typename T, std::size_t D> 01856 dense<std::complex<T>, D> 01857 select(const boolean& condition, const dense<std::complex<T>, D>& true_case, const std::complex<T>& false_case) 01858 { 01859 dense<std::complex<T>, D> result; 01860 result.template set<0>(select(condition, real(true_case), false_case.real())); 01861 result.template set<1>(select(condition, imag(true_case), false_case.imag())); 01862 return result; 01863 } 01864 01879 template <typename T, std::size_t D> 01880 dense<std::complex<T>, D> 01881 select(const dense<boolean, D>& condition, const std::complex<T>& true_case, const std::complex<T>& false_case) 01882 { 01883 dense<std::complex<T>, D> result; 01884 result.template set<0>(select(condition, true_case.real(), false_case.real())); 01885 result.template set<1>(select(condition, true_case.imag(), false_case.imag())); 01886 return result; 01887 } 01888 01890 01891 } // namespace ARBB_CPP_NS 01892 01893 #endif // ARBB_CPP_COMPLEX_HPP
Copyright © 2010, Intel Corporation. All rights reserved.