Skip to content

Commit 28d099d

Browse files
committed
Merge pull request #397 from RcppCore/feature/issue383
Feature/issue383 -- closes #383
2 parents e7da0e7 + ea52d60 commit 28d099d

File tree

5 files changed

+118
-2
lines changed

5 files changed

+118
-2
lines changed

ChangeLog

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,38 @@
1+
2015-11-11 Dirk Eddelbuettel <[email protected]>
2+
3+
* inst/include/Rcpp/vector/Matrix.h: Further simplification
4+
15
2015-11-11 Qiang Kou <[email protected]>
26

37
* include/Rcpp/complex.h: operator<< for Rcomplex
48

9+
2015-11-10 Dirk Eddelbuettel <[email protected]>
10+
11+
* inst/include/Rcpp/vector/Matrix.h: Added transpose for character
12+
matrices as well
13+
14+
* inst/unitTests/runit.Matrix.R: New unit tests
15+
* inst/unitTests/cpp/Matrix.cpp: Ditto
16+
17+
2015-11-08 Dirk Eddelbuettel <[email protected]>
18+
19+
* inst/include/Rcpp/vector/Matrix.h: Matrix transpose is now a free
20+
function for both INTSXP and REALSXP
21+
22+
* inst/unitTests/runit.Matrix.R: New unit tests
23+
* inst/unitTests/cpp/Matrix.cpp: Ditto
24+
525
2015-11-08 Daniel C. Dillon <[email protected]>
626

727
* inst/include/Rcpp/Nullable.h: No longer prevent assignment of
828
R_NilValue to Nullable<> in function signatures
929

30+
* inst/include/Rcpp/vector/Matrix.h: Use showpoint in operator<<()
31+
32+
2015-11-07 Dirk Eddelbuettel <[email protected]>
33+
34+
* inst/include/Rcpp/vector/Matrix.h: Beginnings of a Matrix transpose
35+
1036
2015-11-06 Kevin Ushey <kevinushey@gmailcom>
1137

1238
* inst/include/Rcpp/vector/Subsetter.h: Add sugar math operators

inst/NEWS.Rd

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,12 @@
1515
by Tianqi, fixing \ghit{380})
1616
\item An overflow in Matrix column indexing was corrected (PR \ghpr{390}
1717
by Qiang, fixing a bug reported by Allessandro on the list)
18+
\item Matrix classes now have a \code{transpose()} function (fixing
19+
\ghit{383})
1820
\item \code{Nullable} types can now be assigned \code{R_NilValue} in
1921
function signatures. (PR \ghpr{395} by Dan, fixing issue \ghit{394})
22+
\item \code{operator<<()} now always shows decimal points (PR \ghpr{396}
23+
by Dan)
2024
}
2125
\item Changes in Rcpp Attributes:
2226
\itemize{

inst/include/Rcpp/vector/Matrix.h

Lines changed: 45 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
//
33
// Matrix.h: Rcpp R/C++ interface class library -- matrices
44
//
5-
// Copyright (C) 2010 - 2014 Dirk Eddelbuettel and Romain Francois
5+
// Copyright (C) 2010 - 2015 Dirk Eddelbuettel and Romain Francois
66
//
77
// This file is part of Rcpp.
88
//
@@ -161,7 +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-
165164
private:
166165
inline R_xlen_t offset(const int i, const int j) const { return i + static_cast<R_xlen_t>(nrows) * j ; }
167166

@@ -361,6 +360,50 @@ inline std::ostream &operator<<(std::ostream & s, const Matrix<RTYPE, StoragePol
361360
return s;
362361
}
363362

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+
364407
}
365408

366409
#endif

inst/unitTests/cpp/Matrix.cpp

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -242,3 +242,19 @@ NumericVector runit_const_Matrix_column( const NumericMatrix& m ){
242242
int mat_access_with_bounds_checking(const IntegerMatrix m, int i, int j) {
243243
return m.at(i, j);
244244
}
245+
246+
247+
// [[Rcpp::export]]
248+
IntegerMatrix transposeInteger(const IntegerMatrix & x) {
249+
return transpose(x);
250+
}
251+
252+
// [[Rcpp::export]]
253+
NumericMatrix transposeNumeric(const NumericMatrix & x) {
254+
return transpose(x);
255+
}
256+
257+
// [[Rcpp::export]]
258+
CharacterMatrix transposeCharacter(const CharacterMatrix & x) {
259+
return transpose(x);
260+
}

inst/unitTests/runit.Matrix.R

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -183,4 +183,31 @@ if (.runThisTest) {
183183
checkException(mat_access_with_bounds_checking(m, -1, -1) , msg = "index out of bounds not detected" )
184184
}
185185

186+
test.IntegerMatrix.transpose <- function() {
187+
M <- matrix(1:12, 3, 4)
188+
checkEquals(transposeInteger(M), t(M), msg="integer transpose")
189+
rownames(M) <- letters[1:nrow(M)]
190+
checkEquals(transposeInteger(M), t(M), msg="integer transpose with rownames")
191+
colnames(M) <- LETTERS[1:ncol(M)]
192+
checkEquals(transposeInteger(M), t(M), msg="integer transpose with row and colnames")
193+
}
194+
195+
test.NumericMatrix.transpose <- function() {
196+
M <- matrix(1.0 * (1:12), 3, 4)
197+
checkEquals(transposeNumeric(M), t(M), msg="numeric transpose")
198+
rownames(M) <- letters[1:nrow(M)]
199+
checkEquals(transposeNumeric(M), t(M), msg="numeric transpose with rownames")
200+
colnames(M) <- LETTERS[1:ncol(M)]
201+
checkEquals(transposeNumeric(M), t(M), msg="numeric transpose with row and colnames")
202+
}
203+
204+
test.CharacterMatrix.transpose <- function() {
205+
M <- matrix(as.character(1:12), 3, 4)
206+
checkEquals(transposeCharacter(M), t(M), msg="character transpose")
207+
rownames(M) <- letters[1:nrow(M)]
208+
checkEquals(transposeCharacter(M), t(M), msg="character transpose with rownames")
209+
colnames(M) <- LETTERS[1:ncol(M)]
210+
checkEquals(transposeCharacter(M), t(M), msg="character transpose with row and colnames")
211+
}
212+
186213
}

0 commit comments

Comments
 (0)