comparison armadillo-2.4.4/include/armadillo_bits/op_strans_meat.hpp @ 0:8b6102e2a9b0

Armadillo Library
author maxzanoni76 <max.zanoni@eecs.qmul.ac.uk>
date Wed, 11 Apr 2012 09:27:06 +0100
parents
children
comparison
equal deleted inserted replaced
-1:000000000000 0:8b6102e2a9b0
1 // Copyright (C) 2008-2011 NICTA (www.nicta.com.au)
2 // Copyright (C) 2008-2011 Conrad Sanderson
3 //
4 // This file is part of the Armadillo C++ library.
5 // It is provided without any warranty of fitness
6 // for any purpose. You can redistribute this file
7 // and/or modify it under the terms of the GNU
8 // Lesser General Public License (LGPL) as published
9 // by the Free Software Foundation, either version 3
10 // of the License or (at your option) any later version.
11 // (see http://www.opensource.org/licenses for more info)
12
13
14 //! \addtogroup op_strans
15 //! @{
16
17
18
19 //! for tiny square matrices (size <= 4x4)
20 template<typename eT>
21 inline
22 void
23 op_strans::apply_noalias_tinysq(Mat<eT>& out, const Mat<eT>& A)
24 {
25 const eT* Am = A.memptr();
26 eT* outm = out.memptr();
27
28 switch(A.n_rows)
29 {
30 case 1:
31 {
32 outm[0] = Am[0];
33 }
34 break;
35
36 case 2:
37 {
38 outm[pos<false,0,0>::n2] = Am[pos<true,0,0>::n2];
39 outm[pos<false,1,0>::n2] = Am[pos<true,1,0>::n2];
40
41 outm[pos<false,0,1>::n2] = Am[pos<true,0,1>::n2];
42 outm[pos<false,1,1>::n2] = Am[pos<true,1,1>::n2];
43 }
44 break;
45
46 case 3:
47 {
48 outm[pos<false,0,0>::n3] = Am[pos<true,0,0>::n3];
49 outm[pos<false,1,0>::n3] = Am[pos<true,1,0>::n3];
50 outm[pos<false,2,0>::n3] = Am[pos<true,2,0>::n3];
51
52 outm[pos<false,0,1>::n3] = Am[pos<true,0,1>::n3];
53 outm[pos<false,1,1>::n3] = Am[pos<true,1,1>::n3];
54 outm[pos<false,2,1>::n3] = Am[pos<true,2,1>::n3];
55
56 outm[pos<false,0,2>::n3] = Am[pos<true,0,2>::n3];
57 outm[pos<false,1,2>::n3] = Am[pos<true,1,2>::n3];
58 outm[pos<false,2,2>::n3] = Am[pos<true,2,2>::n3];
59 }
60 break;
61
62 case 4:
63 {
64 outm[pos<false,0,0>::n4] = Am[pos<true,0,0>::n4];
65 outm[pos<false,1,0>::n4] = Am[pos<true,1,0>::n4];
66 outm[pos<false,2,0>::n4] = Am[pos<true,2,0>::n4];
67 outm[pos<false,3,0>::n4] = Am[pos<true,3,0>::n4];
68
69 outm[pos<false,0,1>::n4] = Am[pos<true,0,1>::n4];
70 outm[pos<false,1,1>::n4] = Am[pos<true,1,1>::n4];
71 outm[pos<false,2,1>::n4] = Am[pos<true,2,1>::n4];
72 outm[pos<false,3,1>::n4] = Am[pos<true,3,1>::n4];
73
74 outm[pos<false,0,2>::n4] = Am[pos<true,0,2>::n4];
75 outm[pos<false,1,2>::n4] = Am[pos<true,1,2>::n4];
76 outm[pos<false,2,2>::n4] = Am[pos<true,2,2>::n4];
77 outm[pos<false,3,2>::n4] = Am[pos<true,3,2>::n4];
78
79 outm[pos<false,0,3>::n4] = Am[pos<true,0,3>::n4];
80 outm[pos<false,1,3>::n4] = Am[pos<true,1,3>::n4];
81 outm[pos<false,2,3>::n4] = Am[pos<true,2,3>::n4];
82 outm[pos<false,3,3>::n4] = Am[pos<true,3,3>::n4];
83 }
84 break;
85
86 default:
87 ;
88 }
89
90 }
91
92
93
94 //! Immediate transpose of a dense matrix
95 template<typename eT>
96 inline
97 void
98 op_strans::apply_noalias(Mat<eT>& out, const Mat<eT>& A)
99 {
100 arma_extra_debug_sigprint();
101
102 const uword A_n_cols = A.n_cols;
103 const uword A_n_rows = A.n_rows;
104
105 out.set_size(A_n_cols, A_n_rows);
106
107 if( (A_n_cols == 1) || (A_n_rows == 1) )
108 {
109 arrayops::copy( out.memptr(), A.mem, A.n_elem );
110 }
111 else
112 {
113 if( (A_n_rows <= 4) && (A_n_rows == A_n_cols) )
114 {
115 op_strans::apply_noalias_tinysq(out, A);
116 }
117 else
118 {
119 for(uword k=0; k < A_n_cols; ++k)
120 {
121 uword i, j;
122
123 const eT* colptr = A.colptr(k);
124
125 for(i=0, j=1; j < A_n_rows; i+=2, j+=2)
126 {
127 const eT tmp_i = colptr[i];
128 const eT tmp_j = colptr[j];
129
130 out.at(k, i) = tmp_i;
131 out.at(k, j) = tmp_j;
132 }
133
134 if(i < A_n_rows)
135 {
136 out.at(k, i) = colptr[i];
137 }
138 }
139 }
140 }
141 }
142
143
144
145 template<typename eT>
146 inline
147 void
148 op_strans::apply(Mat<eT>& out, const Mat<eT>& A)
149 {
150 arma_extra_debug_sigprint();
151
152 if(&out != &A)
153 {
154 op_strans::apply_noalias(out, A);
155 }
156 else
157 {
158 const uword n_rows = out.n_rows;
159 const uword n_cols = out.n_cols;
160
161 if(n_rows == n_cols)
162 {
163 arma_extra_debug_print("op_strans::apply(): doing in-place transpose of a square matrix");
164
165 const uword N = n_rows;
166
167 for(uword k=0; k < N; ++k)
168 {
169 eT* colptr = out.colptr(k);
170
171 uword i,j;
172
173 for(i=(k+1), j=(k+2); j < N; i+=2, j+=2)
174 {
175 std::swap(out.at(k,i), colptr[i]);
176 std::swap(out.at(k,j), colptr[j]);
177 }
178
179 if(i < N)
180 {
181 std::swap(out.at(k,i), colptr[i]);
182 }
183 }
184 }
185 else
186 {
187 Mat<eT> tmp;
188 op_strans::apply_noalias(tmp, A);
189
190 out.steal_mem(tmp);
191 }
192 }
193 }
194
195
196
197 template<typename T1>
198 inline
199 void
200 op_strans::apply(Mat<typename T1::elem_type>& out, const Op<T1,op_strans>& in)
201 {
202 arma_extra_debug_sigprint();
203
204 typedef typename T1::elem_type eT;
205
206 const unwrap<T1> tmp(in.m);
207 const Mat<eT>& A = tmp.M;
208
209 op_strans::apply(out, A);
210 }
211
212
213
214 // inline void op_strans::apply_inplace(mat &X)
215 // {
216 // arma_extra_debug_sigprint();
217 //
218 // if((X.n_rows == 1) || (X.n_cols == 1))
219 // {
220 // const uword old_n_rows = X.n_rows;
221 // access::rw(X.n_rows) = X.n_cols;
222 // access::rw(X.n_cols) = old_n_rows;
223 // }
224 // else
225 // if(X.n_rows == X.n_cols)
226 // {
227 // for(uword col=0; col < X.n_cols; ++col)
228 // {
229 // double* X_coldata = X.colptr(col);
230 //
231 // for(uword row=(col+1); row < X.n_rows; ++row)
232 // {
233 // std::swap( A.at(col,row), A_coldata[row] );
234 // }
235 // }
236 // }
237 // else
238 // {
239 // mat tmp = trans(X);
240 //
241 // if(X.mem != X.mem_local)
242 // {
243 // double* old_mem = X.memptr();
244 // access::rw(X.mem) = tmp.memptr();
245 // access::rw(tmp.mem) = old_mem;
246 // }
247 // else
248 // {
249 // X = tmp;
250 // }
251 // }
252 //
253 // }
254
255
256
257
258 //! @}