使用离散方法计算导数
我正在寻找一种使用离散且快速的方法来计算导数的方法。 由于现在我不知道方程的类型,因此我正在寻找类似于我们可以找到的积分方法的离散方法,例如欧拉方法。
I am looking for a method to compute a derivative using a discrete and fast method. Since now I do not know the type of equation I have, I am looking for discrete methods analog to the ones that we can find for the integral such as, the Euler method.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(10)
我认为您正在寻找以点计算的导数。
如果是这种情况,这里有一个简单的方法可以做到这一点。 您需要知道一点的导数,例如a。 它由 h->0 的差商极限给出:
你实际上需要实现 limit 函数。 所以你:
现在DO-WHILE 循环:
1- 将 h 除以 2(或除以 10,重要的是使其更小)
2-再次计算与h的新值的差商,将其存储在f2
3-设置diff = abs(f2-f1)
4-分配f1 = f2
5- 从点 1 开始重复 while (diff>epsilon)
记住:
您假设该函数在 a 中可微。
由于计算机可以处理的有限十进制数字的错误,您得到的每个结果都将是错误的,这是无法避免的。
python 中的示例:
输出:
由于仅使用结果的前 6 位数字,我第一次得到“精确”值,请注意我使用 1e-7 作为 epsilon。之后将打印 REAL 计算值,并且它们epsilon 的大小显然在数学上是错误的。
I think you are looking for the derivative calculated in a point.
If this is the case, here there is a simple way to do that. You need to know the derivative in a point, say a. It is given by the limit of the difference quotient for h->0:
You actually need to implement the limit function. So you:
Now in a DO-WHILE loop:
1- divide h by 2 (or by 10, the important thing is to make it smaller)
2- calculate again the difference quotient with the new value of h, store this in f2
3- set diff = abs(f2-f1)
4- assign f1 = f2
5- repeat from point 1 while (diff>epsilon)
Remember:
You are assuming the function is differentiable in a.
Every result you will get will be wrong due of errors of the finite decimal digit your computer can handle, there is no escape from this.
Example in python:
Output:
The first time I've got "precise" value" because of using only the first 6 digits of the result, note I used 1e-7 as epsilon. The REAL calculated values are printed after that, and they are obviously mathematically wrong. The choose of how small epsilon is depends on how precise you want your results to be.
在计算数值(“有限”)导数方面有相当多的理论(和既定实践)。 确保所有细节正确,让您相信结果,这并非易事。 如果有任何方法可以获得该函数的分析导数(使用笔和纸,或计算机代数系统,例如 Maple ,Mathematica,Sage,或 SymPy),这是由迄今为止最好的选择。
如果您无法获得解析形式,或者您不知道函数(只是它的输出),那么数值估计是您唯一的选择。 C 语言数值复习中的章节是一个好的开始。
There is quite a bit of theory (and established practice) in calculating numerical ("finite") derivatives. Getting all the details correct, such that you believe the result, is not trivial. If there's any way you can get the analytical derivative of the function (using pen and paper, or a computer algebra system such as Maple, Mathematica, Sage, or SymPy), this is by far the best option.
If you can't get the analytical form, or you don't know the function (just it's output), then numerical estimation are your only option. This chapter in Numerical Recipies in C is a good start.
一个简单的方法是计算您感兴趣的导数的每个点的 f 对小值的变化。例如,要计算 ∂f/∂x,您可以使用以下方法:
y 中的其他偏项将类似和z。
为 epsilon 选择的值取决于 f 的内容、所需的精度、使用的浮点类型以及可能的其他因素。 我建议您使用您感兴趣的函数来尝试它的值。
A simple method is to compute the change in f over a small value for each point of the derivative you're interested in. For example, to compute ∂f/∂x, you could use this:
The other partials would be similar in y and z.
The value chosen for epsilon depends on the contents of f, the precision required, the floating point type used, and probably other things. I suggest you experiment with values for it with functions you're interested in.
要进行数值微分(始终是近似值),有两种常见情况:
f'(a) = { f(a+h)-f(ah) } / 2h
这被称为中心差异。
f'n = (fn+1 - fn-1)/2h,
其中 h 是 xn 值之间的相等间距。
*Andrea的答案使用前向差分算子{f(a+h) - f(a)}/h而不是中心差分算子{f(a+h) - f(ah)}/2h,但是前向差分算子在数值解中不太准确。
To do numerical differentiation, which is always an approximation, there are two common scenarios:
f'(a) = { f(a+h)-f(a-h) } / 2h
This is known as a central difference.
f'n = (fn+1 - fn-1)/2h,
where h is the equal spacing between the values of xn.
* Andrea's answer uses the forward difference operator {f(a+h) - f(a)}/h instead of the central difference operator {f(a+h) - f(a-h)}/2h, but the forward difference operator is less accurate in numerical solutions.
如果不使用像 Maple 这样的符号数学语言,你能做的最好的就是在不同的点上近似导数。 (然后插入,如果你需要一个函数。)
如果你已经有了你想要使用的函数,那么你应该使用 向后除差论坛,以及Richardson 外推 来改善您的错误。
另请记住,这些方法适用于一个变量的函数。 然而,每个变量的偏导数将其他变量视为常数。
Short of using a symbolic math language, like Maple, the best you can do is to approximate the derivative at various points. (And then interpolate, if you need a function.)
If you've already got the function you want to use, then you should use the backward divided-difference forumla, and Richardson extrapolation to improve your error.
Also keep in mind that these methods work on functions of one variable. However, partial derivatives of each variable treat the other variables as constants.
自动微分是执行此类操作的最准确且概念上最棒的方法。 只是稍微复杂一点。
Automatic differentiation is the most accurate and conceptually awesome way of doing this kind of thing. Just a bit more complicated.
正式来说,不。 您要么描述离散函数的(偏)导数,要么要求一种数值方法来近似连续函数的(偏)导数。
离散函数没有导数。 如果您查看导数的 epsilon-delta 定义,您会发现您需要能够计算接近您想要导数的点的函数。 如果函数仅具有 x、y 和 z 整数值,则这是没有意义的。 因此,对于任何快速值,都无法找到离散函数的导数。
如果您想要一种数值方法精确计算连续函数的导数,那么您也运气不好。 导数的数值方法是启发式的,而不是算法式的。 没有任何数值方法可以保证精确的解。 幸运的是,存在许多好的启发方法。 Mathematica 默认使用 布伦特主轴法 的专用版本。 我建议您使用 GNU 科学库,它很好地实现了布伦特方法。 我的一门数学课程的全部成绩都归功于 GSL。 如果您喜欢的话,红宝石绑定非常好。 如果有必要,大多数数值微分库都有一些不同的方法可用。
如果你真的想要,我可以拿出一些示例代码。 让我知道。
Formally, no. Either you are describing the (partial) derivitives of discrete functions or you are asking for a numerical method to approximate the (partial) derivatives of continuous functions.
Discrete functions don't have derivatives. If you review the epsilon-delta definition of a derivative, you will see that you would need to be able to evaluate the function close to the point you want the derivative at. That doesn't make sense if the function only has values at integer values of x, y and z. So there is no way to find the derivative of a discrete function for any value of fast.
If you want a numerical method exactly calculate the derivatives of a continuous function, you're out of luck as well. Numerical methods for derivatives are heuristic, not algorithmic. There is no numerical method which guarantees an exact solution. Fortunately, there exist many good heuristics. Mathematica uses a specialized version of Brent's principle axis method by default. I would recommend you use the GNU Scientific Library, which has a very good implementation of Brent's method. I owe my entire grade in one of my math courses to the GSL. The ruby bindings are pretty good if that's your thing. If necessary, most numerical differentiation libraries have a handful of different methods available.
If you really want, I can whip out some sample code. Let me know.
我假设您的函数比您发布的简单函数更复杂,因为封闭式解决方案太简单了。
当您使用“离散”这个词时,我认为您需要“有限差异”。 您需要一些离散化来计算近似值。
Df/Dx ~ (f2-f1)/(x2-x1) 等
I'll assume that your function is more complex than the simple one you posted, because the closed-form solution is far too simple.
When you use the word "discrete" it makes me think you need "finite differences". You'll need some discretization to calculate the approximation.
Df/Dx ~ (f2-f1)/(x2-x1), etc.
我希望这可能会有所帮助数值微分。
I hope this may be helpful NUMERICAL DIFFERENTIATION.
如果函数如您所指出的那样是线性的,那么导数是微不足道的。 'x' 的导数是 'a'; 关于“y”的导数是“b”,关于“z”的导数是“c”。 如果方程具有更复杂的形式,并且您需要一个代表解的公式而不是经验解,那么请提交更复杂的方程形式。
问候
If the function is linear as you have indicated then the derivatives are trivial. The derivative with respect to 'x' is 'a'; the derivative with respect to 'y' is 'b' and the derivative with respect to 'z' is 'c'. If the equation is of a more complex form and you need a formula representing the solution rather than an empirical solution, then please submit the more complex form of the equation.
Regards