Commons Math学习笔记——多项式函数

系统 1872 0

2.2 多项式函数

看其他篇章到 目录 选择。

Commons Math 中的 analysis.polynomials 包中有所有的与多项式函数相关的类和接口定义。这一篇主要从这个包分析,来研究一下多项式函数的应用。

Commons Math学习笔记——多项式函数

 

Polynomials 包中没有 interface 的定义,下属含有 5 个类: PolynomialFunction PolynomialFunctionLagrangeForm PolynomialFunctionNewtonForm PolynomialSplineFunction PolynomialsUtils 。其中主要的只有 PolynomialFunction PolynomialSplineFunction ,正如 api doc 中的介绍, PolynomialFunction 类是 Immutable representation of a real polynomial function with real coefficients ——实数多项式的表示; PolynomialSplineFunction 类是 Represents a polynomial spline function. ——样条曲线多项式的表示。另外两个表示拉格朗日和牛顿形式的多项式函数。而 PolynomialsUtils 类中提供了几个构造个别(比如切比雪夫多项式)多项式的静态方法。

我觉得最常用的应该就是实数系数的多项式了,因此以 PolynomialFunction 类为例来进行分析。实数系数的多项式函数形如: f(x) = ax^2 + bx + c PolynomialFunction 类实现了 DifferentiableUnivariateRealFunction 接口,因此必须实现 value() derivative() 方法,并且实现该接口也表明这是一元可微分的实数函数形式。 PolynomialFunction 类定义了一组 final double coefficients[] 作为多项式系数,其中 coefficients[0] 表示常数项的系数, coefficients[n] 表示指数为 n x^n 次项的系数。因此,这个类所表达的多项式函数是这样的: f(x)=coeff[0] + coeff[1]x + coeff[2]x^2 + … + coeff[n]x^n 。它的构造方法是 PolynomialFunction(double []) 就是接受这样的 coefficients 数组作为系数输入参数来构造多项式的。这个是很好表达也很方便理解的。那么它的 value(double x) 方法是通过调用 double evaluate( double [] coefficients, double argument) 实现的,本质用 Horner's Method 求解多项式的值,没有什么技术难点,非常好理解的一个给定参数和函数求值过程。剩余定义的一些加减乘等操作,都是通过一个类似public PolynomialFunction add( final PolynomialFunction p) 这样的结构实现的。求导数的方法 derivative() 是通过这样的一个微分操作实现的。见源码:

 

 
 1 protected   static   double [] differentiate( double [] coefficients)  {
 2          int  n  =  coefficients.length;
 3          if  (n  <   1 {
 4              throw  MathRuntimeException.createIllegalArgumentException( " empty polynomials coefficients array " );
 5         }

 6          if  (n  ==   1 {
 7              return   new   double [] { 0 } ;
 8         }

 9          double [] result  =   new   double [n  -   1 ];
10          for  ( int  i  =  n  -   1 ; i   >   0 ; i -- {
11             result[i  -   1 =  i  *  coefficients[i];
12         }

13          return  result;
14     }

15
 

测试代码示例如下:

 1 /** */ /**
 2  * 
 3   */

 4 package  algorithm.math;
 5
 6 import  org.apache.commons.math.ArgumentOutsideDomainException;
 7 import  org.apache.commons.math.analysis.polynomials.PolynomialFunction;
 8 import  org.apache.commons.math.analysis.polynomials.PolynomialSplineFunction;
 9
10 /** */ /**
11  *  @author  Jia Yu
12  * @date 2010-11-21
13   */

14 public   class  PolinomialsFunctionTest  {
15
16      /** */ /**
17      *  @param  args
18       */

19      public   static   void  main(String[] args)  {
20          //  TODO Auto-generated method stub
21         polynomials();
22         System.out.println( " ----------------------------------------------- " );
23         polynomialsSpline();
24     }

25
26      private   static   void  polynomialsSpline()  {
27          //  TODO Auto-generated method stub
28         PolynomialFunction[] polynomials  =   {
29                  new  PolynomialFunction( new   double []  { 0d, 1d, 1d } ),
30                  new  PolynomialFunction( new   double []  { 2d, 1d, 1d } ),
31                  new  PolynomialFunction( new   double []  { 4d, 1d, 1d } ) }
;
32          double [] knots  =   - 1 0 1 2  } ;
33         PolynomialSplineFunction spline  =   new  PolynomialSplineFunction(knots,
34                 polynomials);
35          // output directly
36         System.out.println( " poly spline func is  " + spline);
37          //  get the value when x = 0.5
38          try   {
39             System.out.println( " f(0.5) =  " + spline.value( 0.5 ));
40         }
  catch  (ArgumentOutsideDomainException e)  {
41              //  TODO Auto-generated catch block
42             e.printStackTrace();
43         }

44          //  the number of spline segments
45         System.out.println( " spline segments number is  " + spline.getN());
46          //  the polynomials functions
47          for ( int  i = 0 ;i < spline.getN();i ++ ) {
48             System.out.println( " spline:f " + i + " (x) =  " + spline.getPolynomials()[i]);
49         }

50          // function derivative
51         System.out.println( " spline func derivative is  " + spline.derivative());
52     }

53
54      private   static   void  polynomials()  {
55          //  TODO Auto-generated method stub
56          double [] f1_coeff  =   3.0 6.0 - 2.0 1.0  } ;
57          double [] f2_coeff  =   1.0 2.0 - 1.0 - 2.0  } ;
58         PolynomialFunction f1  =   new  PolynomialFunction(f1_coeff);
59         PolynomialFunction f2  =   new  PolynomialFunction(f2_coeff);
60          //  output directly
61         System.out.println( " f1(x) is :  "   +  f1);
62         System.out.println( " f2(x) is :  "   +  f2);
63          //  polynomial degree
64         System.out.println( " f1(x)'s degree is  "   +  f1.degree());
65          //  get the value when x = 2
66         System.out.println( " f1(2) =  "   +  f1.value( 2 ));
67          //  function add
68         System.out.println( " f1(x)+f2(x) =  "   +  f1.add(f2));
69          //  function substract
70         System.out.println( " f1(x)-f2(x) =  "   +  f1.subtract(f2));
71          //  function multiply
72         System.out.println( " f1(x)*f2(x) =  "   +  f1.multiply(f2));
73          //  function derivative
74         System.out.println( " f1'(x) =  "   +  f1.derivative());
75         System.out.println( " f2''(x) =  "
76                  +  ((PolynomialFunction) f2.derivative()).derivative());
77
78     }

79
80 }

81


输出如下:
f1(x) is : 3.0 + 6.0 x - 2.0 x^2 + x^3
f2(x) is : 1.0 + 2.0 x - x^2 - 2.0 x^3
f1(x)'s degree is 3
f1(2) = 15.0
f1(x)+f2(x) = 4.0 + 8.0 x - 3.0 x^2 - x^3
f1(x)-f2(x) = 2.0 + 4.0 x - x^2 + 3.0 x^3
f1(x)*f2(x) = 3.0 + 12.0 x + 7.0 x^2 - 15.0 x^3 - 8.0 x^4 + 3.0 x^5 - 2.0 x^6
f1'(x) = 6.0 - 4.0 x + 3.0 x^2
f2''(x) = -2.0 - 12.0 x
-----------------------------------------------
poly spline func is org.apache.commons.math.analysis.polynomials.PolynomialSplineFunction@69b332
f(0.5) = 2.75
spline segments number is 3
spline:f0(x) = x + x^2
spline:f1(x) = 2.0 + x + x^2
spline:f2(x) = 4.0 + x + x^2
spline func derivative is org.apache.commons.math.analysis.polynomials.PolynomialSplineFunction@173a10f

PolynomialFunction 类也是重写了 toString 方法和 hashCode equals 方法的。

PolynomialSplineFunction 类是多项式样条函数, 样条 是一种特殊的函数,由多项式分段定义。表示了一个由多个多项式组成的样条曲线。它的实现主要是内部定义了一个多项式函数组 PolynomialFunction polynomials[] 和一个样条分界节点数组 double knots[] 。这两个内部成员分别表示什么呢?分界节点表示整条曲线对应在 x 等于 knots[i] 的时候开始使用其他多项式样条,其构造方法 public PolynomialSplineFunction( double knots[], PolynomialFunction polynomials[]) 完成这样的功能。

举例来说,一个多项式样条函数就是一个分段函数:

      X^2+x    [-1,0)

F(x) = x^2+x+2   [0,1)

      X^2+x+4 [1,2)

当然,构造方法中的参数, knots[] 数组必须是递增的。

可以看到,直接输出 PolynomialSplineFunction 是多么丑陋啊 ~~ ,因为它没有重写 toString 方法。同样,它的导数也是一样的丑陋。其中如果给定的值不在定义域内, value 方法还抛出异常 ArgumentOutsideDomainException

最后 PolynomialFunctionLagrangeForm PolynomialFunctionNewtonForm 类完成的其实是多项式插值的功能,放到下一节研究的。

相关资料:

多项式: http://zh.wikipedia.org/zh-cn/%E5%A4%9A%E9%A1%B9%E5%BC%8F%E5%87%BD%E6%95%B0#.E5.A4.9A.E9.A0.85.E5.BC.8F.E5.87.BD.E6.95.B8.E5.8F.8A.E5.A4.9A.E9.A0.85.E5.BC.8F.E7.9A.84.E6.A0.B9

样条函数: http://zh.wikipedia.org/zh-cn/%E6%A0%B7%E6%9D%A1%E5%87%BD%E6%95%B0

Horner Methods http://mathworld.wolfram.com/HornersMethod.html

Commons math 包: http://commons.apache.org/math/index.html

Commons Math学习笔记——多项式函数


更多文章、技术交流、商务合作、联系博主

微信扫码或搜索:z360901061

微信扫一扫加我为好友

QQ号联系: 360901061

您的支持是博主写作最大的动力,如果您喜欢我的文章,感觉我的文章对您有帮助,请用微信扫描下面二维码支持博主2元、5元、10元、20元等您想捐的金额吧,狠狠点击下面给点支持吧,站长非常感激您!手机微信长按不能支付解决办法:请将微信支付二维码保存到相册,切换到微信,然后点击微信右上角扫一扫功能,选择支付二维码完成支付。

【本文对您有帮助就好】

您的支持是博主写作最大的动力,如果您喜欢我的文章,感觉我的文章对您有帮助,请用微信扫描上面二维码支持博主2元、5元、10元、自定义金额等您想捐的金额吧,站长会非常 感谢您的哦!!!

发表我的评论
最新评论 总共0条评论