00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012 #ifndef MTL_CONJ_INCLUDE
00013 #define MTL_CONJ_INCLUDE
00014
00015 #include <boost/numeric/mtl/mtl_fwd.hpp>
00016 #include <boost/numeric/mtl/utility/enable_if.hpp>
00017 #include <boost/numeric/mtl/utility/tag.hpp>
00018 #include <boost/numeric/mtl/utility/category.hpp>
00019 #include <boost/numeric/linear_algebra/identity.hpp>
00020 #include <boost/numeric/mtl/matrix/map_view.hpp>
00021 #include <boost/numeric/mtl/vector/map_view.hpp>
00022
00023 #include <complex>
00024
00025 namespace mtl {
00026
00027 namespace sfunctor {
00028
00029 template <typename Value, typename AlgebraicCategory>
00030 struct conj_aux
00031 {
00032 typedef Value result_type;
00033
00034 static inline result_type apply(const Value& v)
00035 {
00036 return v;
00037 }
00038
00039 result_type operator() (const Value& v) const
00040 {
00041 return v;
00042 }
00043 };
00044
00045
00046 template <typename Value, typename AlgebraicCategory>
00047 struct conj_aux<std::complex<Value>, AlgebraicCategory>
00048 {
00049 typedef std::complex<Value> result_type;
00050
00051 static inline result_type apply(const std::complex<Value>& v)
00052 {
00053 return std::conj(v);
00054 }
00055
00056 result_type operator() (const std::complex<Value>& v) const
00057 {
00058 return std::conj(v);
00059 }
00060 };
00061
00062 template <typename Matrix>
00063 struct conj_aux<Matrix, tag::matrix>
00064 {
00065 typedef matrix::conj_view<Matrix> result_type;
00066
00067 static inline result_type apply(const Matrix& matrix)
00068 {
00069 return result_type(matrix);
00070 }
00071
00072 result_type operator() (const Matrix& matrix) const
00073 {
00074 return apply(matrix);
00075 }
00076 };
00077
00078 template <typename Vector>
00079 struct conj_aux<Vector, tag::vector>
00080 {
00081 typedef mtl::vector::conj_view<Vector> result_type;
00082
00083 static inline result_type apply(const Vector& vector)
00084 {
00085 return result_type(vector);
00086 }
00087
00088 result_type operator() (const Vector& vector) const
00089 {
00090 return apply(vector);
00091 }
00092 };
00093
00094
00095 template <typename Value>
00096 struct conj
00097 : public conj_aux<Value, typename mtl::traits::algebraic_category<Value>::type>
00098 {};
00099
00100 }
00101
00102 namespace vector {
00103
00105 template <typename Vector>
00106 typename mtl::traits::enable_if_vector<Vector, conj_view<Vector> >::type
00107 inline conj(const Vector& v)
00108 {
00109 return conj_view<Vector>(v);
00110 }
00111 }
00112
00113 namespace matrix {
00114
00116 template <typename Matrix>
00117 typename mtl::traits::enable_if_matrix<Matrix, conj_view<Matrix> >::type
00118 inline conj(const Matrix& v)
00119 {
00120 return conj_view<Matrix>(v);
00121 }
00122 }
00123
00124 namespace scalar {
00125
00126
00127 template <typename Value>
00128 typename mtl::traits::enable_if_scalar<
00129 Value
00130 , typename sfunctor::conj<Value>::result_type
00131 >::type
00132 inline conj(const Value& v)
00133 {
00134 return mtl::sfunctor::conj<Value>::apply(v);
00135 }
00136
00137 float inline conj(float v) { return v; }
00138 double inline conj(double v) { return v; }
00139 long double inline conj(long double v) { return v; }
00140 }
00141
00143 using vector::conj;
00144 using matrix::conj;
00145 using scalar::conj;
00146
00147
00148 namespace sfunctor {
00149
00150 template <typename Value>
00151 struct real
00152 {
00153 typedef Value result_type;
00154
00155 static inline Value apply(const Value& v)
00156 {
00157 return v;
00158 }
00159 };
00160
00161 template <typename Value>
00162 struct real<std::complex<Value> >
00163 {
00164 typedef std::complex<Value> result_type;
00165
00166 static inline result_type apply(const std::complex<Value>& v)
00167 {
00168 return std::real(v);
00169 }
00170 };
00171 }
00172
00174 template <typename Value>
00175 inline typename sfunctor::real<Value>::result_type real(const Value& v)
00176 {
00177 return sfunctor::real<Value>::apply(v);
00178 }
00179
00180
00181 namespace sfunctor {
00182
00183 template <typename Value>
00184 struct imag
00185 {
00186 typedef Value result_type;
00187
00188 static inline Value apply(const Value& v)
00189 {
00190 using math::zero;
00191 return zero(v);
00192 }
00193 };
00194
00195 template <typename Value>
00196 struct imag<std::complex<Value> >
00197 {
00198 typedef std::complex<Value> result_type;
00199
00200 static inline std::complex<Value> apply(const std::complex<Value>& v)
00201 {
00202 return std::imag(v);
00203 }
00204 };
00205
00206 }
00207
00209 template <typename Value>
00210 inline typename sfunctor::imag<Value>::result_type imag(const Value& v)
00211 {
00212 return sfunctor::imag<Value>::apply(v);
00213 }
00214
00215
00216 namespace sfunctor {
00217
00218 template <typename Value>
00219 struct signum
00220 {
00221 typedef Value result_type;
00222
00223 static inline Value apply(const Value& v)
00224 {
00225 using math::zero; using math::one;
00226 return v == zero(v) ? zero(v) : ( v < zero(v) ? -one(v) : one(v) );
00227 }
00228 };
00229
00230 template <typename Value>
00231 struct signum<std::complex<Value> >
00232 {
00233 typedef Value result_type;
00234
00235 static inline Value apply(const std::complex<Value>& v)
00236 {
00237 return signum<Value>::apply(mtl::real(v));
00238 }
00239 };
00240
00241 }
00242
00244 template <typename Value>
00245 inline typename sfunctor::signum<Value>::result_type signum(const Value& v)
00246 {
00247 return sfunctor::signum<Value>::apply(v);
00248 }
00249
00250
00251 }
00252
00253 #endif // MTL_CONJ_INCLUDE