Algorithmen zur Separierung reeller Nullstellen U spensky Algorithmus Sturm Algorithmus Anwendung: - Intervallarithmetik - Algebraische Zahlen 1 Definition: Varianz einer Sequenz Def: Sei u = [u0 , u1 , .., us ] eine Sequenz reeller Zahlen, und [u00 , u01 , ..., u0t ] die Teilsequenz aller Werte 6= 0. Dann ist var[u0 , u1 , .., us ], die Anzahl der Vorzeichenwechsel in u0 , also: var[u0 , u1 , .., us ] := | {i | u0i u0i+1 < 0} |. 2 Bsp: var[ 1, −2, −4, 5, 6 ] = 2 var[ 0, 1, −2, −4, 5, 6 ] = 2 var[ 1, 0, 1, −2, −4, 5, 0 ] = 2 var[ −1, 0, 1, −2, −4, 5, 6 ] = 3 3 Descartes’ Rule of Sign : Die Anzahl der Vorzeichenwechsel der Koeffizienten eines Polynoms A, übersteigt die Anzahl der positiven Nullstellen von A um eine nicht negative gerade Zahl. var[a0 , a1 , ..., an ] − |{αi |A(αi ) = 0 ; αi > 0}| = 2k, k ∈ N0 Weiter gilt : var[a0 , a1 , ..., an ] = 0 ⇒ A besitzt keine positiven Nullstellen var[a0 , a1 , ..., an ] = 1 ⇒ A besitzt genau eine positive Nullstelle Negative Nullstellen: betrachte A(-x). 4 Uspensky Algorithmus : Eingabe : Ein primitives quadratfreies Polynom A mit deg(A) = n > 0. Ausgabe : Eine Liste isolierender Intervalle der positiven reellen Nullstellen von A. (1) Bestimme eine rootbound der Form 2k [Rootbound] (2) if (k ≥ 0) then B(x) := A(2k x) [Transform] else B(x) := 2−kn A(2k x) (3) L0 := Subalgorithmus(B) [Subalgorithmus] (4) foreach (a0i , b0i ) in L0 [Output] L.add((2k a0i , 2k b0i )) return L 5 Subalgorithmus : Eingabe : Ein primitives quadratfreies Polynom A mit deg(A) = n > 0. Ausgabe : Eine Liste isolierender Intervalle der reellen Nullstellen von A in (0,1). (1) A∗ := (x + 1)n A(1/(x + 1)) [Basis] Bestimme r über Descartes Rule of Sign von A∗ if (r == 0) then return L := () if (r == 1) then return L := ((0, 1)) (2) if (A(1/2) == 0) [Midpoint] then L.add((1/2, 1/2)); A := A/(2x − 1) (3) A0 := 2n A(x/2); L0 := Subalgorithmus(A0 ) [Left half] foreach (a0i , b0i ) in L0 L.add((a0i /2, b0i /2)) (4) A00 := A0 (x + 1); L00 := Subalgorithmus(A00 ) [Right half] 00 00 foreach (a00 i , bi ) in L 00 L.add(((a00 i + 1)/2, (bi + 1)/2)) (5) return L [Output] 6 GCD - Euklidischer Algorithmus Eingabe : Polynome A,B ∈ Z[x] Ausgabe : GCD(A, B) = Rh A = Q1 B + R2 B = Q 2 R2 + R3 R2 = .. . Q 3 R3 + R4 Rh−2 = Qh−1 Rh−1 + Rh Rh−1 = Q h Rh Polynomial Remainder Sequence P RS(A, B) = [A, B, R2 , R3 , . . . , Rh ] 7 Beispiel GCD - Algorithmus: A = x8 + x6 − 3x4 − 3x3 + 8x2 + 2x − 5 B = 3x6 + 5x4 − 4x2 − 9x + 21 R2 = −15x4 + 3x2 − 9 R3 = 15795x2 + 30375x − 59535 R4 = 1254542875143750x − 1654608338437500 R5 = 12593338795500743100931141992187500∗ (∗ ohne Gewähr) 8 Erstellen einer Sturm Sequenz Bilde GCD(A,A’) ⇒ P RS(A, A0 ) = [A, [A0 , A0 , R2 , . . . , Rh ] A1 , A2 , . . . , Ah ] ⇒ SturmSequence(A) = [σ0 A0 , σ1 A1 , σ2 A2 , . . . , σh Ah ] = A Bestimme σi ∈ {−1, +1}, i ∈ {0, ..., h} durch folgende Regel: 1.: σ0 = +1 2.: σ1 = +1 3.: αi σi−1 Ai−1 = Ai Qi + βi σi+1 Ai + 1 | αi βi < 0 9 Def: Sei A = [A0 , A1 , . . . , As ] eine Polynomsequenz und a ∈ R, dann ist varA (a) := var(A0 (a), A1 (a), . . . , As (a)). Sturm Theorem : Die Anzahl der reellen Nullstellen von A in (a, b] ist V arA (a, b) := varA (a) − varA (b). 10 Sturm Algorithmus : Eingabe : Ein primitives quadratfreies Polynom A mit deg(A)>0. Ausgabe : Eine List isolierender Intervalle der reellen Nullstellen von A. (1) L := ((−b, b]), wobei b Rootbound von A. (2) Erstelle Sturm Sequenz A (3) foreach (a, b] in L bisect((a, b]) (4) foreach (a, b] in L r = Anzahl der Nullstellen in (a, b] (Sturm Theorem) if (r == 0) then ignoriere das Interval if (r == 1) then gib das Interval aus if (r > 1) then belasse Interval in L 11 Laufzeiten: Bestimmt durch zwei Parameter: n = deg(A), Def : f (n) ∈ Lk (n) ⇔ d= qP n 2 i=0 ai f (n)/log k (n) ∈ o(log(n)); Sturm Algorithmus: Schritt (2): Sturm Sequenzen O(n4 L(d)2 ) Schritt (3): Aufteilen und Auswerten O(n7 L(nd)3 ) Der Algorithmus wird aber in der Regel von Schritt(2), also dem erstellen der PRS dominiert. ( Koeffizientenexplosion ) Uspensky Algorithmus worst case : O(n6 L(d)2 ) average case : O(n4 + n3 L(d)) 12