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