RcppbdEigen_hdf5

C++ Function Reference

1 Signature

void BigDataStatMeth::RcppbdEigen_hdf5(std::string filename, std::string strsubgroup, std::string strdataset, int k=0, const std::string &which="LM", int ncv=0, bool bcenter=false, bool bscale=false, double tolerance=1e-10, int max_iter=1000, bool compute_vectors=true, bool bforce=false, Rcpp::Nullable< int > threads=R_NilValue)

2 Description

Main eigenvalue decomposition for HDF5 matrices.

3 Parameters

  • filename (std::string): Path to HDF5 file
  • strsubgroup (std::string): Group path
  • strdataset (std::string): Dataset name (square matrix)
  • k (int): Number of eigenvalues. 0 or >= n -> full decomposition via SelfAdjointEigenSolver. 0 < k < n -> Spectra (partial).
  • which (const std::string &): Which eigenvalues: LM, SM, LR, SR, LI, SI, LA, SA
  • ncv (int): Lanczos vectors (0 = auto)
  • bcenter (bool): Center columns
  • bscale (bool): Scale columns
  • tolerance (double): Convergence tolerance
  • max_iter (int): Maximum iterations
  • compute_vectors (bool): Compute eigenvectors
  • bforce (bool): Overwrite existing results
  • threads (Rcpp::Nullable< int >): OpenMP threads

4 Details

filenamePath to HDF5 file strsubgroupGroup path strdatasetDataset name (square matrix) kNumber of eigenvalues. 0 or >= n -> full decomposition via SelfAdjointEigenSolver. 0 < k < n -> Spectra (partial). whichWhich eigenvalues: LM, SM, LR, SR, LI, SI, LA, SA ncvLanczos vectors (0 = auto) bcenterCenter columns bscaleScale columns toleranceConvergence tolerance max_iterMaximum iterations compute_vectorsCompute eigenvectors bforceOverwrite existing results threadsOpenMP threadsResults written under “EIGEN//values” and “EIGEN//vectors”

5 Call Graph

Function dependencies

6 Source Code

File: inst/include/hdf5Algebra/matrixEigenDecomposition.hppLines 287-434

