r - 从修改后的 arma::vec 对象中高效采样
问题描述
我正在使用 Rcpp 来加速一些 R 代码。但是,我真的在努力处理类型 - 因为这些在 R 中是外来的。这是我正在尝试做的简化版本:
#include <RcppArmadillo.h>
#include <algorithm>
//[[Rcpp::depends(RcppArmadillo)]]
using namespace Rcpp;
using namespace arma;
// [[Rcpp::export]]
NumericVector fun(SEXP Pk, int k, int i, const vec& a, const mat& D) {
// this is dummy version of my actual function - with actual arguments.;
// I'm guessing SEXP is going to need to be replaced with something else when it's called from C++ not R.;
return D.col(i);
}
// [[Rcpp::export]]
NumericVector f(const arma::vec& assignment, char k, int B, const mat& D) {
uvec k_ind = find(assignment == k);
NumericVector output(assignment.size()); // for dummy output.
uvec::iterator k_itr = k_ind.begin();
for(; k_itr != k_ind.end(); ++k_itr) {
// this is R code, as I don't know the best way to do this in C++;
k_rep = sample(c(assignment[assignment != k], -1), size = B, replace = TRUE);
output = fun(k_rep, k, *k_itr, assignment, D);
// do something with output;
}
// compile result, ultimately return a List (after I figure out how to do that. For right now, I'll cheat and return the last output);
return output;
}
我正在努力解决的部分是assignment
. 我知道sample
已经在Rarmadillo
. 但是,我可以看到两种方法,我不确定哪种方法更有效/可行。
方法一:
- 制作一个
assignment
值表。替换assignment == k
为 -1 并将其“计数”设置为 1。 - 从表“名称”中采样,概率与计数成正比。
方法二:
- 将
assignment
向量的相关子集复制到一个新向量中,其中有一个额外的点表示 -1。 - 从复制的向量中以相等的概率采样。
我想说方法 1 会更有效,除了assignment
当前是 type arma::vec
,我不确定如何从中制作表格 - 或者将其转换为更兼容的格式需要多少成本. 我想我可以实施方法 2,但我希望避免昂贵的副本。
感谢您提供的任何见解。
解决方案
许多变量声明与您所做的分配不一致,例如 assignment = k 是不可能比较的,因为分配具有实际价值并且 k 是一个字符。由于queston写得不好,我可以随意更改变量类型。这个编译..
// [[Rcpp::depends(RcppArmadillo)]]
#include <RcppArmadillo.h>
#include <RcppArmadilloExtensions/sample.h>
// [[Rcpp::export]]
arma::vec fun(const Rcpp::NumericVector& Pk, int k, unsigned int i, const arma::ivec& a, const arma::mat& D)
{
return D.col(i);
}
// [[Rcpp::export]]
Rcpp::NumericMatrix f(const arma::ivec& assignment, int k, unsigned int B, const arma::mat& D)
{
arma::uvec k_ind = find(assignment == k);
arma::ivec KK = assignment(find(assignment != k));
//these 2 row are for KK = c(assignment[assignment != k], -1)
//I dont know what is this -1 is for, why -1 ? maybe you dont need it.
KK.insert_rows(KK.n_rows, 1);
KK(KK.n_rows - 1) = -1;
arma::uvec k_ind_not = find(assignment != k);
Rcpp::NumericVector k_rep(B);
arma::mat output(D.n_rows,k_ind.n_rows); // for dummy output.
for(unsigned int i =0; i < k_ind.n_rows ; i++)
{
k_rep = Rcpp::RcppArmadillo::sample(KK, B, true);
output(arma::span::all, i) = fun(k_rep, k, i, assignment, D);
// do something with output;
}
// compile result, ultimately return a List (after I figure out how to do that. For right now, I'll cheat and return the last output);
return Rcpp::wrap(output);
}
这不是优化的(因为问题是假的),这写得不好,因为我认为 R 在搜索向量的索引时会足够快(所以在 R 中这样做并且在 Rcpp 中实现只有乐趣)......不是在这里浪费时间很有用,还有其他问题需要在 Rcpp 中实现求解器,而不是这个搜索的东西......但这不是一个有用的问题,因为您要求的算法比函数签名的更多
推荐阅读
- angular - 服务构造函数调用的行为与构造函数中的方法调用不同
- python - Python线程:继续一个线程直到另一个线程结束
- google-app-engine - 无法在 appspot.com 中查找其他文件 - app.yaml 的问题
- reactjs - Jest + SCSS @import 问题(css 模块)
- html - CSS 背景图像在真实智能手机的浏览器中没有响应
- ffmpeg - 如何将一个视频覆盖在另一个视频上,然后如果一个视频完成则全屏显示另一个视频 [FFMPEG]
- javascript - 如何使用
用于替代图像翻译的 react-i18next? - vuejs2 - 暂存构建配置 - 带有开发数据库的生产代码
- android - 为什么这个函数不能给我一个真实的结果?
- c# - 这是写入 bottonClick 事件的正确 SQL 代码吗?