]> Dogcows Code - chaz/yoink/blob - src/cml/matrix/matrix_transpose.h
now using cml for vectors and math stuff
[chaz/yoink] / src / cml / matrix / matrix_transpose.h
1 /* -*- C++ -*- ------------------------------------------------------------
2
3 Copyright (c) 2007 Jesse Anders and Demian Nave http://cmldev.net/
4
5 The Configurable Math Library (CML) is distributed under the terms of the
6 Boost Software License, v1.0 (see cml/LICENSE for details).
7
8 *-----------------------------------------------------------------------*/
9 /** @file
10 * @brief
11 *
12 * @todo Currently, the transpose() and T() functions copy the transposed
13 * result into a temporary, and return it to avoid aliasing problems, e.g.
14 * C = transpose(C). By checking for C on the right-hand side, this can
15 * be avoided, but experimentation is needed to determine the impact on
16 * performance. Another option is to use a function to explicitly specify
17 * when a temporary is needed; e.g. C = transpose(temp(C)).
18 */
19
20 #ifndef matrix_transpose_h
21 #define matrix_transpose_h
22
23 #include <cml/matrix/matrix_expr.h>
24
25 #define MATRIX_TRANSPOSE_RETURNS_TEMP
26
27 namespace cml {
28 namespace et {
29
30 /** "Transpose" the given matrix expression.
31 *
32 * This does nothing more than change the result type of the expression
33 * into one with the opposite orientation (i.e. row->col, col->row).
34 */
35 template<class ExprT>
36 class MatrixTransposeOp
37 {
38 public:
39
40 typedef MatrixTransposeOp<ExprT> expr_type;
41
42 /* Record ary-ness of the expression: */
43 typedef unary_expression expr_ary;
44
45 /* Copy the expression by value into higher-up expressions: */
46 typedef expr_type expr_const_reference;
47
48 typedef typename ExprT::value_type value_type;
49 typedef matrix_result_tag result_tag;
50 typedef typename ExprT::size_tag size_tag;
51
52 /* Store the expression traits: */
53 typedef ExprTraits<ExprT> expr_traits;
54
55 /* Get the reference type: */
56 typedef typename expr_traits::const_reference expr_reference;
57
58 /* Swap the orientation: */
59 typedef typename expr_traits::result_type::transposed_type result_type;
60
61 /* Get the temporary type: */
62 typedef typename result_type::temporary_type temporary_type;
63
64 /* For matching by assignability: */
65 typedef cml::et::not_assignable_tag assignable_tag;
66
67
68 public:
69
70 /** Record result size as an enum. */
71 enum {
72 array_rows = result_type::array_rows,
73 array_cols = result_type::array_cols
74 };
75
76
77 public:
78
79 /** Return the expression size as a pair. */
80 matrix_size size() const {
81 return matrix_size(this->rows(),this->cols());
82 }
83
84 /** Return result rows.
85 *
86 * The tranpose has the same number of rows as the original has
87 * columns.
88 */
89 size_t rows() const {
90 return expr_traits().cols(m_expr);
91 }
92
93 /** Return result cols.
94 *
95 * The tranpose has the same number of columns as the original has
96 * rows.
97 */
98 size_t cols() const {
99 return expr_traits().rows(m_expr);
100 }
101
102 /** Return reference to contained expression. */
103 expr_reference expression() const { return m_expr; }
104
105 /** Compute value at index i of the result matrix.
106 *
107 * Element (i,j) of the transpose is element (j,i) of the original
108 * expression.
109 */
110 value_type operator()(size_t i, size_t j) const {
111 return expr_traits().get(m_expr,j,i);
112 }
113
114
115 public:
116
117 /** Construct from the subexpression to store. */
118 explicit MatrixTransposeOp(const ExprT& expr) : m_expr(expr) {}
119
120 /** Copy constructor. */
121 MatrixTransposeOp(const expr_type& e) : m_expr(e.m_expr) {}
122
123
124 protected:
125
126 expr_reference m_expr;
127
128
129 private:
130
131 /* Cannot be assigned to: */
132 expr_type& operator=(const expr_type&);
133 };
134
135 /** Expression traits class for VectorTransposeOp<>. */
136 template<class ExprT>
137 struct ExprTraits< MatrixTransposeOp<ExprT> >
138 {
139 typedef MatrixTransposeOp<ExprT> expr_type;
140 typedef typename expr_type::value_type value_type;
141 typedef typename expr_type::expr_const_reference const_reference;
142 typedef typename expr_type::result_tag result_tag;
143 typedef typename expr_type::size_tag size_tag;
144 typedef typename expr_type::result_type result_type;
145 typedef typename expr_type::assignable_tag assignable_tag;
146 typedef expr_node_tag node_tag;
147
148 value_type get(const expr_type& m, size_t i, size_t j) const {
149 return m(i,j);
150 }
151
152 matrix_size size(const expr_type& e) const { return e.size(); }
153 size_t rows(const expr_type& e) const { return e.rows(); }
154 size_t cols(const expr_type& e) const { return e.cols(); }
155 };
156
157 } // namespace et
158
159
160 /* Define the transpose operators in the cml namespace: */
161 #if defined(MATRIX_TRANSPOSE_RETURNS_TEMP)
162
163 /** Matrix transpose operator taking a matrix operand. */
164 template<typename E, class AT, typename BO, typename L>
165 typename et::MatrixTransposeOp<
166 matrix<E,AT,BO,L>
167 >::temporary_type
168 transpose(const matrix<E,AT,BO,L>& expr)
169 {
170 /* Record the matrix type: */
171 typedef matrix<E,AT,BO,L> matrix_type;
172
173 /* Record the type of the transpose op: */
174 typedef et::MatrixTransposeOp<matrix_type> Op;
175
176 /* Determine the returned matrix type: */
177 typedef typename et::MatrixTransposeOp<
178 matrix_type
179 >::temporary_type tmp_type;
180
181 /* The expression to use to assign the temporary: */
182 typedef et::MatrixXpr<Op> ExprT;
183
184 /* Create the temporary and return it: */
185 tmp_type tmp;
186 cml::et::detail::Resize(tmp,expr.rows(),expr.cols());
187 tmp = ExprT(Op(expr));
188 return tmp;
189 }
190
191 /** Matrix transpose operator taking an et::MatrixXpr operand.
192 *
193 * The parse tree is automatically compressed by hoisting the MatrixXpr's
194 * subexpression into the subexpression of the MatrixTransposeOp.
195 */
196 template<class XprT>
197 typename et::MatrixTransposeOp<
198 XprT
199 >::temporary_type
200 transpose(MATXPR_ARG_TYPE expr)
201 {
202 /* Record the type of the transpose op: */
203 typedef et::MatrixTransposeOp<XprT> Op;
204
205 /* Determine the returned matrix type: */
206 typedef typename et::MatrixTransposeOp<XprT>::temporary_type tmp_type;
207
208 /* The expression to use to assign the temporary: */
209 typedef et::MatrixXpr<Op> ExprT;
210
211 /* Create the temporary and return it: */
212 tmp_type tmp;
213 cml::et::detail::Resize(tmp,expr.rows(),expr.cols());
214 tmp = ExprT(Op(expr.expression()));
215 return tmp;
216 }
217
218
219 /* For notational convenience: */
220
221 /** Matrix transpose operator taking a matrix operand. */
222 template<typename E, class AT, typename BO, typename L>
223 typename et::MatrixTransposeOp<
224 matrix<E,AT,BO,L>
225 >::temporary_type
226 T(const matrix<E,AT,BO,L>& expr)
227 {
228 return transpose(expr);
229 }
230
231 /** Matrix transpose operator taking an et::MatrixXpr operand.
232 *
233 * The parse tree is automatically compressed by hoisting the MatrixXpr's
234 * subexpression into the subexpression of the MatrixTransposeOp.
235 */
236 template<class XprT>
237 typename et::MatrixTransposeOp<
238 XprT
239 >::temporary_type
240 T(MATXPR_ARG_TYPE expr)
241 {
242 return transpose(expr);
243 }
244
245 #else
246
247 /* XXX For this to work correctly, matrix assignment and copy have to be
248 * changed to either use a temporary all the time, or to create a temporary
249 * when the same matrix appears on both sides of an assignment, and a
250 * temporary was not already created on the RHS by the ET code.
251 */
252
253 /** Matrix transpose operator taking a matrix operand. */
254 template<typename E, class AT, typename BO, typename L>
255 et::MatrixXpr< et::MatrixTransposeOp< matrix<E,AT,BO,L> > >
256 transpose(const matrix<E,AT,BO,L>& expr)
257 {
258 typedef et::MatrixTransposeOp< matrix<E,AT,BO,L> > ExprT;
259 return et::MatrixXpr<ExprT>(ExprT(expr));
260 }
261
262 /** Matrix transpose operator taking an et::MatrixXpr operand.
263 *
264 * The parse tree is automatically compressed by hoisting the MatrixXpr's
265 * subexpression into the subexpression of the MatrixTransposeOp.
266 */
267 template<class XprT>
268 et::MatrixXpr< et::MatrixTransposeOp<XprT> >
269 transpose(MATXPR_ARG_TYPE expr)
270 {
271 typedef et::MatrixTransposeOp<XprT> ExprT;
272 return et::MatrixXpr<ExprT>(ExprT(expr.expression()));
273 }
274
275
276 /* For notational convenience: */
277
278 /** Matrix transpose operator taking a matrix operand. */
279 template<typename E, class AT, typename BO, typename L>
280 et::MatrixXpr< et::MatrixTransposeOp< matrix<E,AT,BO,L> > >
281 T(const matrix<E,AT,BO,L>& expr)
282 {
283 return transpose(expr);
284 }
285
286 /** Matrix transpose operator taking an et::MatrixXpr operand.
287 *
288 * The parse tree is automatically compressed by hoisting the MatrixXpr's
289 * subexpression into the subexpression of the MatrixTransposeOp.
290 */
291 template<class XprT>
292 et::MatrixXpr< et::MatrixTransposeOp<XprT> >
293 T(MATXPR_ARG_TYPE expr)
294 {
295 return transpose(expr);
296 }
297
298 #endif
299
300 } // namespace cml
301
302 #endif
303
304 // -------------------------------------------------------------------------
305 // vim:ft=cpp
This page took 0.046191 seconds and 4 git commands to generate.