Browse Source

Code clean-up, vars rename, loops merge, matrix saving function

master
Apostolos Fanakis 7 years ago
parent
commit
b56acfcdca
  1. 2
      README.md
  2. 8
      serial.c
  3. 172
      serialDeclarations.c
  4. 9
      serialDeclarations.h

2
README.md

@ -10,7 +10,7 @@
This repository provides a serial implementation of the algorithm in C language, as well as the parallel equivalent in CUDA. The project was undertaken as part of the "Parallel and distributed systems" course of AUTH university. This repository provides a serial implementation of the algorithm in C language, as well as the parallel equivalent in CUDA. The project was undertaken as part of the "Parallel and distributed systems" course of AUTH university.
A [Gaussian] kernel was used for the weighting function. The code was tested for different data sets and information regarding the execution time and correctness were extracted. In addition, two versions of the parallel algorithm was tested and compared, with and without the usage of shared memory respectively. A [Gaussian] kernel was used for the weighting function. The code was tested for different data sets and information regarding the execution time and correctness were extracted. In addition, two versions of the parallel algorithm were tested and compared, with and without the usage of shared memory respectively.
## Compilation ## Compilation

8
serial.c

@ -30,8 +30,8 @@ int main(int argc, char **argv){
for (int i=0; i<ROWS; i++){ for (int i=0; i<ROWS; i++){
int out = fread(vectors[i], sizeof(double), COLUMNS, f); int out = fread(vectors[i], sizeof(double), COLUMNS, f);
} }
//printf("test : %f \n", vectors[0][0]);
//printf("test : %f \n", vectors[ROWS-1][COLUMNS-1]); save_matrix(vectors, 0);
// initializing file that will contain the labels (train) // initializing file that will contain the labels (train)
f = fopen(L, "rb"); f = fopen(L, "rb");
@ -49,11 +49,11 @@ int main(int argc, char **argv){
// MEAN SHIFT OPTIONS // MEAN SHIFT OPTIONS
int h = 1; int h = 1;
struct parameters params; parameters params;
params.epsilon = 0.0001; params.epsilon = 0.0001;
params.verbose = false; params.verbose = false;
params.display = false; params.display = false;
struct parameters *opt; parameters *opt;
opt = &params; opt = &params;
// tic // tic

172
serialDeclarations.c

@ -2,22 +2,23 @@
#include <stdlib.h> #include <stdlib.h>
#include <math.h> #include <math.h>
#include <float.h> #include <float.h>
#include <string.h>
#include "serialDeclarations.h" #include "serialDeclarations.h"
void meanshift(double **x, int h, struct parameters *opt){ void meanshift(double **originalPoints, int h, parameters *opt){
double **y; double **y;
y = alloc_2d_double(ROWS, COLUMNS); y = alloc_2d_double(ROWS, COLUMNS);
y = duplicate(x, y, ROWS, COLUMNS); y = duplicate(originalPoints, y, ROWS, COLUMNS);
// mean shift vectors // mean shift vector
double **m; double **meanShiftVector;
m = alloc_2d_double(ROWS, COLUMNS); meanShiftVector = alloc_2d_double(ROWS, COLUMNS);
// initialize elements of m to inf // initialize elements of meanShiftVector to inf
for (int i=0;i<ROWS;i++){ for (int i=0;i<ROWS;i++){
for (int j=0;j<COLUMNS;j++){ for (int j=0;j<COLUMNS;j++){
m[i][j] = DBL_MAX; meanShiftVector[i][j] = DBL_MAX;
} }
} }
@ -26,122 +27,86 @@ void meanshift(double **x, int h, struct parameters *opt){
// printf("%f \n", opt->epsilon); // printf("%f \n", opt->epsilon);
double ** W = alloc_2d_double(ROWS, ROWS); double ** kernelMatrix = alloc_2d_double(ROWS, ROWS);
double * l = malloc(ROWS * sizeof(double)); double *denominator = malloc(ROWS * sizeof(double));
/** iterate until convergence **/ /** iterate until convergence **/
// printf("norm : %f \n", norm(m, ROWS, COLUMNS)); // printf("norm : %f \n", norm(m, ROWS, COLUMNS));
while (norm(meanShiftVector, ROWS, COLUMNS) > opt->epsilon) {
while (norm(m, ROWS, COLUMNS) > opt->epsilon) {
iter = iter +1; iter = iter +1;
// find pairwise distance matrix (inside radius) // find pairwise distance matrix (inside radius)
/** allocate memory for inside iteration arrays **/
// [I, D] = rangesearch(x,y,h); // [I, D] = rangesearch(x,y,h);
for (int i=0; i<ROWS; i++){ for (int i=0; i<ROWS; i++){
double sum =0;
for (int j=0; j<ROWS; j++){ for (int j=0; j<ROWS; j++){
double dist = calculateDistance(y[i],x[j]); double dist = calculateDistance(y[i],originalPoints[j]);
// 2sparse matrix
if (dist < h){
W[i][j] = dist;
//printf("%f \n", W[i][j]);
}else{
W[i][j] = 0;
}
}
}
// for each element of W (x) do x^2 if (i == j){
// size of W is [600 600] kernelMatrix[i][j] = 1;
// W is a sparse matrix -> apply to non-zero elements } else if (dist < h*h){
for (int i=0; i<ROWS; i++){ kernelMatrix[i][j] = dist * dist;
double sum =0;
for (int j=0; j < ROWS; j++){
if (W[i][j] != 0){
W[i][j] = W[i][j]*W[i][j];
// compute kernel matrix // compute kernel matrix
// apply function to non zero elements of a sparse matrix double pow = ((-1)*(kernelMatrix[i][j]))/(2*(h*h));
double pow = ((-1)*(W[i][j]))/(2*(h*h)); kernelMatrix[i][j] = exp(pow);
W[i][j] = exp(pow); } else {
kernelMatrix[i][j] = 0;
} }
// make sure diagonal elements are 1 sum = sum + kernelMatrix[i][j];
if (i==j){
W[i][j] = W[i][j] +1;
}
// calculate sum(W,2)
sum = sum + W[i][j];
} }
/** l array is correct**/ denominator[i] = sum;
l[i] = sum;
// printf("l[%d] : %f \n", i, l[i]);
} }
/** W is correct**/
//print_matrix(W, ROWS, ROWS);
// create new y vector // create new y vector
double** y_new = alloc_2d_double(ROWS, COLUMNS); double** y_new = alloc_2d_double(ROWS, COLUMNS);
multiply(W, x, y_new); multiply(kernelMatrix, originalPoints, y_new);
/** y_new is CORRECT **/
// print_matrix(y_new, ROWS, COLUMNS);
// divide element-wise // divide element-wise
for (int i=0; i<ROWS; i++){ for (int i=0; i<ROWS; i++){
for (int j=0; j<COLUMNS; j++){ for (int j=0; j<COLUMNS; j++){
y_new[i][j] = y_new[i][j] / l[i]; y_new[i][j] = y_new[i][j] / denominator[i];
// calculate mean-shift vector // calculate mean-shift vector
m[i][j] = y_new[i][j] - y[i][j]; meanShiftVector[i][j] = y_new[i][j] - y[i][j];
// update y // update y
y[i][j] = y_new[i][j]; y[i][j] = y_new[i][j];
} }
} }
save_matrix(y, iter);
printf("Iteration n. %d, error %f \n", iter, norm(m, ROWS, COLUMNS)); printf("Iteration n. %d, error %f \n", iter, norm(meanShiftVector, ROWS, COLUMNS));
// TODO maybe keep y for live display later? // TODO maybe keep y for live display later?
};
}
// allocates a 2d array in continuous memory positions
double **alloc_2d_double(int rows, int cols) {
double *data = (double *)malloc(rows*cols*sizeof(double));
double **array= (double **)malloc(rows*sizeof(double*));
for (int i=0; i<rows; i++)
array[i] = &(data[cols*i]);
return array;
}
// copy the values of a 2d double array to another
double **duplicate(double **a, double **b, int rows, int cols){
for (int i=0;i<rows;i++){
for (int j=0;j<cols;j++){
b[i][j] = a[i][j];
}
} }
return b;
} }
// TODO check why there's is a difference in the norm calculate in matlab // TODO check why there's is a difference in the norm calculate in matlab
double norm(double ** m, int rows, int cols){ double norm(double **matrix, int rows, int cols){
double sum=0, a=0; double sum=0, tempMul=0;
for (int i = 0; i < rows; i++) { for (int i=0; i<rows; i++) {
for (int j = 0; j < cols; j++) { for (int j=0; j<cols; j++) {
a = m[i][j] * m[i][j]; tempMul = matrix[i][j] * matrix[i][j];
sum = sum + a; sum = sum + tempMul;
} }
} }
double norm = sqrt(sum); double norm = sqrt(sum);
return norm; return norm;
} }
void multiply(double **matrix1, double **matrix2, double **output){
// W dims are ROWS ROWS and x dims are ROWS COLUMNS
for (int i=0; i<ROWS; i++){
for (int j=0; j<COLUMNS; j++){
output[i][j] = 0;
for (int k=0; k<ROWS; k++){
output[i][j] += matrix1[i][k] * matrix2[k][j];
}
}
}
}
double calculateDistance(double *y, double *x){ double calculateDistance(double *y, double *x){
double sum = 0, dif; double sum = 0, dif;
for (int i=0;i<COLUMNS;i++){ for (int i=0; i<COLUMNS; i++){
dif = y[i]-x[i]; dif = y[i]-x[i];
sum += dif * dif; sum += dif * dif;
} }
@ -149,25 +114,46 @@ double calculateDistance(double *y, double *x){
return distance; return distance;
} }
void multiply(double ** matrix1, double ** matrix2, double ** output){ // allocates a 2d array in continuous memory positions
// W dims are ROWS ROWS and x dims are ROWS COLUMNS double **alloc_2d_double(int rows, int cols) {
double *data = (double *) malloc(rows*cols*sizeof(double));
double **array = (double **) malloc(rows*sizeof(double*));
for (int i=0; i<rows; i++)
array[i] = &(data[cols*i]);
return array;
}
int i, j, k; // copy the values of a 2d double array to another
for (i=0; i<ROWS; i++){ double **duplicate(double **a, double **b, int rows, int cols){
for (j=0; j<COLUMNS; j++){ for (int i=0; i<rows; i++){
output[i][j] = 0; for (int j=0; j<cols; j++){
for (k=0; k<ROWS; k++){ b[i][j] = a[i][j];
output[i][j] += matrix1[i][k] * matrix2[k][j];
}
} }
} }
return b;
} }
void print_matrix(double ** array, int rows, int cols){ void print_matrix(double **array, int rows, int cols){
for (int i=0; i<cols; i++){ for (int i=0; i<cols; i++){
for (int j=0; j<rows; j++){ for (int j=0; j<rows; j++){
printf("%f ", array[j][i]); printf("%f ", array[j][i]);
} }
printf("\n"); printf("\n");
} }
}
void save_matrix(double **matrix,int iteration){
char filename[18];
snprintf(filename, sizeof(filename), "%s%d", "output/output_", iteration);
FILE *iterOutput;
iterOutput = fopen(filename, "w");
for (int rows=0; rows<ROWS; ++rows){
for (int cols=0; cols<COLUMNS; ++cols){
fprintf(iterOutput, "%f", matrix[rows][cols]);
if (cols != COLUMNS - 1){
fprintf(iterOutput, ",");
}
}
fprintf(iterOutput, "\n");
}
} }

9
serialDeclarations.h

@ -8,18 +8,19 @@
#define COLUMNS 2 #define COLUMNS 2
#define ROWS 600 #define ROWS 600
struct parameters { typedef struct parameters {
double epsilon; double epsilon;
bool verbose; bool verbose;
bool display; bool display;
}; } parameters;
double **alloc_2d_double(int rows, int cols);
double **duplicate(double **a, double **b, int rows, int cols);
void meanshift(double **x, int h, struct parameters *opt); void meanshift(double **x, int h, struct parameters *opt);
double norm(double ** m, int rows, int cols); double norm(double ** m, int rows, int cols);
void multiply(double ** matrix1, double ** matrix2, double ** output); void multiply(double ** matrix1, double ** matrix2, double ** output);
double calculateDistance(double *, double *); double calculateDistance(double *, double *);
double **alloc_2d_double(int rows, int cols);
double **duplicate(double **a, double **b, int rows, int cols);
void print_matrix(double ** array, int rows, int cols); void print_matrix(double ** array, int rows, int cols);
void save_matrix(double **matrix,int iteration);
#endif //SERIAL_DECLARATIONS_H #endif //SERIAL_DECLARATIONS_H
Loading…
Cancel
Save