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 260-377

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* operationTarget = nullptr;
            
            try {

                // BigDataStatMeth::hdf5Dataset* tempA = nullptr;
                // BigDataStatMeth::hdf5Dataset* tempB = nullptr;
                // BigDataStatMeth::hdf5Dataset* tempResult = nullptr;
                std::unique_ptr<BigDataStatMeth::hdf5Dataset> tempA(nullptr);
                std::unique_ptr<BigDataStatMeth::hdf5Dataset> tempB(nullptr);
                std::unique_ptr<BigDataStatMeth::hdf5Dataset> tempResult(nullptr);


                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);
                        throw std::runtime_error("Matrix A must be square for diagonal operations");
                    }
                    std::string tempNameA = dsA->getDatasetName() + "_temp_diag_A";
                    // tempA = new BigDataStatMeth::hdf5Dataset(dsA->getFileptr(), dsA->getGroup(), tempNameA, true);
                    tempA.reset(new BigDataStatMeth::hdf5Dataset(dsA->getFileptr(), dsA->getGroup(), tempNameA, true));
                    extractDiagonalToVector(dsA, tempA.get());
                    finalA = tempA.get();
                }
                
                // Extract diagonal from B if it's a matrix
                if (!isVectorB) {
                    if (dsB->nrows() != dsB->ncols()) {
                        // checkClose_file(tempA, tempB, tempResult);
                        throw std::runtime_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);
                    tempB.reset(new BigDataStatMeth::hdf5Dataset(dsB->getFileptr(), dsB->getGroup(), tempNameB, true));
                    extractDiagonalToVector(dsB, tempB.get());
                    finalB = tempB.get();
                }
                
                // Validate dimensions
                hsize_t sizeA = validateVectorDataset(finalA);
                hsize_t sizeB = validateVectorDataset(finalB);
                
                if (sizeA == 0 || sizeB == 0 || sizeA != sizeB) {
                    // checkClose_file(tempA, tempB, tempResult);
                    throw std::runtime_error("Invalid or incompatible diagonal dimensions: vs");
                    // cleanup_temp_datasets(tempA, tempB);
                    return;
                }
                
                // Determine target for operation result
                
                // std::unique_ptr<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);
                        tempResult.reset(new BigDataStatMeth::hdf5Dataset(dsA->getFileptr(), dsA->getGroup(), tempNameResult, true));
                        operationTarget = tempResult.get();
                    }
                } 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);
                        tempResult.reset(new BigDataStatMeth::hdf5Dataset(dsB->getFileptr(), dsB->getGroup(), tempNameResult, true));
                        operationTarget = tempResult.get();
                    }
                }
                
                // 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;
                    throw std::runtime_error("Unknown diagonal operation");
                }
                
                // Write result back to matrix diagonal if needed
                if (target == "A" && !isVectorA) {
                    writeDiagonalFromVector(tempResult.get(), dsA);
                } else if (target == "B" && !isVectorB) {
                    writeDiagonalFromVector(tempResult.get(), dsB);
                }
                
                //......// delete operationTarget; operationTarget = nullptr;
                // Cleanup
                // cleanup_temp_datasets(tempA, tempB);
                // if (tempResult) { delete tempResult; tempResult = nullptr; }
                
            } catch(std::exception& ex) {
                checkClose_file(operationTarget);
                // checkClose_file(tempA, tempB, tempResult);
                // cleanup_temp_datasets(tempA, tempB);
                // if (tempResult) { delete tempResult; tempResult = nullptr; }
                throw std::runtime_error(std::string("Error in performMatrixDiagonalOperation: ") + ex.what());
            }
        }

7 Usage Example

#include "BigDataStatMeth.hpp"

// Example usage
auto result = performMatrixDiagonalOperation(...);