00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00016
00017
00018
00020 template<typename eT>
00021 inline
00022 void
00023 op_strans::apply_noalias_tinysq(Mat<eT>& out, const Mat<eT>& A)
00024 {
00025 const eT* Am = A.memptr();
00026 eT* outm = out.memptr();
00027
00028 switch(A.n_rows)
00029 {
00030 case 1:
00031 {
00032 outm[0] = Am[0];
00033 }
00034 break;
00035
00036 case 2:
00037 {
00038 outm[pos<false,0,0>::n2] = Am[pos<true,0,0>::n2];
00039 outm[pos<false,1,0>::n2] = Am[pos<true,1,0>::n2];
00040
00041 outm[pos<false,0,1>::n2] = Am[pos<true,0,1>::n2];
00042 outm[pos<false,1,1>::n2] = Am[pos<true,1,1>::n2];
00043 }
00044 break;
00045
00046 case 3:
00047 {
00048 outm[pos<false,0,0>::n3] = Am[pos<true,0,0>::n3];
00049 outm[pos<false,1,0>::n3] = Am[pos<true,1,0>::n3];
00050 outm[pos<false,2,0>::n3] = Am[pos<true,2,0>::n3];
00051
00052 outm[pos<false,0,1>::n3] = Am[pos<true,0,1>::n3];
00053 outm[pos<false,1,1>::n3] = Am[pos<true,1,1>::n3];
00054 outm[pos<false,2,1>::n3] = Am[pos<true,2,1>::n3];
00055
00056 outm[pos<false,0,2>::n3] = Am[pos<true,0,2>::n3];
00057 outm[pos<false,1,2>::n3] = Am[pos<true,1,2>::n3];
00058 outm[pos<false,2,2>::n3] = Am[pos<true,2,2>::n3];
00059 }
00060 break;
00061
00062 case 4:
00063 {
00064 outm[pos<false,0,0>::n4] = Am[pos<true,0,0>::n4];
00065 outm[pos<false,1,0>::n4] = Am[pos<true,1,0>::n4];
00066 outm[pos<false,2,0>::n4] = Am[pos<true,2,0>::n4];
00067 outm[pos<false,3,0>::n4] = Am[pos<true,3,0>::n4];
00068
00069 outm[pos<false,0,1>::n4] = Am[pos<true,0,1>::n4];
00070 outm[pos<false,1,1>::n4] = Am[pos<true,1,1>::n4];
00071 outm[pos<false,2,1>::n4] = Am[pos<true,2,1>::n4];
00072 outm[pos<false,3,1>::n4] = Am[pos<true,3,1>::n4];
00073
00074 outm[pos<false,0,2>::n4] = Am[pos<true,0,2>::n4];
00075 outm[pos<false,1,2>::n4] = Am[pos<true,1,2>::n4];
00076 outm[pos<false,2,2>::n4] = Am[pos<true,2,2>::n4];
00077 outm[pos<false,3,2>::n4] = Am[pos<true,3,2>::n4];
00078
00079 outm[pos<false,0,3>::n4] = Am[pos<true,0,3>::n4];
00080 outm[pos<false,1,3>::n4] = Am[pos<true,1,3>::n4];
00081 outm[pos<false,2,3>::n4] = Am[pos<true,2,3>::n4];
00082 outm[pos<false,3,3>::n4] = Am[pos<true,3,3>::n4];
00083 }
00084 break;
00085
00086 default:
00087 ;
00088 }
00089
00090 }
00091
00092
00093
00095 template<typename eT>
00096 inline
00097 void
00098 op_strans::apply_noalias(Mat<eT>& out, const Mat<eT>& A)
00099 {
00100 arma_extra_debug_sigprint();
00101
00102 const uword A_n_cols = A.n_cols;
00103 const uword A_n_rows = A.n_rows;
00104
00105 out.set_size(A_n_cols, A_n_rows);
00106
00107 if( (A_n_cols == 1) || (A_n_rows == 1) )
00108 {
00109 arrayops::copy( out.memptr(), A.mem, A.n_elem );
00110 }
00111 else
00112 {
00113 if( (A_n_rows <= 4) && (A_n_rows == A_n_cols) )
00114 {
00115 op_strans::apply_noalias_tinysq(out, A);
00116 }
00117 else
00118 {
00119 for(uword k=0; k < A_n_cols; ++k)
00120 {
00121 uword i, j;
00122
00123 const eT* colptr = A.colptr(k);
00124
00125 for(i=0, j=1; j < A_n_rows; i+=2, j+=2)
00126 {
00127 const eT tmp_i = colptr[i];
00128 const eT tmp_j = colptr[j];
00129
00130 out.at(k, i) = tmp_i;
00131 out.at(k, j) = tmp_j;
00132 }
00133
00134 if(i < A_n_rows)
00135 {
00136 out.at(k, i) = colptr[i];
00137 }
00138 }
00139 }
00140 }
00141 }
00142
00143
00144
00145 template<typename eT>
00146 inline
00147 void
00148 op_strans::apply(Mat<eT>& out, const Mat<eT>& A)
00149 {
00150 arma_extra_debug_sigprint();
00151
00152 if(&out != &A)
00153 {
00154 op_strans::apply_noalias(out, A);
00155 }
00156 else
00157 {
00158 const uword n_rows = out.n_rows;
00159 const uword n_cols = out.n_cols;
00160
00161 if(n_rows == n_cols)
00162 {
00163 arma_extra_debug_print("op_strans::apply(): doing in-place transpose of a square matrix");
00164
00165 const uword N = n_rows;
00166
00167 for(uword k=0; k < N; ++k)
00168 {
00169 eT* colptr = out.colptr(k);
00170
00171 uword i,j;
00172
00173 for(i=(k+1), j=(k+2); j < N; i+=2, j+=2)
00174 {
00175 std::swap(out.at(k,i), colptr[i]);
00176 std::swap(out.at(k,j), colptr[j]);
00177 }
00178
00179 if(i < N)
00180 {
00181 std::swap(out.at(k,i), colptr[i]);
00182 }
00183 }
00184 }
00185 else
00186 {
00187 Mat<eT> tmp;
00188 op_strans::apply_noalias(tmp, A);
00189
00190 out.steal_mem(tmp);
00191 }
00192 }
00193 }
00194
00195
00196
00197 template<typename T1>
00198 inline
00199 void
00200 op_strans::apply(Mat<typename T1::elem_type>& out, const Op<T1,op_strans>& in)
00201 {
00202 arma_extra_debug_sigprint();
00203
00204 typedef typename T1::elem_type eT;
00205
00206 const unwrap<T1> tmp(in.m);
00207 const Mat<eT>& A = tmp.M;
00208
00209 op_strans::apply(out, A);
00210 }
00211
00212
00213
00214
00215
00216
00217
00218
00219
00220
00221
00222
00223
00224
00225
00226
00227
00228
00229
00230
00231
00232
00233
00234
00235
00236
00237
00238
00239
00240
00241
00242
00243
00244
00245
00246
00247
00248
00249
00250
00251
00252
00253
00254
00255
00256
00257