[C] soluzione di equazione di 4 grado in linguaggio C

Messaggioda frafrana » 23/02/2017, 16:01

Buongiorno, vorrei risolvere un'equazione di quarto grado (ma va bene come esempio anche un qualsiasi grado superiore al secondo) utilizzando il linguaggio C.

Riporto un esempio:
$x^4-10x^3+35x^2-50x+24$
Ovviamente mi dovrebbe restituire tutte le quattro soluzioni che so essere reali. Conosco già le soluzioni (1,2,3,4) ma mi servirebbe un programma per calcolarle senza conoscerle a priori.

Chi mi dà una mano per il listato?
Grazie a tutti, Francesco.
frafrana
Starting Member
Starting Member
 
Messaggio: 1 di 6
Iscritto il: 25/01/2010, 23:31

Re: [C] soluzione di equazione di 4 grado in linguaggio C

Messaggioda Luc@s » 23/02/2017, 16:34

mi scrivi qui l'algoritmo che hai seguito per trovarle passo passo?
----
Luca Francesca <[email protected]>
System Engineer Lead @ Salesforce

Info: https://www.linkedin.com/in/lucafrancesca/
Luc@s
Senior Member
Senior Member
 
Messaggio: 1473 di 1955
Iscritto il: 01/05/2006, 17:21
Località: Irlanda

Re: [C] soluzione di equazione di 4 grado in linguaggio C

Messaggioda apatriarca » 23/02/2017, 18:21

@Luc@s: Suppongo abbia semplicemente scritto \((x-1)(x-2)(x-3)(x - 4)\) e fatto i calcoli per ottenere i vari coefficienti.

Esiste una formula per il calcolo delle radici di un polinomio di quarto grado. In alternativa puoi ricorrere ad un metodo numerico iterativo. Facci sapere cosa preferisci.
apatriarca
Moderatore
Moderatore
 
Messaggio: 4550 di 10435
Iscritto il: 08/12/2008, 20:37
Località: Madrid

Re: [C] soluzione di equazione di 4 grado in linguaggio C

Messaggioda frafrana » 23/02/2017, 18:44

Ciao.
Allora io ho preparato il seguente listato:

Codice:
#include <stdio.h>
#include <stdlib.h>

float miafunzione(float x);

int main()
{
    float x,y;
    float a=1,b=2;

    printf("inserire il valore della variabile x \n");
    scanf("%f",&x);
    y = miafunzione(x);
    printf("il valore corrispondente e' %f\n",y);

    while (fabs(a-b)<0.01){
        if (miafunzione(a)*miafunzione(a+((b-a)/2))<0){
            a=a;
            b=a+((b-a)/2);
            }
        else if (miafunzione(a+((b-a)/2))*miafunzione(a)>0){
            a=a+((b-a)/2);
            b=b;
            }
    }
    printf("il valore per f(x) uguale 0 e' %f\n",b);
}

float miafunzione(float x){
    float y;
        y=((x*x*x*x)-(10*x*x*x)+(35*x*x)-(50*x)+24);
    return y;
    }


in cui ho inserito una funzione ed una precisione di errore "e".
Il programma mi restituisce il valore della funzione per un dato punto (per esempio io inserisco 0 e mi dice che il valore è 24, che è giusto) e mi restituisce un valore per cui la funzione diventa zero, cioè 2.
E' questa seconda parte che vorrei che fosse precisa perchè le soluzioni sono ovviamente quattro (cioè 1,2,3,4) e invece m e ne da' solo una.
frafrana
Starting Member
Starting Member
 
Messaggio: 2 di 6
Iscritto il: 25/01/2010, 23:31

Re: [C] soluzione di equazione di 4 grado in linguaggio C

Messaggioda apatriarca » 23/02/2017, 22:41

Ci sono diversi problemi nel codice che hai postato:
  1. Il metodo di bisezione che hai usato per trovare gli zeri della tua funzione parte dal presupposto che ci sia una sola radice nell'intervallo preso in considerazione e che \(\mathrm{sign}\bigl(f(a)\bigr) \neq -\mathrm{sign}\bigl(f(b)\bigr).\) Il tuo codice parte da \(a = 1\) e \(b = 2\) e quindi in \([a, b]\) ci sono due radici. Inoltre si ha ovviamente che \(\mathrm{sign}\bigl(f(1)\bigr) = -\mathrm{sign}\bigl(f(2)\bigr) = 0.\) Si tratta insomma dell'algoritmo sbagliato da usare in casi come questo.
  2. La condizione del ciclo è invertita rispetto a quello che dovrebbe essere. Devi infatti rimanere nel ciclo se \( (b - a) > \epsilon \) e uscire quando tale distanza sia inferiore. In effetti il codice restituisce qualcosa \(2\) solo perché hai inizializzato \(b = 2\). Se avessi scritto \(b = 15\) il tuo codice avrebbe restituito \(15\)!
  3. Le due condizioni all'interno del ciclo non esauriscono tutte le combinazioni possibili di valori. Si può insomma finire in un ciclo infinito (dopo aver corretto la condizione del ciclo ovviamente). Per vederlo basta osservare che se prendessi \(1\) e \(3\) come valori per \(a\) e \(b\) avresti \(f(a) = 0,\) \(f(b) = 0, \) e \( f\bigl(a+(b-a)/2\bigr) = 0. \) Sono tutti valori nulli e quindi le condizioni del ciclo non sono soddisfatte.
  4. Il metodo che hai usato per calcolare il valore del polinomio non è particolarmente robusto.. Il metodo normalmente consigliato è quello di https://it.wikipedia.org/wiki/Regola_di_Horner. Nel tuo caso significa calcolare
    \[ \Bigl(\!\bigl((x - 10)\,x +35\bigr)\,x - 50 \Bigr)\,x + 24 \]
  5. Non è necessario (e credo sia anzi meglio evitarlo) separare la dichiarazione di una variabile dalla sua inizializzazione. Meglio mettere tutto nello stesso posto. Inoltre non è più necessario fare tutte le dichiarazioni ad inizio della funzione e in effetti più leggibile dichiarare le variabili quando necessario.

Per quanto riguarda l'algoritmo, puoi scegliere se usare l'algoritmo di Ferrari per la risoluzione di equazioni di quarto grado oppure un qualche metodo iterativo come quelli di Newton, Laguerre, Halley, Jenkins-Traub.. Nel caso iterativo è necessario ridurre il polinomio e applicare il metodo ricorsivamente al polinomio ridotto. E' tuttavia passato un po' di tempo dall'ultima volta che ho visto queste cose e per darti indicazioni più dettagliate dovrei mettermi a leggere questi algoritmi.
apatriarca
Moderatore
Moderatore
 
Messaggio: 4551 di 10435
Iscritto il: 08/12/2008, 20:37
Località: Madrid

Re: [C] soluzione di equazione di 4 grado in linguaggio C

Messaggioda frafrana » 26/02/2017, 20:27

Scusa se ti rispondo in ritardo, mi sono ripromesso di rivedere tutta la questione e studiarmela. Sei stato davvero molto chiaro ed utilissimo.
Ovvio che adesso mi dedicherò ad approfondire l'argomento ma mi hai dato gli elementi utili per farlo.
Ti ringrazio per la collaborazione, Francesco.
frafrana
Starting Member
Starting Member
 
Messaggio: 3 di 6
Iscritto il: 25/01/2010, 23:31


Torna a Informatica

Chi c’è in linea

Visitano il forum: Nessuno e 1 ospite