performMatrixDiagonalOperation
C++ Function Reference
1 Signature
void BigDataStatMeth::DiagonalOps::performMatrixDiagonalOperation(BigDataStatMeth::hdf5Dataset *dsA, BigDataStatMeth::hdf5Dataset *dsB, BigDataStatMeth::hdf5Dataset *dsResult, int operation, std::string target, bool bparal, Rcpp::Nullable< int > threads)2 Description
Perform diagonal operations on matrices using extract-operate-write strategy.
3 Parameters
dsA(BigDataStatMeth::hdf5Dataset *): First input datasetdsB(BigDataStatMeth::hdf5Dataset *): Second input datasetdsResult(BigDataStatMeth::hdf5Dataset *): Result dataset (only used if target=“new”)operation(int): Operation type: 0=add, 1=subtract, 2=multiply, 3=dividetarget(std::string): Where to write result: “A”, “B”, or “new”bparal(bool): Whether to use parallel processingthreads(Rcpp::Nullable< int >): Number of threads
4 Details
Implements the extract-operate-write pattern for matrix diagonal operations. It processes only diagonal elements instead of full matrices.
5 Call Graph
6 Source Code
NoteImplementation
File: inst/include/hdf5Utilities/hdf5DiagonalMethods.hpp • Lines 259-361
inline void performMatrixDiagonalOperation(BigDataStatMeth::hdf5Dataset* dsA, BigDataStatMeth::hdf5Dataset* dsB,
BigDataStatMeth::hdf5Dataset* dsResult, int operation, std::string target,
bool bparal, Rcpp::Nullable<int> threads)
{
BigDataStatMeth::hdf5Dataset* tempA = nullptr;
BigDataStatMeth::hdf5Dataset* tempB = nullptr;
BigDataStatMeth::hdf5Dataset* tempResult = nullptr;
try {
bool isVectorA = isDiagonalVector(dsA);
bool isVectorB = isDiagonalVector(dsB);
BigDataStatMeth::hdf5Dataset* finalA = dsA;
BigDataStatMeth::hdf5Dataset* finalB = dsB;
// Extract diagonal from A if it's a matrix
if (!isVectorA) {
if (dsA->nrows() != dsA->ncols()) {
checkClose_file(tempA, tempB, tempResult);
Rf_error("Matrix A must be square for diagonal operations");
return;
}
std::string tempNameA = dsA->getDatasetName() + "_temp_diag_A";
tempA = new BigDataStatMeth::hdf5Dataset(dsA->getFileptr(), dsA->getGroup(), tempNameA, true);
extractDiagonalToVector(dsA, tempA);
finalA = tempA;
}
// Extract diagonal from B if it's a matrix
if (!isVectorB) {
if (dsB->nrows() != dsB->ncols()) {
checkClose_file(tempA, tempB, tempResult);
Rf_error("Matrix B must be square for diagonal operations");
cleanup_temp_datasets(tempA, tempB);
return;
}
std::string tempNameB = dsB->getDatasetName() + "_temp_diag_B";
tempB = new BigDataStatMeth::hdf5Dataset(dsB->getFileptr(), dsB->getGroup(), tempNameB, true);
extractDiagonalToVector(dsB, tempB);
finalB = tempB;
}
// Validate dimensions
hsize_t sizeA = validateVectorDataset(finalA);
hsize_t sizeB = validateVectorDataset(finalB);
if (sizeA == 0 || sizeB == 0 || sizeA != sizeB) {
checkClose_file(tempA, tempB, tempResult);
Rf_error("Invalid or incompatible diagonal dimensions: %llu vs %llu", sizeA, sizeB);
cleanup_temp_datasets(tempA, tempB);
return;
}
// Determine target for operation result
BigDataStatMeth::hdf5Dataset* operationTarget = nullptr;
if (target == "new") {
operationTarget = dsResult;
} else if (target == "A") {
if (isVectorA) {
operationTarget = dsA;
} else {
std::string tempNameResult = dsA->getDatasetName() + "_temp_result";
tempResult = new BigDataStatMeth::hdf5Dataset(dsA->getFileptr(), dsA->getGroup(), tempNameResult, true);
operationTarget = tempResult;
}
} else if (target == "B") {
if (isVectorB) {
operationTarget = dsB;
} else {
std::string tempNameResult = dsB->getDatasetName() + "_temp_result";
tempResult = new BigDataStatMeth::hdf5Dataset(dsB->getFileptr(), dsB->getGroup(), tempNameResult, true);
operationTarget = tempResult;
}
}
// Perform vector operation
switch (operation) {
case 0: Rcpp_vector_add_hdf5(finalA, finalB, operationTarget, bparal, threads); break;
case 1: Rcpp_vector_subtract_hdf5(finalA, finalB, operationTarget, bparal, threads); break;
case 2: Rcpp_vector_multiply_hdf5(finalA, finalB, operationTarget, bparal, threads); break;
case 3: Rcpp_vector_divide_hdf5(finalA, finalB, operationTarget, bparal, threads); break;
default: Rf_error("Unknown diagonal operation: %d", operation);
}
// Write result back to matrix diagonal if needed
if (target == "A" && !isVectorA) {
writeDiagonalFromVector(tempResult, dsA);
} else if (target == "B" && !isVectorB) {
writeDiagonalFromVector(tempResult, dsB);
}
// Cleanup
cleanup_temp_datasets(tempA, tempB);
if (tempResult) { delete tempResult; tempResult = nullptr; }
} catch(std::exception& ex) {
checkClose_file(tempA, tempB, tempResult);
cleanup_temp_datasets(tempA, tempB);
if (tempResult) { delete tempResult; tempResult = nullptr; }
Rf_error("Error in performMatrixDiagonalOperation: %s", ex.what());
}
}7 Usage Example
#include "BigDataStatMeth.hpp"
// Example usage
auto result = performMatrixDiagonalOperation(...);