import java.awt.*;
import Jama.*;
//import java.awt.event.*;
import java.io.*;
import java.util.Date;
import java.applet.Applet; 

public class Applet1  extends Applet {

TextField renglones;
TextField columnas;
TextField caracteres;
Date start_time;
Date stop_time; 
double etime;
Choice menu1,menu2,menu3,menu4;
Button boton1,boton2,boton3;
TextArea Area = new TextArea(20,90);
Matrix A,B,C;
String ns,ms,paths;

 public void init() {       
       
       CheckboxGroup cbg = new CheckboxGroup();
       Panel p = new Panel();
       boton1 = new Button("Crear"); 
       boton2 = new Button("Leer"); 
       boton3 = new Button("Borrar"); 
      
      // p.setLayout(new GridLayout(7,1));  
       p.add(new Label("n")); 
       p.add(renglones = new TextField(5)); 
       p.add(new Label("m"));
       p.add(columnas = new TextField(5));
       p.add(new Label("No. de caracteres"));
       p.add(caracteres = new TextField(8));
       p.add(boton1);
       p.add(boton2);
       p.add(boton3);

       menu2 = new Choice();
       menu2.add("Suma");
       menu2.add("Resta");
       menu2.add("Multiplicacion");
       menu2.add("Multiplicacion scalar"); 
       menu2.add("Mult elem*elem");
       menu2.add("A./B");
       menu2.add("B./A");
       menu2.add("Resta con la unitaria");
       
       menu3 = new Choice();
       menu3.add("Determinante");
       menu3.add("Inversa");
       menu3.add("Rango");
       menu3.add("Traza"); 
       menu3.add("Transpuesta");

       menu4 = new Choice(); 
       menu4.add("Descomposicion LU");
       menu4.add("Descomposicion Cholesky");
       menu4.add("Descomposicion SVD");
       menu4.add("Descomposicion de Eigen Valores"); 
       menu4.add("Descomposicion QR");
       
      // add(menu2);
       add(menu3);
       add(menu4);  
       add(Area);
       add("West",p); 
       validate();
     }

