Change Dir

          先知cd——熱愛生活是一切藝術的開始

          統計

          留言簿(18)

          積分與排名

          “牛”們的博客

          各個公司技術

          我的鏈接

          淘寶技術

          閱讀排行榜

          評論排行榜

          Commons Math學習筆記——函數方程求解

           

          看其他篇章到目錄選擇。

          函數方程求解,其實是函數的零點問題,也就是說函數的曲線與X軸的交點。對于線性方程,我們可以輕易的求解,對于線性方程組,利用前面講過的的矩陣分解方法也可以求解。那么對于函數表達的很多非線性方程的求解。我們要依賴數值算法。Commons Math包中專門有一個analysis.solver包來解決這個問題。

          Analysis.solver包中有一個基本接口類——UnivariateRealSolver,其中定義了一系列接口方法,最重要的方法就是double solve(UnivariateRealFunction f, double min, double max)了。很明顯,這個方法的參數是函數的表達式以及求解的區間范圍,返回值是函數在區間內的一個零值點。

          Solver包中的這些類的組織結構形式與積分中的類似,結構類圖如下:


           

          具體的求解算法有很多,solver包中也實現了很多算法,包括對分法、牛頓法等。我們這里以這兩個算法的實現為例,看看該如何使用這個包中的接口方法。待求解的函數仍以正弦函數為例。

           

           1/**
           2 * 
           3 */

           4package algorithm.math;
           5
           6import org.apache.commons.math.ConvergenceException;
           7import org.apache.commons.math.FunctionEvaluationException;
           8import org.apache.commons.math.analysis.UnivariateRealFunction;
           9import org.apache.commons.math.analysis.solvers.BisectionSolver;
          10import org.apache.commons.math.analysis.solvers.UnivariateRealSolver;
          11import org.apache.commons.math.analysis.solvers.UnivariateRealSolverFactory;
          12import org.apache.commons.math.analysis.solvers.UnivariateRealSolverFactoryImpl;
          13
          14/**
          15 * @author Jia Yu
          16 * @date   2010-11-24
          17 */

          18public class SolverTest {
          19
          20    /**
          21     * @param args
          22     */

          23    public static void main(String[] args) {
          24        // TODO Auto-generated method stub
          25        solver();
          26        factorySolver();
          27    }

          28
          29    private static void factorySolver() {
          30        // TODO Auto-generated method stub
          31        UnivariateRealFunction f = new SinFunction();
          32        UnivariateRealSolverFactory factory=new UnivariateRealSolverFactoryImpl();
          33        UnivariateRealSolver solver = factory.newNewtonSolver();
          34        try {
          35            System.out.println("NewtonSolver : sin(x)=0 when x from -1 to 1, x = "+ solver.solve(f, -11));
          36        }
           catch (ConvergenceException e) {
          37            // TODO Auto-generated catch block
          38            e.printStackTrace();
          39        }
           catch (FunctionEvaluationException e) {
          40            // TODO Auto-generated catch block
          41            e.printStackTrace();
          42        }

          43    }

          44
          45    private static void solver() {
          46        // TODO Auto-generated method stub
          47        UnivariateRealFunction f = new SinFunction();
          48        UnivariateRealSolver solver = new BisectionSolver();
          49        try {
          50            System.out.println("BisectionSolver : sin(x)=0 when x from 3 to 4, x = "+ solver.solve(f, 34));
          51        }
           catch (ConvergenceException e) {
          52            // TODO Auto-generated catch block
          53            e.printStackTrace();
          54        }
           catch (FunctionEvaluationException e) {
          55            // TODO Auto-generated catch block
          56            e.printStackTrace();
          57        }

          58    }

          59
          60}

          61

           

          輸出結果:
          BisectionSolver : sin(x)=0 when x from 3 to 4, x = 3.141592502593994
          NewtonSolver : sin(x)=0 when x from -1 to 1, x = 0.0
           


          可以看到,程序都輸出了正確的結果。但是,其實還是可以嘗試一些復雜的參數來測試算法的,這里就不再多說,不妨看看牛頓法在
          (-1,4)區間的效果。

          不管是哪種方法,其實都是要設定誤差限的,默認的是10E-6

          一個小的建議是使用工廠模式的構建方法,因為畢竟這個包內提供了工廠的實現,那為什么不用這種更靈活的方式呢?

          寫了方程求解的例子,就不要再問什么求平方根的牛頓法或者立方根什么的問題了,不就是x^n-R=0的方程嘛,設定區間[0,+]就可以了。原理明白,其他的問題都很好解決,不是嗎?

          相關資料:

          對分法:http://mathworld.wolfram.com/Bisection.html

          牛頓法:http://mathworld.wolfram.com/NewtonsMethod.html

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

           

          posted on 2010-12-21 17:18 changedi 閱讀(3626) 評論(0)  編輯  收藏 所屬分類: 數學

          主站蜘蛛池模板: 茌平县| 札达县| 西宁市| 全州县| 天津市| 贵溪市| 新化县| 钦州市| 松滋市| 梁平县| 新丰县| 富民县| 莱州市| 张家港市| 武义县| 维西| 平塘县| 当涂县| 右玉县| 普安县| 松江区| 普定县| 额尔古纳市| 汉阴县| 长垣县| 千阳县| 霍林郭勒市| 西畴县| 昭通市| 桃园市| 宁晋县| 太仓市| 阳东县| 滨州市| 四川省| 柳江县| 太康县| 乌兰浩特市| 东平县| 海兴县| 旅游|