2017-06-30 4 views
2

Je suis censé calculerMa calculatrice de règles de Simpson est-elle correcte (java)?

enter image description here

en utilisant la règle de Simpson, avec des intervalles de 4 sous.

Je ne veux certainement pas le faire à la main, j'ai donc essayé d'écrire cet algorithme en Java.

La formule de la règle de Simpson est

enter image description here

Et voici mon code:

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 

maintenant Si je compare ma solution avec d'autres calculatrices en ligne (http://www.emathhelp.net/calculators/calculus-2/simpsons-rule-calculator/?f=ln+%28x%29&a=1&b=e&n=4&steps=on), il est différent .. Mais je ne vois pas pourquoi le mien aurait tort.

Ma solution est 0.9999788955063609, solution en ligne est 0.999707944567103

Peut-être il y a une erreur que je fait? Mais j'ai tout vérifié et ne pouvais pas trouver.

+2

n'a pas lu par le code à fond, mais vous êtes mélanger des entiers ('6 ',' 4', '2') avec' double's et cela peut provoquer des erreurs d'arrondi. Essayez de les définir comme 'double's place (' 6.0', '4.0',' 2.0') et voir si elle a un effet. –

+0

Le lien que vous avez répertorié a n = 4. Quand j'ai changé l'URL pour avoir n = 16 plutôt que n = 4, je me suis Réponse: ,999998619003165. –

+0

@MickMnemonic J'ai eu un bon sentiment quand j'ai lu votre commentaire, mais il n'a malheureusement pas aidé :(En tout cas, c'est vraiment bon de savoir et je serai au courant que quand j'écris plus de code comme ça. – cnmesr

Répondre

3

Vous pouvez accumuler l'erreur d'arrondi en faisant plusieurs fois b_n = a_ {n} + intervalle. Au lieu de cela, vous pourriez utiliser une approche inductive, où vous dites un intervalle a_n = a_0 + n *, car cela implique seulement d'introduire une erreur d'arrondi une fois.

Je vais tester avec des chiffres réels pour confirmer et étoffer la réponse dans un peu, mais en attendant, vous pouvez regarder cette explication sur l'accumulation d'erreur de handmade hero


PS. En prime, vous pouvez regarder un extrait de héros à la main!

MISE À JOUR: J'ai regardé votre lien. Bien que le problème que j'ai décrit ci-dessus s'applique, la différence de précision est faible (vous obtiendrez la réponse 0.9999788955063612 à la place). La raison de la différence dans votre cas est que la formule utilisée dans votre calculatrice en ligne est une variante légèrement différente en termes de notation, qui traite l'intervalle [a, b] comme 2h. En d'autres termes, vos 4 intervalles sont équivalents à 8 intervalles dans leur calcul.

Si vous mettez 8 rectangles dans cette page Web, vous obtiendrez le même résultat que le nombre (plus précis) ici:

Réponse: ,999978895506362.

Voir une meilleure explication de la notation utilisée sur cette page Web here

3

J'ai changé votre calcul delta vers le haut pour de sorte que vous ne calcule pas le delta encore et encore.Vous étiez également ne pas appliquer les multiplicateurs droit pour les facteurs pairs et impairs, ainsi que ne pas appliquer la formule pour deltaX car il doit être: ((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 

Pour prendre en compte le facteur droit de f (x) i a changé le 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);   
} 

maintenant, il donne le résultat correct:

enter image description here