相同的 Rcpp 函数 returns 如果添加打印语句则输出不同
Same Rcpp function returns different output if print statement added
我使用 Rcpp 编写的一个 C++ 函数根据我在代码中是否有 Rcout
或 Rprintf
语句给出不同的输出。下面的代码 returns 1
,对于带有打印语句 H_sigma_1()
的函数,这是正确的值。但是,对于H_sigma_2()
,没有打印语句的函数,函数returns 2. 我在Ubuntu 16.04.1 和CentOS 6.8 上测试过这个。不过,我无法在 Windows 10 上重现此错误。因此,这似乎是一个 Linux 问题。
Rcpp 代码
library(Rcpp)
cppFunction (
"double H_sigma_1(IntegerVector sigma, NumericMatrix J, NumericVector h)
{
double first_sum, second_sum = 0;
int n = sigma.size();
for(int i = 0; i < n; i++)
{
for(int j = 0; j < n; j++)
{
// skip inside loop if i >= j to stop double counting
if(i >= j) {continue;}
first_sum += J(i, j) * sigma[i] * sigma[j];
Rcout << first_sum << std::endl;
}
second_sum += h[i] * sigma[i];
}
return(-1.0 * first_sum - second_sum);
}"
)
cppFunction (
"double H_sigma_2(IntegerVector sigma, NumericMatrix J, NumericVector h)
{
double first_sum, second_sum = 0;
int n = sigma.size();
for(int i = 0; i < n; i++)
{
for(int j = 0; j < n; j++)
{
// skip inside loop if i >= j to stop double counting
if(i >= j) {continue;}
first_sum += J(i, j) * sigma[i] * sigma[j];
// Rcout << first_sum << std::endl;
}
second_sum += h[i] * sigma[i];
}
return(-1.0 * first_sum - second_sum);
}"
)
调用示例[=34=]
设置:
n = 2
params = rep(1, n)
h = rep(params[1], n)
J = toeplitz(c(0, params[2], rep(0, n - 2)))
测试 1:
H_sigma_1(c(-1, -1), J, h)
输出:
1
[1] 1
测试 2
H_sigma_2(c(-1, -1), J, h)
输出
[1] 2
您 运行 遇到的问题是在使用前未明确声明求和的起始值。
double first_sum, second_sum = 0;
不等于:
double first_sum = 0, second_sum = 0;
查看编译器警告标志:
file11d36f564b15.cpp:17:5: warning: variable 'first_sum' is uninitialized when used here [-Wuninitialized]
first_sum += J(i, j) * sigma[i] * sigma[j];
^~~~~~~~~
file11d36f564b15.cpp:8:21: note: initialize the variable 'first_sum' to silence this warning
double first_sum, second_sum = 0;
您立即使用:
first_sum += J(i, j) * sigma[i] * sigma[j];
没有设置 first_sum = ...;
此外,还有一个问题是:
second_sum = 0;
用整数值初始化双精度数。虽然这个问题的范围很小,但要纠正这个问题,所有要做的就是使用 0.0
而不是 0
.
second_sum = 0.0;
这也适用于 first_sum
。
具有上述修复的代码:
library(Rcpp)
cppFunction (
"double H_sigma_1(IntegerVector sigma, NumericMatrix J, NumericVector h)
{
double first_sum = 0.0, second_sum = 0.0;
int n = sigma.size();
for(int i = 0; i < n; i++) {
for(int j = 0; j < n; j++) {
// skip inside loop if i >= j to stop double counting
if(i >= j) {continue;}
first_sum += J(i, j) * sigma[i] * sigma[j];
Rcout << first_sum << std::endl;
}
second_sum += h[i] * sigma[i];
}
return(-1.0 * first_sum - second_sum);
}"
)
cppFunction (
"double H_sigma_2(IntegerVector sigma, NumericMatrix J, NumericVector h)
{
double first_sum = 0.0, second_sum = 0.0;
int n = sigma.size();
for(int i = 0; i < n; i++) {
for(int j = 0; j < n; j++) {
// skip inside loop if i >= j to stop double counting
if(i >= j) {continue;}
first_sum += J(i, j) * sigma[i] * sigma[j];
}
second_sum += h[i] * sigma[i];
}
return(-1.0 * first_sum - second_sum);
}"
)
测试:
n = 2
params = rep(1, n)
h = rep(params[1], n)
J = toeplitz(c(0, params[2], rep(0, n - 2)))
H_sigma_1(c(-1, -1), J, h)
输出:
1
[1] 1
测试 2:
H_sigma_2(c(-1, -1), J, h)
输出:
[1] 1
我使用 Rcpp 编写的一个 C++ 函数根据我在代码中是否有 Rcout
或 Rprintf
语句给出不同的输出。下面的代码 returns 1
,对于带有打印语句 H_sigma_1()
的函数,这是正确的值。但是,对于H_sigma_2()
,没有打印语句的函数,函数returns 2. 我在Ubuntu 16.04.1 和CentOS 6.8 上测试过这个。不过,我无法在 Windows 10 上重现此错误。因此,这似乎是一个 Linux 问题。
Rcpp 代码
library(Rcpp)
cppFunction (
"double H_sigma_1(IntegerVector sigma, NumericMatrix J, NumericVector h)
{
double first_sum, second_sum = 0;
int n = sigma.size();
for(int i = 0; i < n; i++)
{
for(int j = 0; j < n; j++)
{
// skip inside loop if i >= j to stop double counting
if(i >= j) {continue;}
first_sum += J(i, j) * sigma[i] * sigma[j];
Rcout << first_sum << std::endl;
}
second_sum += h[i] * sigma[i];
}
return(-1.0 * first_sum - second_sum);
}"
)
cppFunction (
"double H_sigma_2(IntegerVector sigma, NumericMatrix J, NumericVector h)
{
double first_sum, second_sum = 0;
int n = sigma.size();
for(int i = 0; i < n; i++)
{
for(int j = 0; j < n; j++)
{
// skip inside loop if i >= j to stop double counting
if(i >= j) {continue;}
first_sum += J(i, j) * sigma[i] * sigma[j];
// Rcout << first_sum << std::endl;
}
second_sum += h[i] * sigma[i];
}
return(-1.0 * first_sum - second_sum);
}"
)
调用示例[=34=]
设置:
n = 2
params = rep(1, n)
h = rep(params[1], n)
J = toeplitz(c(0, params[2], rep(0, n - 2)))
测试 1:
H_sigma_1(c(-1, -1), J, h)
输出:
1
[1] 1
测试 2
H_sigma_2(c(-1, -1), J, h)
输出
[1] 2
您 运行 遇到的问题是在使用前未明确声明求和的起始值。
double first_sum, second_sum = 0;
不等于:
double first_sum = 0, second_sum = 0;
查看编译器警告标志:
file11d36f564b15.cpp:17:5: warning: variable 'first_sum' is uninitialized when used here [-Wuninitialized]
first_sum += J(i, j) * sigma[i] * sigma[j];
^~~~~~~~~
file11d36f564b15.cpp:8:21: note: initialize the variable 'first_sum' to silence this warning
double first_sum, second_sum = 0;
您立即使用:
first_sum += J(i, j) * sigma[i] * sigma[j];
没有设置 first_sum = ...;
此外,还有一个问题是:
second_sum = 0;
用整数值初始化双精度数。虽然这个问题的范围很小,但要纠正这个问题,所有要做的就是使用 0.0
而不是 0
.
second_sum = 0.0;
这也适用于 first_sum
。
具有上述修复的代码:
library(Rcpp)
cppFunction (
"double H_sigma_1(IntegerVector sigma, NumericMatrix J, NumericVector h)
{
double first_sum = 0.0, second_sum = 0.0;
int n = sigma.size();
for(int i = 0; i < n; i++) {
for(int j = 0; j < n; j++) {
// skip inside loop if i >= j to stop double counting
if(i >= j) {continue;}
first_sum += J(i, j) * sigma[i] * sigma[j];
Rcout << first_sum << std::endl;
}
second_sum += h[i] * sigma[i];
}
return(-1.0 * first_sum - second_sum);
}"
)
cppFunction (
"double H_sigma_2(IntegerVector sigma, NumericMatrix J, NumericVector h)
{
double first_sum = 0.0, second_sum = 0.0;
int n = sigma.size();
for(int i = 0; i < n; i++) {
for(int j = 0; j < n; j++) {
// skip inside loop if i >= j to stop double counting
if(i >= j) {continue;}
first_sum += J(i, j) * sigma[i] * sigma[j];
}
second_sum += h[i] * sigma[i];
}
return(-1.0 * first_sum - second_sum);
}"
)
测试:
n = 2
params = rep(1, n)
h = rep(params[1], n)
J = toeplitz(c(0, params[2], rep(0, n - 2)))
H_sigma_1(c(-1, -1), J, h)
输出:
1
[1] 1
测试 2:
H_sigma_2(c(-1, -1), J, h)
输出:
[1] 1