-
Notifications
You must be signed in to change notification settings - Fork 0
/
utils.h
184 lines (145 loc) · 4.4 KB
/
utils.h
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
174
175
176
177
178
179
180
181
182
183
184
#ifndef utils
#define utils
//Siccome pqnn e testindex usano questo file, senza queste righe, l'header viene
//definito più volte
//_____________________Funzioni esterne scritte in assembly_____________________
extern void accumulate( MATRIX dest, MATRIX orig, int dim);
extern float distance(VECTOR x1,VECTOR x2,int d);
extern void divide( MATRIX dividendo, float divisore, int dim);
extern void memset_float( MATRIX data, float val, int dim);
extern float objective_function(int n,int m, MATRIX distances_from_centroids);
extern void residual(VECTOR res,VECTOR x,VECTOR centroid,int d);
/** La funzione seguente calcola il valore della funzione obiettivo
* che deve essere minimizzata al fine avere un buon insieme di centroidi
* C = min sum[ dist^2(y, centroide(y) ) ]
* COSTO: n
* n = numero di punti del data set
* TODO: parallelizzare la somma in assembly
*/
/*
float objective_function(int n,int m, MATRIX distances_from_centroids){
float sum = 0;
int i=0;
for(i; i<n*m-4; i+=4){
sum+=distances_from_centroids[i];
sum+=distances_from_centroids[i+1];
sum+=distances_from_centroids[i+2];
sum+=distances_from_centroids[i+3];
}
for(i;i<n*m;i++){
sum += distances_from_centroids[i];
}
return sqrt(sum);
}
float distance(VECTOR x1,VECTOR x2,int d){
float diff,sum = 0;
int i=0;
// Per ridurre l'overhead dovuto ad ogni passo del ciclo effettuiamo al suo
// interno più operazioni (assumiamo che la dimensione d sia divisibile per
// due)
// Si lavora su gruppi di 4
for(i; i<=d-4; i+=4){
diff = x1[i]-x2[i];
sum += diff*diff;
diff = x1[i+1]-x2[i+1];
sum += diff*diff;
diff = x1[i+2]-x2[i+2];
sum += diff*diff;
diff = x1[i+3]-x2[i+3];
sum += diff*diff;
}
// Processiamo un eventuale residual_centroids
for(i;i<d;i++){
diff = x1[i]-x2[i];
sum += diff*diff;
}
return sum;
// TESTATA
}//distance
/*
// Funzione che calcola il residuo, versione ottimizzata
// Esegue il calcolo: r(x) = x-q_c(x)
void residual(VECTOR res,VECTOR x,VECTOR centroid,int d){
int i=0;
for(i;i<=d-4;i+=4){
res[i] = x[i]-centroid[i];
res[i+1] = x[i+1]-centroid[i+1];
res[i+2] = x[i+2]-centroid[i+2];
res[i+3] = x[i+3]-centroid[i+3];
}
// Ciclo per eventuali cicli residui
for(i;i<d;i++)
res[i] = x[i]-centroid[i];
// TESTATA: OK!
}//residual
void memset_float( MATRIX data, float val, int dim){
for( int j=0; j<dim; j++)
data[j] = val;
}
void accumulate( MATRIX dest, MATRIX orig, int dim){
for(int j=0;j<dim;j++)
dest[j] += orig[j];
}
void divide( MATRIX dividendo, float divisore, int dim){
for(int j=0;j<dim;j++)
dividendo[j] = dividendo[j] / divisore;
}
*/
//----------Stampa tutti i punti-----------
void print_matrix(int rows, int cols, int k, MATRIX data, char c){
printf("Numero punti: %d\nDimensione di ogni punto: %d\n", rows, cols);
for (int i = 0; i < rows; i++) {
if( c=='c'){
if( i%k == 0) printf("Gruppo %d\n", i/k);
printf("Centroide n %d:\t", i%k);
}//else if( c=='p')
printf("Punto n %d:\t", i);
for (int j = 0; j < cols; j++)
printf("%8.2f\t", data[i*cols+j] );
printf("\n");
}
printf("\n\n");
}
//----------Stampa tutti i punti interi-----------
void print_matrix_int(int rows, int cols, int k, int* data, char c){
printf("Numero punti: %d\nDimensione di ogni punto: %d\n", rows, cols);
for (int i = 0; i < rows; i++) {
if( c=='c'){
if( i%k == 0) printf("Gruppo %d\n", i/k);
printf("Centroide n %d:\t", i%k);
}else if( c=='p')
printf("Punto n %d:\t", i);
for (int j = 0; j < cols; j++)
printf("%d\t", data[i*cols+j] );
printf("\n");
}
printf("\n\n");
}
//----------Stampa il quantizzatore-----------
void print_quantizer(int m, int* data){
printf("Ogni numero rapresenta l'indice del centroide più vicino per quel gruppo.\n");
printf("Quantizzatore: [");
for (int j = 0; j < m; j++){
printf("%3d", data[j] );
if( j!=m-1 )
printf(", ");
}
printf("]\n\n");
}
//----------Stampa la matrice triangolare superiore-----------
void print_centroids_distances(int k, int m, float* data){
int val = 0;
for( int g=0; g<m; g++){
printf("Gruppo %d\n", g);
printf(" A->");
for (int j = 0; j < k; j++) printf(" %d ", j);
printf("\n");
for (int i = 0; i < k; i++) {
printf("DA->%d ", i);
for( int j=0; j< i; j++) printf(" ");
for( int j=i; j<k; j++) printf(" %6.2f", data[val++] );
printf("\n");
}
}//for gruppo
}
#endif