Function:
(x^3 - 3*x^2 - 2*x + 7) + (y^2 + 2*y)
Output on Wolfram (which I understand):
x^3 - 3 x^2 - 2 x + y^2 + 2 y + 7
Output of the code in R: (using the polynomial function in package polynom)
7 - 2*x^2 + x^3
R code:
library(polynom)
p <- polynomial(c(7,-2,-3, 1))
q <- polynomial(c(0, 2, 1))
p + q
Entered the code as above in R.
You can use mpoly to manipulate multivariate polynomials.
library(mpoly)
p <- as.mpoly(c(7, -2, -3, 1), 'x')
q <- as.mpoly(c(0, 2, 1), 'y')
reorder(p + q)
# x^3 - 3 x^2 - 2 x + y^2 + 2 y + 7
More functionality
https://dkahle.github.io/mpoly/
Related
I'm now learning about calculus and want to depict a graph of x^2 + 6x + y^4 = 7, which I can using online graphing tool desmos.
But when I'm not sure how this is achievable on R. The first thing I thought is convert it in a form of y = f(x), but return (x^2 + 6*x - 7)^(1/4) gave me a different result.
At the same time, it seems impossible to return a equation in a function (return (x^2 + 6*x + y^4 = 7)). So how can I depict it on R?
Here is a sample code I usually use to depict a continuous graph.
f <- function(x) {
return () # return an equation
}
ggplot(data.frame(x=seq(-10,10,length.out=10)), aes(x)) + stat_function(fun=f)
You can have separate functions for the positive and negative solutions for y
f1 <- function(x) (7 - x^2 - 6*x)^(1/4)
f2 <- function(x) -f1(x)
Now just create a vector each for positive and negative values along the domain of x:
x <- seq(-7, 1, length = 1000)
y1 <- f1(x)
y2 <- f2(x)
And plot:
ggplot() +
geom_line(aes(x, y1)) +
geom_line(aes(x, y2))
You can use contourLines:
f <- function(x,y) x^2 + 6*x + y^4
x <- seq(-10, 3, len = 200)
y <- seq(-3, 3, len = 200)
z <- outer(x, y, f)
cr <- contourLines(x, y, z, levels = 7)
plot(cr[[1]]$x, cr[[1]]$y, type = "l")
library(ggplot2)
dat <- data.frame(x = cr[[1]]$x, y = cr[[1]]$y)
ggplot(dat) + geom_path(aes(x, y))
I will be highly grateful for your help. I am learning how to use geom_function in r. Following is my function:
x0 <- 0.5
x1 <- 1
x2 <- 2
x3 <- 3
x <- c(x0, x1, x2, x3)
myfn <- function(w, b, a, x){
w^(1-b)/(1-b)-a*w-(w>100 & w<=200)*x[3]*(w-100)-(w>200)*x[3]*100-x[4]*(w-200)
}
My objective is to plot above function using geom_function to see how this function behaves with different values of arguments a and b and following is my code:
y=seq(0,1000,5)
ggplot()+
xlim(c(0,1000))+
geom_function(fun=myfn(w=y, b=-4, a=0.5, x=x))
Problem: I feel my logic is correct but when I execute above code, I get nothing. I will be highly grateful for the help. Thank you very much for the help in advance. Any help or direction will be highly appreciated.
Your function myfn is a function of w where a, b and x are parameters. To plot this function over the range of c(0, 1000) pass your function to the fun argument and the parameters as a list via the args argument and set the range via xlim:
x0 <- 0.5
x1 <- 1
x2 <- 2
x3 <- 3
x <- c(x0, x1, x2, x3)
myfn <- function(w, b, a, x) {
w^(1 - b) / (1 - b) - a * w - (w > 100 & w <= 200) * x[3] * (w - 100) - (w > 200) * x[3] * 100 - x[4] * (w - 200)
}
library(ggplot2)
ggplot() +
xlim(c(0, 1000)) +
geom_function(fun = myfn, args = list(b = -4, a = 0.5, x = x))
A second option would be to make use of a lambda function like so:
ggplot() +
xlim(c(0, 1000)) +
geom_function(fun = ~ myfn(.x, b = -4, a = 0.5, x = x))
myfn <- function(x, a, b, c) {
x^(1 - b) / (1 - b) - a * x - (x > 100 & x <= 200) * c[3] * (x - 100) - (x > 200) * c[3] * 100 - c[4] * (x - 200) # outcome is y
}
ggplot() +
xlim(c(0, 1000)) +
geom_function(fun = ~ myfn(x = .x, a = 0.5, b = -4, c = c(0.5, 1, 2, 3)))
If you do not want to add the variables through the args list you can add the variables to your function like this. Note I changed some of the variable names to make it more clear what the actual x and y are in the plot. Also x by the OP is just a list with 4 constants, I provided them as a and b under the name c.
I'm trying to view the monomials of a two-variable polynomial in vector form. So, for example, if I input x^2 + x^3*y + x*y + y^2 + 1, I would like to view it as [[2;0], [3;1], [1;1], [0;2], [0;0]] - a vector made of column vectors.
If I use Vec on a two-variable polynomial, it simply treats the second variable as a number, giving Vec( x^2 + x^3*y + x*y + y^2 + 1 ) = [ y, 1, y, y^2 + 1 ], which I don't think can then be twisted into something that would work for me.
Any ideas on how this might be able to be done?
You have to calc all the monomials by your own. Your bivariate polynomial can be viewed as the univariate polynomial having polynomial coefficients. Firstly, you select the primary variable (e.g. 'x) and find its exponents together with its nonzero coefficients:
exponents(f, v=variable(f)) = {
if(type(f) != "t_POL",
return([[0, f]])
);
my(x = varhigher("#"));
my(coeffs = Vecrev(subst(f, v, x)));
my(indexes = select((c) -> c != 0, coeffs, 1));
[[n-1, coeffs[n]] | n <- Vec(indexes)]
};
exponents(1)
> [[0, 1]]
exponents(x^2 + x^3*y + x*y + y^2 + 1)
> [[0, y^2 + 1], [1, y], [2, 1], [3, y]]
exponents(x^2 + x^3*y + x*y + y^2 + 1, 'y)
> [[0, x^2 + 1], [1, x^3 + x], [2, 1]]
Secondly, given such list of exponents and coefficients you easily obtain the complete list of monomials:
monomial_list(f) = {
concat(
apply(
(xs) -> [[xs[1], p[1]] | p <- exponents(xs[2])],
exponents(f)
)
)
};
monomial_list(0)
> [[0, 0]]
monomial_list(x^2 + x^3*y + x*y + y^2 + 1)
> [[0, 0], [0, 2], [1, 1], [2, 0], [3, 1]]
This question is more for my own curiosity. I was looking through the Polynom documenation pdf for R, and noticed several basic polynomial operations such as:
p <- poly.calc(1:5)
## -120 + 274*x - 225*x^2 + 85*x^3 - 15*x^4 + x^5
However, how would I represent 'x' if I had to solve an equation such as:
(x+1)3x^3 + (x+1)4x^2 + (x+1) 2x + 3 = 17
and as a bonus, what if I wanted to specify x is greater than 0, and would change the equation to (x+1)3x^3 + (x+1)4x^2 + (x+1) 2x + 3 ≈ 17 where x > 0? (if it is even possible)
I think you are asking something like the following:
With the library polynom:
library(polynom)
#(x+1)3x^3 + (x+1)4x^2 + (x+1) 2x + 3 - 17 = (x+1)(3x^3 + 4x^2 + 2x) - 14
p1 <- polynomial(coef = c(1, 1))
p2 <- polynomial(coef = c(0, 2, 4, 3))
p <- p1 * p2 - 14
roots <- solve(p)
real.roots <- Re(roots[Im(roots)==0])
# [1] -2.0554784 0.9069195
real.positive.roots <- real.roots[real.roots > 0]
# [1] 0.9069195
plot(p)
abline(h=0)
abline(v=real.roots, lty=2)
points(real.roots, rep(0, length(real.roots)))
With the function uniroot:
f <- function (x) (x+1)*3*x^3 + (x+1)*4*x^2 + (x+1)*2*x + 3 - 17
root1 <- uniroot(f, c(-2, 1), tol = 0.0001)$root
# [1] 0.9069388
root2 <- uniroot(f, c(-3, -2), tol = 0.0001)$root
# [1] -2.055487
x <- seq(-2.5,1.5,0.001)
plot(x, f(x), type='l')
abline(h=0)
abline(v=root1, lty=2)
abline(v=root2, lty=2)
points(root1, 0, col='red', pch=19)
points(root2, 0, col='red', pch=19)
I want to write an R function that takes a mathematical function in x and returns a new function in x as an output. For example:
The input should be passed in as a mathematical function (or relation) in x:
g <- x^2 + 9*x + log(x)
And the resulting output should be:
function(x) (exp(g))
i.e. I want to return the symbolic exponential expression of the original function in x i.e. exp(x^2 + 9*x + log(x)) in this illustrative example
So ideally it would return the function object:
function(x) (exp(x^2 + 9*x + log(x)))
I tried as follows:
test <- function(g){
h <- function(x){exp(g)}
return(h)
}
m <- test(x^2 + 9*x + log(x))
m(10)
So m(10) should return:
exp(10^2 + 9*10 + log(10))
which is exp(192.3026) in this case.
Could anyone show how to do this please?
You could use package functional:
library(functional)
fun <- Compose(function(x) x^2 + 9*x + log(x), exp)
fun(1)
#[1] 22026.47
Here is one approach:
test <- function(e) {
ee <- substitute(e)
eee <- substitute(exp(X), list(X=ee))
f <- function(x) {}
body(f) <- eee
environment(f) <- parent.frame()
f
}
## Check that it works
m <- test(x^2 + 9*x + log(x))
m
# function (x)
# exp(x^2 + 9 * x + log(x))
m(1)
# [1] 22026.47
m(1) == exp(10)
# [1] TRUE
edit - for functionality in question
f <- function(...) {
l <- eval(substitute(alist(x = x, ...)))
l[[2]] <- substitute(exp(X), list(X = l[[2]]))
as.function(`names<-`(l, l[sapply(l, is.symbol)]))
}
g <- f(x^2 + 2*x + 5)
# function (x = x)
# exp(x^2 + 2 * x + 5)
g(1)
# [1] 2980.958
Here is another way for a general case:
f <- function(...) {
l <- eval(substitute(alist(...)))
as.function(`names<-`(l, l[sapply(l, is.symbol)]))
}
g <- f(x, x^2 + 9*x + log(x))
# function (x = x)
# x^2 + 9 * x + log(x)
g(10)
# [1] 192.3026
This version will also work for any number of variables, just define them followed by the function:
g <- f(x, y, z, x + 2 * y + z ** 3)
# function (x = x, y = y, z = z)
# x + 2 * y + z^3
g(1, 2, 0)
# [1] 5
There may be a better way to add ... to functions, but here is how you can do that
f <- function(..., use_dots = FALSE) {
l <- eval(substitute(alist(...)))
if (use_dots)
l <- c(head(l, -1), list('...' = as.symbol('...')), tail(l, 1))
as.function(`names<-`(l, l[sapply(l, is.symbol)]))
}
So now you don't have to name all the variables/arguments
g <- f(x, y, plot(x, y, ...), use_dots = TRUE)
g(1:5, 1:5, main = 'main title', pch = 16, col = 3, cex = 3, xpd = NA)