% Generated by roxygen2: do not edit by hand
% Please edit documentation in R/as.function.R, R/bezier.R
\name{as-function}
\alias{as-function}
\alias{as.function.mpoly}
\alias{as.function.bernstein}
\alias{as.function.mpolyList}
\alias{as.function.bezier}
\title{Change polynomials into functions.}
\usage{
\method{as.function}{mpoly}(x, varorder = vars(x), vector = TRUE,
  silent = FALSE, ..., plus_pad = 1L, times_pad = 1L, squeeze = TRUE)

\method{as.function}{bernstein}(x, ...)

\method{as.function}{mpolyList}(x, varorder = vars(x), vector = TRUE,
  silent = FALSE, name = FALSE, ..., plus_pad = 1L, times_pad = 1L, squeeze = TRUE)

\method{as.function}{bezier}(x, ...)
}
\arguments{
\item{x}{an object of class mpoly}

\item{varorder}{the order of the variables}

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

\item{silent}{logical; if TRUE, suppresses output}

\item{...}{any additional arguments}

\item{plus_pad}{number of spaces to the left and right of plus sign}

\item{times_pad}{number of spaces to the left and right of times sign}

\item{squeeze}{minify code in the created function}

\item{name}{should the returned object be named? only for \code{mpolyList} objects}
}
\description{
Transform \code{mpoly} and \code{mpolyList} objects into function that can be
evaluated.
}
\details{
Convert polynomials to functions mapping Rn to Rm that are vectorized in the
following way \code{\link[=as.function.mpoly]{as.function.mpoly()}} governs this behavior:

\describe{

\item{[m = 1, n = 1, e.g. 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.}

\item{[m = 1, n = 2+, e.g. 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 \code{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 \code{\link[=as.function.mpolyList]{as.function.mpolyList()}} governs this behavior:

\describe{

\item{[m = 2+, n = 1, e.g. 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.}

\item{[m = 2+, n = 2+, e.g. f(x,y) = (1, x, y)] }{When \code{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.}

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

}
\seealso{
\code{\link[=plug]{plug()}}
}
