matrix_transpose.h

Go to the documentation of this file.
00001 /* -*- C++ -*- ------------------------------------------------------------
00002  
00003 Copyright (c) 2007 Jesse Anders and Demian Nave http://cmldev.net/
00004 
00005 The Configurable Math Library (CML) is distributed under the terms of the
00006 Boost Software License, v1.0 (see cml/LICENSE for details).
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     /* Record ary-ness of the expression: */
00043     typedef unary_expression expr_ary;
00044 
00045     /* Copy the expression by value into higher-up expressions: */
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     /* Store the expression traits: */
00053     typedef ExprTraits<ExprT> expr_traits;
00054 
00055     /* Get the reference type: */
00056     typedef typename expr_traits::const_reference expr_reference;
00057 
00058     /* Swap the orientation: */
00059     typedef typename expr_traits::result_type::transposed_type result_type;
00060 
00061     /* Get the temporary type: */
00062     typedef typename result_type::temporary_type temporary_type;
00063 
00064     /* For matching by assignability: */
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     /* Cannot be assigned to: */
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 } // namespace et
00158 
00159 
00160 /* Define the transpose operators in the cml namespace: */
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     /* Record the matrix type: */
00171     typedef matrix<E,AT,BO,L> matrix_type;
00172 
00173     /* Record the type of the transpose op: */
00174     typedef et::MatrixTransposeOp<matrix_type> Op;
00175 
00176     /* Determine the returned matrix type: */
00177     typedef typename et::MatrixTransposeOp<
00178         matrix_type
00179     >::temporary_type tmp_type;
00180 
00181     /* The expression to use to assign the temporary: */
00182     typedef et::MatrixXpr<Op> ExprT;
00183 
00184     /* Create the temporary and return it: */
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     /* Record the type of the transpose op: */
00203     typedef et::MatrixTransposeOp<XprT> Op;
00204 
00205     /* Determine the returned matrix type: */
00206     typedef typename et::MatrixTransposeOp<XprT>::temporary_type tmp_type;
00207 
00208     /* The expression to use to assign the temporary: */
00209     typedef et::MatrixXpr<Op> ExprT;
00210 
00211     /* Create the temporary and return it: */
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 /* For notational convenience: */
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 /* XXX For this to work correctly, matrix assignment and copy have to be
00248  * changed to either use a temporary all the time, or to create a temporary
00249  * when the same matrix appears on both sides of an assignment, and a
00250  * temporary was not already created on the RHS by the ET code.
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 /* For notational convenience: */
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 } // namespace cml
00301 
00302 #endif
00303 
00304 // -------------------------------------------------------------------------
00305 // vim:ft=cpp

Generated on Sat Jul 18 19:35:27 2009 for CML 1.0 by  doxygen 1.5.9