簡體   English   中英

如何將外部推廣到 n 維?

[英]How to generalize outer to n dimensions?

標准的 R 表達式 external outer(X, Y, f)計算為一個矩陣,其 (i, j)-th 條目的值為f(X[i], Y[j])

我想實現 function multi.outerouter的 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]

謝謝!

這是一種方法:首先使用Vectorizeouter來定義一個 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”上調用applydo.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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM