« 2014年12月 | トップページ | 2015年2月 »

2015年1月23日 (金)

[R]関数をコンパイルして動作を速くする

cmpfun関数を使えばよい。

以下は実行例。以下の例では、rm関数でオブジェクトをすべて削除し、カレントフォルダーにtemp.tmpというファイルを書き出して削除するということを行っているので注意。また、今店頭で売られているようなパソコンでは実行時間が数十秒~1分強かかるので注意。

スクリプト

# パッケージcompilerを使用
library(compiler)
# 最初に全オブジェクトを削除
rm(list = ls(all = TRUE))
# サンプル関数
# 時間を計るための意味のない計算とファイルアクセス
calc <- function() {
    for (i in 1:400) {
        d <- rnorm(3000)
        for (j in 1:3000) {
            d[1] <- d[1] + d[j]
        }
        write(d, file = "temp.tmp")
        for (j in 1:300) {
            d[j] <- d[j] * j
        }
        file.remove("temp.tmp")
    }
}
# 関数実行1回目に要した時間を表示
print(system.time(calc()))
# 関数実行2回目に要した時間を表示
print(system.time(calc()))
# 関数実行3回目に要した時間を表示
print(system.time(calc()))
# サンプル関数をコンパイル
calcc <- cmpfun(calc)
# コンパイルした関数の実行に要した時間を表示
print(system.time(calcc()))

出力

   ユーザ   システム       経過 
      5.90       4.36      14.19
   ユーザ   システム       経過 
      5.70       4.47      11.68
   ユーザ   システム       経過 
      6.04       4.03      11.72
   ユーザ   システム       経過 
      4.28       4.43      10.27

コンパイル前の2回目と3回目が多少早く実行されているのは、コンピューターに残っていたキャッシュを参照しているからかもしれない。コンパイル後に実行したものは明らかに実行時間が短い。

2015年1月15日 (木)

[Fortran]組み込み関数の個別名と総称名について(dsinとsin、dabsとabsなど)

Fortranの組み込み関数(Fortranに標準で搭載されている関数)には個別名と総称名を持つものがある。具体的にはdsinとsin、dabsとabsなどである。

これらはその組み込み関数の引数と戻り値の肩に関するものである。上の例では、dsinとdabsはその関数の引数には倍精度浮動小数点型の変数しか扱えない。これらdsinやdabsといった名前を個別名と呼ぶ。

一方、sinやabsは総称名と呼ばれ、これらは関数の引数に与えられた型を自動で判定して計算し、その関数のも度値も引数で与えた型で返す。

以下は実行例。

program sosho
    implicit none
    real r
    double precision d
    r = 3.14
    d = 3.14d0
    print '(f20.18)', r        ! 単精度定数
    print '(f20.18)', d        ! 倍精度定数
    print '(f20.18)', sin(r)   ! 単精度で計算(総称名)
    print '(f20.18)', dsin(d)  ! 倍精度で計算
    print '(f20.18)', sin(d)   ! 倍精度で計算(総称名)
end program sosho

出力は以下のとおり。

3.140000104904174805
3.140000000000000124
0.001592547981999815
0.001592652916486828
0.001592652916486828

2015年1月 9日 (金)

[Fortran]単精度浮動小数点数と倍精度浮動小数点数

Fortranでは浮動小数点数(※)を扱うとき、変数へ定数を代入するときには単精度が倍精度を明示しなければならない。

例えば、倍精度浮動小数点型の変数へ代入する際、数値定数を「3.14」としただけでは単精度浮動小数点数とみなされてしまう。この場合、有効桁数は6桁程度しかない。指数部に「E」あるいは「e」を使用した場合も同じ。

高精度な数値計算を行いたくて倍精度浮動小数点数で計算を行う場合は、数値定数の指数部に「D」あるいは「d」を用いた表記を使用すること。

以下の例では、倍精度浮動小数点型の変数に代入する際、数値定数の表記による数値の取扱いの差を示したもの。指数部を「d」を使用して表記しなければ倍精度で扱われていないことがわかる。

program doublecheck
    implicit none
    double precision d1, d2, d3
    d1 = 3.14
    d2 = 3.14e0
    d3 = 3.14d0
    print '(f20.18)', d1
    print '(f20.18)', d2
    print '(f20.18)', d3
end program

出力

3.140000104904174805
3.140000104904174805
3.140000000000000124

※Fortranに関する書籍では「実数」と表記するものが多いが、これは簡便な表記であり、プログラミング言語の分野では実数を「浮動小数点数」と呼ぶことが多い。

2015年1月 7日 (水)

[R]正規分布に従う乱数を生成する

rnorm関数を使えばよい。戻り値は実数。引数に数字を与えるとその個数だけ乱数を返す。

初期状態では平均が0、標準偏差が1の乱数を返すが、meanオプションに数値を指定するとその値を平均値とした乱数を返す。sdオプションに数値を指定するとその値を標準偏差とした乱数を返す。

> # 平均0、標準偏差が1の乱数(実数)を1000個作成
> d <- rnorm(1000)
> hist(d)  # 図1
> # 平均100、標準偏差が10の乱数(実数)を1000個作成
> d <- rnorm(1000, mean = 100, sd = 10)
> hist(d)  # 図2

 

Image11図1

 

Image12図2

図2は平均がおおよそ100で標準偏差の範囲(全体の約7割が含まれる範囲)がおおよそ90~110であることが見て取れる。

« 2014年12月 | トップページ | 2015年2月 »

無料ブログはココログ

■■

■■■