裏 RjpWiki

Julia ときどき R, Python によるコンピュータプログラム,コンピュータ・サイエンス,統計学

ダメ出し:自分で

2012年01月25日 | ブログラミング

この一つ前の記事で。

二重の for は効率が悪い。outer を使うのがよい。

system.time({
x <- seq(-0.5, 3, length = 1000)
y <- seq(-2.5, 2.5, length = 1000)
z <- matrix(0, 1000, 1000)
for (i in 1:1000) {
    for (j in 1:1000) {
        z[i, j] <- (x[i] ^ 2 + y[j] ^ 2 - 2 * x[i]) ^ 3 - 4 * x[i] ^ 2 * y[j] ^ 2
    }
}
contour(x, y, z, drawlabels = FALSE, levels = c(0, 1, 2, 5, 10, 20, 30, 50))
})

#   ユーザ   システム       経過 
#    11.962      0.119     12.111

10 倍速だ。

system.time({
x <- seq(-0.5, 3, length = 1000)
y <- seq(-2.5, 2.5, length = 1000)
z <- outer(x, y, function(xi, yj) (xi ^ 2 + yj ^ 2 - 2 * xi) ^ 3 - 4 * xi ^ 2 * yj ^ 2)
contour(x, y, z, drawlabels = FALSE, levels = c(0, 1, 2, 5, 10, 20, 30, 50))
})
#   ユーザ   システム       経過 
#     0.923      0.037      0.956


下記のような cxxfunction を使うのと遜色ない実行速度

library(inline)
src <- '
    Rcpp::NumericVector x(X);
    Rcpp::NumericVector y(Y);
    int nx = x.size();
    int ny = y.size();
    Rcpp::NumericMatrix z(nx, ny);
    for (int i = 0; i < nx; i++) {
        for (int j = 0; j < ny; j++) {
            z(i, j) = pow(x(i) * x(i) + y(j) * y(j) - 2 * x(i), 3) - 4 * x(i) * x(i) * y(j) * y(j);
        }
    }
    return wrap(z);
'
calcZ <- cxxfunction(signature(X="numeric", Y="numeric"), src, plugin="Rcpp")
x <- seq(-0.5, 3, length = 1000)
y <- seq(-2.5, 2.5, length = 1000)
z <- calcZ(x, y)
contour(x, y, z, drawlabels = FALSE, levels = c(0, 1, 2, 5, 10, 20, 30, 50))

もっとも,これを以下のようにするとちょっとだけ速くなる。ループ内で不変な計算はループの外でやることと,何回も同じ計算をするときには一回計算して変数に代入しておくこと。

src <- '
    Rcpp::NumericVector x(X);
    Rcpp::NumericVector y(Y);
    int nx = x.size();
    int ny = y.size();
    Rcpp::NumericMatrix z(nx, ny);
    for (int i = 0; i < nx; i++) {
        double xi2 = x(i) * x(i);
        for (int j = 0; j < ny; j++) {
            double yj2 = y(j) * y(j);
            z(i, j) = pow(xi2 + yj2 - 2 * x(i), 3) - 4 * xi2 * yj2;
        }
    }
    return wrap(z);
'

コメント    この記事についてブログを書く
  • X
  • Facebookでシェアする
  • はてなブックマークに追加する
  • LINEでシェアする
« 陰関数で表された曲線の描画 | トップ | プログラムの使い方が間違っ... »
最新の画像もっと見る

コメントを投稿

ブログ作成者から承認されるまでコメントは反映されません。

ブログラミング」カテゴリの最新記事