Η μέθοδος Newton-Raphson είναι μία αναδρομική διαδικασία που μας επιτρέπει να προσεγγίσουμε με πολύ μικρό σφάλμα μία ρίζα μιας πολυωνυμικής συνάρτησης 5ου βαθμού αν έχουμε μία πραγματική συνάρτηση
Το πρόγραμμα καλείται να επιλύσει 5 βασικά υποπροβλήματα:
Το πρόγραμμα θα πρέπει να δέχεται αυστηρά 7 ορίσματα τα οποία θα είναι οι συντελεστές του πολυωνύμου και το main()
, int argc
. Καθώς δεχόμαστε και ως όρισμα το όνομα του προγράμματος που εκτελούμε ο έλεγχος θα πρέπει να γίνει για 8 ορίσματα:
if(argc != 8) {
return 1;
}
Για την υλοποίηση του προγράμματος θα πρέπει να υπολογίζουμε κάθε φορά την
long double f(long double x0, double FACT[6])
{
return (FACT[0] + FACT[1] * x0 + FACT[2] * pow(x0, 2) + FACT[3] * pow(x0, 3) + FACT[4] * pow(x0, 4) + FACT[5] * pow(x0, 5)); //Υπολογισμός f(x0).
}
Η συνάρτηση δέχεται ως όρισμα έναν δεκαδικό
double pow(double, double)
Η συνάρτηση αυτή περιέχεται στην βιβλιοθήκη math.h
και λειτουργεί ως εξής:
Αυτή η συνάρτηση είναι η παράγωγος της
long double df(long double x0, double FACT[6])
{
return (FACT[1] + 2 * FACT[2] * x0 + 3 * FACT[3] * pow(x0, 2) + 4 * FACT[4] * pow(x0, 3) + 5 * FACT[5] * pow(x0, 4)); //Υπολογισμός f'(x0).
}
Ο πολογισμός αυτός υλοποιείται πολύ εύκολα με την εντολή εκχώρησης:
x = x0 - fx0/dfx0;
Το πρόγραμμα θέλουμε να τερματίζει κανονικά σε 3 περιπτώσεις:
Για την προσέγγιση της λύσης του πολυωνύμου θα πρέπει επαναληπτικά να υπολογίζουμε την
for(int i = 0; i < 1000; i++){ //Επανάληψη υπολογισμού ρίζας που εκτελείται το πολύ για 1000 επαναλήψεις.
fx0 = f(x0, FACT); //Υπολογισμός f(x0).
dfx0 = df(x0, FACT); //Υπολογισμός f'(x0).
x = x0 - fx0/dfx0; //Υπολογισμός του τύπου προσέγγισης της ρίζας.
if(isnan(x)) { //Έλεγχος αν το αποτέλεσμα του υπολογισμού ήταν nan.
printf("nan\n");
return 0;
}
if (fabsl(x - x0) < pow(10, -6)) { //Έλεγχος αν η τρέχουσα προσέγγιση είναι αρκετά ακριβής. Αν είναι τότε εκτυπώνεται και το πρόγραμμα τερματίζει.
printf("%.2Lf\n", x);
return 0;
}
x0 = x; //Αποθήκευση της τρέχουσας προσέγγισης της ρίζας στην μεταβλητή x0 για χρήση στην επόμενη επανάληψη.
}
printf("incomplete\n"); //Αυτή η εντολή εκτελείται μόνο αν η επανάληψη έχει εκτελεστεί 1000 φορές και δεν έχει προκύψει αποδεκτή προσέγγιση ή δεν πάει να γίνει διαίρεση με το 0.
return 0;
}
</br>
Αν οποιαδήποτε στιγμή κατά τον υπολογισμό της ρίζας προκύψει απόκλειση, δηλαδή το αποτέλεσμα της
if(isnan(x)) { //Έλεγχος αν το αποτέλεσμα του υπολογισμού ήταν nan.
printf("nan\n");
return 0;
}
θεωρούμε ότι το πρόγραμμα προσέγγισε αρκετά την λύση της συνάρτησης όταν η διαφορά μεταξύ του
if (fabsl(x - x0) < pow(10, -6)) { //Έλεγχος αν η τρέχουσα προσέγγιση είναι αρκετά ακριβής. Αν είναι τότε εκτυπώνεται και το πρόγραμμα τερματίζει.
printf("%.2Lf\n", x);
return 0;
}
Σε περίπτωση που το πρόγραμμα δεν έχει βρεθεί σε κάποια από τις δύο καταστάσεις εξόδου που αναφέρονται παραπάνω μετά από 1000 επαναλήψεις τότε η δομή επανάληψης θα τερματίζει. Έτσι το πρόγραμμα θα συνεχίζει ακολουθιακά εκτυπώνοντας “incomplete” και θα τερματίζει.