Rから他言語利用(インチキ版)

よいこはRから他言語利用(ご本家)を使うこと。

インチキなやり方で,ほかの言語によるプログラムと連絡を取る

1. 例 2 個一組の一様乱数をたくさん与えて,シミュレーションにより pi を計算する

2. 処理の流れ

2.1. R の関数

  1. 下請けプログラム(get.pi)が使用するデータファイル(urand.dat)を用意する
      urand 関数で 1 行あたり 2 個の一様乱数を urand.dat というファイルに出力する
      注:単純な情報(数個の数値など)の場合には,ファイルを介さずに受け渡せる。
  2. system 関数により,下請けプログラム(get.pi)を起動する
      下請けプログラムの引数は,データ入力ファイル名(urand.dat)と,結果出力ファイル名(result.dat)
  3. 結果出力ファイル(result.dat)ができるまで待つ
  4. 結果を読んで出力する
    simulation <- function(n)
    {
    	sink("urand.dat") # 乱数をファイルに書き出す
    	for (i in 1:n) cat(runif(2), "\n")
    	sink()
    	unlink("result.dat") # 結果ファイルを消去しておく
    	system("./get.pi urand.dat result.dat") # 下請けプログラム起動
    	while (!file.exists("result.dat")) Sys.sleep(1) # 計算終了を待つ
    	scan("result.dat") # 結果を読みとる
    }

2.2. 下請けプログラム

  1. 実行可能であればどのようなものでも良い(C でも,AWK でも,perl や,その他の言語でも。。。)
  2. データ入力ファイル名からデータを読んで(引数から情報を受け取って),計算して,結果出力ファイル名に結果を書く。
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <math.h>
    #define MXLN 1024
    int main(int argc, char *argv[])
    {
            double x, y, pi = 0, n = 0;
            char *p;
            char param[MXLN];
            FILE *in, *out;
            if (argc != 3) return(EXIT_FAILURE);
            if ((in = fopen(argv[1], "r")) == NULL) return(EXIT_FAILURE);
            if ((out = fopen(argv[2], "w")) == NULL) return(EXIT_FAILURE);
            for (;;) {
                    fgets(param, MXLN, in);
                    if (feof(in)) break;
                    p = strtok(param, " ,\t");
                    x = atof(p);
                    p = strtok(NULL, " ,\t");
                    y = atof(p);
                    n++;
                    if (x*x+y*y < 1) pi++;
            }
            fprintf(out, "%g\n", pi/n*4);
            return(EXIT_SUCCESS);
    }

3. 実行結果

> simulation(20000)
Read 1 item
[1] 3.1384

トップ   編集 凍結 差分 バックアップ 添付 複製 名前変更 リロード   新規 一覧 検索 最終更新   ヘルプ   最終更新のRSS
Last-modified: 2023-03-25 (土) 11:19:17