//Ejemplos con  JAMA
//compilar con
//g++ -I./templates  tnt_ejemplos.cpp
#include "algebralineal.h"
#include <cmath>
#include <iostream>
#include <iomanip>
using  namespace std;
using namespace CALNUM;
typedef double Double;
int main(){
setprecision(8);
Stopwatch Q;
Q.start();
{
int N=10;
CALNUM::Matrix<Double> A(N,N),B(N,N),C(N,N);
for (int i=0;i<N;i++)for (int j=0;j<N;j++) 
{A[i][j]=1./(i+j+2); B[i][j]=(1./(i+j+2));}
C=matmult(A,B);
cout<<C<<endl;

//descomposicion LU
CALNUM::LU<Double>  lu(C);
Matrix<Double> L(N,N);
L=lu.getL();
cout<<"L="<<L<<endl;
Matrix<Double> U=lu.getU();
cout<<U<<endl;
Vector<int> p=lu.getPivot();
cout<<p<<endl;
Matrix<Double>NM(N,N);
NM=matmult(L,U);
cout<<"L*U"<<NM<<endl;
Double det=lu.det();
cout<<"det="<<det<<endl;


//valores propios
Eigenvalue<Double> eig(A);
Vector<Double> aa(N);
//pones los valores propios reales en aa
eig.getRealEigenvalues(aa);
//vectores propios, se escriben en la matriz G
eig.getV(L);
//matriz diagonal, seescribe eb H
Matrix<Double> H(N,N);
H=0.;
eig.getD(H);
cout<<"Valores Propios="<<aa<<endl;
cout<<"Vectores Propios="<<L<<endl;
cout<<"Matriz diagonal="<<H<<endl;


//Resolucion de ecuaciones, bb es el Array1D de soluciones
Vector<Double> bb= lu.solve(aa);
cout<<"aa="<<aa;
cout<<"bb="<<bb<<endl;

//calculo de la inversa
//Definicion de la matriz identidad XX
//inicializacion de XX a la matriz nula
Matrix<Double> XX(N,N,0.);
for (int i=0;i<N;i++) XX[i][i]=1.;
//cout<<XX<<endl;
// la inversa ZZ es la solucion de A*ZZ=XX;
Matrix<Double> ZZ=lu.solve(XX);
//cout<<ZZ<<endl;
Matrix<Double> QQ=matmult(ZZ,C);// QQ matriz identidad.
//Incluso con long double falla miserablemente para N=20 y la matriz de Hilbert C=A.
// Para C=A*B falla incluso para N=7
cout<<"Matriz identidad="<<QQ<<endl;

}
Q.stop();
double time=Q.read();

cout<<"time="<<time<<endl;
}
