1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173
|
// FUNCION PARA CALCULAR EL ERROR DEL SISTEMA
real mn_error_sistema(const Array2D< real > &A, const Array1D< real > &u, const Array1D< real > &b)
{
int i;
if(b.dim()==0 || b.dim()!=u.dim() || b.dim()!=A.dim1() || b.dim()!=A.dim2()) return(0.);
Array1D< real > e=A*u-b;
real Sum=0.;
for (i=0;i<b.dim();i++){
Sum = Sum + mn_abs(e[i])/(mn_abs(b[i])+ 1.);
}
return (Sum/b.dim());
}
/* FUNCION PARA LEER UN VECTOR DE DISCO. RETORNA LA DIMENSION DEL VECTOR */
int mn_leer_vector(
char *nombrefichero,
Array1D< real > &vector)
{
int dimension;
float paso;
FILE *f;
// ABRIMOS EL FICHERO
if(f=fopen( nombrefichero, "r"),!f){
printf("Problema con la apertura del fichero\n");
return -1;
}
// LEEMOS LA DIMENSION
fscanf(f,"%d\n",&dimension);
if(dimension<1) return(-2);
// COGEMOS MEMORIA
Array1D< real > v(dimension);
// LEEMOS EL VECTOR
for(int i=0;i<dimension;i++){
fscanf(f,"%f\n",&paso);
v[i]=paso;
}
fclose(f);
vector=v.copy();
return dimension;
}
/* FUNCION PARA ESCRIBIR UN VECTOR DE DISCO DE DIMENSION dimension Y LO ALMACENA EN vector */
int mn_escribir_vector(
char *nombrefichero,
Array1D< real > &vector)
{
int i;
FILE *f;
int dimension=vector.dim();
if(f=fopen( nombrefichero, "w"),!f){
printf("Problema con la escritura del fichero\n");
return 1;
}
fprintf(f,"%d\n",dimension);
for(i=0;i<dimension;i++) fprintf(f,"%f\n",(float) vector[i]);
fclose(f);
return 0;
}
/* FUNCION PARA LEER UNA MATRIZ DE DISCO DE DIMENSION
dimension Y LO ALMACENA EN LA MATRIZ matriz */
int mn_leer_matriz(
char *nombrefichero,
Array2D< real > &matriz)
{
int dimension1,dimension2;
float paso;
FILE *f;
if(f=fopen( nombrefichero, "r"),!f){
printf("Problema con la apertura del fichero\n");
return 1;
}
fscanf(f,"%d %d\n",&dimension1, &dimension2);
if(dimension1<1 || dimension2<1) return(-1);
// RESERVAMOS MEMORIA PARA LA MATRIZ
Array2D< real > m(dimension1,dimension2);
for(int i=0;i<dimension1;i++){
for(int j=0;j<dimension2;j++){
fscanf(f,"%f ",&paso);
m[i][j]=paso;
//printf("paso=%e\n",(double) m[i][j]);
}
fscanf(f,"\n");
}
fclose(f);
matriz=m.copy();
return dimension1;
}
/* FUNCION PARA ESCRIBIR UNA MATRIZ EN DISCO
dimension */
int mn_escribir_matriz(
char *nombrefichero,
Array2D< real > &matriz)
{
int i,j;
FILE *f;
if(f=fopen( nombrefichero, "w"),!f){
printf("Problema con la escritura del fichero\n");
return 1;
}
fprintf(f,"%d %d\n",matriz.dim1(),matriz.dim2());
for(i=0;i<matriz.dim1();i++){
for(j=0;j<matriz.dim2();j++){
fprintf(f,"%f ",(float) matriz[i][j]);
}
fprintf(f,"\n");
}
fclose(f);
return 0;
}
/* FUNCIÓN PARA CALCULAR EL CONDICIONAMIENTO DE UNA MATRIZ SIMETRICA.
UTILIZA EL METODO DE JACOBI PARA CALCULAR LOS AUTOVALORES.
CALCULA EL MÁXIMO Y MÍNIMO EN VALOR ABSOLUTO DE LOS AUTOVALORES.
LA FUNCIÓN DEVUELVE EL COCIENTE ENTRE ELLOS.
*/
real mn_condicionamiento(Array2D< real >&A){
int NMaxIter=100000; //NUMERO MÁXIMO DE ITERACIONES PARA EL MÉTODO DE JACOBI
real TOL=1e-6; //TOLERANCIA PARA EL MÉTODO DE JACOBI
// SE APLICA EL METODO DE JACOBI
Array2D< real > B(A.dim1(),A.dim2()); //matriz de autovectores
int Niter;
Array1D< real > u=jacobi(A,B,NMaxIter,TOL,Niter); //CALCULA LOS AUTOVALORES
real max = u[0];
real min = u[0];
/* A IMPLEMENTAR POR EL ALUMNO */
for (int i = 0; i < A.dim1();i++){//iniciamos B con los autovalores
B[i][i] = u[i];//necesario?
}
for (int k = 1; k < A.dim1(); k++){ //Calculo maximo de u
if (max < fabs(u[k])) max = fabs(u[k]);
}
for (int k = 1; k < A.dim1(); k++){//Calculo minimo de u
if (min > fabs(u[k])) min = fabs(u[k]);
}
return max/min;
}
real mn_condicionamiento(const Array2D< real > &A,const int NMaxIter, const real TOL)
{
// HACER ALUMNO
if(A.dim1()!=A.dim2()) return(-1.); //comprobamos que la matriz es cuadrada
// EJECUTAMOS LA FUNCION JACOBI PARA CALCULAR LOS AUTOVALORES Y AUTOVECTORES
int Niter,N=A.dim1();
Array2D< real > Autovectores(N,N);
Array1D< real > Autovalores=jacobi (A,Autovectores, NMaxIter, TOL,Niter);
if(Niter==-1) return(-1.);
// CALCULAMOS EL AUTOVALOR MAXIMO Y MINIMO EN VALOR ABSOLUTO
real autovalor_minimo=mn_abs(Autovalores[0]);
real autovalor_maximo=autovalor_minimo;
for(int k=1;k<N;k++){
real paso=mn_abs(Autovalores[k]);
if(paso<autovalor_minimo) autovalor_minimo=paso;
else if(paso>autovalor_maximo) autovalor_maximo=paso;
}
return(autovalor_maximo/autovalor_minimo);
}
|