12

私の問題に対して非常に具体的な Simulated Annealing アルゴリズムを使用して R でパッケージを構築していますが、解決できていない C コードと SEXP について疑問があります。私は R の専門家ではありません。R を使用してまだ 3 週間しか経っていませんが、これを行う必要があります。

私が知る限り.Call、R の関数はパラメータを SEXP 構造体として参照によって C に渡します (つまり、それらは複製されません)。私は正しいですか?この SEXP 構造を必要とする C の最初の関数から呼び出される C の別の関数がある場合はどうなりますか? (例を参照)。これらのパラメーターの 1 つが非常に大きく、多くのスペースを使用するため (10^7 ~ 10^18 の double ですが、すべての反復ですべてを使用するわけではありません)、この関数を何度も呼び出すため、質問しています。 、そのため、呼び出すたびにこのパラメーターが複製されると、メモリが不足します。

MWE:

Rコール

MySimAn <- function(def_energy, i_pos, T0, Tfinal){
  ret <- .Call("CMySimAn",def_energy, i_pos, T0, Tfinal, seq0)
  ret
}

C 関数

double Energy(SEXP def_energy, SEXP seq0, int i0){
  int i;
  double res=0;
  for(i=0;i<INTEGER(GET_DIM(seq0))[0];i++){
    res += NUMERIC(def_energy)[i0+INTEGER(seq0)[i]];
  }
  return(res);
}

SEXP CmySimAn(SEXP def_energy, SEXP i_pos, SEXP T0, SEXP Tfinal, SEXP seq0){
  SEXP = Ene;
  PROTECT(Ene = NEW_NUMERIC(1));
  REAL(Ene)[0] = Energy(def_energy, seq0, INTEGER(i_pos));
  UNPROTECT(1);
  return Ene;
}

このようなものは機能しますか (関数内のコードはEnergyチェックされていないため、間違っている可能性があります)? R であれ C であれ、呼び出すたびに def_energy の複製を作成することになりますか? ご助力ありがとうございます。

4

1 に答える 1

8

コードはほぼ (構文的に) 記述どおりであり、メモリのコピーはありません。R から C に渡される引数は、「読み取り専用」として扱われるべきです。

一般的なパラダイムは、純粋な (非 R) C でその層から呼び出されるすべての関数を使用して、R / C インターフェイス層を作成することです。

double Energy(const double *def_energy, const int *seq0, int dim0, int i0)
{
  int i;
  double res=0;
  for(i = 0; i < dim0; i++) {
    res += def_energy[i0 + seq0[i]];
  }
  return(res);
}

constR から渡された値が書き込まれてはならないという暗黙の契約を強制するために使用します。R / Cラッパーで

SEXP CmySimAn(SEXP def_energy, SEXP i_pos, SEXP T0, SEXP Tfinal, SEXP seq0){
  double Ene = Energy(REAL(def_energy), INTEGER(seq0), INTEGER(GET_DIM(seq0)[0]),
                      INTEGER(i_pos)[0]);
  return ScalarReal(Ene);
}

数値要素のアクセサーは(エネルギーでREAL()使用した) です。NUMERICの使い方PROTECT(...); REAL(Ene)[0] = ...; UNPROTECT(Ene);は正しかった。

于 2013-09-27T12:37:02.440 に答える