This library contains functions for multiplying a tatami matrix with a vector or matrix.
It provides specialized code paths depending on the properties of the tatami::Matrix
- namely, sparsity or row-based iteration.
Parallelization is achieved via the usual tatami::parallelize()
function.
Matrix-vector multiplication is pretty straightforward:
#include "tatami_mult/tatami_mult.hpp"
std::shared_ptr<tatami::NumericMatrix> mat(
new tatami::DenseRowMatrix<double, int>(nrows, ncols, vals)
);
// Create an RHS vector.
std::vector<double> rhs(mat.ncol());
// Store the matrix-vector product in 'output'.
std::vector<double> output(mat.nrow());
tatami_mult::Options opt;
tatami_mult::multiply(*mat, rhs.data(), output.data(), opt);
If multiple vectors are present, we can handle it in a single pass through our matrix:
// Create multiple LHS vectors.
std::vector<std::vector<double> > lhs(10, std::vector<double>(mat.nrow()));
std::vector<const double*> lhs_ptrs(10);
for (size_t l = 0; l < lhs.size(); ++l) {
lhs_ptrs[l] = lhs[l].data()
}
// Vector-matrix product for each vector.
std::vector<std::vector<double> > output(10, std::vector<double>(mat.ncol()));
std::vector<double*> out_ptrs(10);
for (size_t l = 0; l < output.size(); ++l) {
out_ptrs[l] = output[l].data()
}
tatami_mult::Options opt;
tatami_mult::multiply(lhs_ptrs, *mat, out_ptrs, opt);
With two tatami::Matrix
objects, multiply()
will prefer a single pass through the larger matrix,
and will save the product as a column-major array.
Both of these behaviors can be modified by changing the settings in Options
.
std::shared_ptr<tatami::NumericMatrix> mat2(
new tatami::DenseRowMatrix<double, int>(ncols, 100, vals)
);
std::vector<double> output(nrow, 100);
tatami_mult::multiply(mat, mat2, output.data(), opt);
Check out the reference documentation for more details.
If you're using CMake, you just need to add something like this to your CMakeLists.txt
:
include(FetchContent)
FetchContent_Declare(
tatami_mult
GIT_REPOSITORY https://github.com/tatami-inc/tatami_mult
GIT_TAG master # or any version of interest
)
FetchContent_MakeAvailable(tatami_mult)
Then you can link to tatami_mult to make the headers available during compilation:
# For executables:
target_link_libraries(myexe tatami_mult)
# For libaries
target_link_libraries(mylib INTERFACE tatami_mult)
You can install the library by cloning a suitable version of this repository and running the following commands:
mkdir build && cd build
cmake .. -DTATAMI_MULT_TESTS=OFF
cmake --build . --target install
Then you can use find_package()
as usual:
find_package(tatami_tatami_mult CONFIG REQUIRED)
target_link_libraries(mylib INTERFACE tatami::tatami_mult)
By default, this will use FetchContent
to fetch all external dependencies.
If you want to install them manually, use -DTATAMI_MULT_FETCH_EXTERN=OFF
.
See extern/CMakeLists.txt
to find compatible versions of each dependency.
If you're not using CMake, the simple approach is to just copy the files the include/
subdirectory -
either directly or with Git submodules - and include their path during compilation with, e.g., GCC's -I
.
You'll need to include the transitive dependencies yourself,
check out extern/CMakeLists.txt
for a list.