  public boolean action(Event event, Object arg){ 
   
     if(event.arg.equals("Leer")){

       int n = new Integer(renglones.getText()).intValue(); 
       int m = new Integer(columnas.getText()).intValue(); 
       int caract = new Integer(caracteres.getText()).intValue(); 
       caract++; 
       A = new Matrix(n,m); 
       for(int i=0,j=caract,k=0,l=0,bandera=0; i <= caract*(n*m-1); i+=caract,j+=caract,l++,bandera++){
	 Area.select(i,j);
	 if(bandera >= m){
	   bandera=0; 
	   l=0;
	   k++;
         }
       A.set(k,l,new Double(Area.getSelectedText()).doubleValue());
       } 
       Area.appendText("\n");
       print(A,Area);

    
    
    
    
    
    /*  
        Lectura de archivos. 
    
       paths = path.getText();
       
       FileInputStream file_in;
       DataInputStream data_in;

       try {
            file_in = new FileInputStream(paths); 
	     data_in = new DataInputStream(file_in); 
            for(int i = 0; i < n; i++)   
              for(int j =0; j < m; j++)
                    A.set(i,j,data_in.readFloat()); 
            
       } 
       catch (FileNotFoundException e){
     	  System.err.println(file_in + " no se encontro");
        } 
        catch (IOException e) {
	     e.printStackTrace();
       } */


   }

     if(event.arg.equals("Crear")){
          
       ns = renglones.getText();
       int n = new Integer(ns).intValue();
       ms = columnas.getText();
       int m = new Integer(ms).intValue();
       A = new Matrix(n,m);
       A = A.random(n,m); 
      // Area.appendText("\n");
       print(A,Area);
   
     }

     if(event.arg.equals("Borrar")){
       Area.selectAll();
       Area.replaceRange("",Area.getSelectionStart(),Area.getSelectionEnd());
     }
  



    if(event.target instanceof Choice){ 
   
       if(event.arg.equals("Suma")){
          start_time = new Date(); 
          C=A.plus(B);
	  stop_time = new Date(); 
          Area.appendText("\n\nSuma\n");
          print(C,Area);
          etime = (stop_time.getTime()-start_time.getTime())/1000.;
          Area.appendText("\nLapso de tiempo es: " +etime); 
     }           
  
     if(event.arg.equals("Resta")){
         Area.appendText("\n\nResta\n");
          start_time = new Date();	
	 C=A.minus(B);
         stop_time = new Date(); 
	 print(C,Area); 
         etime = (stop_time.getTime()-start_time.getTime())/1000.;
         Area.appendText("Lapso de tiempo es: " +etime);
     }  


     if(event.arg.equals("Multiplicacion")){
	 Area.appendText("\n\nMultiplicacion\n");
	 start_time = new Date(); 
	 C=A.times(B);
         stop_time = new Date(); 
	 etime = (stop_time.getTime()-start_time.getTime())/1000.; 
	 print(C,Area);
	 Area.appendText("Lapso de tiempo es: " +etime);
     }
     if(event.arg.equals("Mult elem*elem")){
	Area.appendText("\n\nMultiplicacion elemento por elemento de A*B\n");
        start_time = new Date();	
	C = A.arrayTimes(B);
        stop_time = new Date();	
        etime = (stop_time.getTime()-start_time.getTime())/1000.;	
	print(C,Area);
	Area.appendText("Lapso de tiempo es: " +etime);
     }

     if(event.arg.equals("A./B")){
        Area.appendText("\n\nDivision elemento por lemento de A./B\n");
        start_time = new Date(); 
        C = A.arrayRightDivide(B);
        stop_time = new Date();
        etime = (stop_time.getTime()-start_time.getTime())/1000.;
        print(C,Area);
        Area.appendText("Lapso de tiempo es: " +etime); 
	}
     if(event.arg.equals("B./A")){
         Area.appendText("\n\nDivision elemento por elemento de B./A\n");
         start_time = new Date(); 
         C = A.arrayLeftDivide(B);
         stop_time = new Date();
         etime = (stop_time.getTime()-start_time.getTime())/1000.;
         print(C,Area);
         Area.appendText("Lapso de tiempo es: " +etime);
        }
       if(event.arg.equals("Resta con la unitaria")){
	 Area.appendText("\n\nA menos la unitaria\n");
         start_time = new Date(); 
	 C = A.uminus();
	 stop_time = new Date();
	 etime = (stop_time.getTime()-start_time.getTime())/1000.;
	 print(C,Area);
         Area.appendText("Laso de tiempo es: " +etime); 
       }
        if(event.arg.equals("Determinante")){
	  
           start_time = new Date(); 
	   double  det  = A.det();
           stop_time = new Date(); 
	   etime =(stop_time.getTime()-start_time.getTime())/1000.; 
           Area.appendText("\n\nEl determinante es " +det);
           Area.appendText("\nLapso de tiempo es: " +etime);
      }
	if(event.arg.equals("Inversa")){
	  
	  Area.appendText("\nLa inversa ");  
          start_time = new Date();
	  C = A.inverse();
          stop_time = new Date(); 
	  etime = (stop_time.getTime()-start_time.getTime())/1000.; 
	  print(C,Area);
          Area.appendText("\nLapso de tiempo es: " +etime); 
	} 
	 if(event.arg.equals("Rango")){
	  start_time = new Date();
	  int rango = A.rank();
	  stop_time = new Date();
	  etime = (stop_time.getTime()-start_time.getTime())/1000.; 
	  Area.appendText("\n\nEl rango es " +rango);
          Area.appendText("\nLapso de Tiempo es: " +etime);
	 }

	 if(event.arg.equals("Traza")){
	   start_time = new Date();
	   double traza = A.trace();
	   stop_time = new Date();
	   etime = (stop_time.getTime()-start_time.getTime())/1000.;
	   Area.appendText("\n\nLa traza  es " +traza);
           Area.appendText("\nLapso de tiempo es: " +etime); 
	 }
	if(event.arg.equals("Transpuesta")){
	  start_time = new Date();
	  C = A.transpose();
          stop_time = new Date();
	  etime = (stop_time.getTime()-start_time.getTime())/1000.;
          Area.appendText("\n\nLa transpuesta es"); 
          print(C,Area);
          Area.appendText("\nLapso de tiempo es: " +etime); 
	}

        if(event.arg.equals("Descomposicion LU")) 
           printLU(A,Area); 
        if(event.arg.equals("Descomposicion Cholesky"))
	   printCh(A,Area);
	if(event.arg.equals("Descomposicion de Eigen Valores"))
	   printEV(A,Area);
	if(event.arg.equals("Descomposicion QR"))
	   printQR(A,Area);
        if(event.arg.equals("Descomposicion SVD"))
	   printSVD(A,Area);
         return true;
       }
    return false;
}

public void printLU(Matrix F,TextArea T){
LUDecomposition LU = F.lu();
Matrix L,U;
Date start_time,stop_time; 
double etime;   
   start_time = new Date(); 
   L = LU.getL(); 
   U = LU.getU();
   stop_time = new Date();
   etime =(stop_time.getTime()-start_time.getTime())/1000.;
   T.appendText("\nDescomposicion LU\n"); 
   Area.appendText("\nL = ");
   print(L,T);
   Area.appendText("\nU =");
   print(U,T);
   T.appendText("\nLapso de tiempo es: " +etime);
} 

public void printCh(Matrix F, TextArea T){
CholeskyDecomposition Ch = F.chol();
Matrix L; 
Date start_time,stop_time;
double etime;
    start_time = new Date();  
    L = Ch.getL();
    stop_time = new Date();
    etime = (stop_time.getTime()-start_time.getTime())/1000.;
    T.appendText("\n\nDescomposicion de Cholesky\n"); 
    if (Ch.isSPD())
    print(L,T);
    else
    T.appendText("\n La matriz no es definida positiva");
    T.appendText("\nLapso de tiempo es: "+etime);
}
 
 
public void printEV(Matrix F, TextArea T){
EigenvalueDecomposition EV = F.eig();
Matrix D,V;
double ieigv[], reigv[],etime;
Date start_time,stop_time;
     start_time = new Date();
      D = EV.getD();
      V = EV.getV();
      ieigv = EV.getImagEigenvalues(); 
      reigv = EV.getRealEigenvalues();
      stop_time = new Date();
      etime = (stop_time.getTime()-start_time.getTime())/1000.;
      T.appendText("\n\nDescomposicion Eigen Valores\n");
      T.appendText("\nMatrix diagonal de Eigen Valores ");
      print(D,T);
      T.appendText("\nMatrix de Eigen Vectores ");
      print(V,T);
      T.appendText("\nParte imaginaria de los Eigen Valores: \n");
      for (int i = 0; i<= 5; i++)
        T.appendText(String.valueOf(" " +(float) ieigv[i]));
      T.appendText("\nParte real de los Eigen Valores: \n");
      for (int j = 0; reigv[j] != 0; j++)
      T.appendText(String.valueOf( "  "+ (float) reigv[j]));
 
      T.appendText("\n Lapso de tiempo es: " +etime);
} 
 

public void printQR(Matrix F, TextArea T){
QRDecomposition QR= F.qr();
Matrix H,Q,R;
double etime;
Date start_time,stop_time; 
        
	start_time = new Date();	
	H = QR.getH();
        Q = QR.getQ();
	R = QR.getR();
        stop_time = new Date();	
        etime = (stop_time.getTime()-start_time.getTime())/1000.;	
        T.appendText("\n\nDescomposicion QR\n");	
        T.appendText("\nFactor Triangular Superior");
        print(R,T);
	T.appendText("\nFactor Ortogonal");
	print(Q,T);
	T.appendText("\nVectores Householder");
	print(H,T);
	T.appendText("\nLapso de tiempo es: " +etime);
        
 } 

public void printSVD(Matrix F, TextArea T){
SingularValueDecomposition SVD = F.svd();
Matrix S,U,V;
double etime;
Date start_time, stop_time; 
   start_time = new Date();
   S=SVD.getS();
   U=SVD.getU();
   V=SVD.getV();
   stop_time = new Date();
   etime = (stop_time.getTime()-start_time.getTime())/1000.;
   T.appendText("\n\nDescomposicion SVD\n"); 
   T.appendText("\nMatriz diagonoal de valores singulares");
   print(S,T);
   T.appendText("\nMatriz de vectores singulares izquierdos");
   print(U,T);
   T.appendText("\nMatriz de vectores singulares derechos");
   print(V,T);
   T.appendText("\nLapso de tiempo es: " +etime);

}

public boolean handleEvent(Event evt){
       if(evt.id == Event.WINDOW_DESTROY && evt.target == this)
         System.exit(0);
         return super.handleEvent(evt);
     }

  
     
    public void print(Matrix A, TextArea Area){
     Area.appendText("\n"); 
     for(int i= 0; i < A.getRowDimension(); i++){
	 for(int j=0 ;j < A.getColumnDimension(); j++)
	 // System.out.print(" "+A.get(i,j));
	  Area.appendText(String.valueOf("  "+(float)  A.get(i,j)));
           Area.appendText("\n");
       }
     }
      
  
  } /* Applet */

/*
class Crer extends Frame {

  Crear(String ttle) {
  super(title);
  
*/
