source: proiecte/PPPP/eigenface/new/jacobi.c @ 90

Last change on this file since 90 was 90, checked in by (none), 14 years ago

PPPP - tested jacobi.c

File size: 3.7 KB
Line 
1#include <stdio.h>
2#include <math.h>
3#include <malloc.h>
4#define ROTATE(a,i,j,k,l) g=a[i][j];h=a[k][l];a[i][j]=g-s*(h+g*tau);\
5a[k][l]=h+s*(g-h*tau);
6
7/*
8Computes all eigenvalues and eigenvectors of a real symmetric matrix a[1..n][1..n]. On
9output, elements of a above the diagonal are destroyed. d[1..n] returns the eigenvalues of a.
10v[1..n][1..n] is a matrix whose columns contain, on output, the normalized eigenvectors of
11a. nrot returns the number of Jacobi rotations that were required.
12*/
13void jacobi(float **a, int n, float d[], float **v, int *nrot)
14{
15        int j,iq,ip,i;
16        float tresh,theta,tau,sm,s,h,g,c,*b,*z;
17        float t;       
18        b = (float *) malloc(n * sizeof(float));
19        z = (float *) malloc(n * sizeof(float));
20       
21        printf("in jacobi\n");
22               
23        for (ip=0;ip<n;ip++) {          // Initialize to the identity matrix.
24                for (iq=0;iq<n;iq++) 
25                        v[ip][iq]=0.0;
26                v[ip][ip]=1.0;
27        }
28        printf("in jacobi 2\n");
29        for (ip=0;ip<n;ip++) {     // Initialize b and d to the diagonal of a.
30                b[ip]=d[ip]=a[ip][ip];                                 
31                z[ip]=0.0;                         // This vector will accumulate terms of the form t*a[pq] as in equation (11.1.14).
32        }
33       
34        printf("in jacobi 2\n");
35        *nrot=0;
36        for (i=1;i<=50;i++) {
37                sm=0.0;
38                for (ip=0;ip<n-1;ip++) {                        // Sum off-diagonal elements.
39                        for (iq=ip+1;iq<n;iq++)
40                        sm += fabs(a[ip][iq]);
41                }
42                if (sm == 0.0) {                                // The normal return, which relies on quadratic convergence to machine underflow.
43                        free(z);
44                        free(b);
45                        return;
46                }
47                if (i < 4)
48                        tresh=0.2*sm/(n*n);                             // ...on the first three sweeps.
49                else
50                        tresh=0.0;                                      // ...thereafter.
51                for (ip=0;ip<n-1;ip++) {
52                        for (iq=ip+1;iq<n;iq++) {
53                                g=100.0*fabs(a[ip][iq]);
54                                if (i > 4 && (float)(fabs(d[ip])+g) == (float)fabs(d[ip])       // After four sweeps, skip the rotation if the off-diagonal element is small.
55                                        && (float)(fabs(d[iq])+g) == (float)fabs(d[iq]))
56                                        a[ip][iq]=0.0;
57                                else if (fabs(a[ip][iq]) > tresh) {
58                                        h=d[iq]-d[ip];
59                                        if ((float)(fabs(h)+g) == (float)fabs(h))
60                                                t=(a[ip][iq])/h;        // t = 1/(2*theta)
61                                        else {
62                                                theta=0.5*h/(a[ip][iq]); 
63                                                t=1.0/(fabs(theta)+sqrt(1.0+theta*theta));
64                                                if (theta < 0.0) t = -t;
65                                        }
66                                       
67                                        c=1.0/sqrt(1+t*t);
68                                        s=t*c;
69                                        tau=s/(1.0+c);
70                                        h=t*a[ip][iq];
71                                        z[ip] -= h;
72                                        z[iq] += h;
73                                        d[ip] -= h;
74                                        d[iq] += h;
75                                        a[ip][iq]=0.0;
76                                       
77                                        for (j=0;j<ip-1;j++) { // Case of rotations 1 <= j < p.
78                                                ROTATE(a,j,ip,j,iq)
79                                        } 
80                                        for (j=ip+1;j<iq-1;j++) { // Case of rotations p < j < q.
81                                                ROTATE(a,ip,j,j,iq)
82                                        }
83                                        for (j=iq+1;j<n;j++) {  // Case of rotations q < j <= n.
84                                                ROTATE(a,ip,j,iq,j)
85                                        }
86                                        for (j=0;j<n;j++) {
87                                                ROTATE(v,j,ip,j,iq)
88                                        }
89                                       
90                                        ++(*nrot);
91                                }
92                        }
93                }
94               
95                for (ip=0;ip<n;ip++) {
96                        b[ip] += z[ip];
97                        d[ip]=b[ip];            // Update d with the sum of t*a[pq],
98                        z[ip]=0.0;                      // and reinitialize z.
99                }
100        }
101       
102        printf("Too many iterations in routine jacobi\n");
103}
104
105int main(int argc, char * argv)
106{
107        int n, i, j;
108        float *d;
109        float **a;
110        float **v;
111        int nrot = 0;
112       
113        FILE * f = fopen("mat.in", "r");
114        fscanf(f,"%d", &n);
115       
116        a = (float **)malloc(n * sizeof(float*));
117        for(i = 0; i < n; i++)
118                a[i] = (float *)malloc(n * sizeof(float));
119       
120        v  = (float **)malloc(n * sizeof(float*));
121        for(i = 0; i < n; i++)
122                v[i] = (float *)malloc(n * sizeof(float));
123       
124        d = (float *)malloc(n * sizeof(float));
125       
126        for(i = 0; i < n; i++)
127                for(j = 0; j < n; j++)
128                        fscanf(f,"%f", &a[i][j]);
129        for(i = 0; i < n; i++)
130        {
131                for(j = 0; j < n; j++)
132                        printf("%f ", a[i][j]);
133                printf("\n");
134        }
135       
136        jacobi(a, n, d, v, &nrot); 
137       
138        printf("v:\n");
139        for(i = 0; i < n; i++)
140        {
141                for(j = 0; j < n; j++)
142                        printf("%f ", v[i][j]);
143                printf("\n");
144        }
145
146        printf("d:\n");
147        for(i = 0; i < n; i++)
148        {
149                printf("%f ", d[i]);
150        }
151
152        return 0;
153}
154
Note: See TracBrowser for help on using the repository browser.