|
2 | 2 | //
|
3 | 3 | // Matrix.h: Rcpp R/C++ interface class library -- matrices
|
4 | 4 | //
|
5 |
| -// Copyright (C) 2010 - 2014 Dirk Eddelbuettel and Romain Francois |
| 5 | +// Copyright (C) 2010 - 2015 Dirk Eddelbuettel and Romain Francois |
6 | 6 | //
|
7 | 7 | // This file is part of Rcpp.
|
8 | 8 | //
|
@@ -161,7 +161,6 @@ class Matrix : public Vector<RTYPE, StoragePolicy>, public MatrixBase<RTYPE, tru
|
161 | 161 | return Sub( const_cast<Matrix&>(*this), row_range, Range(0,ncol()-1) ) ;
|
162 | 162 | }
|
163 | 163 |
|
164 |
| - |
165 | 164 | private:
|
166 | 165 | inline R_xlen_t offset(const int i, const int j) const { return i + static_cast<R_xlen_t>(nrows) * j ; }
|
167 | 166 |
|
@@ -361,6 +360,50 @@ inline std::ostream &operator<<(std::ostream & s, const Matrix<RTYPE, StoragePol
|
361 | 360 | return s;
|
362 | 361 | }
|
363 | 362 |
|
| 363 | +template<int RTYPE, template <class> class StoragePolicy > |
| 364 | +Matrix<RTYPE, StoragePolicy> tranpose_impl(const Matrix<RTYPE, StoragePolicy> & x) { |
| 365 | + typedef Matrix<RTYPE, StoragePolicy> MATRIX; |
| 366 | + typedef Vector<RTYPE, StoragePolicy> VECTOR; |
| 367 | + |
| 368 | + Vector<INTSXP, StoragePolicy> dims = ::Rf_getAttrib(x, R_DimSymbol); |
| 369 | + int nrow = dims[0], ncol = dims[1]; |
| 370 | + MATRIX r(Dimension(ncol, nrow)); // new Matrix with reversed dimension |
| 371 | + R_xlen_t len = XLENGTH(x), len2 = XLENGTH(x)-1; |
| 372 | + |
| 373 | + // similar approach as in R: fill by in column, "accessing row-wise" |
| 374 | + VECTOR s = VECTOR(r.get__()); |
| 375 | + for (R_xlen_t i = 0, j = 0; i < len; i++, j += nrow) { |
| 376 | + if (j > len2) j -= len2; |
| 377 | + s[i] = x[j]; |
| 378 | + } |
| 379 | + |
| 380 | + // there must be a simpler, more C++-ish way for this ... |
| 381 | + SEXP dimNames = Rf_getAttrib(x, R_DimNamesSymbol); |
| 382 | + if (!Rf_isNull(dimNames)) { |
| 383 | + // do we need dimnamesnames ? |
| 384 | + Shield<SEXP> newDimNames(Rf_allocVector(VECSXP, 2)); |
| 385 | + SET_VECTOR_ELT(newDimNames, 0, VECTOR_ELT(dimNames, 1)); |
| 386 | + SET_VECTOR_ELT(newDimNames, 1, VECTOR_ELT(dimNames, 0)); |
| 387 | + Rf_setAttrib(r, R_DimNamesSymbol, newDimNames); |
| 388 | + } |
| 389 | + return r; |
| 390 | +} |
| 391 | + |
| 392 | +template<template <class> class StoragePolicy> |
| 393 | +Matrix<REALSXP, StoragePolicy> transpose(const Matrix<REALSXP, StoragePolicy> & x) { |
| 394 | + return tranpose_impl<REALSXP, StoragePolicy>(x); |
| 395 | +} |
| 396 | + |
| 397 | +template<template <class> class StoragePolicy> |
| 398 | +Matrix<INTSXP, StoragePolicy> transpose(const Matrix<INTSXP, StoragePolicy> & x) { |
| 399 | + return tranpose_impl<INTSXP, StoragePolicy>(x); |
| 400 | +} |
| 401 | + |
| 402 | +template<template <class> class StoragePolicy> |
| 403 | +Matrix<STRSXP, StoragePolicy> transpose(const Matrix<STRSXP, StoragePolicy> & x) { |
| 404 | + return tranpose_impl<STRSXP, StoragePolicy>(x); |
| 405 | +} |
| 406 | + |
364 | 407 | }
|
365 | 408 |
|
366 | 409 | #endif
|
0 commit comments