Rcpp::RObjectクラス

Rcppインターフェイスを使ったクラスライブラリを作成するコード側で,たとえば
Rから受け取った SEXP 型 a は,以下のように Rcpp::RObjectクラスの派生クラスに変換する必要があるのだが,

Rcpp::NumericVector xa(a);

この xa はそのまま演算できる.

RcppExport SEXP convolve3cpp(SEXP a, SEXP b) {
  Rcpp::NumericVector xa(a);
  Rcpp::NumericVector xb(b);
  int n_xa = xa.size(), n_xb = xb.size();
  int nab = n_xa + n_xb - 1;
  Rcpp::NumericVector xab(nab);
  for (int i = 0; i < n_xa; i++)
	for (int j = 0; j < n_xb; j++)
	  xab[i + j] += xa[i] * xb[j];
  return xab;
}

これをRに返す際には,明示的に型変換する必要がないので,ついつい SEXP そのものだと誤解しそうになるが,あくまで
Rcpp::RObjectクラスのオブジェクトであることを忘れないようにしないと,妙な代入などをおこなってしまいそうになる.

ちなみに,伝統的な API で,Rinternals.h を使う場合は,演算処理のためにポインタをとる.

 SEXP convolve2(SEXP a, SEXP b)
     {
         R_len_t i, j, na, nb, nab;
         double *xa, *xb, *xab;
         SEXP ab;
          // 型を指定して保護
         PROTECT(a = coerceVector(a, REALSXP));
         PROTECT(b = coerceVector(b, REALSXP));
         na = length(a); nb = length(b); nab = na + nb - 1;
         PROTECT(ab = allocVector(REALSXP, nab));
	// C言語での演算のためポインタを取得
         xa = REAL(a); xb = REAL(b);
         xab = REAL(ab);
         for(i = 0; i < nab; i++) xab[i] = 0.0;
         for(i = 0; i < na; i++)
             for(j = 0; j < nb; j++) xab[i + j] += xa[i] * xb[j];
         UNPROTECT(3);
	//SEXP型なのでそのまま返却できる
         return(ab);
     }

Rdefines.h を使う場合も,演算処理のためにポインタをとる.

SEXP convolve2(SEXP a, SEXP b)
     {
         R_len_t i, j, na, nb, nab;
         double *xa, *xb, *xab;
         SEXP ab;

	// 数値型として保護し
         PROTECT(a = AS_NUMERIC(a));
         PROTECT(b = AS_NUMERIC(b));
         na = LENGTH(a); nb = LENGTH(b); nab = na + nb - 1;
         PROTECT(ab = NEW_NUMERIC(nab));
		 // Cの演算のためにポインタを取り出す
         xa = NUMERIC_POINTER(a); xb = NUMERIC_POINTER(b);
         xab = NUMERIC_POINTER(ab);
		 // ポインタを通した計算
         for(i = 0; i < nab; i++) xab[i] = 0.0;
         for(i = 0; i < na; i++)
              for(j = 0; j < nb; j++) xab[i + j] += xa[i] * xb[j];
         UNPROTECT(3);
		 // SEXP型なのでそのまま返却できる
         return(ab);
     }

と明示的にPROTECTが必要になる.

カテゴリー: R タグ: パーマリンク