2017-06-30 70 views
2

我应该计算我的辛普森规则计算器是否正确(java)?

enter image description here

使用辛普森的规则,以4周的时间间隔。

我当然不想亲手做,因此我试图用Java编写该算法。

辛普森的规则计算公式为

enter image description here

这里是我的代码:

import java.util.Scanner; 
import java.util.Locale; 
public class Simpson { 
    public static void main(String[] args) { 
     Scanner input = new Scanner(System.in).useLocale(Locale.US); 
     //e= 2.718281828459045 to copy paste 
     System.out.println("Interval a: "); 
     double aInt = input.nextDouble(); 
     System.out.println("Interval b: "); 
     double bInt = input.nextDouble(); 
     System.out.println("How many sub intervals: "); 
     double teilInt = input.nextDouble(); 
     double intervaldistance = (bInt-aInt)/teilInt; 
     System.out.println("h = "+"("+bInt+"-"+aInt+")/"+teilInt+ " = "+intervaldistance); 
     double total = 0; 
     System.out.println(""); 
     double totalSum=0; 

     for(double i=0; i<teilInt; i++) { 
      bInt = aInt+intervaldistance; 
      printInterval(aInt, bInt); 
      total = prod1(aInt, bInt); 
      total = total*prod2(aInt, bInt); 
      aInt = bInt; 
      System.out.println(total); 
      totalSum=totalSum+total; 
      total=0; 
     } 
     System.out.println(""); 
     System.out.println("Result: "+totalSum); 
    } 
    static double prod1(double a, double b) { // first product of simpson rule; (b-a)/6 
     double res1 = (b-a)/6; 
     return res1; 
    } 
    static double prod2(double a, double b) { // second pproduct of simpson rule 
     double res2 = Math.log(a)+4*Math.log((a+b)/2)+Math.log(b); 
     return res2; 
    } 
    static void printInterval(double a, double b) { 
     System.out.println(""); 
     System.out.println("["+a+"; "+b+"]"); 
    } 
} 

Output for 4 sub intervals: 

[1.0; 1.4295704571147612] 
0.08130646125926948 

[1.4295704571147612; 1.8591409142295223] 
0.21241421690076787 

[1.8591409142295223; 2.2887113713442835] 
0.31257532785558795 

[2.2887113713442835; 2.7182818284590446] 
0.39368288949073565 

Result: 0.9999788955063609 

现在如果我比较我与其他在线计算器(http://www.emathhelp.net/calculators/calculus-2/simpsons-rule-calculator/?f=ln+%28x%29&a=1&b=e&n=4&steps=on)解决方案,它不同于..但我不明白我为什么应该是错的。

我的解决办法是0.9999788955063609,在线解决方案是0.999707944567103

也许有一个错误,我做?但我已经加倍检查了一切,找不到。

+2

没有通过代码,请仔细阅读,但你混合整数('6 '','4','2')和'double's,这可能会导致舍入错误。尝试将它们定义为'double's('6.0','4.0','2.0'),看看它是否有效果。 –

+0

您列出的链接n = 4。当我改变网址有n = 16而不是n = 4时,我得到了答案:0.999998619003165。 –

+0

@MickMnemonic当我阅读你的评论时,我有一种很好的感觉,但它可悲地没有帮助:(无论如何,这是真的很好知道,当我写这样的代码更多的代码时,我会意识到这一点 – cnmesr

回答

3

您可能会通过多次执行b_n = a_ {n} +区间来累计舍入误差。 相反,您可能会使用归纳方法,您说a_n = a_0 + n *区间,因为这只涉及引入舍入误差一次。

我会与实际数字测试,以确认和充实的回答在一点点,但在此期间,你可以从handmade hero


PS观看有关错误的积累这样的解释。作为奖励,您可以观看手工英雄的摘录!

UPDATE:我看了一下你的链接。虽然我上面描述的的问题确实适用于,但精度的差异很小(相反,您将得到0.9999788955063612的答案)。您的案例中出现差异的原因是,在线计算器中使用的公式在符号方面略有不同,它将间隔[a,b]视为2h。换句话说,你的4个区间在他们的计算中相当于8个区间。

如果你把8个矩形在该网页上,你会得到相同的结果(更准确)号位置:

答:0.999978895506362。

查看该网页here

3

使用的符号的一个更好的解释,我改变了你的增量计算的顶部,这样你就不会一遍遍计算的增量。你还没有应用正确的乘数的奇数和偶数的因素,以及不应用正确的公式DELTAX因为它必须是:((AB)/ N)/ 3

double deltaX = ((bInt-aInt)/teilInt)/3; 

for(int i=0; i<=teilInt; i++) { //changed to <= to include the last interval 
    bInt = aInt+intervaldistance; 
    printInterval(aInt, bInt); 
    total = prod2(aInt, bInt, i+1, teilInt); //added the current interval and n. The interval is +1 to work well with the even and odds 
    totalSum += total; 
    aInt = bInt; 
    System.out.println(total); 
} 

System.out.println(""); 
System.out.println("Result: "+ (totalSum*deltaX)); //multiplication with deltaX is now here 

为了说明f的权系数(X)我改变了Prod2的到:

static double prod2(double a, double b, int interval, double n) { 
    int multiplier = 1; 
    if (interval > 0 && interval <= n){ 
      //applying the right multiplier to f(x) given the current interval 
      multiplier = (interval % 2 == 0) ? 4 : 2; 
    } 

    return multiplier * Math.log(a);   
} 

现在它得到正确的结果:

enter image description here