00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032 #ifndef MORE_MATH_COMPLEX_H
00033 #define MORE_MATH_COMPLEX_H
00034
00035 #include <complex>
00036 #include <more/bits/mathbits.h>
00037 #include <more/io/fwd.h>
00038
00039 namespace more {
00040 namespace math {
00041
00042 using std::complex;
00043 using std::real;
00044 using std::imag;
00045 using std::norm;
00046 using std::conj;
00047 using std::operator+;
00048 using std::operator-;
00049 using std::operator*;
00050 using std::operator/;
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060 struct onei_tag {
00061 operator complex<char>() const { return complex<char>(0, 1); }
00062 operator complex<short>() const { return complex<short>(0, 1); }
00063 operator complex<int>() const { return complex<int>(0, 1); }
00064 operator complex<long>() const { return complex<long>(0, 1l); }
00065 operator complex<float>() const
00066 { return complex<float>(0.0f, 1.0f); }
00067 operator complex<double>() const
00068 { return complex<double>(0.0, 1.0); }
00069 operator complex<long double>() const
00070 { return complex<long double>(0.0l, 1.0l); }
00071 };
00072 extern onei_tag onei;
00073 struct minus_onei_tag {
00074 operator complex<char>() const { return complex<char>(0, -1); }
00075 operator complex<short>() const { return complex<short>(0, -1); }
00076 operator complex<int>() const { return complex<int>(0, -1); }
00077 operator complex<long>() const { return complex<long>(0, -1l); }
00078 operator complex<float>() const
00079 { return complex<float>(0.0f, -1.0f); }
00080 operator complex<double>() const
00081 { return complex<double>(0.0, -1.0); }
00082 operator complex<long double>() const
00083 { return complex<long double>(0.0l, -1.0l); }
00084 };
00085 inline minus_onei_tag operator-(onei_tag)
00086 { return minus_onei_tag(); }
00087 inline onei_tag operator-(minus_onei_tag) { return onei; }
00088
00089 template<typename T>
00090 inline complex<T> operator*(const complex<T>& x, onei_tag)
00091 { return complex<T>(-imag(x), real(x)); }
00092 template<typename T>
00093 inline complex<T> operator*(onei_tag, const complex<T>& y)
00094 { return complex<T>(-imag(y), real(y)); }
00095 template<typename T>
00096 inline complex<T> operator*(const complex<T>& x, minus_onei_tag)
00097 { return complex<T>(imag(x), -real(x)); }
00098 template<typename T>
00099 inline complex<T> operator*(minus_onei_tag, const complex<T>& y)
00100 { return complex<T>(imag(y), -real(y)); }
00101
00102 inline complex<float>
00103 operator*(float x, onei_tag) { return complex<float>(0.0f, x); }
00104 inline complex<double>
00105 operator*(double x, onei_tag) { return complex<double>(0.0, x); }
00106 inline complex<long double>
00107 operator*(long double x, onei_tag)
00108 { return complex<long double>(0.0l, x); }
00109 inline complex<float>
00110 operator*(float x, minus_onei_tag) { return complex<float>(0.0f, -x); }
00111 inline complex<double>
00112 operator*(double x, minus_onei_tag) { return complex<double>(0.0, -x); }
00113 inline complex<long double>
00114 operator*(long double x, minus_onei_tag)
00115 { return complex<long double>(0.0l, -x); }
00116 inline complex<float>
00117 operator*(onei_tag, float x) { return complex<float>(0.0f, x); }
00118 inline complex<double>
00119 operator*(onei_tag, double x) { return complex<double>(0.0, x); }
00120 inline complex<long double>
00121 operator*(onei_tag, long double x)
00122 { return complex<long double>(0.0l, x); }
00123 inline complex<float>
00124 operator*(minus_onei_tag, float x) { return complex<float>(0.0f, -x); }
00125 inline complex<double>
00126 operator*(minus_onei_tag, double x) { return complex<double>(0.0, -x); }
00127 inline complex<long double>
00128 operator*(minus_onei_tag, long double x)
00129 { return complex<long double>(0.0l, -x); }
00130
00131
00132 template<typename T>
00133 struct norm_type_< complex<T> > { typedef T eval; };
00134 template<typename T>
00135 struct scalar_type_< complex<T> > { typedef complex<T> eval; };
00136 template<typename T>
00137 struct outer_product_type_< complex<T> > { typedef complex<T> eval; };
00138
00139
00140
00141
00142 template<typename T> inline int rank(complex<T> const&) { return 0; }
00143 template<typename T> inline int size0(complex<T> const&) { return 1; }
00144 template<typename T> inline int size1(complex<T> const&) { return 1; }
00145 template<typename T> inline int size2(complex<T> const&) { return 1; }
00146
00147 template<typename T> inline complex<T> trace(complex<T> const& x)
00148 { return x; }
00149 template<typename T> inline complex<T> adj(complex<T> const& x)
00150 { return conj(x); }
00151
00152 inline float adj(float x) { return x; }
00153 inline double adj(double x) { return x; }
00154 inline long double adj(long double x) { return x; }
00155 #if 0 // fixme: compiler bug
00156 inline complex<float>
00157 dot(complex<float> const& x, complex<float> const& y)
00158 { return conj(x)*y; }
00159 inline complex<double>
00160 dot(complex<double> const& x, complex<double> const& y)
00161 { return conj(x)*y; }
00162 inline complex<long double>
00163 dot(complex<long double> const& x, complex<long double> const& y)
00164 { return conj(x)*y; }
00165 #else
00166 inline complex<float>
00167 dot(complex<float> const& x, complex<float> const& y)
00168 { complex<float> tmp = conj(x); tmp *= y; return tmp; }
00169 inline complex<double>
00170 dot(complex<double> const& x, complex<double> const& y)
00171 { complex<double> tmp = conj(x); tmp *= y; return tmp; }
00172 inline complex<long double>
00173 dot(complex<long double> const& x, complex<long double> const& y)
00174 { complex<long double> tmp = conj(x); tmp *= y; return tmp; }
00175 #endif
00176
00177 template<typename T> inline int finite(complex<T> const& x) {
00178 return more::finite(real(x)) && more::finite(imag(x));
00179 }
00180
00181 }
00182 using namespace math;
00183 }
00184
00185 #endif