00001 #ifndef BxComplexH
00002 #define BxComplexH
00003
00004
00005 #include <math.h>
00006
00007 #define _RWSTD_C_SCOPE_POW ::powl
00008 #define _RWSTD_C_SCOPE_LOG ::logl
00009 #define _RWSTD_C_SCOPE_COS ::cosl
00010 #define _RWSTD_C_SCOPE_SIN ::sinl
00011 #define _RWSTD_C_SCOPE_EXP ::expl
00012 #define _RWSTD_C_SCOPE_SQRT ::sqrtl
00013 #define _RWSTD_C_SCOPE_ATAN2 ::atan2l
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032 #ifndef _RWSTD_NO_NAMESPACE
00033 namespace std {
00034 #endif
00035
00036 template <class T>
00037 inline T absl (const complex<T>& a) { return (_RWSTD_C_SCOPE_SQRT(norm(a))); }
00038
00039 template <class T>
00040 inline T argl (const complex<T>& a)
00041 {
00042 return a == complex<T>(0,0) ? T(0) : _RWSTD_C_SCOPE_ATAN2(a.imag(), a.real());
00043 }
00044
00045 template <class T>
00046 inline complex<T> logl (const complex<T>& a)
00047 {
00048 return complex<T>(_RWSTD_C_SCOPE_LOG(absl(a)), argl(a));
00049 }
00050
00051 template <class T>
00052 inline complex<T> expl (const complex<T>& a)
00053 {
00054 register T e = _RWSTD_C_SCOPE_EXP(a.real());
00055 return complex<T>(e*_RWSTD_C_SCOPE_COS(a.imag()), e*_RWSTD_C_SCOPE_SIN(a.imag()));
00056 }
00057
00058 template <class T>
00059 inline complex<T> powl (const complex<T>& a, const T& s)
00060 {
00061 if (a == complex<T>(0,0))
00062 {
00063 if (s == T(0))
00064 return complex<T>(1,0);
00065 else
00066 return complex<T>(0,0);
00067 }
00068 if (a.imag() == 0)
00069 {
00070 if (a.real() < 0)
00071 return powl(a, complex<T>(s,0));
00072 else
00073 #ifndef _RWSTD_NO_OVERLOAD_C_POW
00074 return complex<T>(_RWSTD_C_SCOPE_POW(a.real(),s), 0);
00075 #else
00076 return complex<T>(_RWSTD_C_SCOPE_POW((long double)(a.real()),(long double)(s)), 0);
00077 #endif
00078 }
00079 return expl(s*logl(a));
00080 }
00081
00082 template <class T>
00083 inline complex<T> powl (const complex<T>& a, int n)
00084 {
00085 if (a == complex<T>(0,0))
00086 {
00087 if (n == 0)
00088 return complex<T>(1,0);
00089 else
00090 return complex<T>(0,0);
00091 }
00092
00093 if (a.imag() == 0)
00094 {
00095 if (a.real() < 0)
00096 return powl(a, complex<T>(n,0));
00097 else
00098 #ifndef _RWSTD_NO_OVERLOAD_C_POW
00099 return complex<T>(_RWSTD_C_SCOPE_POW(a.real(),T(n)), 0);
00100 #else
00101 return complex<T>(_RWSTD_C_SCOPE_POW((long double)(a.real()),(long double)(n)), 0);
00102 #endif
00103 }
00104
00105 #ifndef _RWSTD_NO_OVERLOAD_C_POW
00106 register T r = _RWSTD_C_SCOPE_POW(T(absl(a)), T(n));
00107 #else
00108 register T r = _RWSTD_C_SCOPE_POW((long double)(absl(a)), (long double)(n));
00109 #endif
00110
00111 register T th = T(n) * argl(a);
00112
00113 return complex<T>(r*_RWSTD_C_SCOPE_COS(th), r*_RWSTD_C_SCOPE_SIN(th));
00114 }
00115
00116 template <class T>
00117 inline complex<T> powl (const complex<T>& a1, const complex<T>& a2)
00118 {
00119 if (a1 == complex<T>(0,0))
00120 {
00121 if (a2 == complex<T>(0,0))
00122 return complex<T>(1,0);
00123 else
00124 return complex<T>(0,0);
00125 }
00126
00127 T r1 = absl(a1);
00128 T u2 = real(a2);
00129 T v2 = imag(a2);
00130 T th1 = argl(a1);
00131 #ifndef _RWSTD_NO_OVERLOAD_C_POW
00132 T rho = _RWSTD_C_SCOPE_POW(r1, u2) * _RWSTD_C_SCOPE_EXP(-v2 *th1);
00133 #else
00134 T rho = _RWSTD_C_SCOPE_POW(r1, u2) * _RWSTD_C_SCOPE_EXP(-v2 *th1);
00135 #endif
00136 T phi = v2 * _RWSTD_C_SCOPE_LOG(r1) + u2 * th1;
00137
00138 return complex<T>(rho*_RWSTD_C_SCOPE_COS(phi), rho*_RWSTD_C_SCOPE_SIN(phi));
00139 }
00140
00141 template <class T>
00142 inline complex<T> powl (const T& s, const complex<T>& a)
00143 {
00144 if (s == T(0))
00145 {
00146 if (a == complex<T>(0,0))
00147 return complex<T>(1,0);
00148 else
00149 return complex<T>(0,0);
00150 }
00151 if (s < 0)
00152 return powl(complex<T>(s,0), a);
00153
00154 if (a.imag() == 0)
00155 #ifndef _RWSTD_NO_OVERLOAD_C_POW
00156 return complex<T>(_RWSTD_C_SCOPE_POW(s, a.real()), 0);
00157 #else
00158 return complex<T>(_RWSTD_C_SCOPE_POW(s, a.real()), 0);
00159 #endif
00160
00161 return complex<T>(expl(a * (T) _RWSTD_C_SCOPE_LOG(s)));
00162 }
00163
00164 #ifndef _RWSTD_NO_NAMESPACE
00165 }
00166 #endif
00167
00168 #endif //BxComplexH