您好,登錄后才能下訂單哦!
這篇文章給大家分享的是有關(guān)Apache Commons Math3之?dāng)?shù)值積分的示例分析的內(nèi)容。小編覺(jué)得挺實(shí)用的,因此分享給大家做個(gè)參考,一起跟隨小編過(guò)來(lái)看看吧。
Apache.Commons.Math4里面的數(shù)值積分支持類(lèi)采用的是“逼近法”,即,先對(duì)大區(qū)間做一次積分,再對(duì)小區(qū)間做一次積分,若兩次積分結(jié)果的差值小于某一設(shè)定的誤差值,則認(rèn)為積分完成。否則,將區(qū)間再次細(xì)分,對(duì)細(xì)分后的區(qū)間進(jìn)行積分,與前一次積分相比較,如此反復(fù)迭代,直至最近的兩次積分差值足夠小。這樣的結(jié)果,有可能會(huì)導(dǎo)致無(wú)法收斂。
為了使用org.apache.commons.math4.analysis.integration包中的積分器類(lèi),需要先實(shí)現(xiàn)UnivariateFunction接口(本文以MyFunction為例),實(shí)現(xiàn)其value方法。然后創(chuàng)建指定的積分器對(duì)象,本文以SimpsonIntegrator為例,最后調(diào)用其integrate(...)方法即可算出MyFunction的積分。
調(diào)用integrate(...)方法時(shí)需要提供4個(gè)參數(shù):
第1個(gè)是最大逼近次數(shù),要適當(dāng)大一些,否則可能會(huì)無(wú)法收斂;
第2個(gè)是MyFunction類(lèi)的實(shí)例;
第3個(gè)是積分區(qū)間下限;
第4個(gè)是積分區(qū)間上限。
SimpsonIntegrator在第一次迭代時(shí)一定是分別以積分下限和積分上限作為x調(diào)用連詞MyFunction.value(...)方法,下一次則會(huì)將區(qū)間分成2份(除上下限x值之外,還有一個(gè)中間x值),再下一次則是分成4份……
以下是使用辛普森積分類(lèi)的例子:
import java.util.ArrayList; import java.util.List; import org.apache.commons.math4.analysis.UnivariateFunction; import org.apache.commons.math4.analysis.integration.SimpsonIntegrator; import org.apache.commons.math4.analysis.integration.UnivariateIntegrator; interface TestCase { public Object run(List<Object> params) throws Exception; public List<Object> getParams(); public void printResult(Object result) throws Exception; } public class TimeCostCalculator { public TimeCostCalculator() { } /** * 計(jì)算指定對(duì)象的運(yùn)行時(shí)間開(kāi)銷(xiāo)。 * * @param testCase 指定被測(cè)對(duì)象。 * @return 返回sub.run的時(shí)間開(kāi)銷(xiāo),單位為s。 * @throws Exception */ private double calcTimeCost(TestCase testCase) throws Exception { List<Object> params = testCase.getParams(); long startTime = System.nanoTime(); Object result = testCase.run(params); long stopTime = System.nanoTime(); testCase.printResult(result); double timeCost = (stopTime - startTime) * 1.0e-9; return timeCost; } public void runTest(TestCase testCase) throws Exception { double timeCost = calcTimeCost(testCase); System.out.println("時(shí)間開(kāi)銷(xiāo):: " + timeCost + "s"); System.out.println("-------------------------------------------------------------------------------"); } public static void main(String[] args) throws Exception { TimeCostCalculator tcc = new TimeCostCalculator(); tcc.runTest(new CalcSimpsonIntegrator()); } } /** * 使用辛普森法求解數(shù)值積分。Apache.Common.Math4中所用的辛普森法是采用逼近法,即先對(duì)整個(gè)積分區(qū)間用矩形積分,然后將區(qū)間分解為4份,再次積分,比較兩次積分的差值,若想對(duì)誤差大于某個(gè)預(yù)訂數(shù)值, * 則認(rèn)為還需要繼續(xù)細(xì)分區(qū)間,因此會(huì)將區(qū)間以2倍再次細(xì)分后求積分,并將結(jié)果與前一次積分的結(jié)果比較,直至差值小于指定的誤差,就停止。 * @author kingfox * */ class CalcSimpsonIntegrator implements TestCase { public CalcSimpsonIntegrator() { System.out.print("本算例用于測(cè)試使用辛普森法計(jì)算積分。正在初始化計(jì)算數(shù)據(jù) ... ..."); inputData = new double[arrayLength]; for (int index = 0; index < inputData.length; index++) // 鏂滃潯鍑芥暟 { inputData[index] = Math.sin(2 * Math.PI * index * MyFunction.factor * 4); } func = new MyFunction(); integrator = new SimpsonIntegrator(); System.out.println("初始化完成!"); } @Override public Object run(List<Object> params) throws Exception { double result = ((SimpsonIntegrator)(params.get(1))).integrate(steps, (UnivariateFunction)(params.get(0)), lower, upper); return result; } /** * 獲取運(yùn)行參數(shù) * @return List對(duì)象,第一個(gè)元素是求積函數(shù),第二個(gè)參數(shù)是積分器。 */ @Override public List<Object> getParams() { List<Object> params = new ArrayList<Object>(); params.add(func); params.add(integrator); return params; } @Override public void printResult(Object result) throws Exception { System.out.println(">>> integration value: " + result); } UnivariateFunction func = null; UnivariateIntegrator integrator = null; class MyFunction implements UnivariateFunction { @Override public double value(double x) { // double y = x * factor; // 1. // double y = 4.0 * x * x * x - 3.0 * x * x + 2.0 * x - 1.0; // 2. // double y = -1.0 * Math.sin(x) + 2.0 * Math.cos(x) - 3.0; // 3. double y = inputData[(int)(x / factor)]; // 4. // System.out.println(x + ", " + y); return y; } private static final double factor = 0.0001; } private double[] inputData = null; private static final int arrayLength = 5000; private static final double lower = 0.0; // private static final double upper = 2.0 * Math.PI; // 3. private static final double upper = (arrayLength - 1) * MyFunction.factor; // 1. 2. 4. private static final int steps = 1000000; }
上述代碼中,注釋為1. 2. 3.的可以正常計(jì)算出結(jié)果,但注釋為4.的就無(wú)法收斂。
基于org.apache.commons.math4.analysis.integration.UnivariateIntegrator的積分器的另一個(gè)局限性在于必須編寫(xiě)一個(gè)繼承于UnivariateFunction的函數(shù)類(lèi),實(shí)現(xiàn)其value方法(根據(jù)輸入的x值計(jì)算出y值),這種做法有利于可用解析式表達(dá)的情況,不利于對(duì)存放于外存的大量數(shù)據(jù)做積分處理。
感謝各位的閱讀!關(guān)于“Apache Commons Math3之?dāng)?shù)值積分的示例分析”這篇文章就分享到這里了,希望以上內(nèi)容可以對(duì)大家有一定的幫助,讓大家可以學(xué)到更多知識(shí),如果覺(jué)得文章不錯(cuò),可以把它分享出去讓更多的人看到吧!
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。