Méthode de Newton pour le calcul de l'inverse d'un réel
Bonsoir à tous,
J'ai défini une classe 'function' ainsi qu'une classe 'polynomial' qui en hérite. Voici leurs interfaces :
Code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37
| #include <iostream>
#include <cmath>
#include <assert.h>
using namespace std;
class function {
public:
function(){};
virtual function* clone()const=0;
virtual float operator()(float x)const=0; //gives the image of a number by the function
virtual function* derivative()const=0;
virtual float inverse(float y)const=0;
virtual ~function(){}
};
class polynomial : public function {
protected:
int degree;
private:
float *coefficient;
public:
//polynomial(){degree=-1;} //default constructor
polynomial(int d);
virtual~polynomial();
virtual function* clone()const;
int get_degree()const;
float operator[](int i)const; //reads the coefficient number i
float& operator[](int i); //updates the coefficient number i
virtual float operator()(float x)const;
virtual function* derivative()const;
virtual float inverse(float y)const;
}; |
J'ai codé toutes les fonctions liées à 'polynomial'. Elles ont l'air de bien marcher jusqu'ici, sauf pour la méthode 'inverse'. Elle est basée sur la méthode de Newton qui donne le zéro d'une fonction. Je l'applique dans la méthode 'inverse' à la fonction x->f(x)-y où y est fixé (c'est l'élément dont on cherche l'antécédent) et f est l'instance en cours.
Code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
| float polynomial::inverse(float y)const
{
int i=0;
float x0=1;
function* deriv=derivative();
float x1=x0+(y-operator()(x0))/(deriv->operator()(x0));
while(i<=250 && std::abs(x1-x0)>1e-5)
{
x0=x1;
x1=x0+(y-operator()(x0))/(deriv->operator()(x0));
i++;
}
if(std::abs(x1-x0)<=1e-5)
{
//delete deriv; // En dé-commentant, j'ai des erreurs de mémoire
return x1;
}
else
{
cout<<"Maximum iteration reached in polynomial method 'inverse'"<<endl;
//delete deriv; // idem
return -1;
}
} |
Je teste ma méthode avec le main ci dessous et il s'avère que le nombre maximum d'itérations est atteint sans obtenir un résultat. J'ai lu quelques articles en ligne et à priori la méthode de Newton marche bien et pas besoin d'un grand nombre d'itérations.
D'un autre côté, je suis allée me documenter sur la fonction 'abs', et elle prend en considération les floats lorsqu'on inclut <cmath>.
Code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14
|
#include "function.h"
int main(int argc, const char * argv[])
{
polynomial p(3);
for(int i=0;i<=2;i++) p[i]=0;
p[3]=1;
cout<<"27^(1/3)="<<p.inverse(27);
return 0;
}
//returns 27^(1/3)=Maximum iteration reached in polynomial method 'inverse' -1 |