|
@ -6,40 +6,53 @@ |
|
|
|
|
|
|
|
|
#include "serialDeclarations.h" |
|
|
#include "serialDeclarations.h" |
|
|
|
|
|
|
|
|
void meanshift(double **originalPoints, int h, parameters *opt){ |
|
|
void get_args(int argc, char **argv, int *h){ |
|
|
|
|
|
if (argc != 6) { |
|
|
|
|
|
printf("Usage: %s h N D Pd Pl\nwhere:\n", argv[0]); |
|
|
|
|
|
printf("\th is the variance\n"); |
|
|
|
|
|
printf("\tN is the the number of points\n"); |
|
|
|
|
|
printf("\tD is the number of dimensions of each point\n"); |
|
|
|
|
|
printf("\tPd is the path of the dataset file\n"); |
|
|
|
|
|
printf("\tPl is the path of the labels file\n"); |
|
|
|
|
|
exit(1); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
*h = atoi(argv[1]); |
|
|
|
|
|
NUMBER_OF_POINTS = atoi(argv[2]); |
|
|
|
|
|
DIMENSIONS = atoi(argv[3]); |
|
|
|
|
|
POINTS_FILENAME = argv[4]; |
|
|
|
|
|
LABELS_FILENAME = argv[5]; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
int meanshift(double **originalPoints, double ***shiftedPoints, int h |
|
|
|
|
|
, parameters *opt, int iteration){ |
|
|
|
|
|
|
|
|
double **y; |
|
|
// allocates space and copies original points on first iteration
|
|
|
y = alloc_2d_double(ROWS, COLUMNS); |
|
|
if (iteration == 1){ |
|
|
y = duplicate(originalPoints, y, ROWS, COLUMNS); |
|
|
(*shiftedPoints) = alloc_2d_double(NUMBER_OF_POINTS, DIMENSIONS); |
|
|
|
|
|
(*shiftedPoints) = duplicate(originalPoints, (*shiftedPoints) |
|
|
|
|
|
, NUMBER_OF_POINTS, DIMENSIONS); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
// mean shift vector
|
|
|
// mean shift vector
|
|
|
double **meanShiftVector; |
|
|
double **meanShiftVector; |
|
|
meanShiftVector = alloc_2d_double(ROWS, COLUMNS); |
|
|
meanShiftVector = alloc_2d_double(NUMBER_OF_POINTS, DIMENSIONS); |
|
|
// initialize elements of meanShiftVector to inf
|
|
|
// initialize elements of meanShiftVector to inf
|
|
|
for (int i=0;i<ROWS;i++){ |
|
|
for (int i=0;i<NUMBER_OF_POINTS;i++){ |
|
|
for (int j=0;j<COLUMNS;j++){ |
|
|
for (int j=0;j<DIMENSIONS;j++){ |
|
|
meanShiftVector[i][j] = DBL_MAX; |
|
|
meanShiftVector[i][j] = DBL_MAX; |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
// initialize iteration counter
|
|
|
double **kernelMatrix = alloc_2d_double(NUMBER_OF_POINTS, NUMBER_OF_POINTS); |
|
|
int iter = 0; |
|
|
double *denominator = malloc(NUMBER_OF_POINTS * sizeof(double)); |
|
|
|
|
|
|
|
|
// printf("%f \n", opt->epsilon);
|
|
|
|
|
|
|
|
|
|
|
|
double ** kernelMatrix = alloc_2d_double(ROWS, ROWS); |
|
|
|
|
|
double *denominator = malloc(ROWS * sizeof(double)); |
|
|
|
|
|
|
|
|
|
|
|
/** iterate until convergence **/ |
|
|
|
|
|
// printf("norm : %f \n", norm(m, ROWS, COLUMNS));
|
|
|
|
|
|
while (norm(meanShiftVector, ROWS, COLUMNS) > opt->epsilon) { |
|
|
|
|
|
iter = iter +1; |
|
|
|
|
|
// find pairwise distance matrix (inside radius)
|
|
|
// find pairwise distance matrix (inside radius)
|
|
|
// [I, D] = rangesearch(x,y,h);
|
|
|
// [I, D] = rangesearch(x,y,h);
|
|
|
for (int i=0; i<ROWS; i++){ |
|
|
for (int i=0; i<NUMBER_OF_POINTS; i++){ |
|
|
double sum =0; |
|
|
double sum =0; |
|
|
for (int j=0; j<ROWS; j++){ |
|
|
for (int j=0; j<NUMBER_OF_POINTS; j++){ |
|
|
double dist = calculateDistance(y[i],originalPoints[j]); |
|
|
double dist = calculateDistance((*shiftedPoints)[i],originalPoints[j]); |
|
|
|
|
|
|
|
|
if (i == j){ |
|
|
if (i == j){ |
|
|
kernelMatrix[i][j] = 1; |
|
|
kernelMatrix[i][j] = 1; |
|
@ -57,25 +70,30 @@ void meanshift(double **originalPoints, int h, parameters *opt){ |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
// create new y vector
|
|
|
// create new y vector
|
|
|
double** y_new = alloc_2d_double(ROWS, COLUMNS); |
|
|
double **y_new = alloc_2d_double(NUMBER_OF_POINTS, DIMENSIONS); |
|
|
|
|
|
|
|
|
multiply(kernelMatrix, originalPoints, y_new); |
|
|
multiply(kernelMatrix, originalPoints, y_new); |
|
|
// divide element-wise
|
|
|
// divide element-wise
|
|
|
for (int i=0; i<ROWS; i++){ |
|
|
for (int i=0; i<NUMBER_OF_POINTS; i++){ |
|
|
for (int j=0; j<COLUMNS; j++){ |
|
|
for (int j=0; j<DIMENSIONS; j++){ |
|
|
y_new[i][j] = y_new[i][j] / denominator[i]; |
|
|
y_new[i][j] = y_new[i][j] / denominator[i]; |
|
|
// calculate mean-shift vector
|
|
|
// calculate mean-shift vector
|
|
|
meanShiftVector[i][j] = y_new[i][j] - y[i][j]; |
|
|
meanShiftVector[i][j] = y_new[i][j] - (*shiftedPoints)[i][j]; |
|
|
// update y
|
|
|
|
|
|
y[i][j] = y_new[i][j]; |
|
|
|
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
shiftedPoints = &y_new; |
|
|
|
|
|
|
|
|
|
|
|
save_matrix((*shiftedPoints), iteration); |
|
|
|
|
|
|
|
|
save_matrix(y, iter); |
|
|
double current_norm = norm(meanShiftVector, NUMBER_OF_POINTS, DIMENSIONS); |
|
|
|
|
|
printf("Iteration n. %d, error %f \n", iteration, current_norm); |
|
|
|
|
|
|
|
|
printf("Iteration n. %d, error %f \n", iter, norm(meanShiftVector, ROWS, COLUMNS)); |
|
|
/** iterate until convergence **/ |
|
|
// TODO maybe keep y for live display later?
|
|
|
if (current_norm > opt->epsilon) { |
|
|
|
|
|
return meanshift(originalPoints, shiftedPoints, h, opt, ++iteration); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
return iteration; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
// 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
|
|
@ -92,12 +110,13 @@ double norm(double **matrix, int rows, int cols){ |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
void multiply(double **matrix1, double **matrix2, double **output){ |
|
|
void multiply(double **matrix1, double **matrix2, double **output){ |
|
|
// W dims are ROWS ROWS and x dims are ROWS COLUMNS
|
|
|
// W dims are NUMBER_OF_POINTS NUMBER_OF_POINTS
|
|
|
|
|
|
// and x dims are NUMBER_OF_POINTS DIMENSIONS
|
|
|
|
|
|
|
|
|
for (int i=0; i<ROWS; i++){ |
|
|
for (int i=0; i<NUMBER_OF_POINTS; i++){ |
|
|
for (int j=0; j<COLUMNS; j++){ |
|
|
for (int j=0; j<DIMENSIONS; j++){ |
|
|
output[i][j] = 0; |
|
|
output[i][j] = 0; |
|
|
for (int k=0; k<ROWS; k++){ |
|
|
for (int k=0; k<NUMBER_OF_POINTS; k++){ |
|
|
output[i][j] += matrix1[i][k] * matrix2[k][j]; |
|
|
output[i][j] += matrix1[i][k] * matrix2[k][j]; |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
@ -106,7 +125,7 @@ void multiply(double **matrix1, double **matrix2, double **output){ |
|
|
|
|
|
|
|
|
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<DIMENSIONS; i++){ |
|
|
dif = y[i]-x[i]; |
|
|
dif = y[i]-x[i]; |
|
|
sum += dif * dif; |
|
|
sum += dif * dif; |
|
|
} |
|
|
} |
|
@ -142,15 +161,15 @@ void print_matrix(double **array, int rows, int cols){ |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
void save_matrix(double **matrix,int iteration){ |
|
|
void save_matrix(double **matrix, int iteration){ |
|
|
char filename[18]; |
|
|
char filename[18]; |
|
|
snprintf(filename, sizeof(filename), "%s%d", "output/output_", iteration); |
|
|
snprintf(filename, sizeof(filename), "%s%d", "output/output_", iteration); |
|
|
FILE *iterOutput; |
|
|
FILE *iterOutput; |
|
|
iterOutput = fopen(filename, "w"); |
|
|
iterOutput = fopen(filename, "w"); |
|
|
for (int rows=0; rows<ROWS; ++rows){ |
|
|
for (int rows=0; rows<NUMBER_OF_POINTS; ++rows){ |
|
|
for (int cols=0; cols<COLUMNS; ++cols){ |
|
|
for (int cols=0; cols<DIMENSIONS; ++cols){ |
|
|
fprintf(iterOutput, "%f", matrix[rows][cols]); |
|
|
fprintf(iterOutput, "%f", matrix[rows][cols]); |
|
|
if (cols != COLUMNS - 1){ |
|
|
if (cols != DIMENSIONS - 1){ |
|
|
fprintf(iterOutput, ","); |
|
|
fprintf(iterOutput, ","); |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|