Introducción



El TDA Polinomio representa un polinomio con coeficientes reales, son mutables y residen en memoria dinámica.

 

El diseño de este TDA trata de buscar la eficiencia, ha prestado más atención a la eficiencia que a modelar el concepto exacto de polinomio, por ello, la mayoría de los operadores aritméticos,  tienen efectos laterales (modificando al receptor) y devuelven  referencias al objeto receptor (modificado), esto también explica que los objetos del TDA se definan como "mutables".



Primitivas del polinomio


Dentro del TDA Polinomio hemos propuesto las siguientes primitivas :

 

·        Polinomio ( ) -> construye el polinomio p(x) = 0.

 

·        Polinomio (float * c, int g) -> construye un polinomio a partir de un vector de coeficientes, crea el polinomio :  c[0] + c[1]*x + c[2] x2 + ... + c[g] xg.

PARÁMETROS : c -> vector de coeficientes, debe tener g+1 componentes.

                                  g -> grado del polinomio que se quiere crear.

 

·        Polinomio (const Polinomio & p) -> constructor de copia, que no comparte.

PARÁMETROS : p -> polinomio que se copia.

 

·        Ostream & operator << (ostream & s, const Polinomio & p) -> sobrecargar el operador de extracción para polinomios,  escribe 'p' sobre el flujo 's' con el formato Coef(Grado()) xGrado() + ... + Coef(1) x + Coef(0), presentando sólo los monomios con coeficiente distinto de 0.

PARÁMETROS : s -> flujo de salida, es modificado.

                                  p -> polinomio que se escribe.

 

·        Bool Nulo () const -> nos dice si el polinomio se puede considerar como nulo.

  

·        Float Coef (int i) const -> obtiene un coeficiente, devuelve el coeficiente del monomio i-ésimo del receptor.

PARÁMETROS : i -> orden del coeficiente a obtener. i >= 0.

 

·        Int Grado () const -> obtiene el grado del polinomio, devuelve el grado del receptor.

 

·        Float operator () (float x) const -> evalúa el polinomio en un punto, devuelve la evaluación del receptor en x.

PARÁMETROS : x -> punto en que se evalúa el receptor.

 

·        Bool operator == (const Polinomio & p) const -> comparación de igualdad, devuelve true, si el receptor y p son iguales. false, en otro caso.

PARÁMETROS : p -> polinomio con que se compara.

 

·        Bool operator != (const Polinomio & p) const -> comparación de desigualdad, devuelve true, si el receptor y p son distintos. false, en otro caso.

PARÁMETROS : p -> polinomio con que se compara.

 

·        Friend Polinomio &operator - (Polinomio & p) -> cambia el signo de los coeficientes de un polinomio, el polinomio p  es cambiado por otro cuyos coeficientes resultan de invertir el signo a los de p.

POSTCONDICIÓN : el receptor es modificado

PARÁMETROS : p -> polinomio a invertir.

 


·        Polinomio &operator + (const Polinomio & p) -> añade al receptor otro polinomio,al polinomio receptor se añade el polinomio p y el resultado se deja sobre el propio receptor.

POSTCONDICIÓN : el receptor es modificado

PARÁMETROS : p -> polinomio que se suma.

 

·        Polinomio &operator - (const Polinomio & p) -> resta al receptor otro polinomio, al polinomio receptor se le resta el polinomio p y el  resultado se deja sobre el propio receptor.

POSTCONDICIÓN : el receptor es modificado

PARÁMETROS : p -> polinomio que se resta.

 

·        Polinomio &operator * (const Polinomio & p) -> multiplica el receptor por otro polinomio, al polinomio receptor es multiplicado por p y el resultado se deja sobre el propio receptor.

POSTCONDICIÓN : el receptor es modificado

PARÁMETROS : p -> segundo factor.

 

·        Polinomio &operator * (const float x) -> producto de un polinomio por un escalar, el receptor es multiplicado por el escalar x.

POSTCONDICIÓN : el receptor es modificado

PARÁMETROS : x -> escalar que se multiplica.

 

·        Friend Polinomio &operator * (float x, Polinomio & p) -> producto de un polinomio por un escalar,  almacena sobre p el producto x * p.

PARÁMETROS : x -> escalar que se multiplica.

                                  p -> polinomio multiplicado, es modificado.

 

·        Polinomio &operator = (const Polinomio & p) -> operador de asignación para polinomios, el objeto receptor se transforma en una copia de p, su valor anterior se pierde.

POSTCONDICIÓN : el receptor es modificado

PARÁMETROS : p -> polinomio que se copia.

 

·        ~Polinomio () -> destructor, destruye el polinomio receptor, liberando los recursos que usaba

