「mandelbrot set」に,以下のようなプログラムが掲載されている。
mandelbrot <- function(step = 0.1, pch = 19, col = 30, n = 2) {
a <- outer(seq(-2, 1, step), seq(-1, 1, step), function(x, y) complex(r = x,
i = y))
a <<- a[Mod(a) <= 2] #絶対値2以下のものだけにする(あまり意味はないが)
d <- c()
dc <- c()
for (c in a) {
z <- 0
for (i in 1:100) {
z <- z^n + c
if (Mod(z) >= 2) {
d <- c(d, c)
dc <- c(dc, i) #何回目で発散したか
break
}
}
}
# 回数で色分け
plot(d, pch = pch, xlab = paste("step:", step, "n = ", n), xlim = c(-2,
1), ylim = c(-1, 1), col = colors()[dc + col])
dc <<- dc
}
c() とは何事かと思うだろうが,NULL と同じである。名は体を表すのだから,NULL って書こうよ。
> identical(NULL, c())
[1] TRUE
それに,d <- NULL にしておき,後で d <- c(d, foo) などとドンドン要素を追加していくのは,プログラム作法に反している。計算時間が指数関数的に増えていく。
必要なだけのメモリを確保して,要素を代入していくのが定石だ。未だにこの辺りのことを体得していないプログラマがいるのは嘆かわしい。
それに,a, b, c, d, dc のように,意味のない変数名を使うのも困ったことだ。
<<- を使っているのも問題。必要ならば,list にして return 文で返すべきだ。
同でもよいことだけど,注釈記号の後には少なくとも空白1個置きましょう。気持ち悪いから。
ということで,一番目の指摘点だけを書き換えるだけで,プログラムの速度はかなり速くなる。
step により指数関数的に増えるのだが,step=0.01 のときは,元のプログラムの3倍ほどの速さになる。
mandelbrot <- function(step = 0.1, pch = 0, col = 30, n = 2) {
a <- outer(seq(-2, 1, step), seq(-1, 1, step), function(x, y) complex(real = x,
imaginary = y))
a <<- a[Mod(a) <= 2] # 絶対値2以下のものだけにする(あまり意味はないが)
len <- length(a) # 追加
d <- complex(len) # 書き直し
dc <- integer(len) # 書き直し
m <- 0 # 追加
for (c in a) {
z <- 0
for (i in 1:100) {
z <- z^n + c
if (Mod(z) >= 2) {
m <- m+1 # 追加
d[m] <- c # 書き直し
dc[m] <- i # 何回目で発散したか # 書き直し
break
}
}
}
# 回数で色分け
d <- d[1:m] # 書き直し
plot(d, pch = pch, xlab = paste("step:", step, "n = ", n), xlim = c(-2,
1), ylim = c(-1, 1), col = colors()[dc + col], asp=1, cex=10*step)
dc <<- dc[1:m]
}
※コメント投稿者のブログIDはブログ作成者のみに通知されます