亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

RCPP通過引用與按值傳遞

RCPP通過引用與按值傳遞

HUX布斯 2019-12-05 16:07:52
我通過第一次對Rcpp函數進行了測試inline,它解決了我的速度問題(感謝Dirk?。?R:將負值替換為零初始版本如下所示:library(inline)cpp_if_src <- '  Rcpp::NumericVector xa(a);  int n_xa = xa.size();  for(int i=0; i < n_xa; i++) {    if(xa[i]<0) xa[i] = 0;  }  return xa;'cpp_if <- cxxfunction(signature(a="numeric"), cpp_if_src, plugin="Rcpp")但是,當調用時cpp_if(p),它會覆蓋p輸出,這與預期不符。因此,我認為它是通過引用傳遞的。所以我用以下版本修復了它:library(inline)cpp_if_src <- '  Rcpp::NumericVector xa(a);  int n_xa = xa.size();  Rcpp::NumericVector xr(a);  for(int i=0; i < n_xa; i++) {    if(xr[i]<0) xr[i] = 0;  }  return xr;'cpp_if <- cxxfunction(signature(a="numeric"), cpp_if_src, plugin="Rcpp")這似乎工作。但是現在當我將其重新加載到R中時,原始版本不再覆蓋其輸入(即,相同的精確代碼現在也不會覆蓋其輸入):> cpp_if_src <- '+   Rcpp::NumericVector xa(a);+   int n_xa = xa.size();+   for(int i=0; i < n_xa; i++) {+     if(xa[i]<0) xa[i] = 0;+   }+   return xa;+ '> cpp_if <- cxxfunction(signature(a="numeric"), cpp_if_src, plugin="Rcpp")> > p [1] -5 -4 -3 -2 -1  0  1  2  3  4  5> cpp_if(p) [1] 0 0 0 0 0 0 1 2 3 4 5> p [1] -5 -4 -3 -2 -1  0  1  2  3  4  5我不是唯一嘗試復制此行為并發現不一致結果的人:http://chat.stackoverflow.com/transcript/message/4357344#4357344這里發生了什么?
查看完整描述

2 回答

?
暮色呼如

TA貢獻1853條經驗 獲得超9個贊

它們的關鍵是“代理模型”-您xa的存儲位置確實與原始對象相同,因此最終需要更改原始對象。


如果您不希望這樣做,則應該做一件事:使用該clone()方法進行(深度)復制,或者顯式創建一個新對象,將更改后的對象寫入該對象。方法二不能做到這一點,您只需使用兩個名稱不同的變量,它們都是原始變量的“指針”(就代理模型而言)。


但是,當您將int向量(從R)傳遞給NumericVector類型時,隱式轉換和復制會帶來另外的復雜性:創建一個副本,然后不再更改原始副本。


這是一個更明確的示例,類似于我在教程或研討會中使用的示例:


library(inline)

f1 <- cxxfunction(signature(a="numeric"), plugin="Rcpp", body='

  Rcpp::NumericVector xa(a);

  int n = xa.size();

  for(int i=0; i < n; i++) {

    if(xa[i]<0) xa[i] = 0;

  }

  return xa;

')


f2 <- cxxfunction(signature(a="numeric"), plugin="Rcpp", body='

  Rcpp::NumericVector xa(a);

  int n = xa.size();

  Rcpp::NumericVector xr(a);            // still points to a

  for(int i=0; i < n; i++) {

    if(xr[i]<0) xr[i] = 0;

  }

  return xr;

')


p <- seq(-2,2)

print(class(p))

print(cbind(f1(p), p))

print(cbind(f2(p), p))

p <- as.numeric(seq(-2,2))

print(class(p))

print(cbind(f1(p), p))

print(cbind(f2(p), p))

這就是我所看到的:


edd@max:~/svn/rcpp/pkg$ r /tmp/ari.r

Loading required package: methods

[1] "integer"

        p

[1,] 0 -2

[2,] 0 -1

[3,] 0  0

[4,] 1  1

[5,] 2  2

        p

[1,] 0 -2

[2,] 0 -1

[3,] 0  0

[4,] 1  1

[5,] 2  2

[1] "numeric"

       p

[1,] 0 0

[2,] 0 0

[3,] 0 0

[4,] 1 1

[5,] 2 2

       p

[1,] 0 0

[2,] 0 0

[3,] 0 0

[4,] 1 1

[5,] 2 2

edd@max:~/svn/rcpp/pkg$

因此,無論是從int到float還是從float到float都是非常重要的。


查看完整回答
反對 回復 2019-12-05
?
BIG陽

TA貢獻1859條經驗 獲得超6個贊

這很有趣。知道這一點的唯一方法是通過我猜想的調試器(或者您像Dirk一樣編寫程序包)。有沒有辦法將調試器附加到Rcpp函數?我正在考慮像Visual Studio調試器那樣附加dll的方法,然后單擊該dll即可進入代碼。

查看完整回答
反對 回復 2019-12-05
  • 2 回答
  • 0 關注
  • 689 瀏覽

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號