階乗の計算をする関数
をテンプレートにして作成
[
トップ
] [
新規
|
一覧
|
検索
|
最終更新
|
ヘルプ
]
開始行:
* 階乗関数 [#ce949f2d]
R で階乗関数 n! = 1 x 2 x ... x n を計算する関数として,...
n! = gamma(n+1) # +1 を忘れないこと!
なるほどです。私は今まで,こんなのを使ってました。
prod(1:n)
n が 0 だと,困るんですけどね。
参考:特定の引数値に対して関数の動作を変更するにはこうし...
> temp <- function (n) ifelse(n == 0, 1, prod(1:n)) # n...
> temp(0)
[1] 1
> temp(5)
[1] 120
引数のチェックなどを含めて,以下のように発展させましょう。
fact <- function(x) ifelse (x != floor(x) | x < 0, NA, i...
> fact(-10)
[1] NA
> fact(0)
[1] 1
> fact(1.2)
[1] NA
> fact(4)
[1] 24
> fact(170)
[1] 7.257416e+306
> fact(171)
[1] Inf
参考:R で n! 用の特別な関数を用意していない真意は、gamma...
> fact(1:5)
[1] 1 1 1 1 1 # ベクトル化されていないので警告が出る
Warning message:
Numerical expression has 5 elements: only the first used...
> system.time(for (i in 1:100000) fact(100)) # 計算時間...
[1] 50.12 0.94 52.04 0.00 0.00
> system.time(for (i in 1:100000) gamma(101))
[1] 0.42 0.03 0.47 0.00 0.00 # 100倍近く早い
=====
fact が遅いのは,いろいろチェックをしているからと思います。
> system.time(for (i in 1:100000) prod(1:100))
[1] 2.0703125 0.3203125 2.6718750 0.0000000 0.0000000
> system.time(for (i in 1:100000) gamma(101))
[1] 0.7734375 0.1093750 0.9375000 0.0000000 0.0000000
あまり差がないと言うべきでしょう
> fact <- function(x) ifelse (x != floor(x) | x < 0, NA...
> system.time(for (i in 1:100000) fact(100))
[1] 95.710938 4.351562 106.625000 0.000000 0.000000
> fact2 <- function(x) ifelse (x != floor(x) | x < 0, N...
> system.time(for (i in 1:100000) fact2(101))
[1] 93.117188 4.671875 105.640625 0.000000 0.000000
ほとんどが,引数チェックのオーバーヘッドです。
> system.time(for (i in 1:100000) fact2(11))
[1] 93.328125 4.351562 104.125000 0.000000 0.000000
> system.time(for (i in 1:100000) fact(10))
[1] 93.43750 4.59375 105.32812 0.00000 0.00000
> system.time(for (i in 1:100000) fact2(3))
[1] 93.046875 4.320312 106.046875 0.000000 0.000000
> system.time(for (i in 1:100000) fact(2))
[1] 93.750000 3.960938 104.625000 0.000000 0.000000
さらに,実際はほとんどが,関数起動のオーバーヘッドのよう...
注:gamma を使うのに反対しているわけではありません。
ベクトル化は以下のようにすればいいでしょうか
> fact <- function(x)
+ {
+ fact2 <- function(x) {
+ ifelse (x != floor(x) | x < 0, NA, ifelse(x ==...
+ }
+ sapply(x, fact2)
+ }
> fact(1:10)
[1] 1 2 6 24 120 720 ...
参考:なるほどあらゆる計算機言語で論理判断は時間を食うの...
> x= <- 1-1e-16; x == floor(x); floor(x)
[1] FALSE
[1] 0
> x <- 1-1e-17; x == floor(x); floor(x)
[1] TRUE
[1] 1
R core チームの苦労が多少分かるような気がします。ところで...
1.9.0 では 内部で gamma(n+1) を呼び出す factorial(n) が追...
終了行:
* 階乗関数 [#ce949f2d]
R で階乗関数 n! = 1 x 2 x ... x n を計算する関数として,...
n! = gamma(n+1) # +1 を忘れないこと!
なるほどです。私は今まで,こんなのを使ってました。
prod(1:n)
n が 0 だと,困るんですけどね。
参考:特定の引数値に対して関数の動作を変更するにはこうし...
> temp <- function (n) ifelse(n == 0, 1, prod(1:n)) # n...
> temp(0)
[1] 1
> temp(5)
[1] 120
引数のチェックなどを含めて,以下のように発展させましょう。
fact <- function(x) ifelse (x != floor(x) | x < 0, NA, i...
> fact(-10)
[1] NA
> fact(0)
[1] 1
> fact(1.2)
[1] NA
> fact(4)
[1] 24
> fact(170)
[1] 7.257416e+306
> fact(171)
[1] Inf
参考:R で n! 用の特別な関数を用意していない真意は、gamma...
> fact(1:5)
[1] 1 1 1 1 1 # ベクトル化されていないので警告が出る
Warning message:
Numerical expression has 5 elements: only the first used...
> system.time(for (i in 1:100000) fact(100)) # 計算時間...
[1] 50.12 0.94 52.04 0.00 0.00
> system.time(for (i in 1:100000) gamma(101))
[1] 0.42 0.03 0.47 0.00 0.00 # 100倍近く早い
=====
fact が遅いのは,いろいろチェックをしているからと思います。
> system.time(for (i in 1:100000) prod(1:100))
[1] 2.0703125 0.3203125 2.6718750 0.0000000 0.0000000
> system.time(for (i in 1:100000) gamma(101))
[1] 0.7734375 0.1093750 0.9375000 0.0000000 0.0000000
あまり差がないと言うべきでしょう
> fact <- function(x) ifelse (x != floor(x) | x < 0, NA...
> system.time(for (i in 1:100000) fact(100))
[1] 95.710938 4.351562 106.625000 0.000000 0.000000
> fact2 <- function(x) ifelse (x != floor(x) | x < 0, N...
> system.time(for (i in 1:100000) fact2(101))
[1] 93.117188 4.671875 105.640625 0.000000 0.000000
ほとんどが,引数チェックのオーバーヘッドです。
> system.time(for (i in 1:100000) fact2(11))
[1] 93.328125 4.351562 104.125000 0.000000 0.000000
> system.time(for (i in 1:100000) fact(10))
[1] 93.43750 4.59375 105.32812 0.00000 0.00000
> system.time(for (i in 1:100000) fact2(3))
[1] 93.046875 4.320312 106.046875 0.000000 0.000000
> system.time(for (i in 1:100000) fact(2))
[1] 93.750000 3.960938 104.625000 0.000000 0.000000
さらに,実際はほとんどが,関数起動のオーバーヘッドのよう...
注:gamma を使うのに反対しているわけではありません。
ベクトル化は以下のようにすればいいでしょうか
> fact <- function(x)
+ {
+ fact2 <- function(x) {
+ ifelse (x != floor(x) | x < 0, NA, ifelse(x ==...
+ }
+ sapply(x, fact2)
+ }
> fact(1:10)
[1] 1 2 6 24 120 720 ...
参考:なるほどあらゆる計算機言語で論理判断は時間を食うの...
> x= <- 1-1e-16; x == floor(x); floor(x)
[1] FALSE
[1] 0
> x <- 1-1e-17; x == floor(x); floor(x)
[1] TRUE
[1] 1
R core チームの苦労が多少分かるような気がします。ところで...
1.9.0 では 内部で gamma(n+1) を呼び出す factorial(n) が追...
ページ名: