scalarOperation

C++ Function Reference

1 Signature

void BigDataStatMeth::DiagonalOps::scalarOperation(BigDataStatMeth::hdf5Dataset *dsInput, BigDataStatMeth::hdf5Dataset *dsResult, double scalar, int operation, std::string target="new", bool bparal=false, Rcpp::Nullable< int > threads=R_NilValue)

2 Description

Perform scalar operations on diagonal elements.

3 Parameters

  • dsInput (BigDataStatMeth::hdf5Dataset *): Input dataset (matrix or vector)
  • dsResult (BigDataStatMeth::hdf5Dataset *): Result dataset (only used if target=“new”)
  • scalar (double): Scalar value for operation
  • operation (int): Operation type: 0=add, 1=subtract, 2=multiply, 3=divide
  • target (std::string): Where to write result: “input”, “new”
  • bparal (bool): Whether to use parallel processing
  • threads (Rcpp::Nullable< int >): Number of threads

4 Details

Applies scalar operations (add, subtract, multiply, divide) to diagonal elements. Automatically detects if input is matrix (extracts diagonal) or vector (direct).

5 Call Graph

Function dependencies

6 Source Code

File: inst/include/hdf5Utilities/hdf5DiagonalMethods.hppLines 579-691

inline void scalarOperation(BigDataStatMeth::hdf5Dataset* dsInput,
                                    BigDataStatMeth::hdf5Dataset* dsResult,
                                    double scalar,
                                    int operation,
                                    std::string target = "new",
                                    bool bparal = false,
                                    Rcpp::Nullable<int> threads = R_NilValue)
        {
            BigDataStatMeth::hdf5Dataset* tempInput = nullptr;
            BigDataStatMeth::hdf5Dataset* tempResult = nullptr;
            
            try {
                bool isVectorInput = isDiagonalVector(dsInput);
                BigDataStatMeth::hdf5Dataset* finalInput = dsInput;
                
                // Extract diagonal from input if it's a matrix
                if (!isVectorInput) {
                    if (dsInput->nrows() != dsInput->ncols()) {
                        Rf_error("Input matrix must be square for diagonal operations");
                        return;
                    }
                    std::string tempNameInput = dsInput->getDatasetName() + "_temp_scalar_input";
                    tempInput = new BigDataStatMeth::hdf5Dataset(dsInput->getFileptr(), dsInput->getGroup(), tempNameInput, true);
                    extractDiagonalToVector(dsInput, tempInput);
                    finalInput = tempInput;
                }
                
                // Validate input
                hsize_t sizeInput = validateVectorDataset(finalInput);
                if (sizeInput == 0) {
                    Rf_error("Invalid input dimensions for scalar operation");
                    cleanup_temp_datasets(tempInput, nullptr);
                    return;
                }
                
                // Determine target for operation result
                BigDataStatMeth::hdf5Dataset* operationTarget = nullptr;
                
                if (target == "new") {
                    operationTarget = dsResult;
                    // CREAR DATASET EXPLÍCITAMENTE siguiendo patrón vectorial
                    // operationTarget->createDataset(1, sizeInput, "real");  // Vector 1×N
                    operationTarget->createDataset( sizeInput, 1, "real");  // Vector 1×N
                } else if (target == "input") {
                    if (isVectorInput) {
                        operationTarget = dsInput;  // Usar vector input directamente
                    } else {
                        // Para matriz, crear temp y después escribir diagonal
                        std::string tempNameResult = dsInput->getDatasetName() + "_temp_scalar_result";
                        tempResult = new BigDataStatMeth::hdf5Dataset(dsInput->getFileptr(), dsInput->getGroup(), tempNameResult, true);
                        // tempResult->createDataset(1, sizeInput, "real");
                        tempResult->createDataset(sizeInput, 1, "real");  
                        operationTarget = tempResult;
                    }
                }
                
                // Read input vector data
                std::vector<hsize_t> stride = {1, 1}, block = {1, 1};
                std::vector<double> input_data(sizeInput);
                
                if (finalInput->nrows() == 1) {
                    finalInput->readDatasetBlock({0, 0}, {1, sizeInput}, stride, block, input_data.data());
                } else {
                    finalInput->readDatasetBlock({0, 0}, {sizeInput, 1}, stride, block, input_data.data());
                }
                
                // Apply scalar operation
                if (bparal && sizeInput > 10000) {
                    #pragma omp parallel num_threads(get_threads(bparal, threads))
                    {
                    #pragma omp for schedule(static)
                        for (hsize_t i = 0; i < sizeInput; ++i) {
                            switch (operation) {
                            case 0: input_data[i] += scalar; break;  // add
                            case 1: input_data[i] -= scalar; break;  // subtract
                            case 2: input_data[i] *= scalar; break;  // multiply
                            case 3: input_data[i] /= scalar; break;  // divide
                            case 4: input_data[i] = std::pow(input_data[i], scalar); break;  // power
                            default: Rf_error("Unknown scalar operation: %d", operation);
                            }
                        }
                    }
                } else {
                    for (hsize_t i = 0; i < sizeInput; ++i) {
                        switch (operation) {
                        case 0: input_data[i] += scalar; break;
                        case 1: input_data[i] -= scalar; break;
                        case 2: input_data[i] *= scalar; break;
                        case 3: input_data[i] /= scalar; break;
                        case 4: input_data[i] = std::pow(input_data[i], scalar); break;
                        default: Rf_error("Unknown scalar operation: %d", operation);
                        }
                    }
                }
                
                // Write result
                operationTarget->writeDatasetBlock(input_data, {0, 0}, {1, sizeInput}, stride, block);
                
                // Write result back to matrix diagonal if needed
                if (target == "input" && !isVectorInput) {
                    writeDiagonalFromVector(tempResult, dsInput);
                }
                
                // Cleanup
                cleanup_temp_datasets(tempInput, nullptr);
                if (tempResult) { delete tempResult; tempResult = nullptr; }
                
            } catch(std::exception& ex) {
                cleanup_temp_datasets(tempInput, nullptr);
                if (tempResult) { delete tempResult; tempResult = nullptr; }
                Rf_error("Error in scalarOperation: %s", ex.what());
            }
        }

7 Usage Example

#include "BigDataStatMeth.hpp"

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