I would like to write a function that converts a polynomial given as a character into a named vector. The entries of the vector should correspond to the coefficients of the polynomial and be named as x^n
, where n is the corresponding exponent.
The output should look like this:
> function("2x^5 x 3x^5 - 1 4x")
x^0 x^1 x^2 x^3 x^4 x^5
-1 5 0 0 0 5
Cheers!
CodePudding user response:
Since your polynomial may contain the same power twice (e.g. x^5
in your example), you need to do some operations to simplify it. The easiest way to do this is to evaluate it and its derivatives at zero. Here's some code to do that:
polycoefs <- function(poly) {
expr <- parse(text = poly)
result <- numeric()
env <- list2env(list(x = 0), parent = baseenv())
i <- 0
while (!identical(expr, 0)) {
coef <- eval(expr, envir = env)/factorial(i)
names(coef) <- paste0("x^", i)
result <- c(result, coef)
expr <- D(expr, "x")
i <- i 1
}
result
}
polycoefs("2*x^5 x 3*x^5 - 1 4*x")
#> x^0 x^1 x^2 x^3 x^4 x^5
#> -1 5 0 0 0 5
Created on 2022-05-23 by the reprex package (v2.0.1)
Note that the polynomial needs to be a legal R expression, and it needs to be a polynomial, not some other kind of expression, or the function won't ever terminate. I'll leave it to you to add some edits and tests to make sure these conditions are met.
CodePudding user response:
Replace digit possibly followed by spaces and then x with digit, space, *, space and x so that character string s represents a valid R expression. Then using the polynom package parse and evaluate the expression containing x as a polynomial and then use as.numeric to convert it to a vector and add names using setNames.
library(polynom)
poly2vec <- function(string) {
s <- gsub("(\\d) *x", "\\1 * x", string)
v <- as.numeric(eval(str2lang(s), list(x = polynomial())))
setNames(v, paste0("x^", seq(0, length = length(v))))
}
poly2vec("2x^5 x 3x^5 - 1 4x")
## x^0 x^1 x^2 x^3 x^4 x^5
## -1 5 0 0 0 5
Alternately it would be possible to use the taylor function from pracma but it has the disadvantage that it involves floating point arithmetic.
library(pracma)
s <- gsub("(\\d) *x", "\\1 * x", "2x^5 x 3x^5 - 1 4x")
f <- function(x) {}
body(f) <- str2lang(s)
taylor(f, 0, 5)
## [1] 5.000006e 00 0.000000e 00 1.369355e-05 0.000000e 00 5.000000e 00
## [6] -1.000000e 00