任意阶次多项式的函数(首选符号方法) [英] Function for polynomials of arbitrary order (symbolic method preferred)

查看:174
本文介绍了任意阶次多项式的函数(首选符号方法)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已经从我的数据中找到了多项式系数:

  R <-c(0.256,0.512,0.768,1.024 ,1.28,1.437,1.594,1.72,1.846,1.972,2.098,2.4029)
Ic <-c(1.78,1.71,1.57,1.44,1.25,1.02,0.87,0.68,0.54,0.38,0.26,0.17 )
NN < - 3
ft -lm(Ic-poly(R,NN,raw = TRUE))
pc < - coef(ft)

所以我可以创建一个多项式函数:

  f1 < - 函数(x)pc [1] + pc [2] * x + pc [3] * x ^ 2 + pc [4] * x ^ 3 

举例来说,取一个衍生物:

  g1 < -  Deriv(f1)

如何创建一个通用函数不必为每个新的多项式程度重写 NN

解决方案

<我的原始答案可能不是你真正想要的,因为它是数字而非象征性的。这是符号解决方案。

  ##使用`x`作为变量名称
##取多项式系数
##
##
##可以返回一个字符串或者一个表达式, ; - paste(x,seq_along(pc)-1,sep =^)
stringexpr < - paste(stringexpr,pc,sep =*)
stringexpr< - paste (strictgexpr,collapse =+)
if(expr)return(parse(text = stringexpr))
else return(stringexpr)
}

##使用R基准的D(具有系数0.1,0.2,0.3,0.4
立方<-f(pc = 1:4/10,真))

##的示例三次多项式需要表达式)
dcubic <-D(立方体,名称=x)
#0.2 + 2 * x * 0.3 + 3 * x ^ 2 * 0.4

# #使用`Deriv :: Deriv`
library(Deriv)

dcubic < - Deriv(立方体,x =x,nderiv = 1L)
#表达式(0.2 + x *(0.6 + 1.2 * x))

Deriv(f(1:4/10,FALSE),x =x ,nderiv = 1L)##使用字符串,得到字符串
#[1]0.2 + x *(0.6 + 1.2 * x)

当然, Deriv 使高阶导数更容易获得。我们可以简单地设置 nderiv 。然而,对于 D ,我们必须使用递归(参见?D )的例子。

  Deriv(立方体,x =x,nderiv = 2L)
#表达式(0.6 + 2.4 * x)

Deriv(立方体,x =x,nderiv = 3L)
#表达式(2.4)

Deriv(立方体,x =x,nderiv = 4L)
#表达式(0)

如果我们使用表达式,我们将能够在稍后评估结果。例如,

  eval(cubic,envir = list(x = 1:4))##三次多项式
#[1] 1.0 4.9 14.2 31.3

eval(dcubic,envir = list(x = 1:4))##其一阶导数
#[1] 2.0 6.2 12.8 21.8

以上意味着我们可以包装一个函数的表达式。使用函数有几个优点,一个是我们可以使用 curve plot.function 来绘制它。 / p>

  fun < - 函数(x,expr)eval.parent(expr,n = 0L)

请注意, fun 的成功需要 expr 作为符号 x 的表达式。例如,如果 expr 定义为 y ,我们需要定义 fun 函数(y,expr)。现在让我们使用 curve 来绘制立方 dcubic ,on范围 0 < x < 5

  curve(fun(x,cubic),from = 0 to to 5) ## colorblack
curve(fun(x,dcubic),add = TRUE,col = 2)## colorred



最方便的方法当然是定义一个单个函数 FUN 而不是执行 f + fun 组合。这样,我们也不需要担心 f fun 使用的变量名的一致性。 。

  FUN < -  function(x,pc,nderiv = 0L){
##检查缺少的参数
if(missing(x)|| missing(pc))stop(arguments missing without default!)
##多项式表达式
stringexpr< - paste(x, seq_along(pc)-1,sep =^)
strictgexpr < - paste(stringexpr,pc,sep =*)
strictgexpr < - paste(stringexpr,collapse =+ )
expr< - parse(text = stringexpr)
##获取导数
dexpr < - Deriv :: Deriv(expr,x =x,nderiv = nderiv)
##评估
val < - eval.parent(dexpr,n = 0L)
##注意,如果我们采用许多衍生工具以使d​​expr变成常量
## `val`没有`x`,所以它的长度只有1
##我们需要重复这个常量来匹配`length(x)`
if(length(val)== 1L )val< - rep.int(val,leng th(x))
##现在我们返回
val
}



假设我们要评估一个三次多项式,它的系数 pc <-c(0.1,0.2,0.3,0.4)及其导数 x< - seq(0,1,0.2),我们可以简单地做到:

  FUN (x,pc)
#[1] 0.1000 0.1552 0.2536 0.4144 0.6568 1.0000

FUN(x,pc,nderiv = 1L)
#[1] 0.200 0.368 0.632 0.992 1.448 2.000

FUN(x,pc,nderiv = 2L)
#[1] 0.60 1.08 1.56 2.04 2.52 3.00

FUN(x,pc,nderiv = 3L )
#[1] 2.4 2.4 2.4 2.4 2.4 2.4

FUN(x,pc,nderiv = 4L)
#[1] 0 0 0 0 0 0

现在绘图也很容易:

