6. Εύρεση ριζών#
6.1. Διατύπωση του προβλήματος#
Ρίζες μιας συνάρτηση
Μια απλή περίπτωση είναι το τριώνυμο
6.2. Επαναληπτικές μέθοδοι#
Στην πράξη συχνά οι εξισώσεις είναι μη γραμμικές και δεν υπάρχει διαθέσιμη αναλυτική λύση για τις ρίζες. Οι αριθμητικές μέθοδοι που έχουν αναπτυχθεί για αυτές τις περιπτώσεις είναι επαναληπτικές, δηλαδή ξεκινάνε από μια εκτίμηση για την ρίζα και σε κάθε επανάληψη την βελτιώνουν προσεγγίζοντας σταδιακά την πραγματική τιμή.
Η επαναληπτική διαδικασία σταματά, όταν ικανοποιηθεί το κριτήριο ακρίβειας.
To κριτήριο ακρίβειας μπορεί να αφορά την απόλυτη ή σχετική απόκλιση μεταξύ δύο διαδοχικών εκτιμήσεων της ρίζας ή το υπόλοιπο της συνάρτησης
6.3. Μέθοδος διχοτόμησης#
Σύμφωνα με το θεώρημα ενδιάμεσης τιμής, μια συνεχής συνάρτηση
Αν τα
τότε πρέπει να υπάρχει τουλάχιστον ένα σημείο
Η μέθοδος της διχοτόμησης ξεκινά με ένα διάστημα
Με δεδομένα τα
Υπολόγισε το
Υπολόγισε το
Αν
και έχουν το ίδιο πρόσημο (μπορεί να ελεγχθεί με διάφορους τρόπους, π.χ. )τότε
καιαλλιώς
και
Αν έχει επιτευχθεί το κριτήριο σύγκλισης,
τότε επίστρεψε την τιμή
,αλλιώς επανάλαβε τα βήματα με το ενημερωμένο
ή .

Fig. 6.1 Παράδειγμα βημάτων της μεθόδου διχοτόμησης. Πηγή: Wikipedia Commons.#
Exercise 6.1
Να βρεθεί μία ρίζα της συνάρτησης
στο διάστημα
import numpy as np
def f(x: float) -> float:
return np.exp(x)+x-5
xa = 0
xb = 10
fa = f(xa)
fb = f(xb)
print(fa*fb < 0) # Check
xm = np.Inf
TOL = 1e-5
print("i\tx\t\tf(x)")
for i in range(100): # 100 is max number of iterations
xm_old = xm
xm = 0.5*(xa+xb)
fm = f(xm)
if fa*fm > 0:
xa = xm
fa = fm
else:
xb = xm
fb = fm
print(f"{i}\t{xm:0.7f}\t{fm:0.7f}")
e = abs(xm-xm_old) # absolute error
if e < TOL:
break
True
i x f(x)
0 5.0000000 148.4131591
1 2.5000000 9.6824940
2 1.2500000 -0.2596570
3 1.8750000 3.3958191
4 1.5625000 1.3332332
5 1.4062500 0.4868743
6 1.3281250 0.1020856
7 1.2890625 -0.0815551
8 1.3085938 0.0095593
9 1.2988281 -0.0361726
10 1.3037109 -0.0133506
11 1.3061523 -0.0019066
12 1.3073730 0.0038236
13 1.3067627 0.0009578
14 1.3064575 -0.0004746
15 1.3066101 0.0002416
16 1.3065338 -0.0001165
17 1.3065720 0.0000625
18 1.3065529 -0.0000270
19 1.3065624 0.0000178
Για τον χαρακτηρισμό της σύγκλισης χρησιμοποιείται ο μαθηματικός ορισμός:
Η μέθοδος της διχοτόμησης συγκλίνει στο
Η μονάδα κώδικα SciPy παρέχει μια έτοιμη υλοποίηση της μεθόδου (scipy.optimize.bisect).
6.4. Μέθοδος Newton-Raphson#
Η μέθοδος Newton-Raphson ή σκέτο μέθοδος Newton βασίζεται στην προσεγγιστική σχέση:
όπου

