Skip to content

Commit 8aa14aa

Browse files
committed
Fix for non-symmetric matrix diagonal fill (Closes #619)
1 parent 2883ef3 commit 8aa14aa

File tree

5 files changed

+65
-15
lines changed

5 files changed

+65
-15
lines changed

ChangeLog

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,11 @@
1+
2016-12-31 James J Balamuta <[email protected]>
2+
3+
* inst/include/Rcpp/vector/Matrix.h: Fixed non-symmetric case of matrix
4+
fills by switching to a loop based solution from iterator.
5+
* inst/unitTests/runit.Matrix.R: Added unit tests for diagonally
6+
filling matrices.
7+
* inst/unitTests/cpp/Matrix.cpp: Idem
8+
19
2016-12-26 Dirk Eddelbuettel <[email protected]>
210

311
* R/Attributes.R: Added #nocov markers

inst/NEWS.Rd

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@
1111
compiler versions (Jim Hester in \ghpr{598})
1212
\item Date and Datetime object and vector now have format methods and
1313
\code{operator<<} support (PR\ghpr{599})
14+
\item Addressed improper diagonal fill for non-symmetric matrices
15+
(James Balamuta in \ghpr{622} addressing \ghit{619})
1416
}
1517
\item Changes in Rcpp Sugar:
1618
\itemize{
@@ -21,7 +23,9 @@
2123
\itemize{
2224
\item Added Environment::find unit tests and an Environment::get(Symbol)
2325
test (James Balamuta in \ghpr{595} addressing issue \ghit{594}).
24-
}
26+
\item Added diagonal matrix fill tests
27+
(James Balamuta in \ghpr{622} addressing \ghit{619})
28+
}
2529
\item Changes in Rcpp Documentation:
2630
\itemize{
2731
\item Exposed pointers macros were included in the Rcpp Extending vignette

inst/include/Rcpp/vector/Matrix.h

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -175,25 +175,25 @@ class Matrix : public Vector<RTYPE, StoragePolicy>, public MatrixBase<RTYPE, tru
175175

176176
template <typename U>
177177
void fill_diag__dispatch( traits::false_type, const U& u) {
178-
Shield<SEXP> elem( converter_type::get( u ) ) ;
179-
int n = Matrix::ncol() ;
180-
int offset = n +1 ;
181-
iterator it( VECTOR::begin()) ;
182-
for( int i=0; i<n; i++){
183-
*it = ::Rf_duplicate( elem );
184-
it += offset;
178+
Shield<SEXP> elem( converter_type::get( u ) );
179+
180+
R_xlen_t bounds = ( Matrix::nrow() < Matrix::ncol() ) ?
181+
Matrix::nrow() : Matrix::ncol();
182+
183+
for (R_xlen_t i = 0; i < bounds; ++i) {
184+
(*this)(i, i) = elem;
185185
}
186186
}
187187

188188
template <typename U>
189189
void fill_diag__dispatch( traits::true_type, const U& u) {
190-
stored_type elem = converter_type::get( u ) ;
191-
int n = Matrix::ncol() ;
192-
int offset = n + 1 ;
193-
iterator it( VECTOR::begin()) ;
194-
for( int i=0; i<n; i++){
195-
*it = elem ;
196-
it += offset;
190+
stored_type elem = converter_type::get( u );
191+
192+
R_xlen_t bounds = ( Matrix::nrow() < Matrix::ncol() ) ?
193+
Matrix::nrow() : Matrix::ncol();
194+
195+
for (R_xlen_t i = 0; i < bounds; ++i) {
196+
(*this)(i, i) = elem;
197197
}
198198
}
199199

inst/unitTests/cpp/Matrix.cpp

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -397,3 +397,16 @@ Rcpp::LogicalMatrix lgl_zeros(int n) {
397397
return Rcpp::LogicalMatrix::zeros(n);
398398
}
399399

400+
// --- Diagonal Fill
401+
402+
// [[Rcpp::export]]
403+
Rcpp::NumericMatrix num_diag_fill(Rcpp::NumericMatrix x, double diag_val) {
404+
x.fill_diag(diag_val);
405+
return x;
406+
}
407+
408+
// [[Rcpp::export]]
409+
Rcpp::CharacterMatrix char_diag_fill(Rcpp::CharacterMatrix x, std::string diag_val) {
410+
x.fill_diag(diag_val);
411+
return x;
412+
}

inst/unitTests/runit.Matrix.R

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -338,5 +338,30 @@ if (.runThisTest) {
338338
"zeros - logical"
339339
)
340340
}
341+
342+
343+
test.Matrix.diagfill <- function() {
344+
345+
checkEquals(num_diag_fill(diag(1.0, 2, 4), 0.0),
346+
matrix(0.0, 2, 4),
347+
msg = "diagonal fill - case: n < p")
348+
349+
checkEquals(num_diag_fill(diag(1.0, 4, 2), 0.0),
350+
matrix(0.0, 4, 2),
351+
msg = "diagonal fill - case: n > p")
352+
353+
checkEquals(num_diag_fill(diag(1.0, 3, 3), 0.0),
354+
matrix(0.0, 3, 3),
355+
msg = "diagonal fill - case: n = p")
356+
357+
m <- matrix("", 2, 4)
358+
diag(m) <- letters[1:2]
359+
360+
checkEquals(char_diag_fill(m, ""),
361+
matrix("", 2, 4),
362+
msg = "diagonal fill - char")
363+
364+
365+
}
341366

342367
}

0 commit comments

Comments
 (0)