Skip to content

Commit ea52d60

Browse files
committed
single transpose_impl with three specialisations
1 parent aa39a45 commit ea52d60

File tree

1 file changed

+13
-56
lines changed

1 file changed

+13
-56
lines changed

inst/include/Rcpp/vector/Matrix.h

Lines changed: 13 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -360,20 +360,20 @@ inline std::ostream &operator<<(std::ostream & s, const Matrix<RTYPE, StoragePol
360360
return s;
361361
}
362362

363-
template<template <class> class StoragePolicy>
364-
Matrix<REALSXP, StoragePolicy> transpose(const Matrix<REALSXP, StoragePolicy> & x) {
365-
typedef Matrix<REALSXP, StoragePolicy> MATRIX;
366-
typedef Vector<REALSXP, StoragePolicy> VECTOR;
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;
367367

368368
Vector<INTSXP, StoragePolicy> dims = ::Rf_getAttrib(x, R_DimSymbol);
369369
int nrow = dims[0], ncol = dims[1];
370370
MATRIX r(Dimension(ncol, nrow)); // new Matrix with reversed dimension
371-
R_xlen_t len = XLENGTH(x), l_1 = XLENGTH(x)-1;
371+
R_xlen_t len = XLENGTH(x), len2 = XLENGTH(x)-1;
372372

373373
// similar approach as in R: fill by in column, "accessing row-wise"
374374
VECTOR s = VECTOR(r.get__());
375375
for (R_xlen_t i = 0, j = 0; i < len; i++, j += nrow) {
376-
if (j > l_1) j -= l_1;
376+
if (j > len2) j -= len2;
377377
s[i] = x[j];
378378
}
379379

@@ -390,61 +390,18 @@ Matrix<REALSXP, StoragePolicy> transpose(const Matrix<REALSXP, StoragePolicy> &
390390
}
391391

392392
template<template <class> class StoragePolicy>
393-
Matrix<INTSXP, StoragePolicy> transpose(const Matrix<INTSXP, StoragePolicy> & x) {
394-
typedef Matrix<INTSXP, StoragePolicy> MATRIX;
395-
typedef Vector<INTSXP, StoragePolicy> VECTOR;
396-
397-
Vector<INTSXP, StoragePolicy> dims = ::Rf_getAttrib(x, R_DimSymbol);
398-
int nrow = dims[0], ncol = dims[1];
399-
MATRIX r(Dimension(ncol, nrow)); // new Matrix with reversed dimension
400-
R_xlen_t len = XLENGTH(x), l_1 = XLENGTH(x)-1;
401-
402-
// similar approach as in R: fill by in column, "accessing row-wise"
403-
VECTOR s = VECTOR(r.get__());
404-
for (R_xlen_t i = 0, j = 0; i < len; i++, j += nrow) {
405-
if (j > l_1) j -= l_1;
406-
s[i] = x[j];
407-
}
393+
Matrix<REALSXP, StoragePolicy> transpose(const Matrix<REALSXP, StoragePolicy> & x) {
394+
return tranpose_impl<REALSXP, StoragePolicy>(x);
395+
}
408396

409-
// there must be a simpler, more C++-ish way for this ...
410-
SEXP dimNames = Rf_getAttrib(x, R_DimNamesSymbol);
411-
if (!Rf_isNull(dimNames)) {
412-
// do we need dimnamesnames ?
413-
Shield<SEXP> newDimNames(Rf_allocVector(VECSXP, 2));
414-
SET_VECTOR_ELT(newDimNames, 0, VECTOR_ELT(dimNames, 1));
415-
SET_VECTOR_ELT(newDimNames, 1, VECTOR_ELT(dimNames, 0));
416-
Rf_setAttrib(r, R_DimNamesSymbol, newDimNames);
417-
}
418-
return r;
397+
template<template <class> class StoragePolicy>
398+
Matrix<INTSXP, StoragePolicy> transpose(const Matrix<INTSXP, StoragePolicy> & x) {
399+
return tranpose_impl<INTSXP, StoragePolicy>(x);
419400
}
420401

421402
template<template <class> class StoragePolicy>
422403
Matrix<STRSXP, StoragePolicy> transpose(const Matrix<STRSXP, StoragePolicy> & x) {
423-
typedef Matrix<STRSXP, StoragePolicy> MATRIX;
424-
typedef Vector<STRSXP, StoragePolicy> VECTOR;
425-
426-
Vector<INTSXP, StoragePolicy> dims = ::Rf_getAttrib(x, R_DimSymbol);
427-
int nrow = dims[0], ncol = dims[1];
428-
MATRIX r(Dimension(ncol, nrow)); // new Matrix with reversed dimension
429-
R_xlen_t len = XLENGTH(x), l_1 = XLENGTH(x)-1;
430-
431-
// similar approach as in R: fill by in column, "accessing row-wise"
432-
VECTOR s = VECTOR(r.get__());
433-
for (R_xlen_t i = 0, j = 0; i < len; i++, j += nrow) {
434-
if (j > l_1) j -= l_1;
435-
s[i] = x[j];
436-
}
437-
438-
// there must be a simpler, more C++-ish way for this ...
439-
SEXP dimNames = Rf_getAttrib(x, R_DimNamesSymbol);
440-
if (!Rf_isNull(dimNames)) {
441-
// do we need dimnamesnames ?
442-
Shield<SEXP> newDimNames(Rf_allocVector(VECSXP, 2));
443-
SET_VECTOR_ELT(newDimNames, 0, VECTOR_ELT(dimNames, 1));
444-
SET_VECTOR_ELT(newDimNames, 1, VECTOR_ELT(dimNames, 0));
445-
Rf_setAttrib(r, R_DimNamesSymbol, newDimNames);
446-
}
447-
return r;
404+
return tranpose_impl<STRSXP, StoragePolicy>(x);
448405
}
449406

450407
}

0 commit comments

Comments
 (0)