如何在声明后将 NumericVector 初始化为特定大小?
How to initialize NumericVector to a specific size after it has been declared?
我编写了以下 Rcpp 代码,它编译但没有给出预期的结果。
// [[Rcpp::export]]
RObject test_1 (Rcpp::NumericVector& x)
{
NumericVector x1;
if (x.size() < 5)
{
NumericVector x1(x.size()*3);
for (int ii = 0; ii < x.size(); ii++)
{
x1[ii] = sqrt(x[ii]);
}
}
else
{
NumericVector x1(x.size()*2);
for (int ii = 0; ii < x.size(); ii++)
{
x1[ii] = sqrt(x[ii]);
}
}
return x1;
}
x1,return 向量在 if 语句外声明,其中 returned 向量 x1 的大小可以变化。但是,如果我用它创建一个新对象的大小声明 NumericVector,但是 returned 在一个空向量中的 x1。
以下代码有效:
// [[Rcpp::export]]
RObject test (const Rcpp::NumericVector& x)
{
NumericVector x1;
if (x.size() < 5)
{
NumericVector tmp(x.size()*3);
for (int ii = 0; ii < x.size(); ii++)
{
tmp[ii] = sqrt(x[ii]);
}
x1 = tmp;
}
else
{
NumericVector tmp(x.size()*2);
for (int ii = 0; ii < x.size(); ii++)
{
tmp[ii] = sqrt(x[ii]);
}
x1 = tmp;
}
return x1;
}
在这里我声明了 temp numericvector 然后将 x1 设置为该向量。
我不久前做过这个,知道有一种方法可以在声明 NumericVector 后将其设置为特定大小,但我不记得如何操作了。
编辑:编辑代码和问题以说明如何在 if 语句之前不知道 return 矢量大小。
你可以这样做
RObject test_1 (Rcpp::NumericVector x)
{
for (int ii = 0; ii < x.size(); ii++)
{
x[ii] = sqrt(x[ii]);
}
return x;
}
通过传递值,您可以创建一个与原始大小相同的新 NumericVector
如果您不想更改 API,第二个代码可以,但不需要临时变量
RObject test_1 (const Rcpp::NumericVector& x)
{
NumericVector x1(x.size());
for (int ii = 0; ii < x.size(); ii++)
{
x1[ii] = sqrt(x[ii]);
}
return x1;
}
你可以有条件地 resize
一个 std::vector<double>
和 Rcpp::wrap()
它,像这样:
#include <Rcpp.h>
// [[Rcpp::export]]
Rcpp::RObject test_1(const Rcpp::NumericVector& x) {
std::vector<double> x1;
if (x.size() < 5) {
x1.resize(3*x.size());
} else {
x1.resize(2*x.size());
}
for (int ii = 0; ii < x.size(); ii++) {
x1[ii] = sqrt(x[ii]);
}
return Rcpp::wrap(x1);
}
/*** R
xa <- 1:3
xb <- 1:10
test_1(xa)
# [1] 1.000000 1.414214 1.732051 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000
test_1(xb)
#[1] 1.000000 1.414214 1.732051 2.000000 2.236068 2.449490 2.645751 2.828427 3.000000 3.162278 0.000000 0.000000
[13] 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000
length(test_1(xa))/length(xa)
#[1] 3
length(test_1(xb))/length(xb)
#[1] 2
*/
你可以使用这种风格:
NumericVector x;
if (foo)
x = NumericVector(1);
else
x = NumericVector(2);
甚至(如果你想避免生成向量的零初始化)
x = static_cast<NumericVector>(no_init(size));
注意写的时候
NumericVector x;
if (foo)
NumericVector x(1);
您实际上正在创建 两个 NumericVector
个名为 x
的对象 -- 一个在顶级范围内,一个在范围内if
语句。
也就是说,当你写的时候值得理解
NumericVector x;
你实际上是在创建一个对象,而不仅仅是声明一个对象(这只适用于内置类型,例如int
)。因此,当您编写 NumericVector x
时,x
实际上是使用零参数 NumericVector
构造函数(创建长度为 0 的数字向量)
进行默认构造的
我编写了以下 Rcpp 代码,它编译但没有给出预期的结果。
// [[Rcpp::export]]
RObject test_1 (Rcpp::NumericVector& x)
{
NumericVector x1;
if (x.size() < 5)
{
NumericVector x1(x.size()*3);
for (int ii = 0; ii < x.size(); ii++)
{
x1[ii] = sqrt(x[ii]);
}
}
else
{
NumericVector x1(x.size()*2);
for (int ii = 0; ii < x.size(); ii++)
{
x1[ii] = sqrt(x[ii]);
}
}
return x1;
}
x1,return 向量在 if 语句外声明,其中 returned 向量 x1 的大小可以变化。但是,如果我用它创建一个新对象的大小声明 NumericVector,但是 returned 在一个空向量中的 x1。
以下代码有效:
// [[Rcpp::export]]
RObject test (const Rcpp::NumericVector& x)
{
NumericVector x1;
if (x.size() < 5)
{
NumericVector tmp(x.size()*3);
for (int ii = 0; ii < x.size(); ii++)
{
tmp[ii] = sqrt(x[ii]);
}
x1 = tmp;
}
else
{
NumericVector tmp(x.size()*2);
for (int ii = 0; ii < x.size(); ii++)
{
tmp[ii] = sqrt(x[ii]);
}
x1 = tmp;
}
return x1;
}
在这里我声明了 temp numericvector 然后将 x1 设置为该向量。
我不久前做过这个,知道有一种方法可以在声明 NumericVector 后将其设置为特定大小,但我不记得如何操作了。
编辑:编辑代码和问题以说明如何在 if 语句之前不知道 return 矢量大小。
你可以这样做
RObject test_1 (Rcpp::NumericVector x)
{
for (int ii = 0; ii < x.size(); ii++)
{
x[ii] = sqrt(x[ii]);
}
return x;
}
通过传递值,您可以创建一个与原始大小相同的新 NumericVector
如果您不想更改 API,第二个代码可以,但不需要临时变量
RObject test_1 (const Rcpp::NumericVector& x)
{
NumericVector x1(x.size());
for (int ii = 0; ii < x.size(); ii++)
{
x1[ii] = sqrt(x[ii]);
}
return x1;
}
你可以有条件地 resize
一个 std::vector<double>
和 Rcpp::wrap()
它,像这样:
#include <Rcpp.h>
// [[Rcpp::export]]
Rcpp::RObject test_1(const Rcpp::NumericVector& x) {
std::vector<double> x1;
if (x.size() < 5) {
x1.resize(3*x.size());
} else {
x1.resize(2*x.size());
}
for (int ii = 0; ii < x.size(); ii++) {
x1[ii] = sqrt(x[ii]);
}
return Rcpp::wrap(x1);
}
/*** R
xa <- 1:3
xb <- 1:10
test_1(xa)
# [1] 1.000000 1.414214 1.732051 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000
test_1(xb)
#[1] 1.000000 1.414214 1.732051 2.000000 2.236068 2.449490 2.645751 2.828427 3.000000 3.162278 0.000000 0.000000
[13] 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000
length(test_1(xa))/length(xa)
#[1] 3
length(test_1(xb))/length(xb)
#[1] 2
*/
你可以使用这种风格:
NumericVector x;
if (foo)
x = NumericVector(1);
else
x = NumericVector(2);
甚至(如果你想避免生成向量的零初始化)
x = static_cast<NumericVector>(no_init(size));
注意写的时候
NumericVector x;
if (foo)
NumericVector x(1);
您实际上正在创建 两个 NumericVector
个名为 x
的对象 -- 一个在顶级范围内,一个在范围内if
语句。
也就是说,当你写的时候值得理解
NumericVector x;
你实际上是在创建一个对象,而不仅仅是声明一个对象(这只适用于内置类型,例如int
)。因此,当您编写 NumericVector x
时,x
实际上是使用零参数 NumericVector
构造函数(创建长度为 0 的数字向量)