inline void RcppbdEigen_hdf5(std::string filename,
                                  std::string strsubgroup,
                                  std::string strdataset,
                                  int k = 0,
                                  const std::string& which = "LM",
                                  int ncv = 0,
                                  bool bcenter = false, bool bscale = false,
                                  double tolerance = 1e-10, int max_iter = 1000,
                                  bool compute_vectors = true, bool bforce = false,
                                  Rcpp::Nullable<int> threads = R_NilValue)
    {
        try {
            std::unique_ptr<BigDataStatMeth::hdf5Dataset> dsA(nullptr);
            std::unique_ptr<BigDataStatMeth::hdf5Dataset> dsd(nullptr);
            std::unique_ptr<BigDataStatMeth::hdf5Dataset> dsu(nullptr);
            
            std::vector<hsize_t> stride = {1, 1}, block = {1, 1},
                                  offset = {0, 0}, count  = {0, 0};
            
            dsA.reset(new BigDataStatMeth::hdf5Dataset(filename, strsubgroup, strdataset, false));
            dsA->openDataset();
            
            if (dsA->getDatasetptr() != nullptr) {
                
                std::string stroutgroup = "EIGEN/" + strdataset;
                
                std::vector<hsize_t> dims_out = {dsA->nrows(), dsA->ncols()};
                count = {dims_out[0], dims_out[1]};
                
                if (dims_out[0] != dims_out[1])
                    throw std::runtime_error("Matrix must be square for eigendecomposition");
                
                hsize_t n = dims_out[0];
                
                // Detect full decomposition BEFORE validateSpectraParams clamps k.
                // k <= 0 means "all" (R layer converts 0 -> n but guard here as well).
                bool full_decomp = (k <= 0 || k >= (int)n);
                
                // For Spectra path: validate params now. For full path: skip (not needed).
                if (!full_decomp)
                    std::tie(k, ncv) = validateSpectraParams((int)n, k, ncv);
                
                dsd.reset(new BigDataStatMeth::hdf5Dataset(filename, stroutgroup, "values", bforce));
                if (compute_vectors)
                    dsu.reset(new BigDataStatMeth::hdf5Dataset(filename, stroutgroup, "vectors", bforce));
                
                // ── Small matrices: load entirely into memory ──────────────────────
                if (n * n < MAXELEMSINBLOCK / 20) {
                    
                    std::vector<double> vdA(count[0] * count[1]);
                    dsA->readDatasetBlock({offset[0], offset[1]}, {count[0], count[1]},
                                          stride, block, vdA.data());
                    Eigen::MatrixXd X = Eigen::Map<Eigen::Matrix<double, Eigen::Dynamic,
                                                                   Eigen::Dynamic,
                                                                   Eigen::RowMajor>>(
                        vdA.data(), count[0], count[1]);
                    
                    eigdecomp reteig;
                    
                    if (full_decomp) {
                        // All eigenvalues: use direct solver (Spectra requires k < n)
                        Eigen::SelfAdjointEigenSolver<Eigen::MatrixXd> solver(X);
                        if (solver.info() != Eigen::Success)
                            throw std::runtime_error("SelfAdjointEigenSolver failed to converge");
                        
                        int nf = (int)n;
                        reteig.eigenvalues_real.resize(nf);
                        for (int i = 0; i < nf; ++i)
                            reteig.eigenvalues_real(i) = solver.eigenvalues()(nf - 1 - i);
                        
                        if (compute_vectors) {
                            reteig.eigenvectors_real.resize(nf, nf);
                            for (int j = 0; j < nf; ++j)
                                reteig.eigenvectors_real.col(j) =
                                    solver.eigenvectors().col(nf - 1 - j);
                        }
                        reteig.bconv           = true;
                        reteig.is_symmetric    = true;
                        reteig.bcomputevectors = compute_vectors;
                        
                    } else {
                        reteig = RcppbdEigen_spectra(X, k, which, ncv,
                                                      bcenter, bscale, tolerance, max_iter);
                        if (!reteig.bconv)
                            throw std::runtime_error("Eigendecomposition failed to converge");
                    }
                    
                    // Write eigenvalues (1 x k dataset)
                    dsd->inheritCompressionLevel(dsA->getCompressionLevel());
                    dsd->createDataset(1, reteig.eigenvalues_real.size(), "real");
                    dsd->writeDataset(Rcpp::wrap(reteig.eigenvalues_real));
                    
                    // Write eigenvectors (n x k dataset)
                    if (compute_vectors && reteig.bcomputevectors) {
                        dsu->inheritCompressionLevel(dsA->getCompressionLevel());
                        dsu->createDataset(reteig.eigenvectors_real.rows(),
                                           reteig.eigenvectors_real.cols(), "real");
                        dsu->writeDataset(Rcpp::wrap(reteig.eigenvectors_real));
                    }
                    
                    // Imaginary parts (non-symmetric matrices only)
                    if (!reteig.is_symmetric &&
                        reteig.eigenvalues_imag.cwiseAbs().maxCoeff() > 1e-14) {
                        
                        std::unique_ptr<BigDataStatMeth::hdf5Dataset> dsd_imag(
                            new BigDataStatMeth::hdf5Dataset(filename, stroutgroup,
                                                              "values_imag", bforce));
                        dsd_imag->inheritCompressionLevel(dsA->getCompressionLevel());
                        dsd_imag->createDataset(1, reteig.eigenvalues_imag.size(), "real");
                        dsd_imag->writeDataset(Rcpp::wrap(reteig.eigenvalues_imag));
                        
                        if (compute_vectors && reteig.bcomputevectors &&
                            reteig.eigenvectors_imag.cwiseAbs().maxCoeff() > 1e-14) {
                            std::unique_ptr<BigDataStatMeth::hdf5Dataset> dsu_imag(
                                new BigDataStatMeth::hdf5Dataset(filename, stroutgroup,
                                                                  "vectors_imag", bforce));
                            dsu_imag->inheritCompressionLevel(dsA->getCompressionLevel());
                            dsu_imag->createDataset(reteig.eigenvectors_imag.rows(),
                                                    reteig.eigenvectors_imag.cols(), "real");
                            dsu_imag->writeDataset(Rcpp::wrap(reteig.eigenvectors_imag));
                        }
                    }
                    
                } else {
                    // ── Large matrices: block-wise path ───────────────────────────
                    // For full_decomp on large matrices: use n-1 (best we can do with Spectra)
                    int k_block = full_decomp ? (int)(n - 1) : k;
                    RcppbdEigen_hdf5_Block(dsA.get(), dsd.get(),
                                            compute_vectors ? dsu.get() : nullptr,
                                            k_block, which, ncv,
                                            bcenter, bscale, tolerance, max_iter,
                                            compute_vectors, threads);
                }
            }
            
        } catch(H5::FileIException& error) {
            throw std::runtime_error("c++ exception RcppbdEigen_hdf5 (File IException)");
        } catch(H5::DataSetIException& error) {
            throw std::runtime_error(
                std::string("c++ exception RcppbdEigen_hdf5 (DataSet IException): ")
                + error.getDetailMsg());
        } catch(std::exception &ex) {
            throw std::runtime_error(
                std::string("c++ exception RcppbdEigen_hdf5: ") + ex.what());
        } catch (...) {
            throw std::runtime_error("C++ exception RcppbdEigen_hdf5 (unknown reason)");
        }
    }

7 Usage Example

#include "BigDataStatMeth.hpp"

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