00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012 #ifndef MTL_CATEGORY_INCLUDE
00013 #define MTL_CATEGORY_INCLUDE
00014
00015 #include <vector>
00016
00017 #include <boost/type_traits.hpp>
00018 #include <boost/mpl/if.hpp>
00019 #include <boost/mpl/bool.hpp>
00020
00021 #include <boost/numeric/mtl/mtl_fwd.hpp>
00022 #include <boost/numeric/mtl/utility/tag.hpp>
00023
00024
00025 namespace mtl { namespace traits {
00026
00028
00032 template <typename Collection> struct category
00033 {
00034 typedef tag::unknown type;
00035 };
00036
00037
00038 template <typename T>
00039 struct category<const T>
00040 {
00041 typedef typename category<T>::type type;
00042 };
00043
00044 template <typename Value, typename Parameters>
00045 struct category<dense2D<Value, Parameters> >
00046 {
00047 typedef tag::dense2D type;
00048 };
00049
00050 template <typename Elt, unsigned long BitMask, typename Parameters>
00051 struct category<morton_dense<Elt, BitMask, Parameters> >
00052 {
00053 typedef mtl::tag::morton_dense type;
00054 };
00055
00056 template <typename Elt, typename Parameters>
00057 struct category<compressed2D<Elt, Parameters> >
00058 {
00059 typedef tag::compressed2D type;
00060 };
00061
00062 template <typename Vector>
00063 struct category<multi_vector<Vector> >
00064 {
00065 typedef tag::multi_vector type;
00066 };
00067
00068 template <typename T, typename Parameters>
00069 struct category< dense_vector<T, Parameters> >
00070 {
00071 typedef typename boost::mpl::if_<
00072 boost::is_same<typename Parameters::orientation, row_major>
00073 , tag::dense_row_vector
00074 , tag::dense_col_vector
00075 >::type type;
00076 } ;
00077
00078 template <typename T, typename Parameters>
00079 struct category< vector::strided_vector_ref<T, Parameters> >
00080 {
00081 typedef typename boost::mpl::if_<
00082 boost::is_same<typename Parameters::orientation, row_major>
00083 , tag::strided_row_vector
00084 , tag::strided_col_vector
00085 >::type type;
00086 } ;
00087
00088
00089
00090 template <class E1, class E2, class SFunctor>
00091 struct category< vector::vec_vec_pmop_expr<E1,E2, SFunctor> >
00092 {
00093 typedef category<E1> type;
00094 };
00095
00096 template <typename Functor, typename Vector>
00097 struct category<vector::map_view<Functor, Vector> >
00098 : public category<Vector>
00099 {};
00100
00101 template <typename Scaling, typename Vector>
00102 struct category< vector::scaled_view<Scaling, Vector> >
00103 : public category< vector::map_view<tfunctor::scale<Scaling, typename Vector::value_type>,
00104 Vector> >
00105 {};
00106
00107
00108 template <typename Vector,typename RScaling>
00109 struct category< vector::rscaled_view<Vector,RScaling> >
00110 : public category< vector::map_view<tfunctor::rscale<typename Vector::value_type,RScaling>,
00111 Vector> >
00112 {};
00113
00114
00115 template <typename Vector,typename Divisor>
00116 struct category< vector::divide_by_view<Vector,Divisor> >
00117 : public category< vector::map_view<tfunctor::divide_by<typename Vector::value_type,Divisor>,
00118 Vector> >
00119 {};
00120
00121 template <typename Vector>
00122 struct category< vector::conj_view<Vector> >
00123 : public category< vector::map_view<sfunctor::conj<typename Vector::value_type>, Vector> >
00124 {};
00125
00126 template <typename Vector>
00127 struct category< vector::negate_view<Vector> >
00128 : public category< vector::map_view<sfunctor::negate<typename Vector::value_type>, Vector> >
00129 {};
00130
00131
00132 template <typename T>
00133 struct category< std::vector<T> >
00134 {
00135 typedef tag::std_vector type;
00136 };
00137
00138 namespace detail {
00139
00140 template <typename Cat> struct view_category { typedef Cat type; };
00141
00142 template <> struct view_category<tag::dense2D> { typedef tag::dense2D_view type; };
00143 template <> struct view_category<tag::morton_dense> { typedef tag::morton_view type; };
00144 template <> struct view_category<tag::compressed2D> { typedef tag::compressed2D_view type; };
00145
00146 template <typename Matrix>
00147 struct simple_matrix_view_category
00148 : view_category<typename category<Matrix>::type>
00149 {};
00150
00151 }
00152
00153
00154 template <typename Functor, typename Matrix>
00155 struct category<mtl::matrix::map_view<Functor, Matrix> >
00156 : public detail::simple_matrix_view_category<Matrix>
00157 {};
00158
00159 template <typename Scaling, typename Matrix>
00160 struct category< mtl::matrix::scaled_view<Scaling, Matrix> >
00161 : public category< matrix::map_view<tfunctor::scale<Scaling, typename Matrix::value_type>,
00162 Matrix> >
00163 {};
00164
00165
00166 template <typename Matrix, typename RScaling>
00167 struct category< mtl::matrix::rscaled_view<Matrix,RScaling> >
00168 : public category< matrix::map_view<tfunctor::rscale<typename Matrix::value_type,RScaling>,
00169 Matrix> >
00170 {};
00171
00172
00173 template <typename Matrix, typename Divisor>
00174 struct category< mtl::matrix::divide_by_view<Matrix,Divisor> >
00175 : public category< matrix::map_view<tfunctor::divide_by<typename Matrix::value_type,Divisor>,
00176 Matrix> >
00177 {};
00178
00179
00180 template <typename Matrix>
00181 struct category<transposed_view<Matrix> >
00182 : public category<Matrix>
00183 {};
00184
00185
00186 template <typename Vector>
00187 struct category< transposed_view< multi_vector<Vector> > >
00188 {
00189 typedef tag::transposed_multi_vector type;
00190 };
00191
00192 template <typename Matrix>
00193 struct category< matrix::conj_view<Matrix> >
00194 : public category< matrix::map_view<sfunctor::conj<typename Matrix::value_type>, Matrix> >
00195 {};
00196
00197 template <typename Matrix>
00198 struct category< matrix::hermitian_view<Matrix> >
00199 : public category< mtl::matrix::map_view<sfunctor::conj<typename Matrix::value_type>,
00200 transposed_view<Matrix> > >
00201 {};
00202
00203
00204 template <typename Vector>
00205 struct category< matrix::hermitian_view<multi_vector<Vector> > >
00206 {
00207 typedef tag::hermitian_multi_vector type;
00208 };
00209
00210
00211 template <typename Matrix>
00212 struct category< mtl::matrix::banded_view<Matrix> >
00213 : public detail::simple_matrix_view_category<Matrix>
00214 {};
00215
00216 template <typename T>
00217 struct is_matrix
00218 : boost::is_base_of<tag::matrix, typename category<T>::type>
00219 {};
00220
00221 template <typename T>
00222 struct is_vector
00223 : boost::is_base_of<tag::vector, typename category<T>::type>
00224 {};
00225
00226 template <typename T>
00227 struct is_scalar
00228 : boost::mpl::bool_< !is_vector<T>::value && !is_matrix<T>::value >
00229 {};
00230
00232
00235 template <typename T>
00236 struct algebraic_category
00237 : boost::mpl::if_<
00238 is_matrix<T>
00239 , tag::matrix
00240 , typename boost::mpl::if_<
00241 is_vector<T>
00242 , tag::vector
00243 , tag::scalar
00244 >::type
00245 >
00246 {};
00247
00248 template <typename T>
00249 struct is_sparse
00250 : boost::is_base_of<tag::sparse, typename category<T>::type>
00251 {};
00252
00253
00254 template <typename T>
00255 struct is_symmetric
00256 : boost::mpl::false_
00257 {};
00258
00259 }}
00260
00261 #endif // MTL_CATEGORY_INCLUDE