@@ -161,6 +161,36 @@ class Matrix : public Vector<RTYPE, StoragePolicy>, public MatrixBase<RTYPE, tru
161161 return Sub ( const_cast <Matrix&>(*this ), row_range, Range (0 ,ncol ()-1 ) ) ;
162162 }
163163
164+ Matrix transpose () {
165+ typedef Vector<CHARSXP, StoragePolicy> CHARVECTOR;
166+ int nrow = VECTOR::dims ()[0 ], ncol = VECTOR::dims ()[1 ];
167+ R_xlen_t len = XLENGTH (*this );
168+
169+ Matrix r (Dimension (ncol, nrow));
170+ R_xlen_t i, j, l_1 = len-1 ;
171+
172+ // similar approach as in R: fill by in column, "accessing row-wise"
173+ VECTOR s = VECTOR (r.get__ ());
174+ for (i = 0 , j = 0 ; i < len; i++, j += nrow) {
175+ if (j > l_1) j -= l_1;
176+ s[i] = (*this )[j];
177+ }
178+
179+ Rf_copyMostAttrib ((*this ), r);
180+
181+ // there must be a simpler, more C++-ish way for this ...
182+ SEXP rnames = internal::DimNameProxy ((*this ), 0 );
183+ SEXP cnames = internal::DimNameProxy ((*this ), 1 );
184+ SEXP dimnames;
185+ PROTECT (dimnames = Rf_allocVector (VECSXP, 2 ));
186+ SET_VECTOR_ELT (dimnames, 0 , cnames);
187+ SET_VECTOR_ELT (dimnames, 1 , rnames);
188+ // do we need dimnamesnames ?
189+ Rf_setAttrib (r, R_DimNamesSymbol, dimnames);
190+ UNPROTECT (1 ); /* dimnames */
191+
192+ return r;
193+ }
164194
165195private:
166196 inline R_xlen_t offset (const int i, const int j) const { return i + static_cast <R_xlen_t>(nrows) * j ; }
0 commit comments