complex.hpp

Go to the documentation of this file.
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

Submit feedback on this help topic

Copyright © 2010, Intel Corporation. All rights reserved.