找到导数的算法

时间:2009-11-22 20:23:59

标签: math calculus derivative

我正在用Python编写程序,我需要找到函数的派生(表示为字符串的函数)。

  • 例如:x^2+3*x
  • 其衍生物为:2*x+3

是否有可用的脚本,或者有什么有用的东西可以告诉我吗?

10 个答案:

答案 0 :(得分:5)

sympy做得很好。

答案 1 :(得分:5)

如果你只限于多项式(看起来是这种情况),基本上会有三个步骤:

  1. 将输入字符串解析为x ^ n
  2. 的系数列表
  3. 取出系数列表,并根据导出多项式的规则将它们转换为新的系数列表。
  4. 获取导数的系数列表,并创建一个描述导数多项式函数的精美字符串。
  5. 如果你需要像a*x^15125 + x^2 + c那样处理多项式,那么使用dict作为系数列表可能有意义,但是在通过这个列表进行迭代时需要多一些注意。

答案 2 :(得分:4)

您可以在已提供的答案中找到您要找的内容。但是,我想就如何计算符号导数做一个简短的解释。

该业务基于运营商重载和衍生产品链规则。例如,v^n的导数是n*v^(n-1)dv/dx,对吗?那么,如果你有v=3*xn=3,衍生品会是什么?答案:如果是f(x)=(3*x)^3,那么衍生物是:

f'(x)=3*(3*x)^2*(d/dx(3*x))=3*(3*x)^2*(3)=3^4*x^2

链规则允许您“链接”操作:每个单独的衍生物都很简单,而您只是“链接”复杂性。另一个例子,u*v的衍生物是v*du/dx+u*dv/dx,对吗?如果你得到一个复杂的功能,你只需链接它,比如说:

d/dx(x^3*sin(x))
u=x^3; v=sin(x)
du/dx=3*x^2; dv/dx=cos(x)
d/dx=v*du+u*dv

正如您所看到的,差异化只是一系列简单的操作。

现在,运营商重载。

如果您可以编写解析器(尝试Pyparsing),那么您可以请求它来评估函数和派生!我这样做(使用Flex / Bison)只是为了好玩,它非常强大。为了得到这个想法,通过重载相应的运算符递归计算导数,并递归地应用链规则,因此"*"的评估将对应于函数值u * v和u*der(v)+v*der(u)衍生价值(在C ++中试用,也很有趣)。

所以你去,我知道你不是要编写自己的解析器 - 一定要使用现有代码(访问www.autodiff.org以自动区分Fortran和C / C ++代码)。但知道这些东西是如何运作总是很有趣。

干杯,

答案 3 :(得分:3)

Symbolic Differentiation是一个令人印象深刻的主题介绍 - 至少对于像我这样的非专家:)代码是用C ++编写的。

答案 4 :(得分:3)

答案 5 :(得分:3)

迟到总比没有好?

我总是通过使用解析树来完成任何语言的符号区分。 但我最近也发现了另一种使用complex numbers的方法。

解析树方法包括将以下微小的Lisp代码翻译成您喜欢的任何语言:

(defun diff (s x)(cond
  ((eq s x) 1)
  ((atom s) 0)
  ((or (eq (car s) '+)(eq (car s) '-))(list (car s)
    (diff (cadr s) x)
    (diff (caddr s) x)
    ))
  ; ... and so on for multiplication, division, and basic functions
  ))

并使用适当的简化器跟随它,所以你摆脱了0的加法,乘以1等。

但复杂的方法,虽然完全是数字,但具有一定的神奇品质。不是以双精度编程计算F,而是在双精度复合体中进行。 然后,如果您需要关于变量X的计算的导数,请将X的虚部设置为非常小的数字h,如1e-100。 然后进行计算并得到结果R. 现在,真实(R)是你通常得到的结果,而成像(R)/ h = dF / dX 准确度非常高!

它是如何工作的?以复数的乘法为例:

(a+bi)(c+di) = ac + i(ad+bc) - bd

现在假设虚部都是零,除了我们想要a的导数。 我们将b设置为非常小的数字h。现在我们得到了什么?

(a+hi)(c) = ac + hci

所以真正的部分是ac,正如您所期望的那样,虚部除以h,是c,它是ac的衍生物。关于a

同样的推理似乎适用于所有差异化规则。

答案 6 :(得分:1)

如果您正在考虑从头开始编写差异化程序,而不使用其他库作为帮助,那么计算my blog中描述的任何代数方程的导数的算法/方法将会有所帮助。

答案 7 :(得分:0)

您可以尝试创建一个严格表示限制的类,然后在x接近a时对其求值(f(x)-f(a))/(x-a)。这应该给出一个非常准确的限制值。

答案 8 :(得分:0)

如果您使用字符串作为输入,您可以使用 + 或 - 字符作为分隔符来分隔各个术语,这将为您提供各个术语。现在你可以使用幂律来求解每个项,假设你有 x^3,使用幂律会给你 3x^2,或者假设你有一个更复杂的项,比如 a/(x^3) 或 a(x^ -3),同样你可以将其他变量作为一个常数单独选出,现在求解 x^-3 会给你 -3a/(x^2)。单独的幂规则应该足够了,但是它需要大量使用因式分解。

答案 9 :(得分:-1)

除非任何已经创建的库派生它非常复杂,因为你需要解析和处理函数和表达式。

单独导出这是一项简单的任务,因为它是机械的,可以通过算法完成,但是你需要一个基本结构来存储函数。