POSTCONDICIÓN : el receptor es modificado



Ejemplos de uso


Imprimir un polinomio

 

Esta función nos va imprimiendo en pantalla cada coeficiente del polinomio.

 

Polinomio p;

 

Void Imprimir ()

    {

    cout << p.Grado ();

    for (int i =0; i <=p.Grado(); i++)

         if (p.Coef (i) != 0.0)

            cout << i << p.Coef (i);

    cout << -1;

    }

 

Implementación del polinomio


Un polinomio viene definido por un grado y por los coeficientes, el grado es una variables entera que nos dice la potencia más alta de un coeficiente del polinomio, y los coeficientes se almacenan en un vector de float llamado coef.

 

 






Vamos a ver la especificación tanto de la función de abstracción como del invariante de la representación del polinomio:

 

 

Función de Abstracción

 

fA : rep ------> p (x)

 

(coef, grado) ------> coef[0] + coef[1]*x + coef[2] *x2 + ... + coef[grado] * xgrado.

 

 

Invariante de Representación

 

Cualquier objeto del tipo rep: {coef, grado} debe verificar:

 

- grado >= 0.

 

- coef apunta a un vector con grado+1 componentes.

 

- coef[grado] != 0 ó grado == 0.

 

De manera que la clase Polinomio en C++ tendría el siguiente aspecto:

 

Class Polinomio

       {

       

       Public:

 

            Polinomio ();

            Polinomio (float * c, int g);

            Polinomio(const Polinomio & p);

            float Coef (int i) const;

            int Grado () const;

            float operator () (float x) const;

            bool operator == (const Polinomio & p) const;

            bool operator != (const Polinomio & p) const;

            friend Polinomio &operator - (Polinomio & p);

            Polinomio &operator + (const Polinomio & p);

            Polinomio &operator - (const Polinomio & p);

            Polinomio &operator * (const Polinomio & p);

            Polinomio &operator * (const float x);

            friend Polinomio &operator * (float x, Polinomio & p);

            Polinomio &operator = (const Polinomio & p);

            ~Polinomio();

 

      Private:

int grado;

float *coef;

 

bool Nulo () const;

Ostream & operator << (ostream & s, const Polinomio & p) ;

 

       }

 

Pasemos ahora a ver la implementación de cada una de las primitivas enunciadas con anterioridad en C++:


static bool Cero (float x)

    {

    const float cero = 1e-20;

    return (x <= cero);

    }



inline bool Polinomio::Nulo() const

    {

    return ((grado == 0) && Cero(coef[0]));

    }



Polinomio::Polinomio()

    {

    coef = new float[1];

    assert(coef != 0);

    coef[0] = 0;

    grado = 0;

    }



Polinomio::Polinomio(float * Coef, int Grado)

    {

    grado = Grado;

    coef = new float[grado + 1];

    assert(coef != 0);

    for (int i = 0; i <= grado; i++)

         coef[i] = Coef[i];

    }



Polinomio::Polinomio(const Polinomio & p)

    {

    grado = p.grado;

    coef = new float[grado];

    assert(coef != 0);

    for (int i = 0; i <= grado; i++)

         coef[i] = p.coef[i];

    }



float Polinomio::Coef(int i) const

    {

    assert (0 <= i);

     if (i > grado)

        return 0;

     return coef[i];

     }



inline int Polinomio::Grado() const

    {

    return grado;

   }



float Polinomio::operator()(float x) const

    {

    float suma = 0;

    for (int i = grado; i > 0; i--)

         suma = x * (coef[i] + suma);

    suma += coef[0];

    return suma;

    }



Polinomio & Polinomio::operator=(const Polinomio & p)

     {

     if (&p == this)

        return *this;

     if (grado == p.grado)

        {

        for (int i = 0; i <= grado; i++)

             coef[i] = p.coef[i];

        return *this;

        }

     grado = p.grado;

     delete [] coef;

     coef = new float[p.grado + 1];

     for (int i = 0; i <= grado; i++)

           coef[i] = p.coef[i];

     return *this;

     }



bool Polinomio::operator==(const Polinomio & p) const

    {

    if (grado != p. grado)

       return false;

    int i = grado;

    while ((coef[i] == p.coef[i]) && i >= 0)

              i--;

    return (i < 0);

    }



inline bool Polinomio::operator!=(const Polinomio & p) const

    {

    return !(*this == p);

    }



Polinomio & operator-(Polinomio & p)

    {

    for (int i = 0; i <= p.grado; i++)

         p.coef[i] = -p.coef[i];

    return p;

    }



