Java - 使用 Apache Commons 数学库计算导数

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/16781563/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-31 23:59:47  来源:igfitidea点击:

Java - Computation of Derivations with Apache Commons Mathematic Library

javaderivativedifferentiationapache-commons-mathautomatic-differentiation

提问by Tobi Wei?haar

I have a problem in using the apache commons math library.
I just want to create functions like f(x) = 4x^2 + 2x and I want to compute the derivative of this function
--> f'(x) = 8x + 2

我在使用 apache commons 数学库时遇到问题。
我只想创建像 f(x) = 4x^2 + 2x 这样的函数,我想计算这个函数的导数
--> f'(x) = 8x + 2

I read the article about Differentiation (http://commons.apache.org/proper/commons-math/userguide/analysis.html, section 4.7).
There is an example which I don't understand:

我阅读了关于区分的文章(http://commons.apache.org/proper/commons-math/userguide/analysis.html,第 4.7 节)。
有一个我不明白的例子:

int params = 1;
int order = 3;
double xRealValue = 2.5;
DerivativeStructure x = new DerivativeStructure(params, order, 0, xRealValue);
DerivativeStructure y = f(x);                    //COMPILE ERROR
System.out.println("y    = " + y.getValue();
System.out.println("y'   = " + y.getPartialDerivative(1);
System.out.println("y''  = " + y.getPartialDerivative(2);
System.out.println("y''' = " + y.getPartialDerivative(3);

In Line 5 a compile error occurs of course. The function f(x)is called and not defined. What I am getting wrong?
Has anyone any experience with the differentiation/derivation with the apache commons math library or does anyone know another library/framework which can help me?

在第 5 行中,当然会发生编译错误。该函数f(x)被调用但未定义。我哪里错了?
有没有人对 apache commons 数学库的微分/推导有任何经验,或者有没有人知道另一个可以帮助我的库/框架?

Thanks

谢谢

回答by Eric Jablow

In the paragraph below that example, the author describes ways to create DerivativeStructures. It isn't magic. In the example you quoted, someone was supposed to write the function f. Well, that wasn't very clear.

在该示例下面的段落中,作者描述了创建DerivativeStructures 的方法。这不是魔法。在您引用的示例中,应该有人编写函数f。嗯,那不是很清楚。

There are several ways a user can create an implementation of the UnivariateDifferentiableFunction interface. The first method is to simply write it directly using the appropriate methods from DerivativeStructure to compute addition, subtraction, sine, cosine... This is often quite straigthforward and there is no need to remember the rules for differentiation: the user code only represent the function itself, the differentials will be computed automatically under the hood. The second method is to write a classical UnivariateFunction and to pass it to an existing implementation of the UnivariateFunctionDifferentiator interface to retrieve a differentiated version of the same function. The first method is more suited to small functions for which user already control all the underlying code. The second method is more suited to either large functions that would be cumbersome to write using the DerivativeStructure API, or functions for which user does not have control to the full underlying code (for example functions that call external libraries).

用户可以通过多种方式创建 UnivariateDifferentiableFunction 接口的实现。第一种方法是直接使用 DerivativeStructure 中的适当方法直接编写它来计算加法、减法、正弦、余弦……这通常很直接,无需记住微分规则:用户代码仅表示函数本身,差异将在引擎盖下自动计算。第二种方法是编写一个经典的 UnivariateFunction 并将其传递给 UnivariateFunctionDifferentiator 接口的现有实现,以检索同一函数的差异版本。第一种方法更适合用户已经控制所有底层代码的小功能。

Use the first idea.

使用第一个想法。

// Function of 1 variable, keep track of 3 derivatives with respect to that variable,
// use 2.5 as the current value.  Basically, the identity function.
DerivativeStructure x = new DerivativeStructure(1, 3, 0, 2.5);
// Basically, x --> x^2.
DerivativeStructure x2 = x.pow(2);
//Linear combination: y = 4x^2 + 2x
DerivativeStructure y = new DerivativeStructure(4.0, x2, 2.0, x);
System.out.println("y    = " + y.getValue());
System.out.println("y'   = " + y.getPartialDerivative(1));
System.out.println("y''  = " + y.getPartialDerivative(2));
System.out.println("y''' = " + y.getPartialDerivative(3));

回答by Unis

The following thread from the Apache mailing listseems to illustrate the two possible ways of how the derivative of a UnivariateDifferentiableFunction can be defined. I am adding a new answer as I'm unable to comment on the previous one (insufficient reputation).

Apache 邮件列表中的以下线程似乎说明了如何定义 UnivariateDifferentiableFunction 的派生类的两种可能方式。我正在添加一个新答案,因为我无法评论前一个(声誉不足)。

The used sample specification of the function is f(x) = x^2.

该函数使用的样本规范是 f(x) = x^2。

(1) Using a DerivativeStructure:

(1) 使用派生结构:

public DerivativeStructure value(DerivativeStructure t) {
     return t.multiply(t);
}

(2) By writing a classical UnivariateFunction:

(2) 通过写一个经典的 UnivariateFunction:

public UnivariateRealFunction derivative() {
    return new UnivariateRealFunction() {
          public double value(double x) {
                // example derivative
                return 2.*x;
          }
     }
}

If I understand well, the advantage of the first case is that the derivative does not need to be obtained manually, as in the second case. In case the derivative is known, there should thus be no advantage of defining a DerivativeStructure, right? The application I have in mind is that of a Newton-Raphson solver, for which generally the function value and its derivative need to be known.

如果我理解的很好,第一种情况的优点是不需要像第二种情况那样手动获取导数。如果导数是已知的,那么定义 DerivativeStructure 应该没有优势,对吗?我想到的应用是 Newton-Raphson 求解器,通常需要知道函数值及其导数。

The full example is provided on the aforementioned web site (authors are Thomas Neidhart and Franz Simons). Any further comments are most welcome!

上述网站提供了完整的示例(作者是 Thomas Neidhart 和 Franz Simons)。欢迎任何进一步的评论!