00001
00002
00003
00004
00005
00006
00007
00008
00020 #ifndef matrix_transpose_h
00021 #define matrix_transpose_h
00022
00023 #include <cml/matrix/matrix_expr.h>
00024
00025 #define MATRIX_TRANSPOSE_RETURNS_TEMP
00026
00027 namespace cml {
00028 namespace et {
00029
00035 template<class ExprT>
00036 class MatrixTransposeOp
00037 {
00038 public:
00039
00040 typedef MatrixTransposeOp<ExprT> expr_type;
00041
00042
00043 typedef unary_expression expr_ary;
00044
00045
00046 typedef expr_type expr_const_reference;
00047
00048 typedef typename ExprT::value_type value_type;
00049 typedef matrix_result_tag result_tag;
00050 typedef typename ExprT::size_tag size_tag;
00051
00052
00053 typedef ExprTraits<ExprT> expr_traits;
00054
00055
00056 typedef typename expr_traits::const_reference expr_reference;
00057
00058
00059 typedef typename expr_traits::result_type::transposed_type result_type;
00060
00061
00062 typedef typename result_type::temporary_type temporary_type;
00063
00064
00065 typedef cml::et::not_assignable_tag assignable_tag;
00066
00067
00068 public:
00069
00071 enum {
00072 array_rows = result_type::array_rows,
00073 array_cols = result_type::array_cols
00074 };
00075
00076
00077 public:
00078
00080 matrix_size size() const {
00081 return matrix_size(this->rows(),this->cols());
00082 }
00083
00089 size_t rows() const {
00090 return expr_traits().cols(m_expr);
00091 }
00092
00098 size_t cols() const {
00099 return expr_traits().rows(m_expr);
00100 }
00101
00103 expr_reference expression() const { return m_expr; }
00104
00110 value_type operator()(size_t i, size_t j) const {
00111 return expr_traits().get(m_expr,j,i);
00112 }
00113
00114
00115 public:
00116
00118 explicit MatrixTransposeOp(const ExprT& expr) : m_expr(expr) {}
00119
00121 MatrixTransposeOp(const expr_type& e) : m_expr(e.m_expr) {}
00122
00123
00124 protected:
00125
00126 expr_reference m_expr;
00127
00128
00129 private:
00130
00131
00132 expr_type& operator=(const expr_type&);
00133 };
00134
00136 template<class ExprT>
00137 struct ExprTraits< MatrixTransposeOp<ExprT> >
00138 {
00139 typedef MatrixTransposeOp<ExprT> expr_type;
00140 typedef typename expr_type::value_type value_type;
00141 typedef typename expr_type::expr_const_reference const_reference;
00142 typedef typename expr_type::result_tag result_tag;
00143 typedef typename expr_type::size_tag size_tag;
00144 typedef typename expr_type::result_type result_type;
00145 typedef typename expr_type::assignable_tag assignable_tag;
00146 typedef expr_node_tag node_tag;
00147
00148 value_type get(const expr_type& m, size_t i, size_t j) const {
00149 return m(i,j);
00150 }
00151
00152 matrix_size size(const expr_type& e) const { return e.size(); }
00153 size_t rows(const expr_type& e) const { return e.rows(); }
00154 size_t cols(const expr_type& e) const { return e.cols(); }
00155 };
00156
00157 }
00158
00159
00160
00161 #if defined(MATRIX_TRANSPOSE_RETURNS_TEMP)
00162
00164 template<typename E, class AT, typename BO, typename L>
00165 typename et::MatrixTransposeOp<
00166 matrix<E,AT,BO,L>
00167 >::temporary_type
00168 transpose(const matrix<E,AT,BO,L>& expr)
00169 {
00170
00171 typedef matrix<E,AT,BO,L> matrix_type;
00172
00173
00174 typedef et::MatrixTransposeOp<matrix_type> Op;
00175
00176
00177 typedef typename et::MatrixTransposeOp<
00178 matrix_type
00179 >::temporary_type tmp_type;
00180
00181
00182 typedef et::MatrixXpr<Op> ExprT;
00183
00184
00185 tmp_type tmp;
00186 cml::et::detail::Resize(tmp,expr.rows(),expr.cols());
00187 tmp = ExprT(Op(expr));
00188 return tmp;
00189 }
00190
00196 template<class XprT>
00197 typename et::MatrixTransposeOp<
00198 XprT
00199 >::temporary_type
00200 transpose(MATXPR_ARG_TYPE expr)
00201 {
00202
00203 typedef et::MatrixTransposeOp<XprT> Op;
00204
00205
00206 typedef typename et::MatrixTransposeOp<XprT>::temporary_type tmp_type;
00207
00208
00209 typedef et::MatrixXpr<Op> ExprT;
00210
00211
00212 tmp_type tmp;
00213 cml::et::detail::Resize(tmp,expr.rows(),expr.cols());
00214 tmp = ExprT(Op(expr.expression()));
00215 return tmp;
00216 }
00217
00218
00219
00220
00222 template<typename E, class AT, typename BO, typename L>
00223 typename et::MatrixTransposeOp<
00224 matrix<E,AT,BO,L>
00225 >::temporary_type
00226 T(const matrix<E,AT,BO,L>& expr)
00227 {
00228 return transpose(expr);
00229 }
00230
00236 template<class XprT>
00237 typename et::MatrixTransposeOp<
00238 XprT
00239 >::temporary_type
00240 T(MATXPR_ARG_TYPE expr)
00241 {
00242 return transpose(expr);
00243 }
00244
00245 #else
00246
00247
00248
00249
00250
00251
00252
00254 template<typename E, class AT, typename BO, typename L>
00255 et::MatrixXpr< et::MatrixTransposeOp< matrix<E,AT,BO,L> > >
00256 transpose(const matrix<E,AT,BO,L>& expr)
00257 {
00258 typedef et::MatrixTransposeOp< matrix<E,AT,BO,L> > ExprT;
00259 return et::MatrixXpr<ExprT>(ExprT(expr));
00260 }
00261
00267 template<class XprT>
00268 et::MatrixXpr< et::MatrixTransposeOp<XprT> >
00269 transpose(MATXPR_ARG_TYPE expr)
00270 {
00271 typedef et::MatrixTransposeOp<XprT> ExprT;
00272 return et::MatrixXpr<ExprT>(ExprT(expr.expression()));
00273 }
00274
00275
00276
00277
00279 template<typename E, class AT, typename BO, typename L>
00280 et::MatrixXpr< et::MatrixTransposeOp< matrix<E,AT,BO,L> > >
00281 T(const matrix<E,AT,BO,L>& expr)
00282 {
00283 return transpose(expr);
00284 }
00285
00291 template<class XprT>
00292 et::MatrixXpr< et::MatrixTransposeOp<XprT> >
00293 T(MATXPR_ARG_TYPE expr)
00294 {
00295 return transpose(expr);
00296 }
00297
00298 #endif
00299
00300 }
00301
00302 #endif
00303
00304
00305