mikrocontroller.net

Forum: Offtopic Lösungsmenge eines Polynoms 3. Grades bestimmen


Autor: Kai G. (runtimeterror)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi zusammen,

ich versuche im Moment die Lösungen eines Polynoms dritten Grades zu 
berechnen und hänge da an einem kleinen Problem:

Ich verwende den Lösungsweg unter
http://en.wikipedia.org/wiki/Cubic_polynomial
Abschnitt "Alternate method" / "Summary"

Die dort vorgeschlagenen Lösungen verwenden folgenden Koeffizienten (für 
k = [0..2])
x0 <= ζ^0 | ζ^0
x1 <= ζ^1 | ζ^2
x2 <= ζ^2 | ζ^1

In einigen Testfällen erhalte ich damit auch die korrekte Lösungsmenge. 
In anderen Fälle muss ich aber andere Koeffizienten miteinander 
kombinieren:
x0 <= ζ^0 | ζ^1
x1 <= ζ^1 | ζ^0
x2 <= ζ^2 | ζ^2

und

x0 <= ζ^0 | ζ^2
x1 <= ζ^1 | ζ^1
x2 <= ζ^2 | ζ^0

Anders formuliert: für jede Nullstelle müssen zwei kubische Wurzeln 
berechnet werden, die jeweils drei Lösungen liefern. Ich weiß nicht, 
welche beiden Lösungen ich jeweils miteinander kombinieren muss.

Ich weiß leider nicht, ob ich da was falsch mache. Nach welchen 
Kriterien kann ich entscheiden, welche Lösungsmenge die richtige ist?

Ich verwende für alle Koeffizienten (a, b, c, d(, e)) komplexe Zahlen.

Wäre super, wenn mal jemand drüberschauen könnte und hoffe, dass ich das 
Problem ausreichend beschrieben habe - ansonsten nochmal nachfragen.

Danke schonmal!

Kai

Autor: Beobachter (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Lösungsformel nach Cardano geht.

Ist einigermassen verständlich beschrieben in:

Mathematische Formeln, Bartsch, VEB Leipzig 1977, 11. Auflage ...

Autor: Beobachter (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ach so, wenn die Koeffizienten kplx. sind, muss/kann man eventl. zwei 
Gl. 3. Grades daraus machen, und jede für sich lösen ???

Autor: Kai G. (runtimeterror)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Die Methode von Cardano bin ich gerade noch am testen - ist noch 
irgendwo ein Fehler drin :/

Die Division würde ich nach Möglichkeit eigentlich gerne vermeiden ...

Autor: Johann L. (gjlayde) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Es gibt doch immer auch Nebenbedingungen, zB ein Produkt , das p/3 sein 
muss. Daran sieht man, welche dritte Einheitswurzel man an die Summenden 
anmultiplizieren muss.

Johann

Autor: Kai G. (runtimeterror)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Die Nebenbedingung -uv = p/3 ist darin ja angeblich schon 
berücksichtigt. Im Abschnitt "Alternate method" steht sogar:
"Note that the above methods do apply if p and q are complex. This 
solution avoids the addition of an inverted cubic radical in the 
solution, and also resolves the ambiguity of signs for the square roots 
in the first solution given above."

Der Code für die Berechnung ist relativ komplex - ich schau mal, ob ich 
eine reduzierte Fassung zum Posten fertig machen kann.

Trotzdem danke soweit.

Autor: Kai G. (runtimeterror)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Kann der Moderator den Thread ggf. in PC-Programmierung verschieben?
Ich denke, da kann man mir noch am ehesten weiterhelfen. Einen 
Mathe-Bereich gibt's leider nicht und es handelt sich zumindest zum Teil 
um ein Problem bei der Implementierung (Java).

Danke!

Autor: Kai G. (runtimeterror)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich habe jetzt eine für mich akzeptable Lösung gefunden:

Mit dem Cardano-Algorithmus bekomme ich zumindest immer die richtigen 
Werte. Um das Problem mit der Division zu umgehen berechne ich sowohl 
/u³/ als auch /v³/ . Je nachdem welcher der beiden betragsmäßig größer 
ist entscheide ich, ob ich u aus v oder v aus u berechne.

u_i = -p/3v_i
bzw.
v_i = -p/3u_i

Hier der zugehörige Codeabschnitt für die Entscheidung:
Complex[] u;
Complex[] v;

if (uuu.isZero() && vvv.isZero()) {
    u = uuu.root(3);
    v = vvv.root(3);
} else if (uuu.sqr() > vvv.sqr()) {
    u = uuu.root(3);
    v = new Complex[] {
            p.div(u[0]).div(-3),
            p.div(u[1]).div(-3),
            p.div(u[2]).div(-3)
            };
} else {
    v = vvv.root(3);
    u = new Complex[] {
            p.div(v[0]).div(-3),
            p.div(v[1]).div(-3),
            p.div(v[2]).div(-3)
            };
}

Die Lösungen berechnen sich dann einfach nach
x_i = u_i + v_i - a/3

Vielleicht kann's ja jemand mal brauchen. Ich habe leider keine 
elegantere Lösung gefunden.

Autor: Johann L. (gjlayde) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Mal ne blöde Frage: Wieso hat ne kompexe Zahl 3 Komponenten (in new 
Complex)? Sind die in projektiver Darstellung?

Johann

Autor: Beobachter (Gast)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
KEINE Gewähr jedweder Art für beigefügtes Programm.

Autor: Kai G. (runtimeterror)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>Mal ne blöde Frage: Wieso hat ne kompexe Zahl 3 Komponenten (in new
>Complex)?
new Complex[] { ... }

Das ist eine Lösungsmenge mit drei komplexen Zahlen. Jede komplexe Zahl 
hat natürlich nur zwei Komponente (real und imaginär). Die Erzeugung 
einer einzelnen Zahl sähe wie folgt aus:
new Complex(1.2, -3.4)

Hoffe, das trägt zur Klärung bei ;)

@Beobachter
Was ist das?

Autor: Simon K. (simon) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Johann L. schrieb:
> Mal ne blöde Frage: Wieso hat ne kompexe Zahl 3 Komponenten (in new
> Complex)? Sind die in projektiver Darstellung?
>
> Johann

Hab ich auch gerade gedacht. Aber du bist auf die "neumodische" Syntax 
reingefallen ;) Das ist ne Array-Initialisierung.
Jagut, und der Name Complex ist in dem Zusammenhang nicht optimal. 
Zumindest wenn man nicht genau hinguckt :-)

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail, Yahoo oder Facebook? Keine Anmeldung erforderlich!
Mit Google-Account einloggen | Mit Yahoo-Account einloggen | Mit Facebook-Account einloggen
Noch kein Account? Hier anmelden.