static bool bpqPeekTest() { SPBPQueue source, source2; SPListElement e1, e2, e3, e4, first, first2; source = spBPQueueCreate(maxSize); ASSERT_TRUE(spBPQueuePeek(source) == NULL); // check edge case // e1, e2, e3, e4 CREATE_4_ELEMENTS() // insert element in unsorted order source2 = quickQ(4, e4, e2, e1, e3); first = spBPQueuePeek(source2); first2 = spBPQueuePeek(source2); ASSERT_TRUE(spListElementCompare(e1, first) == 0); // check that peek is the minimum ASSERT_TRUE(spListElementCompare(first, first2) == 0 && first2 != first); // new copy so not == // free memory spBPQueueDestroy(source); spBPQueueDestroy(source2); spListElementDestroy(first); spListElementDestroy(first2); // e1, e2, e3, e4 DESTROY_4_ELEMENTS() return true; }
// tester for spBPQueueCopy static bool bpqCopyTest() { SPBPQueue source, source2, copy, copy2; SPListElement e1, e2, e3, e4, epeek; ASSERT_TRUE(spBPQueueCopy(NULL) == NULL); // check edge case source = spBPQueueCreate(10); copy = spBPQueueCopy(source); ASSERT_TRUE(copy != NULL); ASSERT_TRUE(0 == spBPQueueSize(copy)); // e1, e2, e3, e4 CREATE_4_ELEMENTS() spBPQueueEnqueue(source, e1); ASSERT_TRUE(0 == spBPQueueSize(copy)); // ensure the copy is a NEW COPY source2 = quickQ(4, e1, e2, e3, e4); copy2 = spBPQueueCopy(source2); ASSERT_TRUE(4 == spBPQueueSize(copy2)); // check that size of copy is correct // check that all elements copied correctly epeek = spBPQueuePeek(copy2); ASSERT_TRUE(spListElementCompare(e1, epeek) == 0); spBPQueueDequeue(copy2); spListElementDestroy(epeek); // free the element // repeat epeek = spBPQueuePeek(copy2); ASSERT_TRUE(spListElementCompare(e2, epeek) == 0); spBPQueueDequeue(copy2); spListElementDestroy(epeek); epeek = spBPQueuePeek(copy2); ASSERT_TRUE(spListElementCompare(e3, epeek) == 0); spBPQueueDequeue(copy2); spListElementDestroy(epeek); epeek = spBPQueuePeek(copy2); ASSERT_TRUE(spListElementCompare(e4, epeek) == 0); spBPQueueDequeue(copy2); spListElementDestroy(epeek); epeek = spBPQueuePeek(copy2); ASSERT_TRUE(epeek == NULL); // free all remaining memory spListElementDestroy(epeek); spBPQueueDestroy(source); spBPQueueDestroy(source2); spBPQueueDestroy(copy); spBPQueueDestroy(copy2); // e1, e2, e3, e4 DESTROY_4_ELEMENTS() return true; }
bool runKnnEdgeTestCase1(knnTestCaseData caseData){ SPListElement curr_elem; bool successFlag; if (caseData == NULL){ spLoggerSafePrintError(COULD_NOT_CREATE_CASE_DATA, __FILE__, __FUNCTION__, __LINE__); FAIL(COULD_NOT_CREATE_CASE_DATA); return false; } if (caseData->tree == NULL){ spLoggerSafePrintError(COULD_NOT_CREATE_POINTS_ARRAY, __FILE__, __FUNCTION__, __LINE__); FAIL(COULD_NOT_CREATE_POINTS_ARRAY); return false; } if (caseData->points == NULL){ spLoggerSafePrintError(COULD_NOT_INITIALIZE_TREE, __FILE__, __FUNCTION__, __LINE__); FAIL(COULD_NOT_INITIALIZE_TREE); return false; } if (caseData->queue == NULL){ spLoggerSafePrintError(COULD_NOT_INITIALIZE_QUEUE, __FILE__, __FUNCTION__, __LINE__); FAIL(COULD_NOT_INITIALIZE_TREE); return false; } if (caseData->queryPoint == NULL){ spLoggerSafePrintError(COULD_NOT_INITIALIZE_QUERY_POINT, __FILE__, __FUNCTION__, __LINE__); FAIL(COULD_NOT_INITIALIZE_TREE); return false; } successFlag = kNearestNeighbors(caseData->tree, caseData->queue, caseData->queryPoint); //general success ASSERT_TRUE(successFlag); ASSERT_TRUE(verifyKNN(caseData->queue, caseData->k, caseData->points, caseData->queryPoint,caseData->size)); //elements should be 1 curr_elem = spBPQueuePeek(caseData->queue); ASSERT_TRUE(spListElementGetIndex(curr_elem) == 1); spListElementDestroy(curr_elem); return true; }
int* SPKDTreeKNN(SPKDTreeNode tree, SPPoint p, int k, SP_KDTREE_MSG* msg) { int i; int* res; SPBPQueue bpq; SPListElement head; if(tree == NULL || k <= 0) { *msg = SP_KDTREE_INVALID_ARGUMENT; return NULL; } bpq = spBPQueueCreate(k); if(bpq == NULL) { *msg = SP_KDTREE_ALLOC_FAIL; return NULL; } res = (int*) malloc(k * sizeof(int)); if(res == NULL) { *msg = SP_KDTREE_ALLOC_FAIL; spBPQueueDestroy(bpq); return NULL; } // Call SPKDTreeKNNRecursive to fill the bpq with the k nearest neighbors SPKDTreeKNNRecursive(tree, p, bpq, msg); if (*msg != SP_KDTREE_SUCCESS) { spBPQueueDestroy(bpq); return NULL; } // Cast the bpq to an array for(i = 0; i < k; i++) { head = spBPQueuePeek(bpq); res[i] = spListElementGetIndex(head); spListElementDestroy(head); spBPQueueDequeue(bpq); } spBPQueueDestroy(bpq); *msg = SP_KDTREE_SUCCESS; return res; }
//general test bool verifyKNN(SPBPQueue rsltQueue, int k,SPPoint* pointsArray,SPPoint queryPoint, int numOfPoints){ SPBPQueue workingQueue = NULL; SPListElement tempElement = NULL; SP_BPQUEUE_MSG msg; bool emptyFlag; int i, queueSize; int* rsltsArray; if (rsltQueue == NULL || pointsArray == NULL || queryPoint == NULL) return false; workingQueue = spBPQueueCopy(rsltQueue); ASSERT_TRUE(workingQueue != NULL); rsltsArray = getRealRsltsArray(k,pointsArray,queryPoint,numOfPoints); if (rsltsArray == NULL){ spBPQueueDestroy(workingQueue); return false; } queueSize = spBPQueueSize(workingQueue); for (i = 0; i< queueSize ; i++){ tempElement = spBPQueuePeek(workingQueue); if (spListElementGetIndex(tempElement) != rsltsArray[i]){ free(rsltsArray); spBPQueueDestroy(workingQueue); return false; } spListElementDestroy(tempElement); msg = spBPQueueDequeue(workingQueue); if (msg != SP_BPQUEUE_SUCCESS){ free(rsltsArray); spBPQueueDestroy(workingQueue); return false; } } emptyFlag = spBPQueueIsEmpty(workingQueue); spBPQueueDestroy(workingQueue); free(rsltsArray); return emptyFlag; }
int* spFindImages(SPPoint* queryFeatures, const int querySize, const SPKDTreeNode root, const SPConfig config, SP_CONFIG_MSG *msg){ int i, knn, numOfSimilarImg, numOfImages; int *imageCounter, *res; SPListElement element; knn = spConfigGetKNN(config, msg); SPBPQueue q = spBPQueueCreate(knn); if(!q){ spLoggerPrintError(ALLOC_FAIL, __FILE__, __FUNCTION__, __LINE__); return NULL; } numOfImages = spConfigGetNumOfImages(config, msg); numOfSimilarImg = spConfigGetNumOfSimilarImages(config, msg); imageCounter = (int*)calloc(numOfImages, sizeof(int)); if(!imageCounter){ spLoggerPrintError(ALLOC_FAIL, __FILE__, __FUNCTION__, __LINE__); spBPQueueDestroy(q); return NULL; } /* count the num of neighbours of every * image for all features of the query */ for(i=0; i<querySize; i++){ spBPQueueClear(q); spKNNSearch(queryFeatures[i], root, q); while((element = spBPQueuePeek(q))!=NULL){ imageCounter[spListElementGetIndex(element)]+=1; spListElementDestroy(element); spBPQueueDequeue(q); } } spBPQueueClear(q); spBPQueueDestroy(q); res = getTopImagesFromArray(imageCounter, numOfImages, numOfSimilarImg); free(imageCounter); return res; }
static bool bpqEnqueueTest() { SPBPQueue source, source2; SPListElement e, e1, e2, e3, e4, e5, peek, peekLast; ASSERT_TRUE(SP_BPQUEUE_INVALID_ARGUMENT == spBPQueueEnqueue(NULL, NULL)); // check edge case CREATE_4_ELEMENTS() // e1, e2, e3, e4 e5 = spListElementCreate(5, 4.0); source = quickQ(3, e2, e1, e4); ASSERT_TRUE(SP_BPQUEUE_SUCCESS == spBPQueueEnqueue(source, e3)); // check that enqueue succeeded ASSERT_TRUE(SP_BPQUEUE_SUCCESS == spBPQueueEnqueue(source, e5)); ASSERT_TRUE(5 == spBPQueueSize(source)); // check that enqueue inserts in order peek = spBPQueuePeek(source); peekLast = spBPQueuePeekLast(source); ASSERT_TRUE(spListElementCompare(e1, peek) == 0); // make sure queue sorts by value and then by index ASSERT_TRUE(spListElementCompare(e5, peekLast) == 0); // e1, e2, e3, e4 DESTROY_4_ELEMENTS() spListElementDestroy(e5); // create new queue with maxSize source2 = spBPQueueCreate(maxSize); // insert 2*maxSize elements from lowest to highest value and check that min and max are correct for (int i = 0; i < maxSize; i++) { e = spListElementCreate(i, (double) i); ASSERT_TRUE(SP_BPQUEUE_SUCCESS == spBPQueueEnqueue(source2, e)); spListElementDestroy(e); } for (int i = maxSize; i < 2 * maxSize; i++) { e = spListElementCreate(i, (double) i); ASSERT_TRUE(SP_BPQUEUE_FULL == spBPQueueEnqueue(source2, e)); // check full when inserting more then maxSize elements spListElementDestroy(e); } ASSERT_TRUE(spBPQueueMinValue(source2) == 0.0); // check that all elements with value too high are not in the queue ASSERT_TRUE((int )spBPQueueMaxValue(source2) == maxSize - 1); spBPQueueClear(source2); // insert 2*maxSize elements from highest to lowest value and check that min and max are correct and same as before for (int i = 2 * maxSize - 1; i >= 0; i--) { e = spListElementCreate(i, (double) i); spBPQueueEnqueue(source2, e); spListElementDestroy(e); } // check min value is correct ASSERT_TRUE(spBPQueueMinValue(source2) == 0.0); ASSERT_TRUE((int )spBPQueueMaxValue(source2) == maxSize - 1); // free memory spBPQueueDestroy(source); spBPQueueDestroy(source2); spListElementDestroy(peek); spListElementDestroy(peekLast); return true; }