-
Notifications
You must be signed in to change notification settings - Fork 0
/
main.c
121 lines (107 loc) · 3.03 KB
/
main.c
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
#include <stdio.h>
#include <xmmintrin.h>
#include <stdlib.h>
#include <time.h>
#define M 10
#define N 2048
void memExcptn(void){
printf("Exception\n");
exit(EXIT_FAILURE);
}
void matrix_gen(float* A, float* I, float* in_A){
if(!A || !I || !in_A)
memExcptn;
for(long i = 0; i < N * N; ++i){
A[i] = (float) rand() / rand();
in_A[i] = 0;
if(i / N == i % N){
I[i] = 1;
} else{
I[i] = 0;
}
}
}
void matrix_transpose(float* A, float* res){
if(!res)
memExcptn;
for(long i = 0; i < N * N; ++i)
res[i] = A[N * (N - 1 - i / N) + (N - 1 - i % N)];
}
int compare (const void * a, const void * b){
return ( *(float*)a - *(float*)b );
}
float max_mul_A(float* A){
float sigma_x[N] = {0};
float sigma_y[N] = {0};
if(!sigma_x || !sigma_y)
memExcptn;
for(long i = 0; i < N; ++i)
for(long j = 0; j < N; ++j){
sigma_x[i] += A[N * i + j];
sigma_y[j] += A[N * i + j];
}
qsort(sigma_x, N, sizeof(float), compare);
qsort(sigma_y, N, sizeof(float), compare);
float xMAX = sigma_x[N - 1];
float yMAX = sigma_y[N - 1];
return xMAX*yMAX;
}
void matrix_null_init(float* A){
for(long i = 0; i < N * N; ++i)
A[i] = 0.0;
}
void matrix_mult_scal(float* A, float k, float* res){
for(long i = 0; i < N; ++i)
for(long j = 0; j < N; ++j)
res[N * i + j] = k * A[N * i + j];
}
void matrix_mul(float* A, float* B, float* res){
matrix_null_init(res);
for(long i = 0; i < N; ++i)
for(long j = 0; j < N; ++j)
for(long k = 0; k < N; ++k)
res[N * i + k] += A[N * i + j] * A[N * j + k];
}
void matrix_sub_I(float* R){
for(long i = 0; i < N; ++i)
for(long j = 0; j < N; ++j)
if(j == i)
R[N * i + j] = 1 - R[N * i + j];
else
R[N * i + j] = - R[N * i + j];
}
void matrix_sum(float* A, float* B, float* res){
for(long i = 0; i < N; i++)
for(long j = 0; j < N; ++j)
res[N * i + j] = A[N * i + j] + B[N * i + j];
}
int main(int argc, char* argv[]){
float* A = (float*)malloc(N * N * sizeof(float));
float* I = (float*)malloc(N * N * sizeof(float));
float* in_A = (float*)malloc(N * N * sizeof(float));
float* B = (float*)malloc(N * N * sizeof(float));
float* R = (float*)malloc(N * N * sizeof(float));
matrix_gen(A, I, in_A);
clock_t start;
start = clock();
double used_time;
matrix_transpose(A, B);
float AA = max_mul_A(A);
matrix_mult_scal(B, 1.0 / AA, B);
matrix_mul(B, A, R);
matrix_sub_I(R);
for(long i = 0; i < M; ++i){
matrix_sum(I, in_A, in_A);
matrix_mul(R, I, A);
matrix_mult_scal(A, 1.0, I);
}
matrix_mul(B, in_A, in_A);
used_time = (double)(clock() - start) / CLOCKS_PER_SEC;
free(in_A);
free(I);
free(A);
free(B);
free(R);
printf("%d: %f seconds\n", N, used_time);
return 0;
}