當我們使用R進行論文模擬時,通常會涉及到許多的循環。一般比較容易的提速方法是將我們的for循環
改寫為apply族
的方法進行向量化運算,但這個方法速度提升的有限,在真實模擬時,如果要與其他算法進行速度的比較,除非自己的算法非常出色,否則還是很難與一些成熟包中的算法相庭抗禮。
這時想要再次進行提速,有多種方法,常見的幾種是將代碼改寫為Fortran
代碼,改寫為C++
代碼抑或改寫為C
代碼。由于Rcpp
包的存在,改寫為C++
代碼相對簡單,所以后面將介紹幾種常用的方法進行改寫,并在R中進行調用。
在RStudio中創建C++文件
這里默認大家都安裝了RStudio
,我們都從里面創建一個C++文件,從這里創建有個好處,就是它直接會顯示一段示例代碼,我們只需在上面稍作改動即可。
首先我們在RStudio
中選擇:文件
——新文件
——C++文件
,創建完一個新文件,里面是如下的內容(這里要在R中安裝Rcpp
包,沒安裝的話,點到這里RStudio
會自動幫忙進行安裝):
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
|
#include <Rcpp.h> using namespace Rcpp; // This is a simple example of exporting a C ++ function to R . You can // source this function into an R session using the Rcpp: :sourceCpp // function ( or via the Source button on the editor toolbar). Learn // more about Rcpp at: // // http://www.rcpp.org/ // http://adv-r.had.co.nz/Rcpp.html // http://gallery.rcpp.org/ // // [[Rcpp: :export ]] NumericVector timesTwo(NumericVector x) { return x * 2 ; } // You can include R code blocks in C ++ files processed with sourceCpp // (useful for testing and development). The R code will be automatically // run after the compilation. // /*** R timesTwo( 42 ) */ |
我們按照上面的英文說明一行一行來進行理解。
詳細說明
1
2
|
#include <Rcpp.h> using namespace Rcpp; |
這個是頭文件,以及使用Rcpp
命名空間。正常的一個C++代碼開頭兩行其實也是這樣,這其實非常像我們R中的library
以及Python中的import
,有了這個,我們就可以在代碼中命名向量、矩陣、數據框等一些R中才有的對象形式,以便于R與C++中的一些內容的相互傳遞。
示例文件中的代碼其實就是命名了一個輸入與輸出對象均為數值向量的函數。這個函數也非常簡單:一個將向量乘以2的運算。
如果我們想在R中使用在C++文件中定義好的函數,需要在C++里面函數的上方加上// [[Rcpp::export]]
。需要注意的是,一個cpp文件可以在里面定義多個函數,但只能傳出一個函數。
然后我們再點擊文件右上方的Source
,即可將我們的函數載入進變量空間,或直接在另一個R腳本文件中運行下述命令:
1
|
Rcpp: :sourceCpp ( 'Desktop/myfun.cpp' ) |
在示例文件中還有另一個trick,就是直接在我們的cpp
文件中加上了下面這句命令:
1
2
3
|
/*** R timesTwo( 42 ) */ |
加上這句之后,我們Source
這個文件后,可以直接測試剛剛定義的函數,看看timesTwo(42)
的運行結果,平時在測試的時候可以多多使用。
更多內容
關于Rcpp里面的一些常用數據類型與常用函數,可以參考博客:R語言學習Rcpp基礎知識全面整理,里面講的很好。這里搬運一些內容過來:
數據類型 | 描述 |
---|---|
int | 整數型 |
double | 數值型 |
bool | 布爾型(TRUE, FALSE) |
String | 字符型 |
IntegerVector | 整型向量 |
NumericVector | 數值型向量(元素的類型為double) |
ComplexVector | 復數向量 |
LogicalVector | 邏輯型向量; R的邏輯型變量可以取三種值:TRUE, FALSE, NA; 而C++布爾值只有兩個,true or false。如果將R的NA轉化為C++中的布爾值,則會返回true。 |
CharacterVector | 字符型向量 |
IntegerMatrix | 整型矩陣 |
NumericMatrix | 數值型矩陣(元素的類型為double) |
LogicalMatrix | 邏輯型矩陣 |
CharacterMatrix | 字符矩陣 |
List | 列表;lists;類似于R中列表,其元素可以使任何數據類型 |
DataFrame | 數據框;data frames;在Rcpp內部,數據框其實是通過列表實現的 |
Function | 函數型 |
Environment | 環境型;可用于引用R環境中的函數、其他R包中的函數、操作R環境中的變量 |
RObject | 可以被R識別的類型 |
關于對矩陣以及數據框的一些基礎操作與常用函數:
操作 | 描述 |
---|---|
[n] | 對于向量類型或者列表,訪問第n個元素。對于矩陣類型,首先把矩陣的下一列接到上一列之下,從而構成一個長列向量,并訪問第n個元素。不同于R,n從0開始。 |
(i,j) | 對于矩陣類型,訪問第(i,j)個元素。不同于R,i和j從0開始。不同于向量,此處用圓括號。 |
List[“name1”] | 訪問List中名為name1的元素。 |
DataFrame[“name2”] | 訪問DataFrame中,名為name2的列。 |
X.size() | 返回X的長度;適用于向量或者矩陣,如果是矩陣,則先向量化 |
X.push_back(a) | 將a添加進X的末尾;適用于向量 |
X.push_front(b) | 將b添加進X的開頭;適用于向量 |
X.ncol() | 返回X的列數 |
X.nrow() | 返回X的行數 |
總結
到這里,一些關于Rcpp基礎使用的相關內容就介紹的差不多了。
還有另外兩個網址也非常推薦:
http://adv-r.had.co.nz/Rcpp.html
前者里面有很多基礎操作的代碼,包括:向量->向量;向量->矩陣;標量->矩陣等等,里面都有示例函數及相關代碼,復制到自己的cpp
文件中運行并理解就很容易上手。
后者相當于一個搜索庫,要使用Rcpp進行矩陣運算、并行計算、常用算法等操作,直接在里面進行搜索,就可以看到大神寫的一些相應代碼,同時知道該調用哪些庫中的函數。
后面的博客中我們將介紹:RcppEigen進行矩陣運算
以上就是Rcpp入門R代碼提速方法過程的詳細內容,更多關于Rcpp入門R代碼提速的資料請關注服務器之家其它相關文章!
原文鏈接:https://blog.csdn.net/weixin_41929524/article/details/81975484