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 operationoperation(int): Operation type: 0=add, 1=subtract, 2=multiply, 3=dividetarget(std::string): Where to write result: “input”, “new”bparal(bool): Whether to use parallel processingthreads(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
6 Source Code
NoteImplementation
File: inst/include/hdf5Utilities/hdf5DiagonalMethods.hpp • Lines 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(...);