// Programita para mostrar el calculo de raices de una ecuacion cuadratica
// Antonio Carrillo Ledesma

#include <stdio.h>
#include <math.h>
#include<iostream>
using namespace std;

class cuadratica {
   private:
	   // Coeficientes del polinomio
	   double A, B, C;

   
	// Funcion cuadratica
	double f(double x, double a, double b, double c) {
		return (x * x * a + x * b + c);
	}

	// Derivada de la funcion cuadratica
	double df(double x, double a, double b) {
		return (2.0 * x * a + b);
	}

	// Evalua el valor X en la función cuadratica
	void evalua(double x, double a, double b, double c) {
		printf("\nRaiz (%1.16f), evaluacion raiz: %1.16e", x, (a * x * x + b * x + c));
	}

	// Metodo Newton-Raphson
	// x = x - f(x)/f'(x)
	double metodoNewtonRapson(double x, int ni, double a, double b, double c) {
		int i;
		for (i = 0; i < ni; i++) {
			 x = x - (f(x, a, b, c) / df(x, a, b));
		}
		return x;
	}

   public: 	
	   // Constructor de la clase
	   cuadratica(double a, double b, double c) {
	      A = a;
	      B = b;
	      C = c;
	   }

	// calculo de raices
	void raices() {
	      // Raices del polinomio
	      double X1, X2, x;
	      // Calculo del discriminante
	      double d = B * B - 4.0 * A * C;
		
	      // Raices reales
	      if (d >= 0.0) {
		 printf("\nPolinomio (%f) X^2 + (%f )X + (%f) = 0\n", A, B, C);
		 printf("\nChicharronera 1");
		 X1 = (-B + sqrt(d)) / (2.0 * A);
		 X2 = (-B - sqrt(d)) / (2.0 * A);
		 evalua(X1, A, B, C);
		 evalua(X2, A, B, C);
		      
		 printf("\n\nChicharronera 2");
		 X1 = (-2.0 * C) / (B + sqrt(d));
		 X2 = (-2.0 * C) / (B - sqrt(d));;
		 evalua(X1, A, B, C);
		 evalua(X2, A, B, C);

		 // Metodo Newton-Raphson
		 printf("\n\nMetodo Newton-Raphson");
		 x = X1 - 1.0;
		 printf("\nValor inicial aproximado de X1 =  %f", x);
		 x = metodoNewtonRapson(x, 6, A, B, C);
		 evalua(x, A, B, C);
		 x = X2 - 1.0;
		 printf("\nValor inicial aproximado de X2 =  %f", x);
		 x = metodoNewtonRapson(x, 6, A, B, C);
		 evalua(x, A, B, C);
		 printf("\n");
	      } else {
		 // Raices complejas
		 printf("Raices Complejas ...");
	      }
	}
};


int main(void)
{
      cuadratica cu1 =  cuadratica(1.0, 4.0, 1.0);
      cu1.raices();

      return 0;	
}