//Ejemplos con TNT y JAMA
//compilar con g++ -I./templates  jama_ejemplos.cpp
#include <iostream>
#include <iomanip>
#include "algebralineal.h"
using namespace std;
using namespace CALNUM;

typedef  long  double Real; //tipo generico Real

int main(){
cout<< "Entrar dimension"<<endl;
int n;
cin>>n;
Matrix<Real> D(n,n);
Matrix<Real> E(n,n);


//Choleski. Atencion la matriz debe ser definida positiva
for(int  i=0;i<n;i++)
  for(int j=0;j<n;j++)
   D[i][j]=Real(1.)/Real(i+j+1.);
cout<<D<<endl;
Cholesky<Real> chol(D);
Matrix<Real>ME=chol.getL();
Matrix<Real> MET= transpose(ME);
cout<<"matriz de Cholesky ME"<<endl<<ME<<endl;
cout<<"transpuesta ME"<<endl<<MET<<endl;
cout<<"producto cholesky"<<endl<<ME*transpose(ME)<<"matriz inicial"<<endl<<
D<<endl;

//descomposicion LU
LU<Real>  lu(D); //Se crea un elemento lu de la clase  de algoritmosLU
Matrix<Real> L=lu.getL();  //obtencion matriz L
cout<<L<<endl;
Matrix<Real>U=lu.getU(); //Obtencion matriz U
cout<<U<<endl;
Real det=lu.det(); //Obtencion determinante
cout<<"det="<<det<<endl;
cout<<"L*U= "<<L*U<<endl; //Producto L*U
Matrix<Real> ID=lu.inv(); //Calculo de la inversa
cout<<"inversa = "<<ID<<endl;
Matrix<Real> X1= D*ID;
cout<<"D*ID="<<X1<<endl; //comprobacion D*inv(D)=I

Matrix<Real> XX(n,n); //Creacion matriz identidad
XX=0;
for(int  i=1;i<=n;i++)
XX(i,i)=1.0;
XX=lu.solve(XX); //Calculo de la inversa por resolucion de ecuaciones
cout<<"XX= "<<XX<<endl;



//valores y vectores  propios
Eigenvalue<Real> eig(D); //Se crea un elemennto eig de la clase Eingenvalue
Vector<Real> lambda; //creacion vector de valores propios reales en lambda
eig.getRealEigenvalues(lambda);  //relleno de lambda con los valores propios
//vectores propios, se escriben en la matriz G
Matrix<Real> G;
eig.getV(G); //relleno de G
//matriz diagonal, seescribe en H
Matrix<Real> H;
eig.getD(H);
cout<<" valores propios = "<<lambda<<endl;
cout<<"Matriz Diagonal= "<<H<<endl;
cout<<" Vectores propios = "<< G<<endl;

//Resolucion de ecuaciones
Vector<Real> bb= lu.solve(lambda); //Solucion de A*bb=lambda
cout<<" bb= "<< bb<<endl;
cout<<"D*bb= "<<D*bb<<endl; //Comprobacion A*bb=lambda

}
