程序问答   发布时间:2022-06-01  发布网站:大佬教程  code.js-code.com
大佬教程收集整理的这篇文章主要介绍了根据 Rcpp.h大佬教程大佬觉得挺不错的,现在分享给大家,也给大家做个参考。

如何解决根据 Rcpp.h?

开发过程中遇到根据 Rcpp.h的问题如何解决?下面主要结合日常开发的经验,给出你关于根据 Rcpp.h的解决方法建议,希望对你解决根据 Rcpp.h有所启发或帮助;

我正在研究一个 Rcpp 稀疏矩阵类,它同时使用 Rcpp::IntegerVector(行/列指针)和模板化的 std::vector<T>。基本原理是,可以通过简单地将它们作为指向 R 对象的指针来避免在极大稀疏矩阵中深度复制整数指针向量(@i@p)的开销,并且始终如一地,微基准显示与转换为 Eigen::SparseMatrix<T>arma::SpMat<T> 相比,这种方法几乎只需要一半的时间,同时使用更少的内存。

bare-bones Rcpp 稀疏矩阵类

namespace SpRcpp {

    template<typename T>
    class SpMatrix {

    public:
        Rcpp::IntegerVector i,p;
        std::vector<T> x;
        unsigned int n_row,n_col;

        // constructor for the class from an Rcpp::S4 object
        SpMatrix(Rcpp::S4& mat) {
            Rcpp::IntegerVector dims = mat.slot("Dim");
            n_row = (unsigned int)dims[0];
            i = mat.slot("i");
            p = mat.slot("p");
            x = Rcpp::as<std::vector<T>>(mat.slot("x"));
        };
        // other constructors,class methods,iterators,etc.
    };
}

示例用法:

//[[Rcpp::export]]
std::vector<float> SpRcpp_SpMatrix(Rcpp::S4& mat) {
    SpRcpp::SpMatrix<float> A(mat);
    return A.x;
}

这有效!

但是,我希望 Rcpp 将 S4 dgCMatrix 对象(例如)隐式转换为 SpRcpp::SpMatrix 对象以启用如下功能:

隐式 Rcpp 包装

//[[Rcpp::export]]
std::vector<float> SpRcpp_SpMatrix2(SpRcpp::SpMatrix<float>& mat) {
    return mat.x;
}

这就是使用 Rcpp::as 的情况。

我尝试了以下方法:

namespace Rcpp {
    namespace Traits {
        template <typename T>
        class Exporter< SpRcpp::SpMatrix<T> > {
        public:
            Exporter(SEXP X) { Rcpp::S4 mat = x; }
            SpRcpp::SpMatrix<T> get() {
                return SpRcpp::SpMatrix<T>(mat);
            }
        private: Rcpp::S4 mat;
        };
    }
}

这可以编译,我知道 SpRcpp::SpMatrix<T>(Rcpp::S4& X) 构造函数可以工作,但是当我尝试将 dgCMatrix 输入 SpRcpp_SpMatrix() 时,我收到错误:

Error in SpRcpp_SpMatrix2(A) : Not an S4 object.

我认为这是因为我在所有类声明之前都声明了以下内容:

#include <RcppCommon.h>
#include <Rcpp.h>

根据文档 here、RcppGallery example 和 RcppArmadillo 实现,#include <Rcpp.h> 不得位于 Rcpp::asRcpp::wrap 函数之前,但就我而言,我不能这样做,因为我的类定义需要 Rcpp.h

问题:Rcpp::as 类依赖于 {{1} 时,如何从 SpRcpp::SpMatrix dgCMatrix 创建 Rcpp::S4SpMatrix }?

解决方法

创建一个 Rcpp SparseMatrix 类其实很简单!我多虑了。

#include <rcpp.h>

// Rcpp for sparse matrices (spRcpp)
namespace Rcpp {
    class SparseMatrix {
    public:
        Rcpp::IntegerVector i,p;
        Rcpp::NumericVector x;
        int n_rows,n_cols;

        // constructor
        SparseMatrix(Rcpp::S4 mat) {
            Rcpp::IntegerVector dim = mat.slot("Dim");
            i = mat.slot("i");
            p = mat.slot("p");
            x = mat.slot("x");
            n_rows = (int)dim[0];
            n_cols = (int)dim[1];
        };
    };
}

namespace Rcpp {
    template <> Rcpp::SparseMatrix as(SEXP mat) {
        return Rcpp::SparseMatrix(mat);
    }
}

//[[Rcpp::export]]
Rcpp::NumericVector toRcppSparseMatrix(Rcpp::SparseMatrix& A) {
    return A.x;
}

给定 @H_19_3@matrix::dgCMatrix、@H_19_3@mat,调用 toRcppSparseMatrix(mat) 会在 1-2 微秒内返回 2500 万个值的非零值。这与 RcppArmadillo 或 RcppEigen 稀疏矩阵转换形成对比,后者需要大约 250 毫秒才能对同一矩阵进行深度复制并在内存中运行

正如 Dirk 所建议的,使用 RcppArmadillo ivecdvec 非常有效,但仍会创建浅拷贝,这会导致大约 100 毫秒的运行时间并消耗一些内存。

显然,上述方法仅限于双精度类型,因此没有深拷贝就无法进行浮点运算。

大佬总结

以上是大佬教程为你收集整理的根据 Rcpp.h全部内容,希望文章能够帮你解决根据 Rcpp.h所遇到的程序开发问题。

如果觉得大佬教程网站内容还不错,欢迎将大佬教程推荐给程序员好友。

本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。
标签:根据