$search
00001 // Copyright (C) 2008-2011 NICTA (www.nicta.com.au) 00002 // Copyright (C) 2008-2011 Conrad Sanderson 00003 // 00004 // This file is part of the Armadillo C++ library. 00005 // It is provided without any warranty of fitness 00006 // for any purpose. You can redistribute this file 00007 // and/or modify it under the terms of the GNU 00008 // Lesser General Public License (LGPL) as published 00009 // by the Free Software Foundation, either version 3 00010 // of the License or (at your option) any later version. 00011 // (see http://www.opensource.org/licenses for more info) 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 // inline void op_strans::apply_inplace(mat &X) 00215 // { 00216 // arma_extra_debug_sigprint(); 00217 // 00218 // if((X.n_rows == 1) || (X.n_cols == 1)) 00219 // { 00220 // const uword old_n_rows = X.n_rows; 00221 // access::rw(X.n_rows) = X.n_cols; 00222 // access::rw(X.n_cols) = old_n_rows; 00223 // } 00224 // else 00225 // if(X.n_rows == X.n_cols) 00226 // { 00227 // for(uword col=0; col < X.n_cols; ++col) 00228 // { 00229 // double* X_coldata = X.colptr(col); 00230 // 00231 // for(uword row=(col+1); row < X.n_rows; ++row) 00232 // { 00233 // std::swap( A.at(col,row), A_coldata[row] ); 00234 // } 00235 // } 00236 // } 00237 // else 00238 // { 00239 // mat tmp = trans(X); 00240 // 00241 // if(X.mem != X.mem_local) 00242 // { 00243 // double* old_mem = X.memptr(); 00244 // access::rw(X.mem) = tmp.memptr(); 00245 // access::rw(tmp.mem) = old_mem; 00246 // } 00247 // else 00248 // { 00249 // X = tmp; 00250 // } 00251 // } 00252 // 00253 // } 00254 00255 00256 00257