Skip to content

Commit

Permalink
coeffRef(it.row(), it.col()) -> it.valueRef()
Browse files Browse the repository at this point in the history
Minor performance optimization.  In a few of the edited places, the code is iterating over the elements of a sparse matrix using an iterator.  However, when it came time to update the sparsematrix at the given position, rather then directly assign the value, the code called `coeffRef` to assign it.

This is inefficient because `coeffRef` involves an expensive binary search to find position `i,j` in the sparse matrix, even though the memory location of i,j is already known to the iterator on the stack.  To directly use the known value, we can just call .valueRef() on the iterator instead of looking for the position again.

A discussion of this difference is given in the `Iterating over the nonzero coefficients` section of this tutorial: https://eigen.tuxfamily.org/dox/group__TutorialSparse.html

Benchmark showed a modest 13% time reduction in a call to NormalizeData.
  • Loading branch information
evolvedmicrobe committed May 25, 2018
1 parent f6e445e commit be7b475
Showing 1 changed file with 7 additions and 7 deletions.
14 changes: 7 additions & 7 deletions src/data_manipulation.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,14 +24,14 @@ Eigen::SparseMatrix<double> RunUMISampling(Eigen::SparseMatrix<double> data, int
if (fmod(entry, 1) != 0){
double rn = runif(1)[0];
if(fmod(entry, 1) <= rn){
data.coeffRef(it.row(), it.col()) = floor(entry);
it.valueRef() = floor(entry);
}
else{
data.coeffRef(it.row(), it.col()) = ceil(entry);
it.valueRef() = ceil(entry);
}
}
else{
data.coeffRef(it.row(), it.col()) = entry;
it.valueRef() = entry;
}
}
}
Expand All @@ -52,14 +52,14 @@ Eigen::SparseMatrix<double> RunUMISamplingPerCell(Eigen::SparseMatrix<double> da
if (fmod(entry, 1) != 0){
double rn = runif(1)[0];
if(fmod(entry, 1) <= rn){
data.coeffRef(it.row(), it.col()) = floor(entry);
it.valueRef() = floor(entry);
}
else{
data.coeffRef(it.row(), it.col()) = ceil(entry);
it.valueRef() = ceil(entry);
}
}
else{
data.coeffRef(it.row(), it.col()) = entry;
it.valueRef() = entry;
}
}
}
Expand Down Expand Up @@ -117,7 +117,7 @@ Eigen::SparseMatrix<double> LogNorm(Eigen::SparseMatrix<double> data, int scale_
for (int k=0; k < data.outerSize(); ++k){
p.increment();
for (Eigen::SparseMatrix<double>::InnerIterator it(data, k); it; ++it){
data.coeffRef(it.row(), it.col()) = log1p(double(it.value()) / colSums[k] * scale_factor);
it.valueRef() = log1p(double(it.value()) / colSums[k] * scale_factor);
}
}
return data;
Expand Down

0 comments on commit be7b475

Please sign in to comment.