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 dataset
  • dsB (BigDataStatMeth::hdf5Dataset *): Second input dataset
  • dsResult (BigDataStatMeth::hdf5Dataset *): Result dataset (only used if target=“new”)
  • operation (int): Operation type: 0=add, 1=subtract, 2=multiply, 3=divide
  • target (std::string): Where to write result: “A”, “B”, or “new”
  • bparal (bool): Whether to use parallel processing
  • threads (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

Function dependencies

6 Source Code

File: inst/include/hdf5Utilities/hdf5DiagonalMethods.hppLines 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(...);