vpiHandle vpi_register_cb(p_cb_data cb_data_p) { _VL_VPI_ERROR_RESET(); // reset vpi error status // cppcheck-suppress nullPointer if (VL_UNLIKELY(!cb_data_p)) { _VL_VPI_WARNING(__FILE__, __LINE__, "%s : callback data pointer is null", VL_FUNC); return NULL; } switch (cb_data_p->reason) { case cbAfterDelay: { QData time = 0; if (cb_data_p->time) time = _VL_SET_QII(cb_data_p->time->high, cb_data_p->time->low); VerilatedVpioCb* vop = new VerilatedVpioCb(cb_data_p, VL_TIME_Q()+time); VL_DEBUG_IF_PLI(VL_PRINTF("-vltVpi: vpi_register_cb %d %p delay=%" VL_PRI64 "u\n",cb_data_p->reason,vop,time);); VerilatedVpi::cbTimedAdd(vop); return vop->castVpiHandle(); } case cbReadWriteSynch: // FALLTHRU // Supported via vlt_main.cpp case cbReadOnlySynch: // FALLTHRU // Supported via vlt_main.cpp case cbNextSimTime: // FALLTHRU // Supported via vlt_main.cpp case cbStartOfSimulation: // FALLTHRU // Supported via vlt_main.cpp case cbEndOfSimulation: // FALLTHRU // Supported via vlt_main.cpp case cbValueChange: // FALLTHRU // Supported via vlt_main.cpp case cbPLIError: // FALLTHRU // NOP, but need to return handle, so make object case cbEnterInteractive: // FALLTHRU // NOP, but need to return handle, so make object case cbExitInteractive: // FALLTHRU // NOP, but need to return handle, so make object case cbInteractiveScopeChange: { // FALLTHRU // NOP, but need to return handle, so make object VerilatedVpioCb* vop = new VerilatedVpioCb(cb_data_p, 0); VL_DEBUG_IF_PLI(VL_PRINTF("-vltVpi: vpi_register_cb %d %p\n",cb_data_p->reason,vop);); VerilatedVpi::cbReasonAdd(vop); return vop->castVpiHandle(); }
/*************************************************** * Function: VL_print_test_status ***************************************************/ void VL_print_test_status( IN int test_status) { const char* msg; if (test_status == 0) msg = "[TEST PASSED]"; else msg = "[TEST FAILED]"; VL_PRINTF("\n\n\t-------------------------------------------\n"); VL_PRINTF("\t\t\t%s\n", msg); VL_PRINTF("\t-------------------------------------------\n\n"); }
void Vtop::eval() { Vtop__Syms* __restrict vlSymsp = this->__VlSymsp; // Setup global symbol table Vtop* __restrict vlTOPp VL_ATTR_UNUSED = vlSymsp->TOPp; // Initialize if (VL_UNLIKELY(!vlSymsp->__Vm_didInit)) _eval_initial_loop(vlSymsp); // Evaluate till stable VL_DEBUG_IF(VL_PRINTF("\n----TOP Evaluate Vtop::eval\n"); );
int main (int argc, char** argv) { int i ; int unsigned numNodes = 0 ; float data [] = {1.01, 5.02, 8, 0.1, 100, 3, 9, 4, 1.02} ; VL_PRINTF("Pushing heap\n") ; for (i = 0 ; i < sizeof(data) / sizeof(data[0]) ; ++i) { VL_PRINTF ("%5d: %f\n", i, data[i]) ; vl_heap_float_push (data, &numNodes) ; } VL_PRINTF("Popping heap\n") ; for (i = 0 ; i < sizeof(data) / sizeof(data[0]) ; ++i) { VL_PRINTF ("%5d: %f\n", i, *vl_heap_float_pop (data, &numNodes)) ; } VL_PRINTF("Refilling, updating fourth element, and popping again\n") ; for (i = 0 ; i < sizeof(data) / sizeof(data[0]) ; ++i) { vl_heap_float_push (data, &numNodes) ; } VL_PRINTF("%f -> %f\n", data[3], 9.01) ; data [3] = 9.01 ; vl_heap_float_update (data, numNodes, 3) ; for (i = 0 ; i < sizeof(data) / sizeof(data[0]) ; ++i) { VL_PRINTF ("%5d: %f\n", i, *vl_heap_float_pop (data, &numNodes)) ; } return 0 ; }
VL_EXPORT int vl_ikm_train (VlIKMFilt *f, vl_uint8 const *data, int N) { int err ; if (f-> verb) { VL_PRINTF ("ikm: training with %d data\n", N) ; VL_PRINTF ("ikm: %d clusters\n", f -> K) ; } switch (f -> method) { case VL_IKM_LLOYD : err = vl_ikm_train_lloyd (f, data, N) ; break ; case VL_IKM_ELKAN : err = vl_ikm_train_elkan (f, data, N) ; break ; default : assert (0) ; } return err ; }
int main(int argc, char** argv) { VL_PRINTF ("Double NaN : `%g'\n", VL_NAN_D ) ; VL_PRINTF ("Double Inf : `%g'\n", VL_INFINITY_D) ; VL_PRINTF ("Double - Inf : `%g'\n", - VL_INFINITY_D) ; VL_PRINTF ("Single NaN : `%g'\n", VL_NAN_F ) ; VL_PRINTF ("Single Inf : `%g'\n", VL_INFINITY_F) ; VL_PRINTF ("Single - Inf : `%g'\n", - VL_INFINITY_F) ; VL_PRINTF ("Double: 0.0 < VL_INFINITY_D: %d\n", 0.0 < VL_INFINITY_D) ; VL_PRINTF ("Double: 0.0 > - VL_INFINITY_D: %d\n", 0.0 > - VL_INFINITY_D) ; return 0 ; }
void VerilatedVcd::printTime (vluint64_t timeui) { // VCD file format specification does not allow non-integers for timestamps // Dinotrace doesn't mind, but Cadence vvision seems to choke if (VL_UNLIKELY(timeui < m_timeLastDump)) { timeui = m_timeLastDump; static bool backTime = false; if (!backTime) { backTime = true; VL_PRINTF("VCD time is moving backwards, wave file may be incorrect.\n"); } } m_timeLastDump = timeui; printQuad(timeui); }
int main (int argc, char** argv) { float * X ; float * Y ; vl_size numDimensions = 1000 ; vl_size numSamples = 2000 ; float * result = vl_malloc (sizeof(float) * numSamples * numSamples) ; VlFloatVectorComparisonFunction f ; init_data (numDimensions, numSamples, &X, &Y) ; X+=1 ; Y+=1 ; vl_set_simd_enabled (VL_FALSE) ; f = vl_get_vector_comparison_function_f (VlDistanceL2) ; vl_tic () ; vl_eval_vector_comparison_on_all_pairs_f (result, numDimensions, X, numSamples, Y, numSamples, f) ; VL_PRINTF("Float L2 distnace: %.3f s\n", vl_toc ()) ; vl_set_simd_enabled (VL_TRUE) ; f = vl_get_vector_comparison_function_f (VlDistanceL2) ; vl_tic () ; vl_eval_vector_comparison_on_all_pairs_f (result, numDimensions, X, numSamples, Y, numSamples, f) ; VL_PRINTF("Float L2 distance (SIMD): %.3f s\n", vl_toc ()) ; X-- ; Y-- ; vl_free (X) ; vl_free (Y) ; vl_free (result) ; return 0 ; }
static VlHIKMNode * xmeans (VlHIKMTree *tree, vl_uint8 const *data, int N, int K, int height) { VlHIKMNode *node = vl_malloc (sizeof(VlHIKMNode)) ; vl_uint *ids = vl_malloc (sizeof(vl_uint) * N) ; node-> filter = vl_ikm_new (tree -> method) ; node-> children = (height == 1) ? 0 : vl_malloc (sizeof(VlHIKMNode*) * K) ; vl_ikm_set_max_niters (node->filter, tree->max_niters) ; vl_ikm_set_verbosity (node->filter, tree->verb - 1 ) ; vl_ikm_init_rand_data (node->filter, data, tree->M, N, K) ; vl_ikm_train (node->filter, data, N) ; vl_ikm_push (node->filter, ids, data, N) ; /* recurse for each child */ if (height > 1) { int k ; for (k = 0 ; k < K ; k ++) { int partition_N ; int partition_K ; vl_uint8 *partition ; partition = vl_hikm_copy_subset (data, ids, N, tree->M, k, &partition_N) ; partition_K = VL_MIN (K, partition_N) ; node->children [k] = xmeans (tree, partition, partition_N, partition_K, height - 1) ; vl_free (partition) ; if (tree->verb > tree->depth - height) { VL_PRINTF("hikmeans: branch at depth %d: %6.1f %% completed\n", tree->depth - height, (double) (k+1) / K * 100) ; } } } vl_free (ids) ; return node ; }
void check(const char* bus, int got, int exp) { if (got != exp) { VL_PRINTF("%%Error: Data mismatch on '%s', got=%x, exp=%x\n", bus, got, exp); pass = false; } }
void siftDesctor::covdet_keypoints_and_descriptors(cv::Mat &img, std::vector<std::vector<float>> &frames, std::vector<std::vector<float>> &desctor, bool rootSIFT, bool verbose){ bool display_image = 0; vl_size numCols, numRows; numCols = img.cols; //61 numRows = img.rows; //74 img = (cv::Mat_<float>)img/255.0; // This is for debugging, checking the image was correctly loaded. if (display_image) { std::string window_name = "Image"; namedWindow(window_name, cv::WINDOW_AUTOSIZE );// Create a window for display. imshow(window_name, img); // Show our image inside it. cv::waitKey(0); // Wait for a keystroke in the window } cv::Mat imageTest(img.rows, img.cols, CV_32FC1); cv::Mat imgT(img.cols, img.rows, CV_32FC1); img.copyTo(imageTest); imgT = img.t(); imgT = imgT.reshape(1,1); //std::cout << imgT << std::endl; float *image = new float[(int)imgT.cols]; for(int i = 0; i < imgT.cols; i++){ image[i] = (float)imgT.at<float>(i); //std::cout << image[i] << " "; } typedef enum _VlCovDetDescriptorType{ VL_COVDET_DESC_SIFT } VlCovDetDescriporType; VlCovDetMethod method = VL_COVDET_METHOD_DOG; //vl_bool estimateAffineShape = VL_FALSE; //vl_bool estimateOrientation = VL_FALSE; vl_bool doubleImage = VL_TRUE; vl_index octaveResolution = -1; double edgeThreshold = 10; double peakThreshold = 0.01; double lapPeakThreshold = -1; int descriptorType = -1; vl_index patchResolution = -1; double patchRelativeExtent = -1; double patchRelativeSmoothing = -1; double boundaryMargin = 2.0; if (descriptorType < 0) descriptorType = VL_COVDET_DESC_SIFT; switch (descriptorType){ case VL_COVDET_DESC_SIFT: if (patchResolution < 0) patchResolution = 15; if (patchRelativeExtent < 0) patchRelativeExtent = 10; if (patchRelativeSmoothing <0) patchRelativeSmoothing = 1; if (verbose){ printf("vl_covdet: VL_COVDET_DESC_SIFT: patchResolution=%lld, patchRelativeExtent=%g, patchRelativeSmoothing=%g\n", patchResolution, patchRelativeExtent, patchRelativeSmoothing); } } if (1) { //clock_t t_start = clock(); // create a detector object: VL_COVDET_METHOD_HESSIAN VlCovDet * covdet = vl_covdet_new(method); // set various parameters (optional) vl_covdet_set_transposed(covdet, VL_TRUE); vl_covdet_set_first_octave(covdet, doubleImage? -1 : 0); if (octaveResolution >= 0) vl_covdet_set_octave_resolution(covdet, octaveResolution); if (peakThreshold >= 0) vl_covdet_set_peak_threshold(covdet, peakThreshold); if (edgeThreshold >= 0) vl_covdet_set_edge_threshold(covdet, edgeThreshold); if (lapPeakThreshold >= 0) vl_covdet_set_laplacian_peak_threshold(covdet, lapPeakThreshold); //vl_covdet_set_target_num_features(covdet, target_num_features); //vl_covdet_set_use_adaptive_suppression(covdet, use_adaptive_suppression); if(verbose){ VL_PRINTF("vl_covdet: doubling image: %s, image size: numRows = %d, numCols = %d\n", VL_YESNO(vl_covdet_get_first_octave(covdet) < 0), numCols, numRows); } // process the image and run the detector, im.shape(1) is column, im.shape(0) is row //see http://www.vlfeat.org/api/covdet_8h.html#affcedda1fdc7ed72d223e0aab003024e for detail vl_covdet_put_image(covdet, image, numRows, numCols); if (verbose) { VL_PRINTF("vl_covdet: detector: %s\n", vl_enumeration_get_by_value(vlCovdetMethods, method)->name); VL_PRINTF("vl_covdet: peak threshold: %g, edge threshold: %g\n", vl_covdet_get_peak_threshold(covdet),vl_covdet_get_edge_threshold(covdet)); } vl_covdet_detect(covdet); if (verbose) { vl_size numFeatures = vl_covdet_get_num_features(covdet) ; VL_PRINTF("vl_covdet: %d features suppressed as duplicate (threshold: %g)\n", vl_covdet_get_num_non_extrema_suppressed(covdet), vl_covdet_get_non_extrema_suppression_threshold(covdet)); VL_PRINTF("vl_covdet: detected %d features", numFeatures); } //drop feature on the margin(optimal) if(boundaryMargin > 0){ vl_covdet_drop_features_outside(covdet, boundaryMargin); if(verbose){ vl_size numFeatures = vl_covdet_get_num_features(covdet); VL_PRINTF("vl_covdet: kept %d inside the boundary margin (%g)\n", numFeatures, boundaryMargin); } } /* affine adaptation if needed */ bool estimateAffineShape = true; if (estimateAffineShape) { if (verbose) { vl_size numFeaturesBefore = vl_covdet_get_num_features(covdet) ; VL_PRINTF("vl_covdet: estimating affine shape for %d features", numFeaturesBefore); } vl_covdet_extract_affine_shape(covdet) ; if (verbose) { vl_size numFeaturesAfter = vl_covdet_get_num_features(covdet) ; VL_PRINTF("vl_covdet: %d features passed affine adaptation\n", numFeaturesAfter); } } // compute the orientation of the features (optional) //vl_covdet_extract_orientations(covdet); // get feature descriptors vl_size numFeatures = vl_covdet_get_num_features(covdet); VlCovDetFeature const * feature = (VlCovDetFeature const *)vl_covdet_get_features(covdet); VlSiftFilt * sift = vl_sift_new(16, 16, 1, 3, 0); vl_size patchSide = 2 * patchResolution + 1; double patchStep = (double)patchRelativeExtent / patchResolution; float tempDesc[128]; //float * desc; if (verbose) { VL_PRINTF("vl_covdet: descriptors: type = sift, resolution = %d, extent = %g, smoothing = %g\n", patchResolution,patchRelativeExtent, patchRelativeSmoothing); } //std::vector<float> points(6 * numFeatures); //std::vector<float> desc(dimension * numFeatures); std::vector<float> desc(128); std::vector<float> frame(6); //std::vector<float> patch(patchSide * patchSide); //std::vector<float> patchXY(2 * patchSide * patchSide); float *patch = (float*)malloc(sizeof(float)*patchSide*patchSide); float *patchXY = (float*)malloc(2*sizeof(float)*patchSide*patchSide); vl_sift_set_magnif(sift, 3.0); for (vl_index i = 0; i < (signed)numFeatures; i++) { frame.clear(); frame.push_back(feature[i].frame.y); frame.push_back(feature[i].frame.x); frame.push_back(feature[i].frame.a22); frame.push_back(feature[i].frame.a12); frame.push_back(feature[i].frame.a21); frame.push_back(feature[i].frame.a11); frames.push_back(frame); //std::cout << std::setiosflags(std::ios::fixed); //std::cout << std::setprecision(6) << feature[i].frame.y << ", " << feature[i].frame.x << ", " << feature[i].frame.a22 << ", "<< feature[i].frame.a12 << ", "<< feature[i].frame.a21 << ", " << feature[i].frame.a11 << ", "<< std::endl; vl_covdet_extract_patch_for_frame(covdet, patch, patchResolution, patchRelativeExtent, patchRelativeSmoothing, feature[i].frame); vl_imgradient_polar_f(patchXY, patchXY+1, 2, 2 * patchSide, patch, patchSide, patchSide, patchSide); vl_sift_calc_raw_descriptor(sift, patchXY, tempDesc, (int)patchSide, (int)patchSide, (double)(patchSide - 1) / 2, (double)(patchSide - 1) / 2, (double)patchRelativeExtent / (3.0 * (4 + 1) / 2) / patchStep, VL_PI / 2); flip_descriptor(desc, tempDesc); // sift or rootsift if(rootSIFT == true){ std::vector<float> rootdesc = rootsift(desc); desctor.push_back(rootdesc); }else{ desctor.push_back(desc); } /*std::cout << std::setiosflags(std::ios::fixed); for(vl_index j = 0; j < 128; j++){ std::cout << std::setprecision(6) << desc[j] << " "; } std::cout << "\n" << std::endl;*/ } vl_sift_delete(sift); vl_covdet_delete(covdet); //delete covdet; delete patch; delete patchXY; } }
void mexFunction(int nout, mxArray *out[], int nin, const mxArray *in[]) { enum {IN_I = 0, IN_END} ; enum {OUT_FRAMES=0, OUT_DESCRIPTORS, OUT_INFO, OUT_END} ; int verbose = 0 ; int opt ; int next = IN_END ; mxArray const *optarg ; VlEnumerator *pair ; float const *image ; vl_size numCols, numRows ; VlCovDetMethod method = VL_COVDET_METHOD_DOG; vl_bool estimateAffineShape = VL_FALSE ; vl_bool estimateOrientation = VL_FALSE ; vl_bool doubleImage = VL_TRUE ; vl_index octaveResolution = -1 ; double edgeThreshold = -1 ; double peakThreshold = -1 ; double lapPeakThreshold = -1 ; int descriptorType = -1 ; vl_index patchResolution = -1 ; double patchRelativeExtent = -1 ; double patchRelativeSmoothing = -1 ; float *patch = NULL ; float *patchXY = NULL ; vl_int liopNumSpatialBins = 6; vl_int liopNumNeighbours = 4; float liopRadius = 6.0; float liopIntensityThreshold = VL_NAN_F ; double boundaryMargin = 2.0 ; double * userFrames = NULL ; vl_size userFrameDimension = 0 ; vl_size numUserFrames = 0 ; VL_USE_MATLAB_ENV ; /* ----------------------------------------------------------------- * Check the arguments * -------------------------------------------------------------- */ if (nin < IN_END) { vlmxError(vlmxErrNotEnoughInputArguments, 0) ; } else if (nout > OUT_END) { vlmxError(vlmxErrTooManyOutputArguments, 0) ; } if (mxGetNumberOfDimensions(IN(I)) != 2 || mxGetClassID(IN(I)) != mxSINGLE_CLASS){ vlmxError(vlmxErrInvalidArgument, "I must be a matrix of class SINGLE.") ; } image = (float*) mxGetData(IN(I)) ; numRows = mxGetM(IN(I)) ; numCols = mxGetN(IN(I)) ; while ((opt = vlmxNextOption (in, nin, options, &next, &optarg)) >= 0) { switch (opt) { case opt_verbose : ++ verbose ; break ; case opt_method: pair = vlmxDecodeEnumeration(optarg, vlCovdetMethods, VL_TRUE) ; if (pair == NULL) { vlmxError(vlmxErrInvalidArgument, "METHOD is not a supported detection method.") ; } method = (VlCovDetMethod)pair->value ; break; case opt_descriptor: pair = vlmxDecodeEnumeration(optarg, vlCovDetDescriptorTypes, VL_TRUE) ; if (pair == NULL) { vlmxError(vlmxErrInvalidArgument, "DESCRIPTOR is not a supported descriptor.") ; } descriptorType = (VlCovDetDescriptorType)pair->value ; break; case opt_estimate_affine_shape: if (!mxIsLogicalScalar(optarg)) { vlmxError(vlmxErrInvalidArgument, "ESTIMATEAFFINESHAPE must be a logical scalar value.") ; } else { estimateAffineShape = *mxGetLogicals(optarg) ; } break ; case opt_estimate_orientation: if (!mxIsLogicalScalar(optarg)) { vlmxError(vlmxErrInvalidArgument, "ESTIMATEORIENTATION must be a logical scalar value.") ; } else { estimateOrientation = *mxGetLogicals(optarg); } break ; case opt_double_image: if (!mxIsLogicalScalar(optarg)) { vlmxError(vlmxErrInvalidArgument, "DOUBLEIMAGE must be a logical scalar value.") ; } else { doubleImage = *mxGetLogicals(optarg); } break ; case opt_octave_resolution : if (!vlmxIsPlainScalar(optarg) || (octaveResolution = (vl_index)*mxGetPr(optarg)) < 1) { vlmxError(vlmxErrInvalidArgument, "OCTAVERESOLUTION must be an integer not smaller than 1.") ; } break ; case opt_edge_threshold : if (!vlmxIsPlainScalar(optarg) || (edgeThreshold = *mxGetPr(optarg)) < 1) { vlmxError(vlmxErrInvalidArgument, "EDGETHRESHOLD must be a real not smaller than 1.") ; } break ; case opt_peak_threshold : if (!vlmxIsPlainScalar(optarg) || (peakThreshold = *mxGetPr(optarg)) < 0) { vlmxError(vlmxErrInvalidArgument, "PEAKTHRESHOLD must be a non-negative real.") ; } break ; case opt_laplacian_peak_threshold : if (!vlmxIsPlainScalar(optarg) || (lapPeakThreshold = *mxGetPr(optarg)) < 0) { vlmxError(vlmxErrInvalidArgument, "LAPLACIANPEAKTHRESHOLD must be a non-negative real.") ; } break ; case opt_patch_relative_smoothing : if (!vlmxIsPlainScalar(optarg) || (patchRelativeSmoothing = *mxGetPr(optarg)) < 0) { vlmxError(vlmxErrInvalidArgument, "PATCHRELATIVESMOOTHING must be a non-negative real.") ; } break ; case opt_patch_relative_extent : if (!vlmxIsPlainScalar(optarg) || (patchRelativeExtent = *mxGetPr(optarg)) <= 0) { vlmxError(vlmxErrInvalidArgument, "PATCHRELATIVEEXTENT must be a posiive real.") ; } break ; case opt_patch_resolution : if (!vlmxIsPlainScalar(optarg) || (patchResolution = (vl_index)*mxGetPr(optarg)) <= 0) { vlmxError(vlmxErrInvalidArgument, "PATCHRESOLUTION must be a positive integer.") ; } break ; case opt_liop_bins : if (!vlmxIsPlainScalar(optarg) || (liopNumSpatialBins = (vl_int)*mxGetPr(optarg)) <= 0) { vlmxError(vlmxErrInvalidArgument, "number of LIOPNUMSPATIALBINS is not a positive scalar.") ; } break ; case opt_liop_neighbours : if (!vlmxIsPlainScalar(optarg) || (liopNumNeighbours = (vl_int)*mxGetPr(optarg)) <= 0) { vlmxError(vlmxErrInvalidArgument, "number of LIOPNUMNEIGHBOURS is not a positive scalar.") ; } break ; case opt_liop_radius : if (!vlmxIsPlainScalar(optarg) || (liopRadius = (float)*mxGetPr(optarg)) <= 0) { vlmxError(vlmxErrInvalidArgument, "LIOPRADIUS must is not a positive scalar.") ; } break ; case opt_liop_threshold : if (!vlmxIsPlainScalar(optarg)) { vlmxError(vlmxErrInvalidArgument, "LIOPINTENSITYTHRESHOLD is not a scalar.") ; } liopIntensityThreshold = *mxGetPr(optarg) ; break ; case opt_frames: if (!vlmxIsPlainMatrix(optarg,-1,-1)) { vlmxError(vlmxErrInvalidArgument, "FRAMES must be a palin matrix.") ; } numUserFrames = mxGetN (optarg) ; userFrameDimension = mxGetM (optarg) ; userFrames = mxGetPr (optarg) ; switch (userFrameDimension) { case 2: case 3: case 4: case 5: case 6: /* ok */ break ; default: vlmxError(vlmxErrInvalidArgument, "FRAMES of dimensions %d are not recognised", userFrameDimension); ; } break ; default : abort() ; } } if (descriptorType < 0) descriptorType = VL_COVDET_DESC_SIFT ; switch (descriptorType) { case VL_COVDET_DESC_NONE : break ; case VL_COVDET_DESC_PATCH : if (patchResolution < 0) patchResolution = 20 ; if (patchRelativeExtent < 0) patchRelativeExtent = 6 ; if (patchRelativeSmoothing < 0) patchRelativeSmoothing = 1 ; break ; case VL_COVDET_DESC_SIFT : /* the patch parameters are selected to match the SIFT descriptor geometry */ if (patchResolution < 0) patchResolution = 15 ; if (patchRelativeExtent < 0) patchRelativeExtent = 7.5 ; if (patchRelativeSmoothing < 0) patchRelativeSmoothing = 1 ; break ; case VL_COVDET_DESC_LIOP : if (patchResolution < 0) patchResolution = 20 ; if (patchRelativeExtent < 0) patchRelativeExtent = 4 ; if (patchRelativeSmoothing < 0) patchRelativeSmoothing = 0.5 ; break ; } if (patchResolution > 0) { vl_size w = 2*patchResolution + 1 ; patch = mxMalloc(sizeof(float) * w * w); patchXY = mxMalloc(2 * sizeof(float) * w * w); } if (descriptorType == VL_COVDET_DESC_LIOP && liopRadius > patchResolution) { vlmxError(vlmxErrInconsistentData, "LIOPRADIUS is larger than PATCHRESOLUTION.") ; } /* ----------------------------------------------------------------- * Detector * -------------------------------------------------------------- */ { VlCovDet * covdet = vl_covdet_new(method) ; /* set covdet parameters */ vl_covdet_set_transposed(covdet, VL_TRUE) ; vl_covdet_set_first_octave(covdet, doubleImage ? -1 : 0) ; if (octaveResolution >= 0) vl_covdet_set_octave_resolution(covdet, octaveResolution) ; if (peakThreshold >= 0) vl_covdet_set_peak_threshold(covdet, peakThreshold) ; if (edgeThreshold >= 0) vl_covdet_set_edge_threshold(covdet, edgeThreshold) ; if (lapPeakThreshold >= 0) vl_covdet_set_laplacian_peak_threshold(covdet, lapPeakThreshold) ; if (verbose) { VL_PRINTF("vl_covdet: doubling image: %s\n", VL_YESNO(vl_covdet_get_first_octave(covdet) < 0)) ; } /* process the image */ vl_covdet_put_image(covdet, image, numRows, numCols) ; /* fill with frames: eitehr run the detector of poure them in */ if (numUserFrames > 0) { vl_index k ; if (verbose) { mexPrintf("vl_covdet: sourcing %d frames\n", numUserFrames) ; } for (k = 0 ; k < (signed)numUserFrames ; ++k) { double const * uframe = userFrames + userFrameDimension * k ; double a11, a21, a12, a22 ; VlCovDetFeature feature ; feature.peakScore = VL_INFINITY_F ; feature.edgeScore = 1.0 ; feature.frame.x = (float)uframe[1] - 1 ; feature.frame.y = (float)uframe[0] - 1 ; switch (userFrameDimension) { case 2: a11 = 1.0 ; a21 = 0.0 ; a12 = 0.0 ; a22 = 1.0 ; break ; case 3: a11 = uframe[2] ; a21 = 0.0 ; a12 = 0.0 ; a22 = uframe[2] ; break ; case 4: { double sigma = uframe[2] ; double c = cos(uframe[3]) ; double s = sin(uframe[3]) ; a11 = sigma * c ; a21 = sigma * s ; a12 = sigma * (-s) ; a22 = sigma * c ; break ; } case 5: { double d2 ; if (uframe[2] < 0) { vlmxError(vlmxErrInvalidArgument, "FRAMES(:,%d) does not have a PSD covariance.", k+1) ; } a11 = sqrt(uframe[2]) ; a21 = uframe[3] / VL_MAX(a11, 1e-10) ; a12 = 0.0 ; d2 = uframe[4] - a21*a21 ; if (d2 < 0) { vlmxError(vlmxErrInvalidArgument, "FRAMES(:,%d) does not have a PSD covariance.", k+1) ; } a22 = sqrt(d2) ; break ; } case 6: { a11 = uframe[2] ; a21 = uframe[3] ; a12 = uframe[4] ; a22 = uframe[5] ; break ; } default: a11 = 0 ; a21 = 0 ; a12 = 0 ; a22 = 0 ; assert(0) ; } feature.frame.a11 = (float)a22 ; feature.frame.a21 = (float)a12 ; feature.frame.a12 = (float)a21 ; feature.frame.a22 = (float)a11 ; vl_covdet_append_feature(covdet, &feature) ; } } else { if (verbose) { mexPrintf("vl_covdet: detector: %s\n", vl_enumeration_get_by_value(vlCovdetMethods, method)->name) ; mexPrintf("vl_covdet: peak threshold: %g, edge threshold: %g\n", vl_covdet_get_peak_threshold(covdet), vl_covdet_get_edge_threshold(covdet)) ; } vl_covdet_detect(covdet) ; if (verbose) { vl_index i ; vl_size numFeatures = vl_covdet_get_num_features(covdet) ; mexPrintf("vl_covdet: %d features suppressed as duplicate (threshold: %g)\n", vl_covdet_get_num_non_extrema_suppressed(covdet), vl_covdet_get_non_extrema_suppression_threshold(covdet)) ; switch (method) { case VL_COVDET_METHOD_HARRIS_LAPLACE: case VL_COVDET_METHOD_HESSIAN_LAPLACE: { vl_size numScales ; vl_size const * numFeaturesPerScale ; numFeaturesPerScale = vl_covdet_get_laplacian_scales_statistics (covdet, &numScales) ; mexPrintf("vl_covdet: Laplacian scales:") ; for (i = 0 ; i <= (signed)numScales ; ++i) { mexPrintf("%d with %d scales;", numFeaturesPerScale[i], i) ; } mexPrintf("\n") ; } break ; default: break ; } mexPrintf("vl_covdet: detected %d features\n", numFeatures) ; } if (boundaryMargin > 0) { vl_covdet_drop_features_outside (covdet, boundaryMargin) ; if (verbose) { vl_size numFeatures = vl_covdet_get_num_features(covdet) ; mexPrintf("vl_covdet: kept %d inside the boundary margin (%g)\n", numFeatures, boundaryMargin) ; } } } /* affine adaptation if needed */ if (estimateAffineShape) { if (verbose) { vl_size numFeaturesBefore = vl_covdet_get_num_features(covdet) ; mexPrintf("vl_covdet: estimating affine shape for %d features\n", numFeaturesBefore) ; } vl_covdet_extract_affine_shape(covdet) ; if (verbose) { vl_size numFeaturesAfter = vl_covdet_get_num_features(covdet) ; mexPrintf("vl_covdet: %d features passed affine adaptation\n", numFeaturesAfter) ; } } /* orientation estimation if needed */ if (estimateOrientation) { vl_size numFeaturesBefore = vl_covdet_get_num_features(covdet) ; vl_size numFeaturesAfter ; vl_covdet_extract_orientations(covdet) ; numFeaturesAfter = vl_covdet_get_num_features(covdet) ; if (verbose && numFeaturesAfter > numFeaturesBefore) { mexPrintf("vl_covdet: %d duplicate features were crated due to ambiguous " "orientation detection (%d total)\n", numFeaturesAfter - numFeaturesBefore, numFeaturesAfter) ; } } /* store results back */ { vl_index i ; vl_size numFeatures = vl_covdet_get_num_features(covdet) ; VlCovDetFeature const * feature = vl_covdet_get_features(covdet); double * pt ; OUT(FRAMES) = mxCreateDoubleMatrix (6, numFeatures, mxREAL) ; pt = mxGetPr(OUT(FRAMES)) ; for (i = 0 ; i < (signed)numFeatures ; ++i) { /* save the transposed frame, adjust origin to MATLAB's*/ *pt++ = feature[i].frame.y + 1 ; *pt++ = feature[i].frame.x + 1 ; *pt++ = feature[i].frame.a22 ; *pt++ = feature[i].frame.a12 ; *pt++ = feature[i].frame.a21 ; *pt++ = feature[i].frame.a11 ; } } if (nout >= 2) { switch (descriptorType) { case VL_COVDET_DESC_NONE: OUT(DESCRIPTORS) = mxCreateDoubleMatrix(0,0,mxREAL); break ; case VL_COVDET_DESC_PATCH: { vl_size numFeatures ; VlCovDetFeature const * feature ; vl_index i ; vl_size w = 2*patchResolution + 1 ; float * desc ; if (verbose) { mexPrintf("vl_covdet: descriptors: type=patch, " "resolution=%d, extent=%g, smoothing=%g\n", patchResolution, patchRelativeExtent, patchRelativeSmoothing); } numFeatures = vl_covdet_get_num_features(covdet) ; feature = vl_covdet_get_features(covdet); OUT(DESCRIPTORS) = mxCreateNumericMatrix(w*w, numFeatures, mxSINGLE_CLASS, mxREAL) ; desc = mxGetData(OUT(DESCRIPTORS)) ; for (i = 0 ; i < (signed)numFeatures ; ++i) { vl_covdet_extract_patch_for_frame(covdet, desc, patchResolution, patchRelativeExtent, patchRelativeSmoothing, feature[i].frame) ; desc += w*w ; } break ; } case VL_COVDET_DESC_SIFT: { vl_size numFeatures = vl_covdet_get_num_features(covdet) ; VlCovDetFeature const * feature = vl_covdet_get_features(covdet); VlSiftFilt * sift = vl_sift_new(16, 16, 1, 3, 0) ; vl_index i ; vl_size dimension = 128 ; vl_size patchSide = 2 * patchResolution + 1 ; double patchStep = (double)patchRelativeExtent / patchResolution ; float tempDesc [128] ; float * desc ; if (verbose) { mexPrintf("vl_covdet: descriptors: type=sift, " "resolution=%d, extent=%g, smoothing=%g\n", patchResolution, patchRelativeExtent, patchRelativeSmoothing); } OUT(DESCRIPTORS) = mxCreateNumericMatrix(dimension, numFeatures, mxSINGLE_CLASS, mxREAL) ; desc = mxGetData(OUT(DESCRIPTORS)) ; vl_sift_set_magnif(sift, 3.0) ; for (i = 0 ; i < (signed)numFeatures ; ++i) { vl_covdet_extract_patch_for_frame(covdet, patch, patchResolution, patchRelativeExtent, patchRelativeSmoothing, feature[i].frame) ; vl_imgradient_polar_f (patchXY, patchXY +1, 2, 2 * patchSide, patch, patchSide, patchSide, patchSide) ; /* Note: the patch is transposed, so that x and y are swapped. However, if NBO is not divisible by 4, then the configuration of the SIFT orientations is not symmetric by rotations of pi/2. Hence the only option is to rotate the descriptor further by an angle we need to compute the descriptor rotaed by an additional pi/2 angle. In this manner, x concides and y is flipped. */ vl_sift_calc_raw_descriptor (sift, patchXY, tempDesc, (int)patchSide, (int)patchSide, (double)(patchSide-1) / 2, (double)(patchSide-1) / 2, (double)patchRelativeExtent / (3.0 * (4 + 1) / 2) / patchStep, VL_PI / 2) ; flip_descriptor (desc, tempDesc) ; desc += dimension ; } vl_sift_delete(sift) ; break ; } case VL_COVDET_DESC_LIOP : { /* TODO: get parameters form input */ vl_size numFeatures = vl_covdet_get_num_features(covdet) ; vl_size dimension ; VlCovDetFeature const * feature = vl_covdet_get_features(covdet); vl_index i ; vl_size patchSide = 2 * patchResolution + 1 ; float * desc ; VlLiopDesc * liop = vl_liopdesc_new(liopNumNeighbours, liopNumSpatialBins, liopRadius, (vl_size)patchSide) ; if (!vl_is_nan_f(liopIntensityThreshold)) { vl_liopdesc_set_intensity_threshold(liop, liopIntensityThreshold) ; } dimension = vl_liopdesc_get_dimension(liop) ; if (verbose) { mexPrintf("vl_covdet: descriptors: type=liop, " "resolution=%d, extent=%g, smoothing=%g\n", patchResolution, patchRelativeExtent, patchRelativeSmoothing); } OUT(DESCRIPTORS) = mxCreateNumericMatrix(dimension, numFeatures, mxSINGLE_CLASS, mxREAL); desc = mxGetData(OUT(DESCRIPTORS)) ; vl_tic(); for(i = 0; i < (signed)numFeatures; i++){ vl_covdet_extract_patch_for_frame(covdet, patch, patchResolution, patchRelativeExtent, patchRelativeSmoothing, feature[i].frame); vl_liopdesc_process(liop, desc, patch); desc += dimension; } mexPrintf("time: %f\n",vl_toc()); mexPrintf("threshold: %f\n",liop->intensityThreshold); break; } default: assert(0) ; /* descriptor type */ } } if (nout >= 3) { vl_index i ; vl_size numFeatures = vl_covdet_get_num_features(covdet) ; VlCovDetFeature const * feature = vl_covdet_get_features(covdet); const char* names[] = { "gss", "css", "peakScores", "edgeScores", "orientationScore", "laplacianScaleScore" }; mxArray * gss_array = _createArrayFromScaleSpace(vl_covdet_get_gss(covdet)) ; mxArray * css_array = _createArrayFromScaleSpace(vl_covdet_get_css(covdet)) ; mxArray * peak_array = mxCreateNumericMatrix(1,numFeatures,mxSINGLE_CLASS,mxREAL) ; mxArray * edge_array = mxCreateNumericMatrix(1,numFeatures,mxSINGLE_CLASS,mxREAL) ; mxArray * orientation_array = mxCreateNumericMatrix(1,numFeatures,mxSINGLE_CLASS,mxREAL) ; mxArray * laplacian_array = mxCreateNumericMatrix(1,numFeatures,mxSINGLE_CLASS,mxREAL) ; float * peak = mxGetData(peak_array) ; float * edge = mxGetData(edge_array) ; float * orientation = mxGetData(orientation_array) ; float * laplacian = mxGetData(laplacian_array) ; for (i = 0 ; i < (signed)numFeatures ; ++i) { peak[i] = feature[i].peakScore ; edge[i] = feature[i].edgeScore ; orientation[i] = feature[i].orientationScore ; laplacian[i] = feature[i].laplacianScaleScore ; } OUT(INFO) = mxCreateStructMatrix(1, 1, 6, names) ; mxSetFieldByNumber(OUT(INFO), 0, 0, gss_array) ; mxSetFieldByNumber(OUT(INFO), 0, 1, css_array) ; mxSetFieldByNumber(OUT(INFO), 0, 2, peak_array) ; mxSetFieldByNumber(OUT(INFO), 0, 3, edge_array) ; mxSetFieldByNumber(OUT(INFO), 0, 4, orientation_array) ; mxSetFieldByNumber(OUT(INFO), 0, 5, laplacian_array) ; } /* cleanup */ vl_covdet_delete (covdet) ; } if (patchXY) mxFree(patchXY) ; if (patch) mxFree(patch) ; }
void mexFunction(int nout, mxArray *out[], int nin, const mxArray *in[]) { enum {IN_FOREST = 0, IN_DATA, IN_QUERY, IN_END} ; enum {OUT_INDEX = 0, OUT_DISTANCE} ; int verbose = 0 ; int opt ; int next = IN_END ; mxArray const *optarg ; VlKDForest * forest ; mxArray const * forest_array = in[IN_FOREST] ; mxArray const * data_array = in[IN_DATA] ; mxArray const * query_array = in[IN_QUERY] ; void * query ; vl_uint32 * index ; void * distance ; vl_size numNeighbors = 1 ; vl_size numQueries ; unsigned int numComparisons = 0 ; unsigned int maxNumComparisons = 0 ; mxClassID dataClass ; vl_index i ; VL_USE_MATLAB_ENV ; /* ----------------------------------------------------------------- * Check the arguments * -------------------------------------------------------------- */ if (nin < 3) { vlmxError(vlmxErrNotEnoughInputArguments, NULL) ; } if (nout > 2) { vlmxError(vlmxErrTooManyOutputArguments, NULL) ; } forest = new_kdforest_from_array (forest_array, data_array) ; dataClass = mxGetClassID (data_array) ; if (mxGetClassID (query_array) != dataClass) { vlmxError(vlmxErrInvalidArgument, "QUERY must have the same storage class as DATA.") ; } if (! vlmxIsReal (query_array)) { vlmxError(vlmxErrInvalidArgument, "QUERY must be real.") ; } if (! vlmxIsMatrix (query_array, forest->dimension, -1)) { vlmxError(vlmxErrInvalidArgument, "QUERY must be a matrix with TREE.NUMDIMENSIONS rows.") ; } while ((opt = vlmxNextOption (in, nin, options, &next, &optarg)) >= 0) { switch (opt) { case opt_num_neighs : if (! vlmxIsScalar(optarg) || (numNeighbors = mxGetScalar(optarg)) < 1) { vlmxError(vlmxErrInvalidArgument, "NUMNEIGHBORS must be a scalar not smaller than one.") ; } break; case opt_max_num_comparisons : if (! vlmxIsScalar(optarg)) { vlmxError(vlmxErrInvalidArgument, "MAXNUMCOMPARISONS must be a scalar.") ; } maxNumComparisons = mxGetScalar(optarg) ; break; case opt_verbose : ++ verbose ; break ; } } vl_kdforest_set_max_num_comparisons (forest, maxNumComparisons) ; query = mxGetData (query_array) ; numQueries = mxGetN (query_array) ; out[OUT_INDEX] = mxCreateNumericMatrix (numNeighbors, numQueries, mxUINT32_CLASS, mxREAL) ; out[OUT_DISTANCE] = mxCreateNumericMatrix (numNeighbors, numQueries, dataClass, mxREAL) ; index = mxGetData (out[OUT_INDEX]) ; distance = mxGetData (out[OUT_DISTANCE]) ; if (verbose) { VL_PRINTF ("vl_kdforestquery: number of queries: %d\n", numQueries) ; VL_PRINTF ("vl_kdforestquery: number of neighbors per query: %d\n", numNeighbors) ; VL_PRINTF ("vl_kdforestquery: max num of comparisons per query: %d\n", vl_kdforest_get_max_num_comparisons (forest)) ; } numComparisons = vl_kdforest_query_with_array (forest, index, numNeighbors, numQueries, distance, query) ; vl_kdforest_delete(forest) ; /* adjust for MATLAB indexing */ for (i = 0 ; i < (signed) (numNeighbors * numQueries) ; ++i) { index[i] ++ ; } if (verbose) { VL_PRINTF ("vl_kdforestquery: number of comparisons per query: %.3f\n", ((double) numComparisons) / numQueries) ; VL_PRINTF ("vl_kdforestquery: number of comparisons per neighbor: %.3f\n", ((double) numComparisons) / (numQueries * numNeighbors)) ; } }
void mexFunction(int nout, mxArray *out[], int nin, const mxArray *in[]) { enum {IN_FOREST = 0, IN_DATA, IN_QUERY, IN_END} ; enum {OUT_INDEX = 0, OUT_DISTANCE} ; int verbose = 0 ; int opt ; int next = IN_END ; mxArray const *optarg ; VlKDForest * forest ; mxArray const * forest_array = in[IN_FOREST] ; mxArray const * data_array = in[IN_DATA] ; mxArray const * query_array = in[IN_QUERY] ; mxArray * index_array ; mxArray * distance_array ; void * query ; vl_uint32 * index ; void * distance ; vl_size numNeighbors = 1 ; vl_size numQueries ; vl_uindex qi, ni; unsigned int numComparisons = 0 ; unsigned int maxNumComparisons = 0 ; VlKDForestNeighbor * neighbors ; mxClassID dataClass ; VL_USE_MATLAB_ENV ; /* ----------------------------------------------------------------- * Check the arguments * -------------------------------------------------------------- */ if (nin < 3) { vlmxError(vlmxErrNotEnoughInputArguments, NULL) ; } if (nout > 2) { vlmxError(vlmxErrTooManyOutputArguments, NULL) ; } forest = new_kdforest_from_array (forest_array, data_array) ; dataClass = mxGetClassID (data_array) ; if (mxGetClassID (query_array) != dataClass) { vlmxError(vlmxErrInvalidArgument, "QUERY must have the same storage class as DATA.") ; } if (! vlmxIsReal (query_array)) { vlmxError(vlmxErrInvalidArgument, "QUERY must be real.") ; } if (! vlmxIsMatrix (query_array, forest->dimension, -1)) { vlmxError(vlmxErrInvalidArgument, "QUERY must be a matrix with TREE.NUMDIMENSIONS rows.") ; } while ((opt = vlmxNextOption (in, nin, options, &next, &optarg)) >= 0) { switch (opt) { case opt_num_neighs : if (! vlmxIsScalar(optarg) || (numNeighbors = mxGetScalar(optarg)) < 1) { vlmxError(vlmxErrInvalidArgument, "NUMNEIGHBORS must be a scalar not smaller than one.") ; } break; case opt_max_num_comparisons : if (! vlmxIsScalar(optarg)) { vlmxError(vlmxErrInvalidArgument, "MAXNUMCOMPARISONS must be a scalar.") ; } maxNumComparisons = mxGetScalar(optarg) ; break; case opt_verbose : ++ verbose ; break ; } } vl_kdforest_set_max_num_comparisons (forest, maxNumComparisons) ; neighbors = vl_malloc (sizeof(VlKDForestNeighbor) * numNeighbors) ; query = mxGetData (query_array) ; numQueries = mxGetN (query_array) ; out[OUT_INDEX] = index_array = mxCreateNumericMatrix (numNeighbors, numQueries, mxUINT32_CLASS, mxREAL) ; out[OUT_DISTANCE] = distance_array = mxCreateNumericMatrix (numNeighbors, numQueries, dataClass, mxREAL) ; index = mxGetData (index_array) ; distance = mxGetData (distance_array) ; if (verbose) { VL_PRINTF ("vl_kdforestquery: number of queries: %d\n", numQueries) ; VL_PRINTF ("vl_kdforestquery: number of neighbors per query: %d\n", numNeighbors) ; VL_PRINTF ("vl_kdforestquery: max num of comparisons per query: %d\n", vl_kdforest_get_max_num_comparisons (forest)) ; } for (qi = 0 ; qi < numQueries ; ++ qi) { numComparisons += vl_kdforest_query (forest, neighbors, numNeighbors, query) ; switch (dataClass) { case mxSINGLE_CLASS: { float * distance_ = (float*) distance ; for (ni = 0 ; ni < numNeighbors ; ++ni) { *index++ = neighbors[ni].index + 1 ; *distance_++ = neighbors[ni].distance ; } query = (float*)query + vl_kdforest_get_data_dimension (forest) ; distance = distance_ ; break ; } case mxDOUBLE_CLASS: { double * distance_ = (double*) distance ; for (ni = 0 ; ni < numNeighbors ; ++ni) { *index++ = neighbors[ni].index + 1 ; *distance_++ = neighbors[ni].distance ; } query = (double*)query + vl_kdforest_get_data_dimension (forest) ; distance = distance_ ; break ; } default: abort() ; } } if (verbose) { VL_PRINTF ("vl_kdforestquery: number of comparisons per query: %.3f\n", ((double) numComparisons) / numQueries) ; VL_PRINTF ("vl_kdforestquery: number of comparisons per neighbor: %.3f\n", ((double) numComparisons) / (numQueries * numNeighbors)) ; } vl_kdforest_delete (forest) ; vl_free (neighbors) ; }
void dpii_display_call(const char* c) { VL_PRINTF("dpii_display_call: %s\n", c); }
static double VL_XCAT(_vl_kmeans_refine_centers_elkan_, SFX) (VlKMeans * self, TYPE const * data, vl_size numData) { vl_size d, iteration, x ; vl_uint32 c, j ; vl_bool allDone ; TYPE * distances = vl_malloc (sizeof(TYPE) * numData) ; vl_uint32 * assignments = vl_malloc (sizeof(vl_uint32) * numData) ; vl_size * clusterMasses = vl_malloc (sizeof(vl_size) * numData) ; #if (FLT == VL_TYPE_FLOAT) VlFloatVectorComparisonFunction distFn = vl_get_vector_comparison_function_f(self->distance) ; #else VlDoubleVectorComparisonFunction distFn = vl_get_vector_comparison_function_d(self->distance) ; #endif TYPE * nextCenterDistances = vl_malloc (sizeof(TYPE) * self->numCenters) ; TYPE * pointToClosestCenterUB = vl_malloc (sizeof(TYPE) * numData) ; vl_bool * pointToClosestCenterUBIsStrict = vl_malloc (sizeof(vl_bool) * numData) ; TYPE * pointToCenterLB = vl_malloc (sizeof(TYPE) * numData * self->numCenters) ; TYPE * newCenters = vl_malloc(sizeof(TYPE) * self->dimension * self->numCenters) ; TYPE * centerToNewCenterDistances = vl_malloc (sizeof(TYPE) * self->numCenters) ; vl_uint32 * permutations = NULL ; vl_size * numSeenSoFar = NULL ; double energy ; vl_size totDistanceComputationsToInit = 0 ; vl_size totDistanceComputationsToRefreshUB = 0 ; vl_size totDistanceComputationsToRefreshLB = 0 ; vl_size totDistanceComputationsToRefreshCenterDistances = 0 ; vl_size totDistanceComputationsToNewCenters = 0 ; vl_size totDistanceComputationsToFinalize = 0 ; if (self->distance == VlDistanceL1) { permutations = vl_malloc(sizeof(vl_uint32) * numData * self->dimension) ; numSeenSoFar = vl_malloc(sizeof(vl_size) * self->numCenters) ; VL_XCAT(_vl_kmeans_sort_data_helper_, SFX)(self, permutations, data, numData) ; } /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ /* Initialization */ /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ /* An iteration is: get_new_centers + reassign + get_energy. This counts as iteration 0, where get_new_centers is assumed to be performed before calling the train function by the initialization function */ /* update distances between centers */ totDistanceComputationsToInit += VL_XCAT(_vl_kmeans_update_center_distances_, SFX)(self) ; /* assigmen points to the initial centers and initialize bounds */ memset(pointToCenterLB, 0, sizeof(TYPE) * self->numCenters * numData) ; for (x = 0 ; x < numData ; ++x) { TYPE distance ; /* do the first center */ assignments[x] = 0 ; distance = distFn(self->dimension, data + x * self->dimension, (TYPE*)self->centers + 0) ; pointToClosestCenterUB[x] = distance ; pointToClosestCenterUBIsStrict[x] = VL_TRUE ; pointToCenterLB[0 + x * self->numCenters] = distance ; totDistanceComputationsToInit += 1 ; /* do other centers */ for (c = 1 ; c < self->numCenters ; ++c) { /* Can skip if the center assigned so far is twice as close as its distance to the center under consideration */ if (((self->distance == VlDistanceL1) ? 2.0 : 4.0) * pointToClosestCenterUB[x] <= ((TYPE*)self->centerDistances) [c + assignments[x] * self->numCenters]) { continue ; } distance = distFn(self->dimension, data + x * self->dimension, (TYPE*)self->centers + c * self->dimension) ; pointToCenterLB[c + x * self->numCenters] = distance ; totDistanceComputationsToInit += 1 ; if (distance < pointToClosestCenterUB[x]) { pointToClosestCenterUB[x] = distance ; assignments[x] = c ; } } } /* compute UB on energy */ energy = 0 ; for (x = 0 ; x < numData ; ++x) { energy += pointToClosestCenterUB[x] ; } if (self->verbosity) { VL_PRINTF("kmeans: Elkan iter 0: energy = %g, dist. calc. = %d\n", energy, totDistanceComputationsToInit) ; } /* #define SANITY*/ #ifdef SANITY { int xx ; int cc ; TYPE tol = 1e-5 ; VL_PRINTF("inconsistencies after initial assignments:\n"); for (xx = 0 ; xx < numData ; ++xx) { for (cc = 0 ; cc < self->numCenters ; ++cc) { TYPE a = pointToCenterLB[cc + xx * self->numCenters] ; TYPE b = distFn(self->dimension, data + self->dimension * xx, (TYPE*)self->centers + self->dimension * cc) ; if (cc == assignments[xx]) { TYPE z = pointToClosestCenterUB[xx] ; if (z+tol<b) VL_PRINTF("UB %d %d = %f < %f\n", cc, xx, z, b) ; } if (a>b+tol) VL_PRINTF("LB %d %d = %f > %f\n", cc, xx, a, b) ; } } } #endif /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ /* Iterations */ /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ for (iteration = 1 ; 1; ++iteration) { vl_size numDistanceComputationsToRefreshUB = 0 ; vl_size numDistanceComputationsToRefreshLB = 0 ; vl_size numDistanceComputationsToRefreshCenterDistances = 0 ; vl_size numDistanceComputationsToNewCenters = 0 ; /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ /* Compute new centers */ /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ memset(clusterMasses, 0, sizeof(vl_size) * numData) ; for (x = 0 ; x < numData ; ++x) { clusterMasses[assignments[x]] ++ ; } switch (self->distance) { case VlDistanceL2: memset(newCenters, 0, sizeof(TYPE) * self->dimension * self->numCenters) ; for (x = 0 ; x < numData ; ++x) { TYPE * cpt = newCenters + assignments[x] * self->dimension ; TYPE const * xpt = data + x * self->dimension ; for (d = 0 ; d < self->dimension ; ++d) { cpt[d] += xpt[d] ; } } for (c = 0 ; c < self->numCenters ; ++c) { TYPE mass = clusterMasses[c] ; TYPE * cpt = newCenters + c * self->dimension ; for (d = 0 ; d < self->dimension ; ++d) { cpt[d] /= mass ; } } break ; case VlDistanceL1: for (d = 0 ; d < self->dimension ; ++d) { vl_uint32 * perm = permutations + d * numData ; memset(numSeenSoFar, 0, sizeof(vl_size) * self->numCenters) ; for (x = 0; x < numData ; ++x) { c = assignments[perm[x]] ; if (2 * numSeenSoFar[c] < clusterMasses[c]) { newCenters [d + c * self->dimension] = data [d + perm[x] * self->dimension] ; } numSeenSoFar[c] ++ ; } } break ; default: abort(); } /* done compute centers */ /* compute the distance from the old centers to the new centers */ for (c = 0 ; c < self->numCenters ; ++c) { TYPE distance = distFn(self->dimension, newCenters + c * self->dimension, (TYPE*)self->centers + c * self->dimension) ; centerToNewCenterDistances[c] = distance ; numDistanceComputationsToNewCenters += 1 ; } /* make the new centers current */ { TYPE * tmp = self->centers ; self->centers = newCenters ; newCenters = tmp ; } /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ /* Reassign points to a centers */ /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ /* Update distances between centers. */ numDistanceComputationsToRefreshCenterDistances += VL_XCAT(_vl_kmeans_update_center_distances_, SFX)(self) ; for (c = 0 ; c < self->numCenters ; ++c) { nextCenterDistances[c] = (TYPE) VL_INFINITY_D ; for (j = 0 ; j < self->numCenters ; ++j) { if (j == c) continue ; nextCenterDistances[c] = VL_MIN(nextCenterDistances[c], ((TYPE*)self->centerDistances) [j + c * self->numCenters]) ; } } /* Update upper bounds on point-to-closest-center distances based on the center variation. */ for (x = 0 ; x < numData ; ++x) { TYPE a = pointToClosestCenterUB[x] ; TYPE b = centerToNewCenterDistances[assignments[x]] ; if (self->distance == VlDistanceL1) { pointToClosestCenterUB[x] = a + b ; } else { #if (FLT == VL_TYPE_FLOAT) TYPE sqrtab = sqrtf (a * b) ; #else TYPE sqrtab = sqrt (a * b) ; #endif pointToClosestCenterUB[x] = a + b + 2.0 * sqrtab ; } pointToClosestCenterUBIsStrict[x] = VL_FALSE ; } /* Update lower bounds on point-to-center distances based on the center variation. */ for (x = 0 ; x < numData ; ++x) { for (c = 0 ; c < self->numCenters ; ++c) { TYPE a = pointToCenterLB[c + x * self->numCenters] ; TYPE b = centerToNewCenterDistances[c] ; if (a < b) { pointToCenterLB[c + x * self->numCenters] = 0 ; } else { if (self->distance == VlDistanceL1) { pointToCenterLB[c + x * self->numCenters] = a - b ; } else { #if (FLT == VL_TYPE_FLOAT) TYPE sqrtab = sqrtf (a * b) ; #else TYPE sqrtab = sqrt (a * b) ; #endif pointToCenterLB[c + x * self->numCenters] = a + b - 2.0 * sqrtab ; } } } } #ifdef SANITY { int xx ; int cc ; TYPE tol = 1e-5 ; VL_PRINTF("inconsistencies before assignments:\n"); for (xx = 0 ; xx < numData ; ++xx) { for (cc = 0 ; cc < self->numCenters ; ++cc) { TYPE a = pointToCenterLB[cc + xx * self->numCenters] ; TYPE b = distFn(self->dimension, data + self->dimension * xx, (TYPE*)self->centers + self->dimension * cc) ; if (cc == assignments[xx]) { TYPE z = pointToClosestCenterUB[xx] ; if (z+tol<b) VL_PRINTF("UB %d %d = %f < %f\n", cc, xx, z, b) ; } if (a>b+tol) VL_PRINTF("LB %d %d = %f > %f (assign = %d)\n", cc, xx, a, b, assignments[xx]) ; } } } #endif /* Scan the data and to the reassignments. Use the bounds to skip as many point-to-center distance calculations as possible. */ for (allDone = VL_TRUE, x = 0 ; x < numData ; ++x) { /* A point x sticks with its current center assignmets[x] the UB to d(x, c[assigmnets[x]]) is not larger than half the distance of c[assigments[x]] to any other center c. */ if (((self->distance == VlDistanceL1) ? 2.0 : 4.0) * pointToClosestCenterUB[x] <= nextCenterDistances[assignments[x]]) { continue ; } for (c = 0 ; c < self->numCenters ; ++c) { vl_uint32 cx = assignments[x] ; TYPE distance ; /* The point is not reassigned to a given center c if either: 0 - c is already the assigned center 1 - The UB of d(x, c[assignments[x]]) is smaller than half the distance of c[assigments[x]] to c, OR 2 - The UB of d(x, c[assignmets[x]]) is smaller than the LB of the distance of x to c. */ if (cx == c) { continue ; } if (((self->distance == VlDistanceL1) ? 2.0 : 4.0) * pointToClosestCenterUB[x] <= ((TYPE*)self->centerDistances) [c + cx * self->numCenters]) { continue ; } if (pointToClosestCenterUB[x] <= pointToCenterLB [c + x * self->numCenters]) { continue ; } /* If the UB is loose, try recomputing it and test again */ if (! pointToClosestCenterUBIsStrict[x]) { distance = distFn(self->dimension, data + self->dimension * x, (TYPE*)self->centers + self->dimension * cx) ; pointToClosestCenterUB[x] = distance ; pointToClosestCenterUBIsStrict[x] = VL_TRUE ; pointToCenterLB[cx + x * self->numCenters] = distance ; numDistanceComputationsToRefreshUB += 1 ; if (((self->distance == VlDistanceL1) ? 2.0 : 4.0) * pointToClosestCenterUB[x] <= ((TYPE*)self->centerDistances) [c + cx * self->numCenters]) { continue ; } if (pointToClosestCenterUB[x] <= pointToCenterLB [c + x * self->numCenters]) { continue ; } } /* Now the UB is strict (equal to d(x, assignments[x])), but we still could not exclude that x should be reassigned to c. We therefore compute the distance, update the LB, and check if a reassigmnet must be made */ distance = distFn(self->dimension, data + x * self->dimension, (TYPE*)self->centers + c * self->dimension) ; numDistanceComputationsToRefreshLB += 1 ; pointToCenterLB[c + x * self->numCenters] = distance ; if (distance < pointToClosestCenterUB[x]) { assignments[x] = c ; pointToClosestCenterUB[x] = distance ; allDone = VL_FALSE ; /* the UB strict flag is already set here */ } } /* assign center */ } /* next data point */ totDistanceComputationsToRefreshUB += numDistanceComputationsToRefreshUB ; totDistanceComputationsToRefreshLB += numDistanceComputationsToRefreshLB ; totDistanceComputationsToRefreshCenterDistances += numDistanceComputationsToRefreshCenterDistances ; totDistanceComputationsToNewCenters += numDistanceComputationsToNewCenters ; #ifdef SANITY { int xx ; int cc ; TYPE tol = 1e-5 ; VL_PRINTF("inconsistencies after assignments:\n"); for (xx = 0 ; xx < numData ; ++xx) { for (cc = 0 ; cc < self->numCenters ; ++cc) { TYPE a = pointToCenterLB[cc + xx * self->numCenters] ; TYPE b = distFn(self->dimension, data + self->dimension * xx, (TYPE*)self->centers + self->dimension * cc) ; if (cc == assignments[xx]) { TYPE z = pointToClosestCenterUB[xx] ; if (z+tol<b) VL_PRINTF("UB %d %d = %f < %f\n", cc, xx, z, b) ; } if (a>b+tol) VL_PRINTF("LB %d %d = %f > %f (assign = %d)\n", cc, xx, a, b, assignments[xx]) ; } } } #endif /* compute UB on energy */ energy = 0 ; for (x = 0 ; x < numData ; ++x) { energy += pointToClosestCenterUB[x] ; } if (self->verbosity) { vl_size numDistanceComputations = numDistanceComputationsToRefreshUB + numDistanceComputationsToRefreshLB + numDistanceComputationsToRefreshCenterDistances + numDistanceComputationsToNewCenters ; VL_PRINTF("kmeans: Elkan iter %d: energy <= %g, dist. calc. = %d\n", iteration, energy, numDistanceComputations) ; if (self->verbosity > 1) { VL_PRINTF("kmeans: Elkan iter %d: total dist. calc. per type: " "UB: %.1f%% (%d), LB: %.1f%% (%d), " "intra_center: %.1f%% (%d), " "new_center: %.1f%% (%d)\n", iteration, 100.0 * numDistanceComputationsToRefreshUB / numDistanceComputations, numDistanceComputationsToRefreshUB, 100.0 *numDistanceComputationsToRefreshLB / numDistanceComputations, numDistanceComputationsToRefreshLB, 100.0 * numDistanceComputationsToRefreshCenterDistances / numDistanceComputations, numDistanceComputationsToRefreshCenterDistances, 100.0 * numDistanceComputationsToNewCenters / numDistanceComputations, numDistanceComputationsToNewCenters) ; } } /* check termination conditions */ if (iteration >= self->maxNumIterations) { if (self->verbosity) { VL_PRINTF("kmeans: Elkan terminating because maximum number of iterations reached\n") ; } break ; } if (allDone) { if (self->verbosity) { VL_PRINTF("kmeans: Elkan terminating because the algorithm fully converged\n") ; } break ; } } /* next Elkan iteration */ /* compute true energy */ energy = 0 ; for (x = 0 ; x < numData ; ++ x) { vl_uindex cx = assignments [x] ; energy += distFn(self->dimension, data + self->dimension * x, (TYPE*)self->centers + self->dimension * cx) ; totDistanceComputationsToFinalize += 1 ; } { vl_size totDistanceComputations = totDistanceComputationsToInit + totDistanceComputationsToRefreshUB + totDistanceComputationsToRefreshLB + totDistanceComputationsToRefreshCenterDistances + totDistanceComputationsToNewCenters + totDistanceComputationsToFinalize ; double saving = (double)totDistanceComputations / (iteration * self->numCenters * numData) ; if (self->verbosity) { VL_PRINTF("kmeans: Elkan: total dist. calc.: %d (%.2f %% of Lloyd)\n", totDistanceComputations, saving * 100.0) ; } if (self->verbosity > 1) { VL_PRINTF("kmeans: Elkan: total dist. calc. per type: " "init: %.1f%% (%d), UB: %.1f%% (%d), LB: %.1f%% (%d), " "intra_center: %.1f%% (%d), " "new_center: %.1f%% (%d), " "finalize: %.1f%% (%d)\n", 100.0 * totDistanceComputationsToInit / totDistanceComputations, totDistanceComputationsToInit, 100.0 * totDistanceComputationsToRefreshUB / totDistanceComputations, totDistanceComputationsToRefreshUB, 100.0 *totDistanceComputationsToRefreshLB / totDistanceComputations, totDistanceComputationsToRefreshLB, 100.0 * totDistanceComputationsToRefreshCenterDistances / totDistanceComputations, totDistanceComputationsToRefreshCenterDistances, 100.0 * totDistanceComputationsToNewCenters / totDistanceComputations, totDistanceComputationsToNewCenters, 100.0 * totDistanceComputationsToFinalize / totDistanceComputations, totDistanceComputationsToFinalize) ; } } if (permutations) { vl_free(permutations) ; } if (numSeenSoFar) { vl_free(numSeenSoFar) ; } vl_free(distances) ; vl_free(assignments) ; vl_free(clusterMasses) ; vl_free(nextCenterDistances) ; vl_free(pointToClosestCenterUB) ; vl_free(pointToClosestCenterUBIsStrict) ; vl_free(pointToCenterLB) ; vl_free(newCenters) ; vl_free(centerToNewCenterDistances) ; return energy ; }
static double VL_XCAT(_vl_kmeans_refine_centers_lloyd_, SFX) (VlKMeans * self, TYPE const * data, vl_size numData) { vl_size c, d, x, iteration ; vl_bool allDone ; double previousEnergy = VL_INFINITY_D ; double energy ; TYPE * distances = vl_malloc (sizeof(TYPE) * numData) ; vl_uint32 * assignments = vl_malloc (sizeof(vl_uint32) * numData) ; vl_size * clusterMasses = vl_malloc (sizeof(vl_size) * numData) ; vl_uint32 * permutations = NULL ; vl_size * numSeenSoFar = NULL ; if (self->distance == VlDistanceL1) { permutations = vl_malloc(sizeof(vl_uint32) * numData * self->dimension) ; numSeenSoFar = vl_malloc(sizeof(vl_size) * self->numCenters) ; VL_XCAT(_vl_kmeans_sort_data_helper_, SFX)(self, permutations, data, numData) ; } for (energy = VL_INFINITY_D, iteration = 0, allDone = VL_FALSE ; 1 ; ++ iteration) { /* assign data to cluters */ VL_XCAT(_vl_kmeans_quantize_, SFX)(self, assignments, distances, data, numData) ; /* compute energy */ energy = 0 ; for (x = 0 ; x < numData ; ++x) energy += distances[x] ; if (self->verbosity) { VL_PRINTF("kmeans: Lloyd iter %d: energy = %g\n", iteration, energy) ; } /* check termination conditions */ if (iteration >= self->maxNumIterations) { if (self->verbosity) { VL_PRINTF("kmeans: Lloyd terminating because maximum number of iterations reached\n") ; } break ; } if (energy == previousEnergy) { if (self->verbosity) { VL_PRINTF("kmeans: Lloyd terminating because the algorithm fully converged\n") ; } break ; } /* begin next iteration */ previousEnergy = energy ; /* update clusters */ memset(clusterMasses, 0, sizeof(vl_size) * numData) ; for (x = 0 ; x < numData ; ++x) { clusterMasses[assignments[x]] ++ ; } switch (self->distance) { case VlDistanceL2: memset(self->centers, 0, sizeof(TYPE) * self->dimension * self->numCenters) ; for (x = 0 ; x < numData ; ++x) { TYPE * cpt = (TYPE*)self->centers + assignments[x] * self->dimension ; TYPE const * xpt = data + x * self->dimension ; for (d = 0 ; d < self->dimension ; ++d) { cpt[d] += xpt[d] ; } } for (c = 0 ; c < self->numCenters ; ++c) { TYPE mass = clusterMasses[c] ; TYPE * cpt = (TYPE*)self->centers + c * self->dimension ; for (d = 0 ; d < self->dimension ; ++d) { cpt[d] /= mass ; } } break ; case VlDistanceL1: for (d = 0 ; d < self->dimension ; ++d) { vl_uint32 * perm = permutations + d * numData ; memset(numSeenSoFar, 0, sizeof(vl_size) * self->numCenters) ; for (x = 0; x < numData ; ++x) { c = assignments[perm[x]] ; if (2 * numSeenSoFar[c] < clusterMasses[c]) { ((TYPE*)self->centers) [d + c * self->dimension] = data [d + perm[x] * self->dimension] ; } numSeenSoFar[c] ++ ; } } break ; default: abort(); } /* done compute centers */ } /* next Lloyd iteration */ if (permutations) { vl_free(permutations) ; } if (numSeenSoFar) { vl_free(numSeenSoFar) ; } vl_free(distances) ; vl_free(assignments) ; vl_free(clusterMasses) ; return energy ; }
VL_EXPORT double vl_kmeans_cluster (VlKMeans * self, void const * data, vl_size dimension, vl_size numData, vl_size numCenters) { vl_uindex repetition ; double bestEnergy = VL_INFINITY_D ; void * bestCenters = NULL ; for (repetition = 0 ; repetition < self->numRepetitions ; ++ repetition) { double energy ; double timeRef ; if (self->verbosity) { VL_PRINTF("kmeans: repetition %d of %d\n", repetition + 1, self->numRepetitions) ; } timeRef = vl_get_cpu_time() ; switch (self->initialization) { case VlKMeansRandomSelection : vl_kmeans_seed_centers_with_rand_data (self, data, dimension, numData, numCenters) ; break ; case VlKMeansPlusPlus : vl_kmeans_seed_centers_plus_plus (self, data, dimension, numData, numCenters) ; break ; default: abort() ; } if (self->verbosity) { VL_PRINTF("kmeans: K-means initialized in %.2f s\n", vl_get_cpu_time() - timeRef) ; } timeRef = vl_get_cpu_time () ; energy = vl_kmeans_refine_centers (self, data, numData) ; if (self->verbosity) { VL_PRINTF("kmeans: K-means termineted in %.2f s with energy %g\n", vl_get_cpu_time() - timeRef, energy) ; } /* copy centers to output if current solution is optimal */ if (energy < bestEnergy) { void * temp ; bestEnergy = energy ; if (bestCenters == NULL) { bestCenters = vl_malloc(vl_get_type_size(self->dataType) * self->dimension * self->numCenters) ; } /* swap buffers */ temp = bestCenters ; bestCenters = self->centers ; self->centers = temp ; } /* better energy */ } /* next repetition */ vl_free (self->centers) ; self->centers = bestCenters ; return bestEnergy ; }
VL_EXPORT vl_bool vl_gaussian_elimination (double * A, vl_size numRows, vl_size numColumns) { vl_index i, j, ii, jj ; assert(A) ; assert(numRows <= numColumns) ; #define Aat(i,j) A[(i) + (j)*numRows] /* Gauss elimination */ for(j = 0 ; j < (signed)numRows ; ++j) { double maxa = 0 ; double maxabsa = 0 ; vl_index maxi = -1 ; double tmp ; #if 0 { vl_index iii, jjj ; for (iii = 0 ; iii < 2 ; ++iii) { for (jjj = 0 ; jjj < 3 ; ++jjj) { VL_PRINTF("%5.2g ", Aat(iii,jjj)) ; } VL_PRINTF("\n") ; } VL_PRINTF("\n") ; } #endif /* look for the maximally stable pivot */ for (i = j ; i < (signed)numRows ; ++i) { double a = Aat(i,j) ; double absa = vl_abs_d (a) ; if (absa > maxabsa) { maxa = a ; maxabsa = absa ; maxi = i ; } } i = maxi ; /* if singular give up */ if (maxabsa < 1e-10) return VL_ERR_OVERFLOW ; /* swap j-th row with i-th row and normalize j-th row */ for(jj = j ; jj < (signed)numColumns ; ++jj) { tmp = Aat(i,jj) ; Aat(i,jj) = Aat(j,jj) ; Aat(j,jj) = tmp ; Aat(j,jj) /= maxa ; } #if 0 { vl_index iii, jjj ; VL_PRINTF("after swap %d %d\n", j, i); for (iii = 0 ; iii < 2 ; ++iii) { for (jjj = 0 ; jjj < 3 ; ++jjj) { VL_PRINTF("%5.2g ", Aat(iii,jjj)) ; } VL_PRINTF("\n") ; } VL_PRINTF("\n") ; } #endif /* elimination */ for (ii = j+1 ; ii < (signed)numRows ; ++ii) { double x = Aat(ii,j) ; for (jj = j ; jj < (signed)numColumns ; ++jj) { Aat(ii,jj) -= x * Aat(j,jj) ; } } #if 0 { VL_PRINTF("after elimination\n"); vl_index iii, jjj ; for (iii = 0 ; iii < 2 ; ++iii) { for (jjj = 0 ; jjj < 3 ; ++jjj) { VL_PRINTF("%5.2g ", Aat(iii,jjj)) ; } VL_PRINTF("\n") ; } VL_PRINTF("\n") ; } #endif } /* backward substitution */ for (i = numRows - 1 ; i > 0 ; --i) { /* substitute in all rows above */ for (ii = i - 1 ; ii >= 0 ; --ii) { double x = Aat(ii,i) ; /* j = numRows */ for (j = numRows ; j < (signed)numColumns ; ++j) { Aat(ii,j) -= x * Aat(i,j) ; } } } #if 0 { VL_PRINTF("after substitution\n"); vl_index iii, jjj ; for (iii = 0 ; iii < 2 ; ++iii) { for (jjj = 0 ; jjj < 3 ; ++jjj) { VL_PRINTF("%5.2g ", Aat(iii,jjj)) ; } VL_PRINTF("\n") ; } VL_PRINTF("\n") ; } #endif return VL_ERR_OK ; }
void vl_print_host_info () { char const *arch = 0, *endian = 0, *comp = 0, *dm = 0 ; int compver ; #ifdef VL_ARCH_IA6 arch = "IA64" ; #endif #ifdef VL_ARCH_IX86 arch = "IX86" ; #endif #ifdef VL_ARCH_PPC arch = "PPC" ; #endif #ifdef VL_ARCH_BIN_ENDIAN endian = "big endian" ; #endif #ifdef VL_ARCH_LITTLE_ENDIAN endian = "little endian" ; #endif #ifdef VL_COMPILER_MSC comp = "Microsoft Visual C++" ; compver = VL_COMPILER_MSC ; #endif #ifdef VL_COMPILER_GNUC comp = "GNU C" ; compver = VL_COMPILER_GNUC ; #endif #ifdef VL_COMPILER_LP64 dm = "LP64" ; #endif #ifdef VL_COMPILER_LLP64 dm = "LP64" ; #endif #ifdef VL_COMPILER_ILP32 dm = "ILP32" ; #endif #define YESNO(x) ((x)?"yes":"no") VL_PRINTF("Host: Compiler: %s %d\n", comp, compver) ; VL_PRINTF(" Compiler data model: %s\n", dm) ; VL_PRINTF(" CPU architecture: %s\n", arch) ; VL_PRINTF(" CPU endianness: %s\n", endian) ; #ifdef HAS_CPUID { struct x86cpu_ const* c = _vl_x86cpu_get() ; VL_PRINTF(" CPU vendor string: %s\n", c->vendor_string) ; VL_PRINTF(" CPU has MMX: %s\n", YESNO(c->has_mmx)) ; VL_PRINTF(" CPU has SSE: %s\n", YESNO(c->has_sse)) ; VL_PRINTF(" CPU has SSE2: %s\n", YESNO(c->has_sse2)) ; VL_PRINTF(" CPU has SSE3: %s\n", YESNO(c->has_sse3)) ; VL_PRINTF(" CPU has SSE4.1: %s\n", YESNO(c->has_sse41)) ; VL_PRINTF(" CPU has SSE4.2: %s\n", YESNO(c->has_sse42)) ; VL_PRINTF("VLFeat uses SIMD: %s\n", YESNO(vl_get_simd_enabled())) ; } #endif }
int main(int argc, char** argv) { int error = 0 ; /* ----------------------------------------------------------------- * vl_fast_resqrt_* * -------------------------------------------------------------- */ VL_PRINTF ("%20s %10s %10s %10s\n", "func", "elaps [s]", "eval/s", "chksum") ; #define SFX f #define SFX2 FLT #define T float #define SQRT sqrtf #define ABS fabsf #define ONE 1.0F #include "test_mathop_fast_resqrt.tc" #undef ONE #undef ABS #undef SQRT #undef T #undef SFX2 #undef SFX #define SFX d #define SFX2 DBL #define T float #define SQRT sqrt #define ABS fabs #define ONE 1.0 #include "test_mathop_fast_resqrt.tc" #undef ONE #undef ABS #undef SQRT #undef T #undef SFX2 #undef SFX VL_PRINTF("\n") ; /* ----------------------------------------------------------------- * vl_fast_sqrt_ui* * -------------------------------------------------------------- */ VL_PRINTF ("%20s %10s %10s %10s\n", "func", "elaps [s]", "eval/s", "chksum") ; #undef SFX #undef T #undef STEP #define SFX 32 #define T vl_uint32 #define STEP 7 #include "test_mathop_fast_sqrt_ui.tc" #undef SFX #undef T #undef STEP #define SFX 16 #define T vl_uint16 #define STEP 0 #include "test_mathop_fast_sqrt_ui.tc" #undef SFX #undef T #undef STEP #define SFX 8 #define T vl_uint8 #define STEP 0 #include "test_mathop_fast_sqrt_ui.tc" return error ; }
int RoccTest::parseOptions(int argc, char** argv) { opts_.argv0 = argv[0]; int c; while (1) { static struct option long_options[] = { {"trace", required_argument, 0, 'c'}, {"debug", no_argument, 0, 'd'}, {"help", no_argument, 0, 'h'}, {"memory", required_argument, 0, 'm'}, {"no-fail", no_argument, &opts_.nofail, 1}, {"timeout", required_argument, 0, 't'}, {"verbose", no_argument, 0, 'v'}, {0, 0, 0, 0} }; int option_index = 0; c = getopt_long (argc, argv, "c:dhm:t:v", long_options, &option_index); if (c == -1) break; switch (c) { case 0: break; case 'c': #if VM_TRACE opts_.filename_vcd = optarg; break; #else std::cerr << "[ERROR] Trace unsupported. Verilator needs the `--trace` arg to build an\n" "[ERROR] executable that can emit VCD files (use `make debug`).\n"; opts_.exit_code = -3; return opts_.exit_code; #endif case 'd': verbose = true; break; case 'h': usage(argv[0]); opts_.exit_code = 0; return opts_.exit_code; case 'm': opts_.filename_mem = optarg; loadMemory(opts_.filename_mem); break; case 't': opts_.timeout = atoi(optarg) * 2; break; case 'v': opts_.verbose = true; break; default: printf("[ERROR] Bad command line option %d (%c)\n", c, c); opts_.exit_code = -2; return opts_.exit_code; } } #if VM_TRACE Verilated::traceEverOn(true); VL_PRINTF("Enabling waves...\n"); tfp_ = new VerilatedVcdC; t_->trace (tfp_, 99); if (opts_.filename_vcd) { tfp_->open(opts_.filename_vcd); if (verbose) std::cout << "[INFO] Writing VCD file" << opts_.filename_vcd << "\n"; } #endif return opts_.exit_code; }
int main() { Verilated::debug(0); tb = new VM_PREFIX ("tb"); #ifdef SYSTEMC_VERSION sc_signal<vluint32_t> i3; sc_signal<vluint32_t> o3; sc_signal<vluint32_t> i34[4]; sc_signal<vluint32_t> o34[4]; sc_signal<vluint32_t> i345[4][5]; sc_signal<vluint32_t> o345[4][5]; tb->i3(i3); tb->o3(o3); for (int i=0; i<4; i++) { tb->i34[i](i34[i]); tb->o34[i](o34[i]); for (int j=0; j<5; j++) { tb->i345[i][j](i345[i][j]); tb->o345[i][j](o345[i][j]); } } #endif // loop through every possibility and check the result #ifdef SYSTEMC_VERSION sc_start(1,SC_NS); # define ASSIGN(s,v) s.write(v) # define READ(s) s.read() #else tb->eval(); # define ASSIGN(s,v) tb->s = (v) # define READ(s) tb->s #endif ASSIGN(i3, 13); for (int i=0; i<4; i++) { ASSIGN(i34[i], i); for (int j=0; j<5; j++) { ASSIGN(i345[i][j], i*8 + j); } } #ifdef SYSTEMC_VERSION sc_start(1,SC_NS); #else tb->eval(); #endif check("o3", READ(o3), 13); for (int i=0; i<4; i++) { check("o34", READ(o34[i]), i); for (int j=0; j<5; j++) { check("o345", READ(o345[i][j]), i*8 + j); } } if (pass) { VL_PRINTF("*-* All Finished *-*\n"); } else { vl_fatal(__FILE__,__LINE__,"top", "Unexpected results from test\n"); } return 0; }
VL_EXPORT void vl_print_info () { VL_PRINTF ("VLFeat version %s\n", vl_get_version_string()) ; vl_print_host_info () ; }