Documentos de Académico
Documentos de Profesional
Documentos de Cultura
COMPUTACIONAL 2
MÉTODO DE JACOBI
Quispe Chuquitarqui Henry Nicolás CUI:20162704
31 de diciembre de 2017
1. Introducción
1
por métodos directos (como eliminación o factorización).
El método de Jácobi es un método iterativo con el cual se resuelve el sistema
lineal
Ax = b
Comienza con una aproximación inicial x(0) a la solución x y genera una
sucesión de vectores x(k) que convergen a la solución x.
Un sistema de ecuaciones algebraicas lineales es un conjunto de ecuaciones
de la forma:
1.2.1. DESCRIPCIÓN:
La base del método consiste en construir una sucesión convergente
definida iterativamente. El lı́mite de esta sucesión es precisamente la
solución del sistema. A efectos prácticos si el algoritmo se detiene después
de un número finito de pasos se llega a una aproximación al valor de x de la
solución del sistema.
2
La sucesión se construye descomponiendo la matriz del sistema A en la
forma siguiente:
A=D+R
Dx + Rx = b
Luego:
x = D−1 (B − Rx)
3
21
22 void ru n_jaco bi_met hod
23 ( int n , double ** A , double *b ,
24 double epsilon , int maxit ,
25 int * numit , double * x ) ;
26 /*
27 * Runs the Jacobi method for A * x = b .
28 *
29 * ON ENTRY :
30 * n the dimension of the system ;
31 * A an n - by - n matrix A [ i ][ i ] /= 0;
32 * b an n - dimensional vector ;
33 * epsilon accuracy requirement ;
34 * maxit maximal number of iterations ;
35 * x start vector for the iteration .
36 *
37 * ON RETURN :
38 * numit number of iterations used ;
39 * x approximate solution to A * x = b . */
40
41 int main ( int argc , char * argv [] )
42 {
43 int n = 150 , i ;
44 double * b ;
45 b = ( double *) calloc (n , sizeof ( double ) ) ;
46 double ** A ;
47 A = ( double **) calloc (n , sizeof ( double *) ) ;
48 for ( i =0; i < n ; i ++)
49 A [ i ] = ( double *) calloc (n , sizeof ( double ) ) ;
50 test_system (n ,A , b ) ;
51 double * x ;
52 x = ( double *) calloc (n , sizeof ( double ) ) ;
53 /* we start at an array of all zeroes */
54 for ( i =0; i < n ; i ++) x [ i ] = 0.0;
55 double eps = 1.0 e -4;
56 int maxit = 2* n * n ;
57 int cnt = 0;
58 run_ jacob i_meth od (n ,A ,b , eps , maxit ,& cnt , x ) ;
59 printf ( " computed %d iterations \ n " , cnt ) ;
60 double sum = 0.0;
61 for ( i =0; i < n ; i ++) /* compute the error */
62 {
63 double d = x [ i ] - 1.0;
64 sum += ( d >= 0.0) ? d : -d ;
65 }
4
66 printf ( " error : %.3 e \ n " , sum ) ;
67 return 0;
68 }
69
70 void test_system ( int n , double ** A , double * b )
71 {
72 int i ,j , k ;
73 // comando que lee los datos de iris
74 FILE * fp = fopen ( " iris_3 . data " , " r " ) ;
75
76 double sum0 = 0.0;
77 double sum1 = 0.0;
78 double sum2 = 0.0;
79 double sum3 = 0.0;
80
81 int aux ;
82
83 double mat [ n ][4];
84
85 for ( i =0; i < n ; i ++) {
86 // recoger valores
87 fscanf ( fp , " %lf %lf %lf %lf %d " , & mat [ i
][0] , & mat [ i ][1] , & mat [ i ][2] , & mat [ i
][3] , & aux ) ;
88
89 // acumular las sumas de una columna
90 sum0 += mat [ i ][0];
91 sum1 += mat [ i ][1];
92 sum2 += mat [ i ][2];
93 sum3 += mat [ i ][3];
94 }
95
96 // promedio
97 double prom0 = sum0 / n ;
98 double prom1 = sum1 / n ;
99 double prom2 = sum2 / n ;
100 double prom3 = sum3 / n ;
101
102 // restar el promedio
103 for ( i =0; i < n ; i ++) {
104 mat [ i ][0] -= prom0 ;
105 mat [ i ][1] -= prom1 ;
106 mat [ i ][2] -= prom2 ;
107 mat [ i ][3] -= prom3 ;
108 }
5
109
110 // crear la matriz transpuesta
111 double matTrans [4][ n ];
112 for ( i =0; i < n ; i ++) {
113 matTrans [0][ i ] = mat [ i ][0];
114 matTrans [1][ i ] = mat [ i ][1];
115 matTrans [2][ i ] = mat [ i ][2];
116 matTrans [3][ i ] = mat [ i ][3];
117 }
118
119 // multiplicar normal por la transpuesta
120 double matAnswer [150][150];
121 for ( i =0; i < n ; i ++) {
122 for ( j =0; j < n ; j ++) {
123 double suma = 0.0;
124 for ( k =0; k <4; k ++) {
125 suma += mat [ i ][ k ]* matTrans [
k ][ j ];
126 }
127 matAnswer [ i ][ j ] = suma ;
128 }
129 }
130
131 // multiplicar todo por 1/ n = 1/150
132 for ( i =0; i <150; i ++) {
133 for ( j =0; j <150; j ++) {
134 matAnswer [ i ][ j ] /= 1.0* n ;
135 }
136 }
137
138
139
140
141 fclose ( fp ) ;
142
143 for ( i =0; i < n ; i ++)
144 {
145 b [ i ] = 0.0;
146 for ( j =0; j < n ; j ++)
147 A [ i ][ j ] = 1.0;
148 A [ i ][ i ] = matAnswer [ i ][ j ];
149 }
150 }
151
6
152 void ru n_jaco bi_met hod ( int n , double ** A , double *b ,
double epsilon , int maxit , int * numit , double * x )
153 {
154 double * dx ,* y ;
155 dx = ( double *) calloc (n , sizeof ( double ) ) ;
156 y = ( double *) calloc (n , sizeof ( double ) ) ;
157 int i ,j , k ;
158
159 for ( k =0; k < maxit ; k ++)
160 {
161 double sum = 0.0;
162 for ( i =0; i < n ; i ++)
163 {
164 dx [ i ] = b [ i ];
165 for ( j =0; j < n ; j ++)
166 dx [ i ] -= A [ i ][ j ]* x [ j ];
167 dx [ i ] /= A [ i ][ i ];
168 y [ i ] += dx [ i ];
169 sum += ( ( dx [ i ] >= 0.0) ? dx [ i ] : - dx [ i ]) ;
170 }
171 for ( i =0; i < n ; i ++) x [ i ] = y [ i ];
172 printf ( " %4d : %.3 e \ n " ,k , sum ) ;
173 if ( sum <= epsilon ) break ;
174 }
175 * numit = k +1;
176 free ( dx ) ; free ( y ) ;
177 }
7
3. Análisis de resultados
8
Utilizando los comandos de octave se calculo los autovalores de la matriz
de covarianza.
1 roots ( poly ( load ( ’ psm . dat ’) ) )
9
4. METODO DE LA POTENCIA SIMPLE
Es un metodo numerico iterativo que se encarga de calcular el autovalor
de mayor valor (autovalor dominate).
1 /* potencia simple */
2
3 # include < stdio .h >
4 # include < stdlib .h >
5 # include < math .h >
6
7 double max ( double a , double b ) {
8 return (a > b ) ? a : b ;
9 }
10
11 int main () {
12 int n = 150;
13 int i ,j , k ;
14
15 FILE * fp = fopen ( " iris_3 . data " , " r " ) ;
16
17 double sum0 = 0.0;
18 double sum1 = 0.0;
19 double sum2 = 0.0;
20 double sum3 = 0.0;
21
22 int aux ;
23
24 double mat [ n ][4];
25
26 for ( i =0; i < n ; i ++) {
27 // recoger valores
28 fscanf ( fp , " %lf %lf %lf %lf %d " , & mat [ i
][0] , & mat [ i ][1] , & mat [ i ][2] , & mat [ i
][3] , & aux ) ;
29
30 // acumular las sumas de una columna
31 sum0 += mat [ i ][0];
32 sum1 += mat [ i ][1];
33 sum2 += mat [ i ][2];
34 sum3 += mat [ i ][3];
35 }
36
37 // promedio
38 double prom0 = sum0 / n ;
10
39 double prom1 = sum1 / n ;
40 double prom2 = sum2 / n ;
41 double prom3 = sum3 / n ;
42
43 // restar el promedio
44 for ( i =0; i < n ; i ++) {
45 mat [ i ][0] -= prom0 ;
46 mat [ i ][1] -= prom1 ;
47 mat [ i ][2] -= prom2 ;
48 mat [ i ][3] -= prom3 ;
49 }
50
51 // crear la matriz transpuesta
52 double matTrans [4][ n ];
53 for ( i =0; i < n ; i ++) {
54 matTrans [0][ i ] = mat [ i ][0];
55 matTrans [1][ i ] = mat [ i ][1];
56 matTrans [2][ i ] = mat [ i ][2];
57 matTrans [3][ i ] = mat [ i ][3];
58 }
59
60 // multiplicar normal por la transpuesta
61 double matAnswer [ n ][ n ];
62 for ( i =0; i < n ; i ++) {
63 for ( j =0; j < n ; j ++) {
64 double suma = 0.0;
65 for ( k =0; k <4; k ++) {
66 suma += mat [ i ][ k ]* matTrans [
k ][ j ];
67 }
68 matAnswer [ i ][ j ] = suma ;
69 }
70 }
71
72 // multiplicar todo por 1/ n = 1/150 para finalmente
73 // optener la matriz de covarianzas
74 for ( i =0; i < n ; i ++) {
75 for ( j =0; j < n ; j ++) {
76 matAnswer [ i ][ j ] /= 1.0* n ;
77 }
78 }
79
80 // metodo de potencia simple
81
82 double z [ n ][1];
11
83 for ( i =0; i < n ; i ++) {
84 z [ i ][0] = 1.0;
85 }
86
87 double w [ n ][1];
88 for ( i =0; i < n ; i ++) {
89 w [ i ][0] = 0.0;
90 }
91
92 // norma de z - w
93 double sum = 0.0;
94 for ( i =0; i < n ; i ++) {
95 sum += pow ( z [ i ][0] - w [ i ][0] , 2) ;
96 }
97 double norma = sqrt ( sum ) ;
98
99
100 while ( norma > pow (10 , -14) ) {
101 // w = z
102 for ( i =0; i < n ; i ++) {
103 w [ i ][0] = z [ i ][0];
104 }
105
106 // z = A * w
107 double maxValue = 0;
108 for ( i =0; i < n ; i ++) {
109 for ( j =0; j <1; j ++) {
110 z [ i ][ j ] = 0.0;
111 for ( k =0; k < n ; k ++) {
112 z [ i ][ j ] +=
matAnswer [ i ][ k
]* w [ k ][ j ];
113 }
114 maxValue = max ( maxValue ,
fabs ( z [ i ][ j ]) ) ;
115 }
116 }
117
118 // comprobacion
119
120 for ( i =0; i < n ; i ++) {
121 if ( fabs ( z [ i ][0]) == maxValue ) {
122 break ;
123 }
124 }
12
125
126
127 // z = z / z [ end ]
128 for ( i =0; i < n ; i ++) {
129 z [ i ][0] /= z [n -1][0];
130 }
131
132 // hallar nueva norma
133 sum = 0.0;
134 for ( i =0; i < n ; i ++) {
135 sum += pow ( z [ i ][0] - w [ i ][0] , 2) ;
136 }
137 norma = sqrt ( sum ) ;
138 }
139
140 // autovalor = ( z ’* A * z ) /( z ’* z )
141
142 // zt = z ’
143 double zt [1][ n ];
144 for ( i =0; i < n ; i ++) {
145 zt [0][ i ] = z [ i ][0];
146 }
147
148 // ztA = z ’* A
149 double ztA [1][ n ];
150 for ( i =0; i <1; i ++) {
151 for ( j =0; j < n ; j ++) {
152 ztA [ i ][ j ] = 0.0;
153 for ( k =0; k < n ; k ++) {
154 ztA [ i ][ j ] += zt [ i ][ k ]*
matAnswer [ k ][ j ];
155 }
156 }
157 }
158
159 // ztAz = z ’* A * z
160 double ztAz = 0.0;
161 for ( i =0; i < n ; i ++) {
162 ztAz += ztA [0][ i ]* z [ i ][0];
163 }
164
165 // ztz = z ’* z
166 double ztz = 0.0;
167 for ( i =0; i < n ; i ++) {
168 ztz += z [ i ][0]* z [ i ][0];
13
169 }
170
171 // calculo del autovalor
172 double autovalor = 1.0* ztAz / ztz ;
173
174 printf ( " Autovalor dominante = %.2 lf \ n " , autovalor ) ;
175
176 fclose ( fp ) ;
177 return 0;
178 }
14
5. bibliografı́a
https://es.wikipedia.org/wiki/M%C3%A9todo_iterativo
http://test.cua.uam.mx/MN/Methods/EcLineales/Jacobi/
Jacobi.php
https://es.wikipedia.org/wiki/M%C3%A9todo_de_Jacobi
15