as-function: Change polynomials into functions.

as-functionR Documentation

Change polynomials into functions.

Description

Transform mpoly and mpolyList objects into function that can be evaluated.

Usage

## S3 method for class 'mpoly'
as.function(x, varorder = vars(x), vector = TRUE,
  silent = FALSE, ..., plus_pad = 1L, times_pad = 1L, squeeze = TRUE)

## S3 method for class 'mpolyList'
as.function(x, varorder = vars(x), vector = TRUE,
  silent = FALSE, name = FALSE, ..., plus_pad = 1L, times_pad = 1L, squeeze = TRUE)

## S3 method for class 'bezier'
as.function(x, ...)

Arguments

x

an object of class mpoly

varorder

the order of the variables

vector

whether the function should take a vector argument (TRUE) or a series of arguments (FALSE)

silent

logical; if TRUE, suppresses output

...

any additional arguments

plus_pad

number of spaces to the left and right of plus sign

times_pad

number of spaces to the left and right of times sign

squeeze

minify code in the created function

name

should the returned object be named? only for mpolyList objects

Details

Convert polynomials to functions mapping Rn to Rm that are vectorized in the following way as.function.mpoly() governs this behavior:

  • [m = 1, n = 1, like f(x) = x^2 + 2x] Ordinary vectorized function returned, so that if you input a numeric vector x, the returned function is evaluated at each of the input values, and a numeric vector is returned.

  • [m = 1, n = 2+, like f(x,y) = x^2 + 2x + 2xy] A function of a single vector argument f(v) = f(c(x,y)) is returned. If a N x n matrix is input to the returned function, the function will be applied across the rows and return a numeric vector of length N. If desired, setting vector = FALSE changes this behavior so that an arity-n function is returned, i.e. the function f(x,y) of two arguments. In this case, the returned function will accept equal-length numeric vectors and return a numeric vector, vectorizing it.

And as.function.mpolyList() governs this behavior:

  • [m = 2+, n = 1, like f(x) = (x, x^2)] Ordinary vectorized function returned, so that if you input a numeric vector x, the function is evaluated at each of the input values, and a numeric matrix N x m, where N is the length of the input vector.

  • [m = 2+, n = 2+, like f(x,y) = (1, x, y)] When vector = FALSE (the default), the created function accepts a numeric vector and returns a numeric vector. The function will also accept an N x n matrix, in which case the function is applied to its rows to return a N x m matrix.

See Also

plug()

Examples


# basic usage. m = # polys/eqns, n = # vars

# m = 1, n = 1, `as.function.mpoly()`
p <- mp("x^2 + 1")
(f <- as.function(p))
f(2)
f(1:3) # vectorized


# m = 1, n = 2 , `as.function.mpoly()`
p <- mp("x y")
(f <- as.function(p))
f(1:2) 
(mat <- matrix(1:6, ncol = 2))
f(mat) # vectorized across rows of input matrix

 
# m = 2, n = 1, `as.function.mpolyList()`
p <- mp(c("x", "x^2"))
(f <- as.function(p))
f(2)
f(1:3) # vectorized

(f <- as.function(p, name = TRUE))
f(2)
f(1:3) # vectorized


# m = 3, n = 2, `as.function.mpolyList()`
p <- mp("(x + y)^2")
(p <- monomials(p))

(f <- as.function(p))
f(1:2) 
(mat <- cbind(x = 1:3, y = 4:6))
f(mat) # vectorized across rows of input matrix

(f <- as.function(p, name = TRUE))
f(1:2) 
f(mat)



# setting vector = FALSE changes the function to a sequence of arguments
# this is only of interest if n = # of vars > 1

# m = 1, n = 2, `as.function.mpoly()`
p <- mp("x y")
(f <- as.function(p, vector = FALSE))
f(1, 2) 
(mat <- matrix(1:6, ncol = 2))
f(mat[,1], mat[,2]) # vectorized across input vectors

# m = 3, n = 2, `as.function.mpolyList()`
p <- mp(c("x", "y", "x y"))
(f <- as.function(p, vector = FALSE))
f(1, 2) 
(mat <- matrix(1:4, ncol = 2))
f(mat[,1], mat[,2]) # vectorized across rows of input matrix
(f <- as.function(p, vector = FALSE, name = TRUE))
f(1, 2) 
(mat <- matrix(1:4, ncol = 2))
f(mat[,1], mat[,2]) # vectorized across rows of input matrix



# it's almost always a good idea to use the varorder argument, 
# otherwise, mpoly has to guess at the order of the arguments
invisible( as.function(mp("y + x")) )
invisible( as.function(mp("x + y")) )
invisible( as.function(mp("y + x"), varorder = c("x","y")) )


# constant polynomials have some special rules
f <- as.function(mp("1"))
f(2)
f(1:10)
f(matrix(1:6, nrow = 2))



# you can use this to create a gradient function, useful for optim()
p <- mp("x + y^2 + y z")
(ps <- gradient(p))
(f <- as.function(ps, varorder = c("x","y","z")))
f(c(0,2,3)) # -> [1, 7, 2]



# a m = 1, n = 2+ mpolyList creates a vectorized function
# whose rows are the evaluated quantities
(ps <- basis_monomials("x", 3))
(f <- as.function(ps))
s <- seq(-1, 1, length.out = 11)
f(s)

# another example
(ps <- chebyshev(1:3))
f <- as.function(ps)
f(s)

# the binomial pmf as an algebraic (polynomial) map
# from [0,1] to [0,1]^size
# p |-> {choose(size, x) p^x (1-p)^(size-x)}_{x = 0, ..., size}
abinom <- function(size, indet = "p"){
  chars4mp <- vapply(0:size, function(x){
    sprintf("%d %s^%d (1-%s)^%d", choose(size, x), indet, x, indet, size-x)
  }, character(1))
  mp(chars4mp)
}
(ps <- abinom(2, "p")) # = mp(c("(1-p)^2", "2 p (1-p)", "p^2"))
f <- as.function(ps)

f(.50) # P[X = 0], P[X = 1], and P[X = 2] for X ~ Bin(2, .5)
dbinom(0:2, 2, .5)

f(.75) # P[X = 0], P[X = 1], and P[X = 2] for X ~ Bin(2, .75)
dbinom(0:2, 2, .75)

f(c(.50, .75)) # the above two as rows

# as the degree gets larger, you'll need to be careful when evaluating
# the polynomial.  as.function() is not currently optimized for
# stable numerical evaluation of polynomials; it evaluates them in
# the naive way
all.equal(
  as.function(abinom(10))(.5),
  dbinom(0:10, 10, .5)
)

all.equal(
  as.function(abinom(30))(.5),
  dbinom(0:30, 20, .5)
)


# the function produced is vectorized:
number_of_probs <- 11
probs <- seq(0, 1, length.out = number_of_probs)
(mat <- f(probs))
colnames(mat) <- sprintf("P[X = %d]", 0:2)
rownames(mat) <- sprintf("p = %.2f", probs)
mat


dkahle/mpoly documentation built on July 27, 2023, 11:44 p.m.