Du verwendest einen veralteten Browser. Es ist möglich, dass diese oder andere Websites nicht korrekt angezeigt werden. Du solltest ein Upgrade durchführen oder ein alternativer Browser verwenden.
Das Legendre Polynom konnte ich programmieren doch wie soll ich das Bisektionsverfahren programmieren . Hier was ich bis jetzt habe.
Java:
public static double[] legendre (int n, double x) {
double[] funktionswert = new double [n];
funktionswert[0] = 1 ;
funktionswert[1] = x ;
for(int i = 2; i < n ; i++) {
funktionswert[i] = ((2i-1)/(i))* funktionswert[i-1] - ((i-1)/(i))*funktionswert[i-2] ;
}
return funktionswert ;
}
public static double[] bisektion (int n, double a , double b) {
}
public static void main(String[] args) {
int = 10;
int z ;
double [] feld = new double [n-1];
for(int i = 0; i < 10 ; i++) {
}
for(int i = 0; i < z ; i++) {
System.out.println("feld ");
}
}
Bist du sicher dass du das Legendre-Polynom richtig hast ? Ich kenne das gerade nicht aber sollte die Methode legendre(n,x) nicht den Wert des Polynoms an der Stelle x zurückliefern ? Wieso lieferst du ein ganzes Array zurück ?
Und bisection ist genau das gleiche. Wieso soll die ein ganzes Array zurückliefern ? Und bitte Code-Tags benutzen dann wird es lesbarer.
public static double bisektion(int n, double a, double b) {
double x0, c=(a+b)/2, fc = legendre(n, c);
if (b-a < 1e-8 || Math.abs(fc) < 1e-15) {
x0 = c; // Ende der Rekursion
} else if (fc > 0.0) {
x0 = bisektion(n, c, b); // weiter mit oberer Hälfte
} else {
x0 = bisektion(n, a, c); // weiter mit unterer Hälfte
}
return x0;
}
Und wie gesagt, ich weiss nicht genau wie Legendre geht aber ich habe folgende Definition gefunden:
(k+1)P(k+1) = Sum( (2k+1) x Pk(x) - k Pk-1(x))
Und dann würde die Methode so aussehen:
Java:
public static double legendre(int n, double x) {
// (2k+1) x Pk(x) - k Pk-1(x)
double[] funktionswert = new double [n+1];
funktionswert[0] = 1 ;
funktionswert[1] = x ;
for (int k = 1; k < n ; k++) {
funktionswert[k+1] = (2*k+1)* x * funktionswert[k]/(k+1) - k * funktionswert[k-1]/(k+1);
}
return funktionswert[n];
}
Ja, tut sie. Und zwar so wie die Abfragen oben sind immer die kleinste. Das ist eine Eigenschaft des Bisektionsverfahrens. Wenn du dann wissen willst ob es noch mehr in deinem ursprünglichen Intervall gibt musst du das Verfahren erneut auf die restlichen Teilintervalle anwenden.
ich soll ja alle nullstellen für alle legendre-polynome von 1-10 berechnen.
Das Bisektionsverfahren an sich hab ich mehr oder weniger verstanden aber wie programiiere ich es , dass alle teilintervalle die nullstellen enthalten können getestet werden?
Na ja, du hast jetzt mal die Werkzeuge dafür (legendre() und bisektion() ) Das was du jetzt ansprichst ist ja das was du laut Aufgabenstellung in der main-Methode machen sollst. Und das habe ich auch noch nicht so ganz verstanden. Was ist mit dem Hinweis "gemäß (4)" gemeint? Du sollst dir da ja wohl ein Array mit Intervallgrenzen aufbauen und anschliessend sollst du die Nullstellen per Bisektion für jedes dieser Intervalle ausrechnen. Ich denke mal in (4) steht wie man die Intervalle so wählt dass sie genau eine Nullstelle enthalten !!!!
OK. Also erstmal kannst du die legendre() dann so umschreiben wie sie in der Aufgabe angegeben ist ( ist dasselbe wie meine nur umgeformt):
Code:
public static double legendre(int n, double x) {
double[] funktionswert = new double [n+1];
funktionswert[0] = 1 ; // p0
funktionswert[1] = x ; // p1
for (int k = 2; k <= n ; k++) { // p2 .... pn
funktionswert[k] = (2*k-1) * x * funktionswert[k-1]/k - (k-1) * funktionswert[k-2]/k;
}
return funktionswert[n];
}
Und die Definition (4) besagt dass die Intervalle für das Polynom vom Grad n sich jeweils aus den Nullstellen des Polynoms vom Grad n-1 ergeben. (und am oberen und unteren Rand halt von -1 bis zur ersten Nullstelle usw. Das musst du jetzt in deiner main entsprechend codieren.
public static void main(String[] args) {
final int MAX_GRAD = 10;
double[] intervalle = new double[MAX_GRAD + 1];
// Initialisiere das Polynom P1
intervalle[0] = -1.0;
intervalle[1] = 0.0; // Nullstelle von P1
intervalle[2] = 1.0;
for (int grad = 2; grad <= MAX_GRAD; grad++) {
System.out.println("Grad:"+grad);
double[] nullstellen = new double[grad];
for (int i = 0; i < grad; i++) {
nullstellen[i] = bisektion(grad, intervalle[i], intervalle[i + 1]);
System.out.println("Nullstelle: " + nullstellen[i]);
}
// jetzt stehen alle Nullstellen im array nullstellen
// jetzt legen wir die neuen intervalle für den naechsten Grad fest
if (grad < MAX_GRAD) {
for (int i = 1; i <= grad; i++) {
intervalle[i] = nullstellen[i - 1];
}
intervalle[grad + 1] = 1.0;
}
}
}
Die ausgaben kannst du ja noch etwas schöner gestalten. Und evtl. die Ausgabe für P1 noch dazu nehemen. P1 hat eine Nullstelle bei 0.0 !!
Ich habe das ganze mal zusammengebaut und getestet . Was ich jetzt aber nicht verstehe ist warum jeder zweiter Wert falsch ist. ( Vergleiche Musterwerte von obigen bild) Screenshot (240).png
Ja. Das ist zwar das was oben schon war, aber hier nochmal komplett:
Java:
public static double bisektion(int n, double a, double b) {
double x0, c = (a + b) / 2, fc = legendre(n, c);
if (b - a < 1e-12 || Math.abs(fc) < 1e-16) {
x0 = c; // Ende der Rekursion
} else if (legendre(n, a) * fc > 0.0) {
x0 = bisektion(n, c, b); // weiter mit oberer Hälfte
} else {
x0 = bisektion(n, a, c); // weiter mit unterer Hälfte
}
return x0;
}
public static double legendre(int n, double x) {
double[] funktionswert = new double[n + 1];
funktionswert[0] = 1; // p0
funktionswert[1] = x; // p1
for (int k = 2; k <= n; k++) { // p2 .... pn
funktionswert[k] = (2 * k - 1) * x * funktionswert[k - 1] / k - (k - 1) * funktionswert[k - 2] / k;
}
return funktionswert[n];
}
/**
* @param args the command line arguments
*/
public static void main(String[] args) {
final int MAX_GRAD = 10;
double[] intervalle = new double[MAX_GRAD + 1];
// Initialisiere das Polynom P1
intervalle[0] = -1.0;
intervalle[1] = 0.0; // Nullstelle von P1
intervalle[2] = 1.0;
for (int grad = 2; grad <= MAX_GRAD; grad++) {
System.out.println("Grad:"+grad);
double[] nullstellen = new double[grad];
for (int i = 0; i < grad; i++) {
nullstellen[i] = bisektion(grad, intervalle[i], intervalle[i + 1]);
System.out.println("Nullstelle: " + nullstellen[i]);
}
// jetzt stehen alle Nullstellen im array nullstellen
// jetzt legen wir die neuen intervalle für den naechsten Grad fest
if (grad < MAX_GRAD) {
for (int i = 1; i <= grad; i++) {
intervalle[i] = nullstellen[i - 1];
}
intervalle[grad + 1] = 1.0;
}
}
}
Sehr merkwürdig. Ich habe auch gerade noch mal alles von hier rückwärts kopiert. Ergebnisse sind richtig ??
Da ja richtige Werte dabei sind tippe ich mal drauf dass legendre und bisektion richtig sind. Es sieht eher so aus als wären die intervalle in der main falsch. Ich habe zur Kontrolle mal ein Print dafür eingebaut:
Code:
for (int i = 0; i < grad; i++) {
System.out.println("Intervall: "+intervalle[i]+" "+intervalle[i+1]);
nullstellen[i] = bisektion(grad, intervalle[i], intervalle[i + 1]);
System.out.println("Nullstelle: " + nullstellen[i]);
}
Dann ist irgendwo in deinem Code noch ein Fehler und er kompiliert gar nicht. Wenn du es trotzdem ausführst führt er einen älteren Stand aus !! Deshalb die falschen Ausgaben. Ich tippe darauf dass irgendwo was mit Klammern nicht passt.
Hast du ein "class"-Statement drum herum ? Das war bei mir ja nicht dabei !! Ich hatte dir nur die drei Methoden legendre, bisektion und main gepostet !!