Polinomio & Polinomio::operator+(const Polinomio & p)

    {

    if (p.grado < grado)

       {

       for (int i = 0; i <= p.grado; i++)

                     coef[i] += p.coef[i];

       }

    else

          if (p.grado > grado)

             {

             float * c = new float[p.grado + 1];

             assert (c != 0);

                      int i = 0;

             for (; i <= grado; i++)

               c[i] = coef[i] + p.coef[i];

                      for (; i <= p.grado; i++)

                           c[i] = p.coef[i];

                      delete [] coef;

             coef = c;

                      grado = p.grado;

             }

         else

               {

            int i = grado;

            while (Cero(coef[i] + p.coef[i]) && (i >= 0))

                                  --i;

            if (i < 0) {

               delete [] coef;

                  grado = 0;

                  coef = new float[1];

                           coef[0] = 0.0;

               }

               else 

                  if (i == grado) {

                     for (int i = 0; i <= grado; i++)

                           coef[i] += p.coef[i];

                     }

                  else

                        {

                        grado = i;

                        float * c = new float[i + 1];

                                    assert (c != 0);

                       for (; i >= 0; i--)

                                         c[i] = coef[i] + p.coef[i];

                        delete [] coef;

                        coef = c;

                        }

                 }

    return *this;

    }



Polinomio & Polinomio::operator-(const Polinomio & p)

    {

    if (p.grado < grado)

       {

       for (int i = 0; i <= grado; i++)

            coef[i] -= p.coef[i];

       }

    else

          if (p.grado > grado)

             {

                      float * c = new float[p.grado + 1];

                      assert (c != 0);

             int i = 0;

                      for (; i <= grado; i++)

                           c[i] = coef[i] - p.coef[i];

                      for (; i <= p.grado; i++)

                           c[i] = -p.coef[i];

                      delete [] coef;

             coef = c;

             grado = p.grado;

             }

          else

                {

             int i = grado;

 while (Cero(coef[i] - p.coef[i]) && (i >= 0))

           --i;

                         if (i < 0)

                {

                            delete [] coef;

                            grado = 0;

                            coef = new float[1];

                            coef[0] = 0.0;

                }

               else 

                               if (i == grado)

                                  for (int i = 0; i <= grado; i++)

             coef[i] -= p.coef[i];

                               else

             {

                        grado = i;

                                     float * c = new float[i + 1];

                                     assert (c != 0);

             for (; i >= 0; i--)

                c[i] = coef[i] - p.coef[i];

             delete [] coef;

             coef = c;

                                     }

              }

    return *this;

    }



Polinomio & Polinomio::operator*(const Polinomio & p)

    {

    if (p.Nulo() || Nulo())

       {

       delete [] coef;

       coef = new float[1];

       assert(coef != 0);

       coef[0] = 0;

       grado = 0;

       }

   else

         {

         int nuevo_grado = grado + p.grado;

         float * c = new float[nuevo_grado + 1];

         assert(c != 0);

         for (int k = 0; k <= nuevo_grado; k++)

                        c[k] = 0.0;

         for (int j = p.grado; j >= 0; j--)

                       for (int i = 0; i >= grado; i--)

                             c[i+j] += p.coef[j] * coef[i];

         grado = p.grado;

         delete [] coef;

         coef = c;

         }

    return *this;

    }



Polinomio & Polinomio::operator*(const float x)

    {

    if (Cero(x))

       {

       delete [] coef;

       coef = new float[1];

       coef[0] = 0;

       grado = 0;

       }

    else

          {

          for (int i = 0; i <= grado; i++)

                        coef[i] *= x;

          }

    return *this;

    }



Polinomio & operator*(float x, Polinomio & p)

    {

    if (Cero(x))

       {

       delete [] p.coef;

       p.coef = new float[1];

       p.coef[0] = 0;

       p.grado = 0;

       }

    else

          {

          for (int i = 0; i <= p.grado; i++)

                         p.coef[i] *= x;

          }

    return p;

    }



ostream & operator<<(ostream & s, const Polinomio & p)

    {

    if (p.Grado() > 1)

       {

       int i = p.Grado();

       s << p.Coef(i) << " x^" << i;

       for (i--; i > 1; i--)

                      if (!Cero(p.Coef(i)))

                         s << " + " << p.Coef(i) << "x^" << i;

       if (!Cero(p.Coef(1)))

          s << " + " << p.Coef(1)<< "x";

       if (!Cero(p.Coef(0)))

                   s << " + " << p.Coef(0);

       }

    else if (p.Grado() == 1)

              {

              s << p.Coef(1) << "x";

              if (!Cero(p.Coef(0)))

                          s << " + " << p.Coef(0);

              }

           else

                 s << p.Coef(0);

    return s;

    }



inline Polinomio::~Polinomio()

    {

    delete [] coef;

    }