|
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