Среды в функциях R и Rcpp

У меня странная проблема, когда функция, которую я написал, изменяет значение моего ввода после запуска.

Вот мой код R:

library(entropy)
y = c(4, 2, 3, 0, 2, 4, 0, 0, 2, 1, 1)
y=rbind(y,2*(y%%2),y%%3)
y
#4    2    3    0    2    4    0    0    2     1     1
#0    0    2    0    0    0    0    0    0     2     2
#1    2    0    0    2    1    0    0    2     1     1
freqs.shrink(y)

freqs.shrinkC<-function(y,lambda.freqs,verbose=TRUE) {
if (missing(lambda.freqs)) {
lambda.freqs = getlambdashrinkC(y)
}
if (verbose==TRUE) {
cat(paste("Specified shrinkage intensity lambda.freq (frequencies):",
round(lambda.freqs, 4)), "\n")
}
ismatrix<-attributes(y)$dim
out<-freqsshrinkC(y,lambda.freqs)
attr(out,"lambda.freq")=lambda.freqs
attr(out,"dim")=ismatrix
return(out)
}

freqs.shrinkC(y)
y
#0.05280131 0.0374932 0.04514725 0.0221851 0.0374932 0.05280131 0.0221851 0.0221851 0.0374932 0.02983915 0.02983915
#0.02218510 0.0221851 0.03749320 0.0221851 0.0221851 0.02218510 0.0221851 0.0221851 0.0221851 0.03749320 0.03749320
#0.02983915 0.0374932 0.02218510 0.0221851 0.0374932 0.02983915 0.0221851 0.0221851 0.0374932 0.02983915 0.02983915

Я не считаю, что значение y должно измениться после запуска freqs.shrinkC, так как функция работает в своей собственной среде.

Вот мой код C ++:

#include <Rcpp.h>
using namespace Rcpp;

// [[Rcpp::export]]
NumericVector freqsshrinkC(NumericVector y,double lambda) {
int m=y.length();
double n=0;
for (int i=0;i<m;i++) {
n+=y(i);
}
y=y/n;

NumericVector add(m,lambda/m);
y=y*(1-lambda);

y+=add;
return y;
}

// [[Rcpp::export]]
double getlambdashrinkC(NumericVector y) {
double n=0;
int m=y.length();
double lambda;
for (int i=0;i<m;i++) {
n+=y[i];
}
NumericVector u=y/n;NumericVector temp(m,1.0);
NumericVector varu=u*(temp-u)/(n-1);

double msp=0;
for (int i=0;i<m;i++) {
msp+=pow(u[i]-(1.0/m),2);
}
if (msp==0) {
lambda=1;
} else {
lambda=0;
for (int i=0;i<m;i++) {
lambda+=varu[i];
}
lambda=lambda/msp;
}
if (lambda>1) {
lambda=1;
}
if (lambda<0) {
lambda=0;
}
return lambda;
}

Я новичок в C ++ и Rcpp, поэтому я прошу прощения, если мой код не элегантен. Если кому-то интересно, я переписываю пакет энтропии, используя Rcpp в качестве упражнения. Я озадачен, почему у меняются значения, когда я запускаю свою функцию, поэтому любая помощь приветствуется.

С Уважением,

деревенщина

1

Решение

Скорее всего, это связано с тем, что ваш freqsshrinkC функция выполняет (модифицирует) операции над y аргумент напрямую. поскольку Rcpp::Vectorэто прокси-объекты, это будут влияет на исходный объект, который вы передаете. Попробуйте использовать Rcpp::clone сделать глубокую копию вектора, который вы передаете, как показано ниже:

// [[Rcpp::export]]
NumericVector freqsshrinkC2(NumericVector y_, double lambda) {
Rcpp::NumericVector y = Rcpp::clone(y_);
int m = y.length();
double n = 0;
for (int i = 0; i < m; i++) {
n += y(i);
}
y = y/n;

NumericVector add(m,lambda/m);
y = y*(1-lambda);

y += add;
return y;
}

/*** R

y1 <- c(4, 2, 3, 0, 2, 4, 0, 0, 2, 1, 1)
y1 <- rbind(y1, 2*(y1%%2), y1%%3)
x1 <- freqsshrinkC(y1, 1.5)

y2 <- c(4, 2, 3, 0, 2, 4, 0, 0, 2, 1, 1)
y2 <- rbind(y2, 2*(y2%%2), y2%%3)
x2 <- freqsshrinkC2(y2, 1.5)all.equal(y1, x1)
R> all.equal(y1, x1)
#[1] TRUE       # y1 was modified

all.equal(y2, x2)
R> all.equal(y2, x2)
#[1] "Mean relative difference: 1.01039"  # y2 was not

*/

куда freqsshrinkC версия в вашем вопросе, и freqsshrinkC2 использования Rcpp::clone на (сейчас переименован в y_) входной вектор.

2

Другие решения


По вопросам рекламы ammmcru@yandex.ru
Adblock
detector