从$ 0到= 5,add = TRUE,
曲线(FUN(x,pc,1))的曲线(FUN(x,pc) (FUN(x,pc,2),from = 0,to = 5,add = TRUE,col = 3)
曲线(FUN(x,pc,3),从= 0到= 5,add = TRUE,col = 4)


I've found polynomial coefficients from my data:

R <- c(0.256,0.512,0.768,1.024,1.28,1.437,1.594,1.72,1.846,1.972,2.098,2.4029)
Ic <- c(1.78,1.71,1.57,1.44,1.25,1.02,0.87,0.68,0.54,0.38,0.26,0.17)
NN <- 3
ft <- lm(Ic ~ poly(R, NN, raw = TRUE))
pc <- coef(ft)

So I can create a polynomial function:

f1 <- function(x) pc[1] + pc[2] * x + pc[3] * x ^ 2 + pc[4] * x ^ 3

And for example, take a derivative:

g1 <- Deriv(f1)

How to create a universal function so that it doesn't have to be rewritten for every new polynomial degree NN?

解决方案

My original answer may not be what you really want, as it was numerical rather symbolic. Here is the symbolic solution.

## use `"x"` as variable name
## taking polynomial coefficient vector `pc`
## can return a string, or an expression by further parsing (mandatory for `D`)
f <- function (pc, expr = TRUE) {
  stringexpr <- paste("x", seq_along(pc) - 1, sep = " ^ ")
  stringexpr <- paste(stringexpr, pc, sep = " * ")
  stringexpr <- paste(stringexpr, collapse = " + ")
  if (expr) return(parse(text = stringexpr))
  else return(stringexpr)
  }

## an example cubic polynomial with coefficients 0.1, 0.2, 0.3, 0.4
cubic <- f(pc = 1:4 / 10, TRUE)

## using R base's `D` (requiring expression)
dcubic <- D(cubic, name = "x")
# 0.2 + 2 * x * 0.3 + 3 * x^2 * 0.4

## using `Deriv::Deriv`
library(Deriv)

dcubic <- Deriv(cubic, x = "x", nderiv = 1L)
# expression(0.2 + x * (0.6 + 1.2 * x))

Deriv(f(1:4 / 10, FALSE), x = "x", nderiv = 1L)  ## use string, get string
# [1] "0.2 + x * (0.6 + 1.2 * x)"

Of course, Deriv makes higher order derivatives easier to get. We can simply set nderiv. For D however, we have to use recursion (see examples of ?D).

Deriv(cubic, x = "x", nderiv = 2L)
# expression(0.6 + 2.4 * x)

Deriv(cubic, x = "x", nderiv = 3L)
# expression(2.4)

Deriv(cubic, x = "x", nderiv = 4L)
# expression(0)

If we use expression, we will be able to evaluate the result later. For example,

eval(cubic, envir = list(x = 1:4))  ## cubic polynomial
# [1]  1.0  4.9 14.2 31.3

eval(dcubic, envir = list(x = 1:4))  ## its first derivative
# [1]  2.0  6.2 12.8 21.8

The above implies that we can wrap up an expression for a function. Using a function has several advantages, one being that we are able to plot it using curve or plot.function.

fun <- function(x, expr) eval.parent(expr, n = 0L)

Note, the success of fun requires expr to be an expression in terms of symbol x. If expr was defined in terms of y for example, we need to define fun with function (y, expr). Now let's use curve to plot cubic and dcubic, on a range 0 < x < 5:

curve(fun(x, cubic), from = 0, to = 5)  ## colour "black"
curve(fun(x, dcubic), add = TRUE, col = 2)  ## colour "red"

The most convenient way, is of course to define a single function FUN rather than doing f + fun combination. In this way, we also don't need to worry about the consistency on the variable name used by f and fun.

FUN <- function (x, pc, nderiv = 0L) {
  ## check missing arguments
  if (missing(x) || missing(pc)) stop ("arguments missing with no default!")
  ## expression of polynomial
  stringexpr <- paste("x", seq_along(pc) - 1, sep = " ^ ")
  stringexpr <- paste(stringexpr, pc, sep = " * ")
  stringexpr <- paste(stringexpr, collapse = " + ")
  expr <- parse(text = stringexpr)
  ## taking derivatives
  dexpr <- Deriv::Deriv(expr, x = "x", nderiv = nderiv)
  ## evaluation
  val <- eval.parent(dexpr, n = 0L)
  ## note, if we take to many derivatives so that `dexpr` becomes constant
  ## `val` is free of `x` so it will only be of length 1
  ## we need to repeat this constant to match `length(x)`
  if (length(val) == 1L) val <- rep.int(val, length(x))
  ## now we return
  val
  }

Suppose we want to evaluate a cubic polynomial with coefficients pc <- c(0.1, 0.2, 0.3, 0.4) and its derivatives on x <- seq(0, 1, 0.2), we can simply do:

FUN(x, pc)
# [1] 0.1000 0.1552 0.2536 0.4144 0.6568 1.0000

FUN(x, pc, nderiv = 1L)
# [1] 0.200 0.368 0.632 0.992 1.448 2.000

FUN(x, pc, nderiv = 2L)
# [1] 0.60 1.08 1.56 2.04 2.52 3.00

FUN(x, pc, nderiv = 3L)
# [1] 2.4 2.4 2.4 2.4 2.4 2.4

FUN(x, pc, nderiv = 4L)
# [1] 0 0 0 0 0 0

Now plotting is also easy:

curve(FUN(x, pc), from = 0, to = 5)
curve(FUN(x, pc, 1), from = 0, to = 5, add = TRUE, col = 2)
curve(FUN(x, pc, 2), from = 0, to = 5, add = TRUE, col = 3)
curve(FUN(x, pc, 3), from = 0, to = 5, add = TRUE, col = 4)

这篇关于任意阶次多项式的函数(首选符号方法)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