[英]How to generalize outer to n dimensions?
標准的 R 表達式 external outer(X, Y, f)
計算為一個矩陣,其 (i, j)-th 條目的值為f(X[i], Y[j])
。
我想實現 function multi.outer
, outer
的 n 維概括: multi.outer(f, X_1, ..., X_n)
,其中 f 是一些 n 元 function,會產生 (length(X_1 ) *... * length(X_n)) 數組,其 (i_1, f(X_1[i_1], ..., X_n[i_n])
,i_n)-th 條目對於所有有效索引集 ( i_1,...,i_n)。 顯然,對於 {1, ..., n} 中的每個 i, multi.outer(f, X_1,...,X_i,..., X_n)
中X_i
的所有元素都必須允許第 i 個 arguments function f
。 對於 n=2 的情況, multi.outer
會做與 external 相同的事情,盡管它會有不同的簽名 (IOW, multi.outer(f, X, Y)
將等價於outer
outer(X, Y, f)
)。
需要注意的是,雖然 multi.outer 的multi.outer
X_1, ..., X_n 都是向量,但它們不一定都具有相同的模式。 例如 X_1 和 X_2 可以分別是c(1, 2, 3)
和LETTERS[10:20]
。
謝謝!
這是一種方法:首先使用Vectorize
和outer
來定義一個 function ,它創建一個 n 維矩陣,其中每個條目是 arguments 的列表,將在其上應用給定的 function
list_args <- Vectorize( function(a,b) c( as.list(a), as.list(b) ),
SIMPLIFY = FALSE)
make_args_mtx <- function( alist ) {
Reduce(function(x, y) outer(x, y, list_args), alist)
}
現在multi.outer
只需要在這個“args-matrix”上調用apply
和do.call
:
multi.outer <- function(f, ... ) {
args <- make_args_mtx(list(...))
apply(args, 1:length(dim(args)), function(a) do.call(f, a[[1]] ) )
}
讓我們用一個例子 function 來試試這個:
fun <- function(a,b,c) paste(a,b,c)
ans <- multi.outer(fun, LETTERS[1:2], c(3, 4, 5), letters[6:7] )
> ans
, , 1
[,1] [,2] [,3]
[1,] "A 3 f" "A 4 f" "A 5 f"
[2,] "B 3 f" "B 4 f" "B 5 f"
, , 2
[,1] [,2] [,3]
[1,] "A 3 g" "A 4 g" "A 5 g"
[2,] "B 3 g" "B 4 g" "B 5 g"
這個怎么樣:
multi.outer<-function(f,...){
apply(expand.grid(...),1,function(x){do.call(f,as.list(x))})
}
我認為我們可以使用 Outer 和 Vectorize 來做到這一點。
sigm = function(a=0,b=0,x){
return(exp(x*a+b))
}
sigm1 = Vectorize(function(a=-1:1,b=-1:1,x){
outer(a,b,sigm,x)
},SIMPLIFY = FALSE)
現在,sigm1(x=1:3) 給出了所需的 output
[[1]]
[,1] [,2] [,3]
[1,] 0.1353353 0.3678794 1.000000
[2,] 0.3678794 1.0000000 2.718282
[3,] 1.0000000 2.7182818 7.389056
[[2]]
[,1] [,2] [,3]
[1,] 0.04978707 0.1353353 0.3678794
[2,] 0.36787944 1.0000000 2.7182818
[3,] 2.71828183 7.3890561 20.0855369
[[3]]
[,1] [,2] [,3]
[1,] 0.01831564 0.04978707 0.1353353
[2,] 0.36787944 1.00000000 2.7182818
[3,] 7.38905610 20.08553692 54.5981500
此代碼片段的唯一缺點是我使用的是默認值 a=-1:1 和 b=-1:1。 當我在 function 調用期間嘗試通過相同的方法時,它會變得混亂。 例如
sigm1(-1:1,-1:1,1:3)
[[1]]
[,1]
[1,] 0.1353353
[[2]]
[,1]
[1,] 1
[[3]]
[,1]
[1,] 54.59815
我無法弄清楚為什么通過 arguments 會在 output 中產生這種差異。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.