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

4
我在使用Apache Commons Math库时遇到了问题。我只想创建像f(x) = 4x^2 + 2x这样的函数,并且我想计算该函数的导数 --> f'(x) = 8x + 2。
我阅读了关于微分的文章(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);

在第5行显然出现了编译错误。函数f(x)被调用但未定义。我错在哪里了? 有没有人使用过apache commons math库进行微分/导数,或者有没有其他库/框架可以帮助我?谢谢。

这可能是因为方法f和变量x不存在。 - Lews Therin
1
是的,这个方法并不存在,但这只是apache commons math网站上的一个例子。它们的目的是什么?展示一个使用的函数未定义的例子吗? - Tobi Weißhaar
2个回答

4
在上面的段落中,作者描述了创建DerivativeStructure的方法。这并不是魔法。在你引用的例子中,有人应该编写函数f。嗯,那并不是很清楚。
引用块中提到,用户可以通过几种方式创建UnivariateDifferentiableFunction接口的实现。第一种方法是直接使用DerivativeStructure的适当方法来计算加法、减法、正弦、余弦等,这通常非常简单,无需记住微分规则:用户代码仅表示函数本身,差分将在幕后自动计算。第二种方法是编写经典的UnivariateFunction,并将其传递给现有的UnivariateFunctionDifferentiator接口实现,以检索相同函数的差分版本。第一种方法更适合于小型函数,用户已经控制所有基础代码。第二种方法更适合于大型函数,使用DerivativeStructure API编写这些函数会很麻烦,或者对于用户无法完全控制基础代码的函数(例如调用外部库的函数)。使用第一种方法。
// 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));

Commons-math有更简单的创建数学函数的方法,但是DerivativeStructure是获取导数的方法。是的,我知道文档非常晦涩。 - Eric Jablow
我想知道是谁想出了这种区分方式?不是数学家或物理学家。 - Aksakal almost surely binary

3
以下Apache邮件列表中的帖子似乎说明了如何定义UnivariateDifferentiableFunction的导数的两种可能方式。我正在添加一个新答案,因为我无法对先前的答案进行评论(声望不足)。
所使用的函数样本规范是f(x)=x^2。
(1) 使用DerivativeStructure:
public DerivativeStructure value(DerivativeStructure t) {
     return t.multiply(t);
}

(2)通过编写经典的UnivariateFunction:

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

如果我理解正确,第一种情况的优点在于不需要像第二种情况那样手动获取导数。如果已知导数,则定义DerivativeStructure没有任何优势,对吗?我考虑的应用是牛顿-拉弗森求解器,通常需要知道函数值及其导数。
完整示例可在上述网站(作者为Thomas Neidhart和Franz Simons)中找到。欢迎提出任何进一步的评论!

1
第二种解决方案可能存在两个问题:(i) 在当前版本的math3中,类“UnivariateRealFunction”似乎已被替换为“UnivariateFunction”。(ii) 第二对括号可能缺少一个分号来关闭。 - Unis

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接