简体   繁体   English

R中的函数式编程:带vandermonde矩阵的图示

[英]Functional programming in R : illustration with vandermonde matrix

I would like to get a feel of functional programming in R. To that effect, I would like to write the vandermonde matrix computation, as it can involve a few constructs. 我想对R中的函数编程有所了解。为此,我想编写vandermonde矩阵计算,因为它可能涉及一些构造。

In imperative style that would be : 命令式将是:

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)
}

How would you write that elegantly in R in functional style ? 您将如何用R优雅地以功能性风格写出来?

The following does not work : 以下无效:

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

As it tells me Error: Results must have one or more dimensions. 告诉我Error: Results must have one or more dimensions. for list of function which go from i in seq_len(3-1) to the function x -> x**i. 用于从i in seq_len(3-1)中的i in seq_len(3-1)到函数x -> x**i.的函数x -> x**i.

It does not seem very natural to use Reduce for this task. Reduce用于此任务似乎不太自然。 The error message is caused by aaply , which tries to return an array: you can use alply instead; 该错误消息是由aaply引起的,它试图返回一个数组:您可以改用alply you also need to call your functions, somewhere. 您还需要在某个地方调用函数。

Here are a few idiomatic alternatives: 以下是一些惯用的替代方法:

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

Here it is with Reduce : 这是与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

Here's another option, that uses the environment features of R: 这是另一个使用R的环境功能的选项:

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

This will work for arbitrary n (the number of columns). 这适用于任意n (列数)。

To create the "Vandermonde functional" for a given a , use this: 要为给定的a创建“范德蒙函数”,请使用以下命令:

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

To build a matrix all at once, use this: 要一次构建一个矩阵,请使用以下命令:

> 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

Note that index a[3] is out of bounds, thus returning NA (except for the first column, which is 1 ). 请注意,索引a[3]超出范围,因此返回NA (第一列除外,即1 )。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM