【问题标题】:Functional programming in R : illustration with vandermonde matrixR中的函数式编程:用范德蒙德矩阵说明
【发布时间】:2013-07-05 17:43:17
【问题描述】:

我想体验一下 R 中的函数式编程。 为此,我想编写vandermonde matrix 计算,因为它可能涉及一些构造。

在命令式风格中:

vandermonde.direct <- function (alpha, n) 
{
  if (!is.vector(alpha))  stop("argument alpha is not a vector")
  if (!is.numeric(alpha)) stop("argument n is not a numeric vector")
  m <- length(alpha)
  V <- matrix(0, nrow = m, ncol = n)
  V[, 1] <- rep(1, m)
  j <- 2
  while (j <= n) {
    V[, j] <- alpha^(j - 1)
    j <- j + 1
  }
  return(V)
}

你会如何在 R 中以函数式风格优雅地编写它?

以下不起作用:

x10 <- runif(10)
n <- 3
Reduce(cbind, aaply(seq_len(n-1),1, function (i) { function (x) {x**i}}), matrix(1,length(x10),1))

它告诉我Error: Results must have one or more dimensions. 的函数列表从i in seq_len(3-1) 到函数x -&gt; x**i.

【问题讨论】:

标签: r functional-programming higher-order-functions


【解决方案1】:

在这个任务中使用Reduce 似乎不太自然。 错误信息是由aaply 引起的,它试图返回一个数组: 您可以改用alply;你还需要在某个地方调用你的函数。

这里有一些惯用的替代方法:

outer( x10, 0:n, `^` )
t(sapply( x10, function(u) u^(0:n) ))
sapply( 0:3, function(k) x10^k )

【讨论】:

    【解决方案2】:

    这里是Reduce:

    m <- as.data.frame(Reduce(f=function(left, right) left * x10, 
                              x=1:(n-1), init=rep(1,length(x10)), accumulate=TRUE))
    names(m) <- 1:n - 1
    

    【讨论】:

      【解决方案3】:

      这是另一个选项,它使用 R 的环境特性:

      vdm <- function(a)
      {
          function(i, j) a[i]^(j-1)
      }
      

      这适用于任意n(列数)。

      要为给定的a 创建“Vandermonde 泛函”,请使用:

      v <- vdm(a=c(10,100))
      

      要一次构建一个矩阵,使用这个:

      > outer(1:3, 1:4, v)
           [,1] [,2]  [,3]  [,4]
      [1,]    1   10   100 1e+03
      [2,]    1  100 10000 1e+06
      [3,]    1   NA    NA    NA
      

      请注意,索引a[3] 超出范围,因此返回NA(第一列除外,即1)。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2018-06-23
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多