Skip to content

Commit 1a82598

Browse files
committed
transpose is now a free function for int and numeric
1 parent 57dcb71 commit 1a82598

File tree

2 files changed

+72
-31
lines changed

2 files changed

+72
-31
lines changed

ChangeLog

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,8 @@
1+
2015-11-08 Dirk Eddelbuettel <[email protected]>
2+
3+
* inst/include/Rcpp/vector/Matrix.h (Rcpp): Matrix transpose is now a
4+
free function for both INTSXP and REALSXP
5+
16
2015-11-08 Daniel C. Dillon <[email protected]>
27

38
* inst/include/Rcpp/Nullable.h: No longer prevent assignment of

inst/include/Rcpp/vector/Matrix.h

Lines changed: 67 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -161,37 +161,6 @@ 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-
}
194-
195164
private:
196165
inline R_xlen_t offset(const int i, const int j) const { return i + static_cast<R_xlen_t>(nrows) * j ; }
197166

@@ -391,6 +360,73 @@ inline std::ostream &operator<<(std::ostream & s, const Matrix<RTYPE, StoragePol
391360
return s;
392361
}
393362

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;
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), l_1 = 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 > l_1) j -= l_1;
377+
s[i] = x[j];
378+
}
379+
//Rf_copyMostAttrib((*this), r);
380+
381+
// there must be a simpler, more C++-ish way for this ...
382+
SEXP rnames = internal::DimNameProxy(x, 0);
383+
SEXP cnames = internal::DimNameProxy(x, 1);
384+
if (!Rf_isNull(rnames) || !Rf_isNull(cnames)) {
385+
SEXP dimnames;
386+
PROTECT(dimnames = Rf_allocVector(VECSXP, 2));
387+
SET_VECTOR_ELT(dimnames, 0, cnames);
388+
SET_VECTOR_ELT(dimnames, 1, rnames);
389+
// do we need dimnamesnames ?
390+
Rf_setAttrib(r, R_DimNamesSymbol, dimnames);
391+
UNPROTECT(1); /* dimnames */
392+
}
393+
return r;
394+
}
395+
396+
template<template <class> class StoragePolicy>
397+
Matrix<INTSXP, StoragePolicy> transpose(const Matrix<INTSXP, StoragePolicy> & x) {
398+
typedef Matrix<INTSXP, StoragePolicy> MATRIX;
399+
typedef Vector<INTSXP, StoragePolicy> VECTOR;
400+
401+
Vector<INTSXP, StoragePolicy> dims = ::Rf_getAttrib(x, R_DimSymbol);
402+
int nrow = dims[0], ncol = dims[1];
403+
MATRIX r(Dimension(ncol, nrow)); // new Matrix with reversed dimension
404+
R_xlen_t len = XLENGTH(x), l_1 = XLENGTH(x)-1;
405+
406+
// similar approach as in R: fill by in column, "accessing row-wise"
407+
VECTOR s = VECTOR(r.get__());
408+
for (R_xlen_t i = 0, j = 0; i < len; i++, j += nrow) {
409+
if (j > l_1) j -= l_1;
410+
s[i] = x[j];
411+
}
412+
//Rf_copyMostAttrib((*this), r);
413+
414+
// there must be a simpler, more C++-ish way for this ...
415+
SEXP rnames = internal::DimNameProxy(x, 0);
416+
SEXP cnames = internal::DimNameProxy(x, 1);
417+
if (!Rf_isNull(rnames) || !Rf_isNull(cnames)) {
418+
SEXP dimnames;
419+
PROTECT(dimnames = Rf_allocVector(VECSXP, 2));
420+
SET_VECTOR_ELT(dimnames, 0, cnames);
421+
SET_VECTOR_ELT(dimnames, 1, rnames);
422+
// do we need dimnamesnames ?
423+
Rf_setAttrib(r, R_DimNamesSymbol, dimnames);
424+
UNPROTECT(1); /* dimnames */
425+
}
426+
return r;
427+
}
428+
429+
394430
}
395431

396432
#endif

0 commit comments

Comments
 (0)