Fig. 6.2 Παράδειγμα ενός βήματος της μεθόδου Newton-Raphson. Πηγή: Wikipedia Commons.#
Η διαδικασία εφαρμόζεται ξεκινώντας από μια αρκετά καλή εκτίμηση και επαναλαμβάνοντας την ίδια διαδικασία μέχρι να ικανοποιηθεί το κριτήριο ακρίβειας. Το πληθος των σωστών ψηφίων διπλασιάζεται περίπου σε κάθε επανάληψη και η τάξη της σύγκλισης είναι τετραγωνική (
Πλεονέκτημα της μεθόδου είναι η ταχύτητα σε σχέση με την μέθοδο διχοτόμησης και μειονεκτήματα της μεθόδου είναι ότι:
πρέπει να υπολογιστεί η παράγωγος, που δεν είναι πάντα εύκολο,
η μέθοδος δεν συγκλίνει σε κάποιες περιπτώσεις, όπως
ασυνέχεια της παραγώγου
μέγιστα και ελάχιστα της συνάρτησης (
)κακή αρχική εκτίμηση (μπορεί να προσεγγίσει άλλη ρίζα)
πολλαπλές ρίζες
Η μέθοδος Newton-Raphson έχει υλοποιηθεί στην συνάρτηση scipy.optimize.newton.
Exercise 6.2
Να επιλυθεί η Άσκηση 6.1 με χρήση της συνάρτησης scipy.optimize.newton.
Για την λύση της άσκησης πρέπει να υπολογιστεί η πρώτη παράγωγος:
και να δηλωθούν οι δύο συναρτήσεις:
import numpy as np
from scipy.optimize import newton
def f(x: float) -> float:
return np.exp(x)+x-5
def fp(x: float) -> float:
return np.exp(x)+1
x = newton(f, x0=0, fprime=fp, tol=1e-5)
print(x, f(x))
1.3065586410393504 8.881784197001252e-16
6.5. Μέθοδος της τέμνουσας#
Για την εφαρμογή της μεθόδου Newton-Raphson είναι απαραίτητος ο υπολογισμός της πρώτης παραγώγου
Η μέθοδος αυτή ονομάζεται μέθοδος της τέμνουσας. Σε σχέση με την κλασσική Newton-Raphson, η μέθοδος της τέμνουσας είναι πιο οικονομική από άποψη πράξεων ανά επανάληψη καθώς όλοι οι όροι είναι ήδη γνωστοί. Από την άλλη, η προσεγγιστική εκτίμηση της παραγώγου μπορεί να οδηγήσει σε περισσότερες επαναλήψεις (υποτετράγωνη τάξη σύγκλισης,
Η μέθοδος της τέμνουσας θεωρείται παραλλαγή της μεθόδου Newton-Raphson και γιαυτό εφαρμόζεται με την ίδια συνάρτηση (scipy.optimize.newton) παραλείποντας απλώς το προαιρετικό όρισμα για την πρώτη παράγωγο και εισάγοντας ένα όρισμα
import numpy as np
from scipy.optimize import newton
def f(x: float) -> float:
return np.exp(x)+x-5
x = newton(f, x0=0, x1=1e-4, tol=1e-5)
print(x, f(x))
1.3065586415194725 2.253425890330618e-09
6.6. Εύρεση πολλαπλών ριζών#
Για την εύρεση πολλαπλών ριζών μπορεί να χρησιμοποιηθεί η συνάρτηση scipy.optimize.fsolve, η οποία βασίζεται σε μια παραλλαγή της κατάβασης βαθμίδας (gradient descent) που έχει υλοποιηθεί στην βιβλιοθήκη MINPACK. Όπως φαίνεται κι από το όνομα της επιλεγμένης μονάδα κώδικα (scipy.optimize), υπάρχει επικάλυψη μεταξύ των τεχνικών που εφαρμόζονται στην εύρεση ριζών έχουν και στην βελτιστοποίηση. Ο ορισμός της αρχικής εκτίμησης είναι πολύ σημαντικός, καθώς επηρεάζει σε ποια ρίζα θα συγκλίνει η μέθοδος όσο και το πλήθος των επαναλήψεων.
Όταν η εξίσωση είναι πολυωνυμικής μορφής ενδείκνυται η χρήση της εξειδικευμένης συνάρτησης numpy.roots, η οποία υπολογίζει και τις μιγαδικές ρίζες.
Exercise 6.3
Να βρεθούν οι ρίζες του παρακάτω πολυωνύμου με χρήση της scipy.optimize.fsolve και της numpy.roots.
Στην πρώτη περίπτωση να χρησιμοποιηθούν οι αρχικές εκτιμήσεις
import numpy as np
from scipy.optimize import fsolve
def f(x: float) -> float:
return 5e-2*x**4-0.2*x**3-6*x-50
x = fsolve(f, [-100,-10,0,10,100])
print(x)
p=[5e-2,-0.2,0,-6.,-50.]
x=np.roots(p)
print(x)
[-4.01403447 -4.01403447 7.92266417 7.92266417 7.92266417]
[ 7.92266417+0.j 0.04568515+5.60737258j 0.04568515-5.60737258j
-4.01403447+0.j ]