for 迴圈

用 Rcpp 最佳化 R 程式碼

Romain François

Consulting Datactive, ThinkR

C++ for 迴圈的 4 個部分

  • 初始化
  • 繼續條件
  • 遞增
  • 主體
用 Rcpp 最佳化 R 程式碼

for 迴圈-初始化

在迴圈一開始執行:

for( init ;  ;  ){

}
用 Rcpp 最佳化 R 程式碼

for 迴圈-繼續條件

用來控制是否繼續的邏輯條件

for(  ; condition ;  ){

}
用 Rcpp 最佳化 R 程式碼

for 迴圈-遞增

每次反覆結尾執行

for(  ;  ; increment ){

}
用 Rcpp 最佳化 R 程式碼

for 迴圈-主體

每次反覆執行。也就是迴圈要做的事。

for(  ;  ;  ){
    body
}
用 Rcpp 最佳化 R 程式碼

典型的 for 迴圈

for (int i=0; i<n; i++ ){
    // some code using i
}
用 Rcpp 最佳化 R 程式碼

典型的 for 迴圈

for (int i=0; ; ){

}
用 Rcpp 最佳化 R 程式碼

典型的 for 迴圈

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

}
用 Rcpp 最佳化 R 程式碼

典型的 for 迴圈

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

}
用 Rcpp 最佳化 R 程式碼

範例:前 n 個整數的總和

// [[Rcpp::export]]
int nfirst( int n ){
    if( n < 0 ) {
        stop( "n must be positive, I see n=%d", n ) ;
    }

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

    return result ;
}
用 Rcpp 最佳化 R 程式碼

跳出 for 迴圈

// [[Rcpp::export]]
int nfirst( int n ){
    if( n < 0 ) {
        stop( "n must be positive, I see n=%d", n ) ;
    }    

    int result = 0 ;
    for( int i=0; i<n; i++){
        if( i == 13 ){
            Rprintf( "I cannot handle that, I am superstitious" ) ;
            break ;
        }
        result = result + (i+1) ;
    }

    return result ;
}
用 Rcpp 最佳化 R 程式碼

牛頓法計算平方根

求 $\sqrt{S}$ 等同於求 $f(x) = x^2 - S$ 的根。

可得反覆運算式:

$$ x_{n+1} = x_n - \frac{f(x_n)}{f'(x_n)} = x_n - \frac{x^2_n - S}{2 x_n} = \frac{1}{2} \left( x_n + \frac{S}{x_n} \right) $$

演算法:

  • 取初始值 $x_0$
  • 依上式更新 $x$ 指定次數
用 Rcpp 最佳化 R 程式碼

C++ 中的牛頓法

$$ x_{n+1} = \frac{1}{2} \left( x_n + \frac{S}{x_n} \right) $$

對應到虛擬碼:

int n = ... // number of iterations
double res = ... // initialization

for( int i=0; i<n; i++){
    // update the value of res
    // i.e. calculate x_{n+1} given x_{n}
    res = ( res + S / res ) / 2.0 ; 
}

return res ;
用 Rcpp 最佳化 R 程式碼

一起來練習吧!

用 Rcpp 最佳化 R 程式碼

Preparing Video For Download...