Skip to content

Commit 7e9766f

Browse files
committed
classical gram schmidt, serial
1 parent 4c5df38 commit 7e9766f

File tree

2 files changed

+123
-2
lines changed

2 files changed

+123
-2
lines changed

lab2.pdf

22.8 KB
Binary file not shown.

lab2_omp.c

+123-2
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,134 @@
11
#include <malloc.h>
22
#include <omp.h>
3+
#include <assert.h>
4+
#include <string.h>
5+
#include <math.h>
36

4-
7+
#define TOLERANCE 1e-3
58
// /*
69
// *****************************************************
710
// TODO -- You must implement this function
811
// *****************************************************
912
// */
10-
void SVD(int M, int N, float* D, float** U, float** SIGMA, float** V_T)
13+
14+
void multiply(float *M_1, int m1, int n1, float *M_2, int m2, int n2, float *result)
15+
{
16+
assert(n1 == m2);
17+
float sum = 0.0;
18+
int i,j,k;
19+
for (i=0; i<m1; i++)
20+
{
21+
for (j=0; j<n2; j++)
22+
{
23+
for (k=0; k<n1; k++)
24+
{
25+
sum+=M_1[i*n1+k]*M_2[k*n2+j];
26+
}
27+
result[i*n2+j] = sum;
28+
sum=0.0;
29+
}
30+
}
31+
}
32+
33+
void transpose(float* M, int m, int n, float* M_T)
34+
{
35+
int i,j;
36+
for (i=0; i<m; i++)
37+
{
38+
for (j=0; j<n; j++)
39+
{
40+
M_T[j*m+i]=M[i*m+j];
41+
}
42+
}
43+
}
44+
45+
float* initialize_identity(int size)
46+
{
47+
float *E_0 = (float *) calloc(P*P, sizeof(float));
48+
for (int i=0; i<size; i++)
49+
{
50+
E_0[i*size+i] = 1.0;
51+
}
52+
}
53+
54+
float l2_norm(float *v_col, int length)
1155
{
56+
float norm = 0.0, sum_sq=0.0;
57+
for (int i=0; i<length; i++)
58+
{
59+
sum_sq+=v_col[i]*v_col[i];
60+
}
61+
return norm = sqrtf(sum_sq);
62+
}
63+
64+
float l2_norm_diagonal_diff(float *A_next, float *A_current, int P)
65+
{
66+
float norm, sum_sq=0.0;
67+
for (int i=0; i<P; i++)
68+
{
69+
sum_sq+=(A_next[i*P+i]-A_current[i*P+i])*(A_next[i*P+i]-A_current[i*P+i]);
70+
}
71+
return norm=sqrtf(sum_sq);
72+
}
73+
74+
void classicalGS(float *A_current, float* A_T, int P, float *Q_current, float *R_current)
75+
{
76+
float *v_col = (float *) malloc(sizeof(float)*P);
77+
int col, row, row_;
78+
float result;
79+
for (col=0; col<P; col++)
80+
{
81+
memcpy(v_col, A_T+col*P, P*sizeof(float));
82+
//v_col = a_col
83+
for (row=0; row<col; row++)
84+
{
85+
//perform inner product:
86+
result = 0.0;
87+
for (row_=0; row_<P; row_++)
88+
{
89+
result+=(Q_current[row_*P+row]*(A_T[col*P+row_]));
90+
}
91+
R_current[row*P+col]=result;
92+
}
93+
R_current[col*P+col] = l2_norm(v_col, P);
94+
for (row=0; row<P; row++)
95+
{
96+
Q_current[row*P+col]=v_col[row]/R_current[col*P+col];
97+
}
98+
}
99+
free(v_col);
100+
}
101+
102+
void SVD(int N, int P, float* D, float** U, float** SIGMA, float** V_T)
103+
{
104+
/* 1.Perform SVD for D_T */
105+
// Get eigen-values & eigen-vectors for D_T*D
106+
float *D_T = (float *) malloc(sizeof(float)*N*P);
107+
transpose(D, N, P, D_T);
108+
float *A = (float *) calloc(P*P, sizeof(float)); //A=D_T*D|(PxP)
109+
float *A_T = (float *) calloc(P*P, sizeof(float)); //A_T|(PXP)
110+
multiply(D_T, P, N, D, N, P, A);
111+
112+
//begin QR-algorithm for A:
113+
float *A_current = A; //PxP; initialised to A_0
114+
float *E_current = initialize_identity(P); //PXP; initialised to E_0
115+
float *A_next = (float *) calloc(P*P, sizeof(float));
116+
float *E_next = (float *) calloc(P*P, sizeof(float));
117+
float *Q_ = (float *) calloc(P*P, sizeof(float));
118+
float *R_ = (float *) calloc(P*P, sizeof(float));
119+
float diff_norm;
120+
do //convergence condition for QR-algorithm
121+
{
122+
transpose(A_current, P, P, A_T);
123+
classicalGS(A_current, A_T, P, Q_, R_);
124+
multiply(R_, P, P, Q_, P, P, A_next);
125+
multiply(E_current, P, P, Q_, P, P, E_next);
126+
diff_norm = l2_norm_diagonal_diff(A_next, A_current, P);
127+
A_current = A_next;
128+
E_current = E_next;
129+
printf("diff_norm: %f\n", diff_norm);
130+
}
131+
while(diff_norm<TOLERANCE);
12132
}
13133

14134
// /*
@@ -18,5 +138,6 @@ void SVD(int M, int N, float* D, float** U, float** SIGMA, float** V_T)
18138
// */
19139
void PCA(int retention, int M, int N, float* D, float* U, float* SIGMA, float** D_HAT, int *K)
20140
{
141+
21142

22143
}

0 commit comments

Comments
 (0)