// Clase para manipular vectores
// Antonio Carrillo Ledesma


public class Vector <T extends Numero> {

   // Coeficientes del vector
   private Numero [] c;

   // Guarda la dimension del arreglo de coeficientes
   private int dim;

   // Constructor de la clase
   public Vector() {
      dim = 0;
   }


   // Asigna coeficientes
   public void asignaCoeficientes(Numero []coef) {
      int i, n = coef.length;
      c = new Numero[n];
      for (i = 0; i < n; i++) c[i] = coef[0].nuevo();
      dim = n;
      for (i = 0; i < n; i++) c[i]  = coef[i];
   }


   // Retorna los coeficientes
   Numero coeficiente(int i) {
      if (i >= dim) {
         System.out.print("Error");
         return c[0].nuevo();
      }
      return c[i];
   }


   // Retorna la dimension del arreglo de coeficientes
   int dimension() {
      return dim;
   }


   // Visualiza el vector
   public void visualiza() {
      int i;
      System.out.print("(");
      for (i = 0; i < dim; i++) {
         c[i].visualiza();
         if(i < dim - 1) System.out.print(", ");
      }
      System.out.print(")");
   }

   // Visualiza el vector
   public void visualizaLN() {
      visualiza();
      System.out.println("");
   }


   // Suma con dos operandos
   public void suma(Vector a, Vector b) {
      int i;
      dim = 0;

      // Revisa el tamano de los vectores
      if(a.dimension() != b.dimension()) {
         System.out.println("Error, las dimensiones no son iguales");
      } else {
         // Solicita memoria para los coeficientes del vector resultante
         dim = a.dimension();
         c = new Numero[dim];
         for (i = 0; i < dim; i++) c[i] = a.coeficiente(0).nuevo();
         // Realiza la suma entre el coeficientes comunes
         for (i = 0; i < dim; i++)  c[i].suma(a.coeficiente(i), b.coeficiente(i));
      }
   }


   // Suma con un operando
   public void suma(Vector a) {
      int i;
      dim = 0;
      // Revisa el tamano de los vectores
      if(dimension() != a.dimension()) {
         System.out.println("Error, las dimensiones no son iguales");
      } else {
         // Realiza la suma entre el coeficientes comunes
         for (i = 0; i < dim; i++)  c[i].suma(a.coeficiente(i));
      }
   }




   // Funcion Principal ....
   public static void main(String[] args) {

      // Ejemplito para vectores de coeficientes de tipo Double
      Double []r = new Double[3];
      r[0] = new Double(1);
      r[1] = new Double(2);
      r[2] = new Double(3);
      Double []s = new Double[3];
      s[0] = new Double(5);
      s[1] = new Double(6);
      s[2] = new Double(7);

      Vector<Double> R = new Vector<Double> ();
      R.asignaCoeficientes(r);
      Vector<Double> S = new Vector<Double> ();
      S.asignaCoeficientes(s);
      Vector<Double> TT = new Vector<Double> ();

      System.out.println("Double");
      R.visualizaLN();
      System.out.println("+");
      S.visualizaLN();
      TT.suma(R, S);
      System.out.println("=====================");
      TT.visualizaLN();
      System.out.println("");
      System.out.println("");



      // Ejemplito para vectores de coeficientes de tipo Fraccion
      Fraccion []a = new Fraccion[3];
      a[0] = new Fraccion(1, 2);
      a[1] = new Fraccion(2, 2);
      a[2] = new Fraccion(3, 2);
      Fraccion []b = new Fraccion[3];
      b[0] = new Fraccion(1, 3);
      b[1] = new Fraccion(2, 3);
      b[2] = new Fraccion(3, 3);

      Vector<Fraccion> A = new Vector<Fraccion> ();
      A.asignaCoeficientes(a);
      Vector<Fraccion> B = new Vector<Fraccion> ();
      B.asignaCoeficientes(b);
      Vector<Fraccion> C = new Vector<Fraccion> ();

      System.out.println("Fraccion");
      A.visualizaLN();
      System.out.println("+");
      B.visualizaLN();
      C.suma(A, B);
      System.out.println("=====================");
      C.visualizaLN();
      System.out.println("");
      System.out.println("");



      // Ejemplito de vectores de coeficionets de tipo Complejos
      Complejos []x = new Complejos[3];
      x[0] = new Complejos(2, 3);
      x[1] = new Complejos(2, 2);
      x[2] = new Complejos(3, 2);
      Complejos []y = new Complejos[3];
      y[0] = new Complejos(-2, -3);
      y[1] = new Complejos(2, 3);
      y[2] = new Complejos(3, 3);

      Vector<Complejos> X = new Vector<Complejos>();
      X.asignaCoeficientes(x);
      Vector<Complejos> Y = new Vector<Complejos>();
      Y.asignaCoeficientes(y);
      Vector<Complejos> Z = new Vector<Complejos>();

      System.out.println("Complejo");
      X.visualizaLN();
      System.out.println("+");
      Y.visualizaLN();
      Z.suma(X, Y);
      System.out.println("=====================");
      Z.visualizaLN();
      System.out.println("");
      System.out.println("");



      // Ejemplito de vectores de coeficionets de tipo ComplejoFraccionario
      ComplejoFraccionario []xx = new ComplejoFraccionario[3];
      xx[0] = new ComplejoFraccionario(2, 3, 4, 5);
      xx[1] = new ComplejoFraccionario(2, 2, 3, 7);
      xx[2] = new ComplejoFraccionario(3, 2);
      ComplejoFraccionario []xy = new ComplejoFraccionario[3];
      xy[0] = new ComplejoFraccionario(-2, 3, 5, 6);
      xy[1] = new ComplejoFraccionario(2, 3, 7, 9);
      xy[2] = new ComplejoFraccionario(3, 3);

      Vector<ComplejoFraccionario> xX = new Vector<ComplejoFraccionario>();
      xX.asignaCoeficientes(xx);
      Vector<ComplejoFraccionario> xY = new Vector<ComplejoFraccionario>();
      xY.asignaCoeficientes(xy);
      Vector<ComplejoFraccionario> xZ = new Vector<ComplejoFraccionario>();

      System.out.println("Complejo Fraccionario");
      xX.visualizaLN();
      System.out.println("+");
      xY.visualizaLN();
      xZ.suma(xX, xY);
      System.out.println("=====================");
      xZ.visualizaLN();
      System.out.println("");
      System.out.println("");

   }
}