double distCE(FVector *pFVectors, int fVectorTotal, int clusterCnt, FVector **pCores, int *coresNdx) { int i, j; int clusterNum; double result = 0; for (i = 0; i < fVectorTotal; i++) { // traverse feature vectors clusterNum = pFVectors[i].cluster; for (j = 0; j < coresNdx[clusterNum]; j++) { result += twoNorm(pCores[clusterNum][j], pFVectors[i]); } } return result; }
int main(int argc, char* argv[]) { size_t size; double btime, etime; double *vec_x; double result; srand(time(NULL)); if(argc > 1) { size = atoi(argv[1]); #ifndef DEBUG printf("%zd\t", size); #endif } else { printf("Not enough parameters!\n"); return EXIT_FAILURE; } vec_x = (double*)malloc(size*sizeof(double)); if(vec_x == NULL) { printf("The memory allocation failed! Exit Now!\n"); return EXIT_FAILURE; } else { size_t i; for(i = 0; i < size; ++i) { vec_x[i] = rand()%(MAX-MIN+1); #ifdef DEBUG printf("The random data generated is %.4f\n", vec_x[i]); #endif } } //Calculate the execution time of the 2 norm of a vector btime = get_cur_time(); result = twoNorm(vec_x, size); etime = get_cur_time(); //verify the result if(verify(result, vec_x, size)) { #ifdef DEBUG printf("The result is accurate!\n"); #endif } else { #ifdef DEBUG printf("The result is not acccurate! Exit Now!\n"); #endif return EXIT_FAILURE; } //Free the allocated memory free(vec_x); vec_x = NULL; #ifdef DEBUG printf("Elapsed time is %lf seconds\n", etime - btime); printf("The FLOPS is %lf GOps/sec\n", size * 2 / (etime - btime)); #else printf("%.16f\t", etime - btime); printf("%.16f\n", size * 2 / (etime - btime) / 1e+9); #endif return EXIT_SUCCESS; }
void didayDynamicClusterMethod(FVector *pFVectors, int fVectorTotal, int clusterCnt, int *pCoreCnt, int iteration) { srand(time(NULL)); int i, j, k, m; FVector initCenters[clusterCnt]; FVector *pCores[clusterCnt]; int coresNdx[clusterCnt]; int *pCluster[clusterCnt]; int clusterNdx[clusterCnt]; double minDist; double tmp; FVector *pCandidate; for (i = 0; i < clusterCnt; i++) { pCores[i] = calloc(pCoreCnt[i], sizeof(FVector)); pCluster[i] = calloc(fVectorTotal, sizeof(int)); coresNdx[i] = 0; clusterNdx[i] = 0; } // assign the first clusterCnt feature vectors as initCenters for (i = 0; i < clusterCnt; i++) { initCenters[i] = pFVectors[i]; initCenters[i].cluster = i; } // assign feature vectors to clusters by min. distance for (i = 0; i < fVectorTotal; i++) { minDist = DBL_MAX; for (j = 0; j < clusterCnt; j++) { tmp = twoNorm(initCenters[j], pFVectors[i]); if (tmp < minDist) { pCandidate = &(initCenters[j]); minDist = tmp; } } pFVectors[i].cluster = pCandidate->cluster; pCluster[pCandidate->cluster][clusterNdx[pCandidate->cluster]++] = i; } // randomly select multicenter cores for all clusters randCore(pFVectors, fVectorTotal, clusterCnt, pCoreCnt, pCluster, clusterNdx, pCores, coresNdx); // find the best cluster sets and core sets iteratively int bestCoreSet[fVectorTotal]; int bestClusterSet[fVectorTotal]; double minDistCE = DBL_MAX; for (i = 0; i < iteration; i++) { for (j = 0; j < clusterCnt; j++) clusterNdx[j] = 0; for (j = 0; j < fVectorTotal; j++) { // assign feature vectors to clusters via min. dist. to cores minDist = DBL_MAX; for (k = 0; k < clusterCnt; k++) { for (m = 0; m < coresNdx[k]; m++) { tmp = twoNorm(pCores[k][m], pFVectors[j]); if (tmp < minDist) { pCandidate = &(pCores[k][m]); minDist = tmp; } } } pFVectors[j].cluster = pCandidate->cluster; pCluster[pCandidate->cluster][clusterNdx[pCandidate->cluster]++] = j; } // compute D(k) and D(C, E) tmp = distCE(pFVectors, fVectorTotal, clusterCnt, pCores, coresNdx); if (tmp < minDistCE) { // candidate minDistCE = tmp; for (j = 0; j < fVectorTotal; j++) { bestCoreSet[j] = pFVectors[j].core; bestClusterSet[j] = pFVectors[j].cluster; } } // reselect random new core sets randCore(pFVectors, fVectorTotal, clusterCnt, pCoreCnt, pCluster, clusterNdx, pCores, coresNdx); } // print final results to standard output int memberCnts[clusterCnt]; for (i = 0; i < clusterCnt; i++) memberCnts[i] = 0; for (i = 0; i < clusterCnt; i++) { printf("\ncluster #%d:\n", i); for (j = 0; j < fVectorTotal; j++) { if (pFVectors[j].cluster == i) { memberCnts[i]++; printf("(%d, %d, %d)", (int)pFVectors[j].x, (int)pFVectors[j].y, (int)pFVectors[j].z); if (pFVectors[j].core == i) printf(" <- core of cluster #%d", i); printf("\n"); } } } printf("\n"); for (i = 0; i < clusterCnt; i++) printf("# of cluster %d: %d\n", i, memberCnts[i]); printf("\nmin( D(C,E) ): %f\n", minDistCE); }
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) { #define facesInput prhs[0] #define verticesInput prhs[1] #define edgesOutput plhs[0] #define edgeLengthsOutput plhs[1] #define edgeUnitsOutput plhs[2] #define edgeCentersOutput plhs[3] #define edgeNormalsOutput plhs[4] #define faceNormalsOutput plhs[5] #define faceAreasOutput plhs[6] #define volumeOutput plhs[7] mxArray *faceCell, *edgesCell, *edgeCentersCell, *edgeLengthsCell, *edgeUnitsCell, *faceNormalCell, *edgeNormalsCell; double *face, *vertices, *edges, *edgeCenters, *edgeLengths, *edgeUnits, *faceNormal, *edgeNormals, *faceAreas, *volume; double tmp; mwIndex f, e, i; mwIndex currentVertexIdx, nextVertexIdx, edgeIdx; mwSize faceNumber, edgeNumber, vertexNumber; mwSize edgesOutputSize[EDGES_OUTPUT_DIM]; if (nrhs != 2) mexErrMsgTxt("There should be exactly two inputs, faces and vertices."); if (nlhs != 8) mexErrMsgTxt("There should be exactly 8 outputs. " "edges, edgeLengths, edgeCenters, edgeUnits, edgeCenters, " "edgeNormals, faceNormals."); if (!mxIsCell(facesInput)) mexErrMsgTxt("Input faces should be a cell array!"); if (!mxIsDouble(verticesInput)) mexErrMsgTxt("Input vertices should be a double matrix!"); faceNumber = mxGetNumberOfElements(facesInput); vertices = mxGetPr(verticesInput); vertexNumber = mxGetN(verticesInput); edgesOutputSize[0] = faceNumber; edgesOutputSize[1] = 1; edgesOutput = mxCreateCellArray(EDGES_OUTPUT_DIM, edgesOutputSize); edgeLengthsOutput = mxCreateCellArray(EDGES_OUTPUT_DIM, edgesOutputSize); edgeUnitsOutput = mxCreateCellArray(EDGES_OUTPUT_DIM, edgesOutputSize); edgeCentersOutput = mxCreateCellArray(EDGES_OUTPUT_DIM, edgesOutputSize); edgeNormalsOutput = mxCreateCellArray(EDGES_OUTPUT_DIM, edgesOutputSize); faceNormalsOutput = mxCreateCellArray(EDGES_OUTPUT_DIM, edgesOutputSize); faceAreasOutput = mxCreateDoubleMatrix(faceNumber, 1, mxREAL); faceAreas = mxGetPr(faceAreasOutput); volumeOutput = mxCreateDoubleMatrix(1, 1, mxREAL); volume = mxGetPr(volumeOutput); for (f = 0; f < faceNumber; f++) { faceCell = mxGetCell(facesInput, f); face = mxGetPr(faceCell); edgeNumber = (mwIndex)(mxGetN(faceCell)) - 1; // face is 1 by e + 1 array, the last entry is duplication of // the first one edgesCell = mxCreateDoubleMatrix(dim, edgeNumber, mxREAL); edges = mxGetPr(edgesCell); edgeCentersCell = mxCreateDoubleMatrix(dim, edgeNumber, mxREAL); edgeCenters = mxGetPr(edgeCentersCell); edgeLengthsCell = mxCreateDoubleMatrix(1, edgeNumber, mxREAL); edgeLengths = mxGetPr(edgeLengthsCell); edgeUnitsCell = mxCreateDoubleMatrix(dim, edgeNumber, mxREAL); edgeUnits = mxGetPr(edgeUnitsCell); edgeNormalsCell = mxCreateDoubleMatrix(dim, edgeNumber, mxREAL); edgeNormals = mxGetPr(edgeNormalsCell); faceNormalCell = mxCreateDoubleMatrix(dim, 1, mxREAL); faceNormal = mxGetPr(faceNormalCell); for (e = 0; e < edgeNumber; e++) { for (i = 0; i < dim; i++) { nextVertexIdx = (mwIndex)face[e+1] * dim + i; currentVertexIdx = (mwIndex)face[e] * dim + i; edgeIdx = dim * e + i; edgeCenters[edgeIdx] = (vertices[nextVertexIdx] + vertices[currentVertexIdx]) / 2; edges[edgeIdx] = vertices[nextVertexIdx] - vertices[currentVertexIdx]; } edgeLengths[e] = twoNorm(edges + e * dim, dim); for (i = 0; i < dim; i++) { edgeIdx = dim * e + i; edgeUnits[edgeIdx] = edges[edgeIdx] / edgeLengths[e]; } } cross(edgeUnits, edgeUnits + dim, faceNormal); mexPrint1dArray(faceNormal, dim); tmp = twoNorm(faceNormal, dim); divideScaler(faceNormal, dim, tmp); faceAreas[f] = calcFaceArea(vertices, vertexNumber, face, edgeNumber, faceNormal); for (e = 0; e < edgeNumber; e++){ cross(edgeUnits + e * dim, faceNormal, edgeNormals + e * dim); for (i = 0; i < dim; i++){ edgeNormals[e * dim + i] *= edgeLengths[e]; } } mxSetCell(edgesOutput, f, edgesCell); mxSetCell(edgeCentersOutput, f, edgeCentersCell); mxSetCell(edgeLengthsOutput, f, edgeLengthsCell); mxSetCell(edgeUnitsOutput, f, edgeUnitsCell); mxSetCell(faceNormalsOutput, f, faceNormalCell); mxSetCell(edgeNormalsOutput, f, edgeNormalsCell); } *volume = calcPolyVolumeCellFaces(faceAreas, vertices, facesInput, faceNormalsOutput); }