void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) { //----------------------- // Input pointers double *h_fMRI_Volumes_double, *h_Quadrature_Filter_1_Real_double, *h_Quadrature_Filter_2_Real_double, *h_Quadrature_Filter_3_Real_double, *h_Quadrature_Filter_1_Imag_double, *h_Quadrature_Filter_2_Imag_double, *h_Quadrature_Filter_3_Imag_double; float *h_fMRI_Volumes, *h_Quadrature_Filter_1_Real, *h_Quadrature_Filter_2_Real, *h_Quadrature_Filter_3_Real, *h_Quadrature_Filter_1_Imag, *h_Quadrature_Filter_2_Imag, *h_Quadrature_Filter_3_Imag; int MOTION_CORRECTION_FILTER_SIZE, NUMBER_OF_ITERATIONS_FOR_MOTION_CORRECTION; int OPENCL_PLATFORM,OPENCL_DEVICE; float EPI_VOXEL_SIZE_X, EPI_VOXEL_SIZE_Y, EPI_VOXEL_SIZE_Z; //----------------------- // Output pointers double *h_Motion_Corrected_fMRI_Volumes_double, *h_Motion_Parameters_double; float *h_Motion_Corrected_fMRI_Volumes, *h_Motion_Parameters; //--------------------- /* Check the number of input and output arguments. */ if(nrhs<10) { mexErrMsgTxt("Too few input arguments."); } if(nrhs>10) { mexErrMsgTxt("Too many input arguments."); } if(nlhs<2) { mexErrMsgTxt("Too few output arguments."); } if(nlhs>2) { mexErrMsgTxt("Too many output arguments."); } /* Input arguments */ // The data h_fMRI_Volumes_double = (double*)mxGetData(prhs[0]); EPI_VOXEL_SIZE_X = (float)mxGetScalar(prhs[1]); EPI_VOXEL_SIZE_Y = (float)mxGetScalar(prhs[2]); EPI_VOXEL_SIZE_Z = (float)mxGetScalar(prhs[3]); h_Quadrature_Filter_1_Real_double = (double*)mxGetPr(prhs[4]); h_Quadrature_Filter_1_Imag_double = (double*)mxGetPi(prhs[4]); h_Quadrature_Filter_2_Real_double = (double*)mxGetPr(prhs[5]); h_Quadrature_Filter_2_Imag_double = (double*)mxGetPi(prhs[5]); h_Quadrature_Filter_3_Real_double = (double*)mxGetPr(prhs[6]); h_Quadrature_Filter_3_Imag_double = (double*)mxGetPi(prhs[6]); NUMBER_OF_ITERATIONS_FOR_MOTION_CORRECTION = (int)mxGetScalar(prhs[7]); OPENCL_PLATFORM = (int)mxGetScalar(prhs[8]); OPENCL_DEVICE = (int)mxGetScalar(prhs[9]); int NUMBER_OF_DIMENSIONS = mxGetNumberOfDimensions(prhs[0]); const int *ARRAY_DIMENSIONS_DATA = mxGetDimensions(prhs[0]); const int *ARRAY_DIMENSIONS_FILTER = mxGetDimensions(prhs[4]); int DATA_H, DATA_W, DATA_D, DATA_T, NUMBER_OF_MOTION_CORRECTION_PARAMETERS; NUMBER_OF_MOTION_CORRECTION_PARAMETERS = 6; DATA_H = ARRAY_DIMENSIONS_DATA[0]; DATA_W = ARRAY_DIMENSIONS_DATA[1]; DATA_D = ARRAY_DIMENSIONS_DATA[2]; DATA_T = ARRAY_DIMENSIONS_DATA[3]; MOTION_CORRECTION_FILTER_SIZE = ARRAY_DIMENSIONS_FILTER[0]; int DATA_SIZE = DATA_W * DATA_H * DATA_D * DATA_T * sizeof(float); int MOTION_PARAMETERS_SIZE = NUMBER_OF_MOTION_CORRECTION_PARAMETERS * DATA_T * sizeof(float); int FILTER_SIZE = MOTION_CORRECTION_FILTER_SIZE * MOTION_CORRECTION_FILTER_SIZE * MOTION_CORRECTION_FILTER_SIZE * sizeof(float); int VOLUME_SIZE = DATA_W * DATA_H * DATA_D * sizeof(float); mexPrintf("Data size : %i x %i x %i x %i \n", DATA_W, DATA_H, DATA_D, DATA_T); mexPrintf("Voxel size : %f x %f x %f \n", EPI_VOXEL_SIZE_X, EPI_VOXEL_SIZE_Y, EPI_VOXEL_SIZE_Z); mexPrintf("Filter size : %i x %i x %i \n", MOTION_CORRECTION_FILTER_SIZE,MOTION_CORRECTION_FILTER_SIZE,MOTION_CORRECTION_FILTER_SIZE); mexPrintf("Number of iterations : %i \n", NUMBER_OF_ITERATIONS_FOR_MOTION_CORRECTION); //------------------------------------------------- // Output to Matlab // Create pointer for volumes to Matlab NUMBER_OF_DIMENSIONS = 4; int ARRAY_DIMENSIONS_OUT_MOTION_CORRECTED_FMRI_VOLUMES[4]; ARRAY_DIMENSIONS_OUT_MOTION_CORRECTED_FMRI_VOLUMES[0] = DATA_H; ARRAY_DIMENSIONS_OUT_MOTION_CORRECTED_FMRI_VOLUMES[1] = DATA_W; ARRAY_DIMENSIONS_OUT_MOTION_CORRECTED_FMRI_VOLUMES[2] = DATA_D; ARRAY_DIMENSIONS_OUT_MOTION_CORRECTED_FMRI_VOLUMES[3] = DATA_T; plhs[0] = mxCreateNumericArray(NUMBER_OF_DIMENSIONS,ARRAY_DIMENSIONS_OUT_MOTION_CORRECTED_FMRI_VOLUMES,mxDOUBLE_CLASS, mxREAL); h_Motion_Corrected_fMRI_Volumes_double = mxGetPr(plhs[0]); NUMBER_OF_DIMENSIONS = 2; int ARRAY_DIMENSIONS_OUT_MOTION_PARAMETERS[2]; ARRAY_DIMENSIONS_OUT_MOTION_PARAMETERS[0] = DATA_T; ARRAY_DIMENSIONS_OUT_MOTION_PARAMETERS[1] = NUMBER_OF_MOTION_CORRECTION_PARAMETERS; plhs[1] = mxCreateNumericArray(NUMBER_OF_DIMENSIONS,ARRAY_DIMENSIONS_OUT_MOTION_PARAMETERS,mxDOUBLE_CLASS, mxREAL); h_Motion_Parameters_double = mxGetPr(plhs[1]); // ------------------------------------------------ // Allocate memory on the host h_fMRI_Volumes = (float *)mxMalloc(DATA_SIZE); h_Quadrature_Filter_1_Real = (float *)mxMalloc(FILTER_SIZE); h_Quadrature_Filter_1_Imag = (float *)mxMalloc(FILTER_SIZE); h_Quadrature_Filter_2_Real = (float *)mxMalloc(FILTER_SIZE); h_Quadrature_Filter_2_Imag = (float *)mxMalloc(FILTER_SIZE); h_Quadrature_Filter_3_Real = (float *)mxMalloc(FILTER_SIZE); h_Quadrature_Filter_3_Imag = (float *)mxMalloc(FILTER_SIZE); h_Motion_Corrected_fMRI_Volumes = (float *)mxMalloc(DATA_SIZE); h_Motion_Parameters = (float *)mxMalloc(MOTION_PARAMETERS_SIZE); // Pack data (reorder from y,x,z to x,y,z and cast from double to float) pack_double2float_volumes(h_fMRI_Volumes, h_fMRI_Volumes_double, DATA_W, DATA_H, DATA_D, DATA_T); pack_double2float_volume(h_Quadrature_Filter_1_Real, h_Quadrature_Filter_1_Real_double, MOTION_CORRECTION_FILTER_SIZE, MOTION_CORRECTION_FILTER_SIZE, MOTION_CORRECTION_FILTER_SIZE); pack_double2float_volume(h_Quadrature_Filter_1_Imag, h_Quadrature_Filter_1_Imag_double, MOTION_CORRECTION_FILTER_SIZE, MOTION_CORRECTION_FILTER_SIZE, MOTION_CORRECTION_FILTER_SIZE); pack_double2float_volume(h_Quadrature_Filter_2_Real, h_Quadrature_Filter_2_Real_double, MOTION_CORRECTION_FILTER_SIZE, MOTION_CORRECTION_FILTER_SIZE, MOTION_CORRECTION_FILTER_SIZE); pack_double2float_volume(h_Quadrature_Filter_2_Imag, h_Quadrature_Filter_2_Imag_double, MOTION_CORRECTION_FILTER_SIZE, MOTION_CORRECTION_FILTER_SIZE, MOTION_CORRECTION_FILTER_SIZE); pack_double2float_volume(h_Quadrature_Filter_3_Real, h_Quadrature_Filter_3_Real_double, MOTION_CORRECTION_FILTER_SIZE, MOTION_CORRECTION_FILTER_SIZE, MOTION_CORRECTION_FILTER_SIZE); pack_double2float_volume(h_Quadrature_Filter_3_Imag, h_Quadrature_Filter_3_Imag_double, MOTION_CORRECTION_FILTER_SIZE, MOTION_CORRECTION_FILTER_SIZE, MOTION_CORRECTION_FILTER_SIZE); //------------------------ BROCCOLI_LIB BROCCOLI(OPENCL_PLATFORM,OPENCL_DEVICE); // Something went wrong... if (BROCCOLI.GetOpenCLInitiated() == 0) { printf("Initialization error is \"%s\" \n",BROCCOLI.GetOpenCLInitializationError()); printf("OpenCL error is \"%s\" \n",BROCCOLI.GetOpenCLError()); // Print create kernel errors int* createKernelErrors = BROCCOLI.GetOpenCLCreateKernelErrors(); for (int i = 0; i < BROCCOLI.GetNumberOfOpenCLKernels(); i++) { if (createKernelErrors[i] != 0) { mexPrintf("Create kernel error for kernel '%s' is '%s' \n",BROCCOLI.GetOpenCLKernelName(i),BROCCOLI.GetOpenCLErrorMessage(createKernelErrors[i])); } } mexPrintf("OPENCL initialization failed, aborting \n"); // Print build info mexPrintf("Build info \n \n %s \n", BROCCOLI.GetOpenCLBuildInfoChar()); } else if (BROCCOLI.GetOpenCLInitiated() == 1) { BROCCOLI.SetEPIWidth(DATA_W); BROCCOLI.SetEPIHeight(DATA_H); BROCCOLI.SetEPIDepth(DATA_D); BROCCOLI.SetEPITimepoints(DATA_T); BROCCOLI.SetEPIVoxelSizeX(EPI_VOXEL_SIZE_X); BROCCOLI.SetEPIVoxelSizeY(EPI_VOXEL_SIZE_Y); BROCCOLI.SetEPIVoxelSizeZ(EPI_VOXEL_SIZE_Z); BROCCOLI.SetInputfMRIVolumes(h_fMRI_Volumes); BROCCOLI.SetImageRegistrationFilterSize(MOTION_CORRECTION_FILTER_SIZE); BROCCOLI.SetLinearImageRegistrationFilters(h_Quadrature_Filter_1_Real, h_Quadrature_Filter_1_Imag, h_Quadrature_Filter_2_Real, h_Quadrature_Filter_2_Imag, h_Quadrature_Filter_3_Real, h_Quadrature_Filter_3_Imag); BROCCOLI.SetNumberOfIterationsForMotionCorrection(NUMBER_OF_ITERATIONS_FOR_MOTION_CORRECTION); BROCCOLI.SetOutputMotionCorrectedfMRIVolumes(h_Motion_Corrected_fMRI_Volumes); BROCCOLI.SetOutputMotionParameters(h_Motion_Parameters); BROCCOLI.PerformMotionCorrectionWrapper(); // Print create buffer errors int* createBufferErrors = BROCCOLI.GetOpenCLCreateBufferErrors(); for (int i = 0; i < BROCCOLI.GetNumberOfOpenCLKernels(); i++) { if (createBufferErrors[i] != 0) { mexPrintf("Create buffer error %i is %d \n",i,createBufferErrors[i]); } } // Print create kernel errors int* createKernelErrors = BROCCOLI.GetOpenCLCreateKernelErrors(); for (int i = 0; i < BROCCOLI.GetNumberOfOpenCLKernels(); i++) { if (createKernelErrors[i] != 0) { mexPrintf("Create kernel error for kernel '%s' is '%s' \n",BROCCOLI.GetOpenCLKernelName(i),BROCCOLI.GetOpenCLErrorMessage(createKernelErrors[i])); } } // Print run kernel errors int* runKernelErrors = BROCCOLI.GetOpenCLRunKernelErrors(); for (int i = 0; i < BROCCOLI.GetNumberOfOpenCLKernels(); i++) { if (runKernelErrors[i] != 0) { mexPrintf("Run kernel error for kernel '%s' is '%s' \n",BROCCOLI.GetOpenCLKernelName(i),BROCCOLI.GetOpenCLErrorMessage(runKernelErrors[i])); } } } // Unpack results to Matlab unpack_float2double_volumes(h_Motion_Corrected_fMRI_Volumes_double, h_Motion_Corrected_fMRI_Volumes, DATA_W, DATA_H, DATA_D, DATA_T); unpack_float2double(h_Motion_Parameters_double, h_Motion_Parameters, NUMBER_OF_MOTION_CORRECTION_PARAMETERS * DATA_T); // Free all the allocated memory on the host mxFree(h_fMRI_Volumes); mxFree(h_Quadrature_Filter_1_Real); mxFree(h_Quadrature_Filter_1_Imag); mxFree(h_Quadrature_Filter_2_Real); mxFree(h_Quadrature_Filter_2_Imag); mxFree(h_Quadrature_Filter_3_Real); mxFree(h_Quadrature_Filter_3_Imag); mxFree(h_Motion_Corrected_fMRI_Volumes); mxFree(h_Motion_Parameters); return; }
// diffs = sumSqDiffBtwWin(I,windowSize); void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) { /* Takes a zero-padded image and a filter window size. * Outputs the matrix of squared, summed pixel differences between each * pair of windows. */ // declare variables double *zIz; // padded image double *windowSize; // size of filter window double *diffs2; // output matrix int *zizSz; // size of padded image zIz int iSz[2]; // size of un-padded image int outSz[2]; // size of output matrix // error checking on argument numbers if( nrhs!=2 ) mexErrMsgTxt("Four inputs expected."); if( nlhs>1 ) mexErrMsgTxt("One output expected."); // get size of I zizSz = (int*) mxGetDimensions(prhs[0]); // assert size and type are supported if( (mxGetNumberOfDimensions(prhs[0])!=2) || (mxGetClassID(prhs[0])!=mxDOUBLE_CLASS) ) mexErrMsgTxt("I should be a 2D double array."); // get I zIz=(double*)mxGetData(prhs[0]); // get size of windowSize int* wsSz = (int*) mxGetDimensions(prhs[1]); // assert size and type are supported if( (mxGetNumberOfDimensions(prhs[1])!=2) || (mxGetClassID(prhs[1])!=mxDOUBLE_CLASS) || (wsSz[0]!=1) || (wsSz[1]!=2) ) mexErrMsgTxt("windowSize should be a 1-by-2 double array."); // get windowSize windowSize=(double*)mxGetData(prhs[1]); // compute un-padded image size iSz[0] = zizSz[0]-(int)windowSize[0]+1; iSz[1] = zizSz[1]-(int)windowSize[1]+1; // compute output matrix size outSz[0] = iSz[0]*iSz[1]; outSz[1] = iSz[0]*iSz[1]; // create output array plhs[0] = mxCreateNumericArray(2, (const mwSize*) outSz, mxDOUBLE_CLASS, mxREAL); diffs2 = (double*)mxGetData(plhs[0]); // for each image pixel for (int u1=0; u1<iSz[0]; u1++) { for (int v1=0; v1<iSz[1]; v1++) { // for each image pixel (do not repeat) for (int u2=u1; u2<iSz[0]; u2++) { for (int v2=(u2==u1)?v1:0 ; v2<iSz[1]; v2++) { // for each window pixel for (int i=0; i<(int)windowSize[0]; i++) { for (int j=0; j<(int)windowSize[1]; j++) { // add squared pixel difference to accumulator diffs2[u1+iSz[0]*v1+outSz[0]*(u2+iSz[0]*v2)] += pow(zIz[(u1+i)+zizSz[0]*(v1+j)]-zIz[(u2+i)+zizSz[0]*(v2+j)],2); } } } } } } }
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray*prhs[]) { double *x, *b, *s; mwSize sz[3], stepsize[3], n[3], ndims; mwIndex i, j, k, l, m, blocknum; /* Check for proper number of arguments */ if (nrhs < 2 || nrhs > 3) { mexErrMsgTxt("Invalid number of input arguments."); } else if (nlhs > 1) { mexErrMsgTxt("Too many output arguments."); } /* Check the the input dimensions */ ndims = mxGetNumberOfDimensions(X_IN); if (!mxIsDouble(X_IN) || mxIsComplex(X_IN) || ndims>3) { mexErrMsgTxt("X should be a 2-D or 3-D double matrix."); } if (!mxIsDouble(SZ_IN) || mxIsComplex(SZ_IN) || mxGetNumberOfDimensions(SZ_IN)>2 || mxGetM(SZ_IN)*mxGetN(SZ_IN)!=ndims) { mexErrMsgTxt("Invalid block size."); } if (nrhs == 3) { if (!mxIsDouble(S_IN) || mxIsComplex(S_IN) || mxGetNumberOfDimensions(S_IN)>2 || mxGetM(S_IN)*mxGetN(S_IN)!=ndims) { mexErrMsgTxt("Invalid step size."); } } /* Get parameters */ s = mxGetPr(SZ_IN); if (s[0]<1 || s[1]<1 || (ndims==3 && s[2]<1)) { mexErrMsgTxt("Invalid block size."); } sz[0] = (mwSize)(s[0] + 0.01); sz[1] = (mwSize)(s[1] + 0.01); sz[2] = ndims==3 ? (mwSize)(s[2] + 0.01) : 1; if (nrhs == 3) { s = mxGetPr(S_IN); if (s[0]<1 || s[1]<1 || (ndims==3 && s[2]<1)) { mexErrMsgTxt("Invalid step size."); } stepsize[0] = (mwSize)(s[0] + 0.01); stepsize[1] = (mwSize)(s[1] + 0.01); stepsize[2] = ndims==3 ? (mwSize)(s[2] + 0.01) : 1; } else { stepsize[0] = stepsize[1] = stepsize[2] = 1; } n[0] = (mxGetDimensions(X_IN))[0]; n[1] = (mxGetDimensions(X_IN))[1]; n[2] = ndims==3 ? (mxGetDimensions(X_IN))[2] : 1; if (n[0]<sz[0] || n[1]<sz[1] || (ndims==3 && n[2]<sz[2])) { mexErrMsgTxt("Block size too large."); } /* Create a matrix for the return argument */ B_OUT = mxCreateDoubleMatrix(sz[0]*sz[1]*sz[2], ((n[0]-sz[0])/stepsize[0]+1)*((n[1]-sz[1])/stepsize[1]+1)*((n[2]-sz[2])/stepsize[2]+1), mxREAL); /* Assign pointers */ x = mxGetPr(X_IN); b = mxGetPr(B_OUT); /* Do the actual computation */ blocknum = 0; /* iterate over all blocks */ for (k=0; k<=n[2]-sz[2]; k+=stepsize[2]) { for (j=0; j<=n[1]-sz[1]; j+=stepsize[1]) { for (i=0; i<=n[0]-sz[0]; i+=stepsize[0]) { /* copy single block */ for (m=0; m<sz[2]; m++) { for (l=0; l<sz[1]; l++) { memcpy(b + blocknum*sz[0]*sz[1]*sz[2] + m*sz[0]*sz[1] + l*sz[0], x+(k+m)*n[0]*n[1]+(j+l)*n[0]+i, sz[0]*sizeof(double)); } } blocknum++; } } } return; }
void mexFunction(int nout, mxArray *out[], int nin, const mxArray *in[]) { enum {IN_I=0,IN_END} ; enum {OUT_FRAMES=0, OUT_DESCRIPTORS} ; int verbose = 0 ; int opt ; int next = IN_END ; mxArray const *optarg ; vl_sift_pix const *data ; int M, N ; int O = - 1 ; int S = 3 ; int o_min = 0 ; double edge_thresh = -1 ; double peak_thresh = -1 ; double norm_thresh = -1 ; double magnif = -1 ; double window_size = -1 ; mxArray *ikeys_array = 0 ; double *ikeys = 0 ; int nikeys = -1 ; vl_bool force_orientations = 0 ; vl_bool floatDescriptors = 0 ; VL_USE_MATLAB_ENV ; /* ----------------------------------------------------------------- * Check the arguments * -------------------------------------------------------------- */ if (nin < 1) { mexErrMsgTxt("One argument required.") ; } else if (nout > 2) { mexErrMsgTxt("Too many output arguments."); } if (mxGetNumberOfDimensions (in[IN_I]) != 2 || mxGetClassID (in[IN_I]) != mxSINGLE_CLASS ) { mexErrMsgTxt("I must be a matrix of class SINGLE") ; } data = (vl_sift_pix*) mxGetData (in[IN_I]) ; M = mxGetM (in[IN_I]) ; N = mxGetN (in[IN_I]) ; while ((opt = vlmxNextOption (in, nin, options, &next, &optarg)) >= 0) { switch (opt) { case opt_verbose : ++ verbose ; break ; case opt_octaves : if (!vlmxIsPlainScalar(optarg) || (O = (int) *mxGetPr(optarg)) < 0) { mexErrMsgTxt("'Octaves' must be a positive integer.") ; } break ; case opt_levels : if (! vlmxIsPlainScalar(optarg) || (S = (int) *mxGetPr(optarg)) < 1) { mexErrMsgTxt("'Levels' must be a positive integer.") ; } break ; case opt_first_octave : if (!vlmxIsPlainScalar(optarg)) { mexErrMsgTxt("'FirstOctave' must be an integer") ; } o_min = (int) *mxGetPr(optarg) ; break ; case opt_edge_thresh : if (!vlmxIsPlainScalar(optarg) || (edge_thresh = *mxGetPr(optarg)) < 1) { mexErrMsgTxt("'EdgeThresh' must be not smaller than 1.") ; } break ; case opt_peak_thresh : if (!vlmxIsPlainScalar(optarg) || (peak_thresh = *mxGetPr(optarg)) < 0) { mexErrMsgTxt("'PeakThresh' must be a non-negative real.") ; } break ; case opt_norm_thresh : if (!vlmxIsPlainScalar(optarg) || (norm_thresh = *mxGetPr(optarg)) < 0) { mexErrMsgTxt("'NormThresh' must be a non-negative real.") ; } break ; case opt_magnif : if (!vlmxIsPlainScalar(optarg) || (magnif = *mxGetPr(optarg)) < 0) { mexErrMsgTxt("'Magnif' must be a non-negative real.") ; } break ; case opt_window_size : if (!vlmxIsPlainScalar(optarg) || (window_size = *mxGetPr(optarg)) < 0) { mexErrMsgTxt("'WindowSize' must be a non-negative real.") ; } break ; case opt_frames : if (!vlmxIsMatrix(optarg, 4, -1)) { mexErrMsgTxt("'Frames' must be a 4 x N matrix.x") ; } ikeys_array = mxDuplicateArray (optarg) ; nikeys = mxGetN (optarg) ; ikeys = mxGetPr (ikeys_array) ; if (! check_sorted (ikeys, nikeys)) { qsort (ikeys, nikeys, 4 * sizeof(double), korder) ; } break ; case opt_orientations : force_orientations = 1 ; break ; case opt_float_descriptors : floatDescriptors = 1 ; break ; default : abort() ; } } /* ----------------------------------------------------------------- * Do job * -------------------------------------------------------------- */ { VlSiftFilt *filt ; vl_bool first ; double *frames = 0 ; void *descr = 0 ; int nframes = 0, reserved = 0, i,j,q ; /* create a filter to process the image */ filt = vl_sift_new (M, N, O, S, o_min) ; if (peak_thresh >= 0) vl_sift_set_peak_thresh (filt, peak_thresh) ; if (edge_thresh >= 0) vl_sift_set_edge_thresh (filt, edge_thresh) ; if (norm_thresh >= 0) vl_sift_set_norm_thresh (filt, norm_thresh) ; if (magnif >= 0) vl_sift_set_magnif (filt, magnif) ; if (window_size >= 0) vl_sift_set_window_size (filt, window_size) ; if (verbose) { mexPrintf("vl_sift: filter settings:\n") ; mexPrintf("vl_sift: octaves (O) = %d\n", vl_sift_get_noctaves (filt)) ; mexPrintf("vl_sift: levels (S) = %d\n", vl_sift_get_nlevels (filt)) ; mexPrintf("vl_sift: first octave (o_min) = %d\n", vl_sift_get_octave_first (filt)) ; mexPrintf("vl_sift: edge thresh = %g\n", vl_sift_get_edge_thresh (filt)) ; mexPrintf("vl_sift: peak thresh = %g\n", vl_sift_get_peak_thresh (filt)) ; mexPrintf("vl_sift: norm thresh = %g\n", vl_sift_get_norm_thresh (filt)) ; mexPrintf("vl_sift: window size = %g\n", vl_sift_get_window_size (filt)) ; mexPrintf("vl_sift: float descriptor = %d\n", floatDescriptors) ; mexPrintf((nikeys >= 0) ? "vl_sift: will source frames? yes (%d read)\n" : "vl_sift: will source frames? no\n", nikeys) ; mexPrintf("vl_sift: will force orientations? %s\n", force_orientations ? "yes" : "no") ; } /* ............................................................... * Process each octave * ............................................................ */ i = 0 ; first = 1 ; while (1) { int err ; VlSiftKeypoint const* keys = 0 ; int nkeys = 0 ; if (verbose) { mexPrintf ("vl_sift: processing octave %d\n", vl_sift_get_octave_index (filt)) ; } /* Calculate the GSS for the next octave .................... */ if (first) { err = vl_sift_process_first_octave (filt, data) ; first = 0 ; } else { err = vl_sift_process_next_octave (filt) ; } if (err) break ; if (verbose > 1) { mexPrintf("vl_sift: GSS octave %d computed\n", vl_sift_get_octave_index (filt)); } /* Run detector ............................................. */ if (nikeys < 0) { vl_sift_detect (filt) ; keys = vl_sift_get_keypoints (filt) ; nkeys = vl_sift_get_nkeypoints (filt) ; i = 0 ; if (verbose > 1) { printf ("vl_sift: detected %d (unoriented) keypoints\n", nkeys) ; } } else { nkeys = nikeys ; } /* For each keypoint ........................................ */ for (; i < nkeys ; ++i) { double angles [4] ; int nangles ; VlSiftKeypoint ik ; VlSiftKeypoint const *k ; /* Obtain keypoint orientations ........................... */ if (nikeys >= 0) { vl_sift_keypoint_init (filt, &ik, ikeys [4 * i + 1] - 1, ikeys [4 * i + 0] - 1, ikeys [4 * i + 2]) ; if (ik.o != vl_sift_get_octave_index (filt)) { break ; } k = &ik ; /* optionally compute orientations too */ if (force_orientations) { nangles = vl_sift_calc_keypoint_orientations (filt, angles, k) ; } else { angles [0] = VL_PI / 2 - ikeys [4 * i + 3] ; nangles = 1 ; } } else { k = keys + i ; nangles = vl_sift_calc_keypoint_orientations (filt, angles, k) ; } /* For each orientation ................................... */ for (q = 0 ; q < nangles ; ++q) { vl_sift_pix buf [128] ; vl_sift_pix rbuf [128] ; /* compute descriptor (if necessary) */ if (nout > 1) { vl_sift_calc_keypoint_descriptor (filt, buf, k, angles [q]) ; transpose_descriptor (rbuf, buf) ; } /* make enough room for all these keypoints and more */ if (reserved < nframes + 1) { reserved += 2 * nkeys ; frames = mxRealloc (frames, 4 * sizeof(double) * reserved) ; if (nout > 1) { if (! floatDescriptors) { descr = mxRealloc (descr, 128 * sizeof(vl_uint8) * reserved) ; } else { descr = mxRealloc (descr, 128 * sizeof(float) * reserved) ; } } } /* Save back with MATLAB conventions. Notice tha the input * image was the transpose of the actual image. */ frames [4 * nframes + 0] = k -> y + 1 ; frames [4 * nframes + 1] = k -> x + 1 ; frames [4 * nframes + 2] = k -> sigma ; frames [4 * nframes + 3] = VL_PI / 2 - angles [q] ; if (nout > 1) { if (! floatDescriptors) { for (j = 0 ; j < 128 ; ++j) { float x = 512.0F * rbuf [j] ; x = (x < 255.0F) ? x : 255.0F ; ((vl_uint8*)descr) [128 * nframes + j] = (vl_uint8) x ; } } else { for (j = 0 ; j < 128 ; ++j) { float x = 512.0F * rbuf [j] ; ((float*)descr) [128 * nframes + j] = x ; } } } ++ nframes ; } /* next orientation */ } /* next keypoint */ } /* next octave */ if (verbose) { mexPrintf ("vl_sift: found %d keypoints\n", nframes) ; } /* ............................................................... * Save back * ............................................................ */ { mwSize dims [2] ; /* create an empty array */ dims [0] = 0 ; dims [1] = 0 ; out[OUT_FRAMES] = mxCreateNumericArray (2, dims, mxDOUBLE_CLASS, mxREAL) ; /* set array content to be the frames buffer */ dims [0] = 4 ; dims [1] = nframes ; mxSetPr (out[OUT_FRAMES], frames) ; mxSetDimensions (out[OUT_FRAMES], dims, 2) ; if (nout > 1) { /* create an empty array */ dims [0] = 0 ; dims [1] = 0 ; out[OUT_DESCRIPTORS]= mxCreateNumericArray (2, dims, floatDescriptors ? mxSINGLE_CLASS : mxUINT8_CLASS, mxREAL) ; /* set array content to be the descriptors buffer */ dims [0] = 128 ; dims [1] = nframes ; mxSetData (out[OUT_DESCRIPTORS], descr) ; mxSetDimensions (out[OUT_DESCRIPTORS], dims, 2) ; } } /* cleanup */ vl_sift_delete (filt) ; if (ikeys_array) mxDestroyArray(ikeys_array) ; } /* end: do job */ }
void mexFunction( int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[] ) { double *window, *data, *filtered; int windowSize[2], dataSize[2]; /* Check for proper number of arguments. */ if(nrhs != 2){ mexErrMsgIdAndTxt( "MATLAB:Filter:median1d:invalidNumInputs", "Two input arguments required." ); } else if(nlhs > 1){ mexErrMsgIdAndTxt( "MATLAB:Filter:median1d:maxlhs", "Too many output arguments." ); } /* The input must be a noncomplex double.*/ if( !mxIsDouble(prhs[0]) || mxIsComplex(prhs[0]) || !mxIsDouble(prhs[1]) || mxIsComplex(prhs[1]) ){ mexErrMsgIdAndTxt( "MATLAB:Filter:median1d:inputNotRealDouble", "Input must be a noncomplex double." ); } dataSize[0] = (int) mxGetM(prhs[0]); dataSize[1] = (int) mxGetN(prhs[0]); windowSize[0] = (int) mxGetM(prhs[1]); windowSize[1] = (int) mxGetN(prhs[1]); if( windowSize[0] != 1 || windowSize[1] != 1 ){ mexErrMsgIdAndTxt( "MATLAB:Filter:median1d:windowSizeNoScalar", "Window input must be a scalar." ); } /* Create matrix for the return argument. */ plhs[0] = mxCreateDoubleMatrix(dataSize[0], dataSize[1], mxREAL); mxSetDimensions(plhs[0], mxGetDimensions(prhs[0]), mxGetNumberOfDimensions(prhs[0])); /* Assign pointers to each input and output. */ data = mxGetPr(prhs[0]); window = mxGetPr(prhs[1]); filtered = mxGetPr(plhs[0]); long windowS = (long) *window; if (windowS <= 0){ windowS = 1; } /* Call the MedianFilter::filter subroutine. */ if (dataSize[0] != 1 && dataSize[1] != 1){ int i; for (i = 0; i < dataSize[1]; i++){ MedianFilter::filter( &data[i * dataSize[0]], &filtered[i * dataSize[0]], dataSize[0], windowS ); } } else { int size = dataSize[0] > dataSize[1]? dataSize[0]: dataSize[1]; MedianFilter::filter( data, filtered, size, windowS ); } }
void mexFunction( int nlhs, mxArray *plhs[] , int nrhs, const mxArray *prhs[] ) { unsigned char *I; int *dimsH; const int *dimsI , *dimsshiftbox; int numdimsI , numdimsshiftbox; unsigned int *H; int bincurrent; int i , j , ny , nx , P=1 , maxN=-1 , nH = 1 , powmaxN , powN = 256 , indmaxN , indnR; struct opts options; double *mapsorted; double currentbin , maxR ; mxArray *mxtemp; options.nR = 1; /* Input 1 */ numdimsI = mxGetNumberOfDimensions(prhs[0]); if( (numdimsI > 3) || !mxIsUint8(prhs[0]) ) { mexErrMsgTxt("I must be (ny x nx x P) in double format"); } I = (unsigned char *)mxGetData(prhs[0]); dimsI = mxGetDimensions(prhs[0]); ny = dimsI[0]; nx = dimsI[1]; if(numdimsI == 3) { P = dimsI[2]; } /* Input 2 */ if ((nrhs > 1) && !mxIsEmpty(prhs[1]) ) { mxtemp = mxGetField(prhs[1] , 0 , "N"); if(mxtemp != NULL) { options.N = mxGetPr(mxtemp); options.nR = mxGetN(mxtemp); for (i = 0 ; i < options.nR ; i++) { maxN = max(maxN , (int)options.N[i]); } powmaxN = (int) (pow(2 , maxN)); } else { options.N = (double *)mxMalloc(sizeof(double)); options.N[0] = 8; options.nR = 1; } mxtemp = mxGetField(prhs[1] , 0 , "R"); if(mxtemp != NULL) { if( (mxGetNumberOfDimensions(mxtemp) != 2) || (mxGetN(mxtemp) != options.nR) ) { mexErrMsgTxt("R must be (1 x nR)"); } options.R = mxGetPr(mxtemp); maxR = options.R[0]; for(i = 1 ; i < options.nR ; i++) { maxR = max(maxR , options.R[i]); } } else { options.R = (double *)mxMalloc(sizeof(double)); options.R[0] = 1.0; options.nR = 1; } mxtemp = mxGetField(prhs[1] , 0 , "map"); if(mxtemp != NULL) { if( (mxGetNumberOfDimensions(mxtemp) != 2) || mxGetM(mxtemp) != powmaxN || mxGetN(mxtemp) != options.nR ) { mexErrMsgTxt("map must be (2^Nmax x nR)"); } options.map = mxGetPr(mxtemp); /* Determine unique values in map vector */ mapsorted = (double *)mxMalloc(powmaxN*sizeof(double)); options.bin = (int *) mxMalloc(options.nR*sizeof(int)); indmaxN = 0; for(j = 0 ; j < options.nR ; j++) { powN = (int) (pow(2 , (int) options.N[j])); for ( i = 0 ; i < powN ; i++ ) { mapsorted[i] = options.map[i + indmaxN]; } qs( mapsorted , 0 , powN - 1 ); bincurrent = 0; currentbin = mapsorted[0]; for (i = 1 ; i < powN ; i++) { if (currentbin != mapsorted[i]) { currentbin = mapsorted[i]; bincurrent++; } } bincurrent++; options.bin[j] = bincurrent; indmaxN += powmaxN; } } else { options.map = (double *)mxMalloc(powmaxN*options.nR*sizeof(double)); options.bin = (int *) mxMalloc(options.nR*sizeof(int)); indmaxN = 0; for(j = 0 ; j < options.nR ; j++) { powN = (int) (pow(2 , (int) options.N[j])); for(i = indmaxN ; i < powN + indmaxN ; i++) { options.map[i] = i; } indmaxN += powmaxN; options.bin[j] = powN; } } mxtemp = mxGetField(prhs[1] , 0 , "shiftbox"); if(mxtemp != NULL) { if( mxGetNumberOfDimensions(mxtemp) > 3 ) { mexErrMsgTxt("shiftbox must be (2 x 2 x nbox)"); } numdimsshiftbox = mxGetNumberOfDimensions(mxtemp); dimsshiftbox = mxGetDimensions(mxtemp); if(dimsshiftbox[0] !=2 || dimsshiftbox[1] !=2 ) { mexErrMsgTxt("shiftbox must be (2 x 2 x nR)"); } options.shiftbox = mxGetPr(mxtemp); if(numdimsshiftbox == 3) { if(dimsshiftbox[2] != options.nR) { mexErrMsgTxt("shiftbox must be (2 x 2 x nR)"); } } for(i = 0 ; i < options.nR ; i++) { if( (options.shiftbox[0 + i*4] < 2.0*maxR+1) || (options.shiftbox[2 + i*4] < 2.0*maxR+1) ) { mexErrMsgTxt("by and bx must be > 2*max(R) + 1"); } } } else { options.shiftbox = (double *)mxMalloc(4*options.nR*sizeof(double)); indnR = 0; for( i = 0 ; i < options.nR ; i++) { options.shiftbox[0 + indnR] = (double) ny; options.shiftbox[1 + indnR] = 0.0; options.shiftbox[2 + indnR] = (double) nx; options.shiftbox[3 + indnR] = 0.0; indnR += 4; } } } nH = number_chlbp_features(ny , nx , options.bin , options.shiftbox , options.nR ); /*----------------------- Outputs -------------------------------*/ dimsH = (int *)mxMalloc(2*sizeof(int)); dimsH[0] = nH; dimsH[1] = P; plhs[0] = mxCreateNumericArray(2 , dimsH , mxUINT32_CLASS , mxREAL); H = (unsigned int *)mxGetPr(plhs[0]); /*------------------------ Main Call ----------------------------*/ chlbp(I , ny , nx , P , options , H , nH ); /*--------------------------- Free memory -----------------------*/ mxFree(dimsH); mxFree(options.bin); if ( (nrhs > 1) && !mxIsEmpty(prhs[1]) ) { if ( (mxGetField( prhs[1] , 0 , "N" )) == NULL ) { mxFree(options.N); } if ( (mxGetField( prhs[1] , 0 , "R" )) == NULL ) { mxFree(options.R); } if ( (mxGetField( prhs[1] , 0 , "map" )) == NULL ) { mxFree(options.map); } else { mxFree(mapsorted); } if ( (mxGetField( prhs[1] , 0 , "shiftbox" )) == NULL ) { mxFree(options.shiftbox); } } else { mxFree(options.N); mxFree(options.R); mxFree(options.map); mxFree(options.shiftbox); } }
/*-------------------------------------------------------------------------------------------------------------- */ void mexFunction( int nlhs, mxArray *plhs[] , int nrhs, const mxArray *prhs[] ) { double *X , *y , *Wproto_ini , *yproto_ini; #ifdef OMP OPTIONS options = {0.05 , 0.01 , 1.0 , 0.6 , 1 , 1000 , 1 , (UL)NULL , -1}; #else OPTIONS options = {0.05 , 0.01 , 1.0 , 0.6 , 1 , 1000 , 1 , (UL)NULL}; #endif double *Wproto_est , *yproto_est , *E_H2MGLVQ; int d , N , Nproto , m = 0; int i , j , l , co , Nprotom , ld , id , indice; double currentlabel , ind , temp; double *tmp , *ysorted , *labels , *mtemp , *stdtemp; mxArray *mxtemp; int *Nk; int tempint; UL templint; if (nrhs < 1) { mexPrintf( "\n" "\n" "\n" "Harmonic to Minimum Generalized Learning Vector Quantization (H2M-GLVQ) classification.\n" "\n" "\n" "Usage\n" "-----\n" "\n" "\n" "[Wproto_est , yproto_est , E_H2MGLVQ] = h2m_glvq_model(X , y , [options] , [yproto_ini] , [Wproto_ini]);\n" "\n" "\n" "Inputs\n" "------\n" "\n" "\n" "X Train data (d x N)\n" "y Train label vector (1 x N) with yi = {1,...m}, m different classes\n" "options Options'structure\n" " epsilonk Update weight's for class label between prototype and train data (default epsilonk = 0.05).\n" " epsilonl Update weight's for class label between prototype and train data (default epsilonl = 0.01).\n" " tmax Maximum temperature for cooling schudeling (default tmax = 1.0).\n" " tmin Minimum temperature for cooling schudeling (default tmin = 0.6).\n" " xi Constant in the sigmoid function (default xi = 1.0).\n" " nb_iterations Number of iterations (default nb_iterations = 1000).\n" " shuffle Randomly permute order of train data between each iteration if shuffle=1 (default shuffle = 1).\n" " seed Seed number for internal random generator (default random seed according to time).\n" #ifdef OMP " num_threads Number of threads. If num_threads = -1, num_threads = number of core (default num_threads = -1)\n" #endif "yproto_ini Intial prototypes label (1 x Nproto) where card(yproto_ini)=card(y).\n" "Wproto_ini Initial prototypes weights (d x Nproto) (default Wproto_ini (d x Nproto) where Nproto=round(sqrt(N)).\n" " Wproto_ini ~ N(m_{y=i},sigma_{y=i}), where m_{y=i} = E[X|y=i], sigma_{y=i} = E[XX'|y=i].\n" "\n" "\n" "Outputs\n" "-------\n" "\n" "\n" "yproto_est Final prototypes labels (1 x Nproto)\n" "Wproto_est Final prototypes weigths (d x Nproto)\n" "E_H2MGLVQ Energy criteria versus iteration (1 x options.nb_iterations)\n" "\n" "\n" ); return; } /* Input 1 X */ X = mxGetPr(prhs[0]); if( mxGetNumberOfDimensions(prhs[0]) != 2 ) { mexErrMsgTxt("X must be (d x N)"); } d = mxGetM(prhs[0]); N = mxGetN(prhs[0]); Nproto = (int)floor(sqrt(N)); /* Input 2 y */ y = mxGetPr(prhs[1]); if((mxGetNumberOfDimensions(prhs[1]) != 2) || (mxGetN(prhs[1]) != N)) { mexErrMsgTxt("y must be (1 x N)"); } /* Determine unique Labels */ ysorted = (double *)malloc(N*sizeof(double)); for ( i = 0 ; i < N; i++ ) { ysorted[i] = y[i]; } qs( ysorted , 0 , N - 1 ); labels = (double *)malloc(sizeof(double)); labels[m] = ysorted[0]; currentlabel = labels[0]; for (i = 0 ; i < N ; i++) { if (currentlabel != ysorted[i]) { labels = (double *)realloc(labels , (m+2)*sizeof(double)); labels[++m] = ysorted[i]; currentlabel = ysorted[i]; } } m++; /* Input 5 option */ if ( (nrhs > 2) && !mxIsEmpty(prhs[2]) ) { mxtemp = mxGetField(prhs[2] , 0, "epsilonk"); if(mxtemp != NULL) { tmp = mxGetPr(mxtemp); temp = tmp[0]; if((temp < 0.0)) { mexPrintf("epsilonk >= 0.0, force to 0.005\n"); options.epsilonk = 0.005; } else { options.epsilonk = temp; } } mxtemp = mxGetField(prhs[2] , 0, "epsilonl"); if(mxtemp != NULL) { tmp = mxGetPr(mxtemp); temp = tmp[0]; if((temp < 0.0) || (temp > options.epsilonk)) { mexPrintf("epsilonl >= 0.0 and epsilonl < epsilonk, force to 0.001\n"); options.epsilonl = 0.001; } else { options.epsilonl = temp; } } mxtemp = mxGetField(prhs[2] , 0, "tmax"); if(mxtemp != NULL) { tmp = mxGetPr(mxtemp); temp = tmp[0]; if((temp < 0.0) ) { mexPrintf("tmax >= 0.0, force to 1.0\n"); options.tmax = 1.0; } else { options.tmax = temp; } } mxtemp = mxGetField(prhs[2] , 0, "tmin"); if(mxtemp != NULL) { tmp = mxGetPr(mxtemp); temp = tmp[0]; if((temp < 0.0) || (temp > options.tmax)) { mexPrintf("tmin >= 0.0 and tmin < tmax, force to 0.6\n"); options.tmin = 0.6; } else { options.tmin = temp; } } mxtemp = mxGetField(prhs[2] , 0, "xi"); if(mxtemp != NULL) { tmp = mxGetPr(mxtemp); temp = tmp[0]; if((temp < 0.0)) { mexPrintf("xi >= 0.0, force to 1\n"); options.xi = 1.0; } else { options.xi = temp; } } mxtemp = mxGetField(prhs[2] , 0, "nb_iterations"); if(mxtemp != NULL) { tmp = mxGetPr(mxtemp); tempint = (int) tmp[0]; if( (tempint < 1) ) { mexPrintf("nb_iterations > 1 , force to 1000\n"); options.nb_iterations = 1000; } else { options.nb_iterations = tempint; } } mxtemp = mxGetField(prhs[2] , 0, "shuffle"); if(mxtemp != NULL) { tmp = mxGetPr(mxtemp); tempint = (int) tmp[0]; if( (tempint < 0)|| (tempint > 2) ) { mexPrintf("shuffle = {0,1} , force to 1\n"); options.shuffle = 1; } else { options.shuffle = tempint; } } mxtemp = mxGetField(prhs[2] , 0 , "seed"); if(mxtemp != NULL) { tmp = mxGetPr(mxtemp); templint = (UL) tmp[0]; if( (templint < 1) ) { mexPrintf("seed >= 1 , force to NULL (random seed)\n"); options.seed = (UL)NULL; } else { options.seed = templint; } } #ifdef OMP mxtemp = mxGetField(prhs[2] , 0 , "num_threads"); if(mxtemp != NULL) { tmp = mxGetPr(mxtemp); tempint = (int) tmp[0]; if( (tempint < -1)) { mexPrintf("num_threads must be >= -1, force to -1\n"); options.num_threads = -1; } else { options.num_threads = tempint; } } } #endif /* Input 4 yproto_ini */ if ((nrhs < 4) || mxIsEmpty(prhs[3]) ) { plhs[0] = mxCreateDoubleMatrix(1 , Nproto, mxREAL); yproto_est = mxGetPr(plhs[0]); co = 0; Nprotom = ceil((double)Nproto/(double)m); for(i = 0 ; i < m-1 ; i++) { ind = labels[i]; for(j = 0 ; j < Nprotom ; j++) { yproto_est[co] = labels[i]; co++; } } ind = labels[m-1]; for(j = (m-1)*Nprotom ; j < Nproto ; j++) { yproto_est[co] = ind; co++; } } else { yproto_ini = mxGetPr(prhs[3]); if(mxGetNumberOfDimensions(prhs[3]) !=2) { mexErrMsgTxt("yproto_ini must be (1 x Nproto)"); } Nproto = mxGetN(prhs[3]); plhs[0] = mxCreateDoubleMatrix(1 , Nproto, mxREAL); yproto_est = mxGetPr(plhs[0]); for( i = 0 ; i < Nproto ; i++) { yproto_est[i] = yproto_ini[i]; } } }
GPUtype * mxCreateGPUtype(gpuTYPE_t type, GPUmanager *GPUman, int nrhs, const mxArray *prhs[]) { // My garbage collector MyGC mgc = MyGC(); // Garbage collector for Malloc MyGCObj<GPUtype> mgcobj; // Garbage collector for GPUtype // Make the following test // 1) complex elements // 2) should be either a scalar or a vector with dimension 2 // 3) If there are more arguments, each argument is checked to be scalar afterwards int nrhsstart = 0; // first 2 arguments are type and GPUmanager int nrhseff = nrhs-0; for (int i = nrhsstart; i < nrhs; i++) { if (mxIsComplex(prhs[i]) || (mxGetNumberOfDimensions(prhs[i]) != 2) || (mxGetM(prhs[i]) != 1)) mexErrMsgTxt("Size vector must be a row vector with real elements."); } int *mysize = NULL; int ndims; if (nrhseff == 1) { if (mxGetNumberOfElements(prhs[nrhsstart]) == 1) { mysize = (int*) Mymalloc(2 * sizeof(int),&mgc); mysize[0] = (int) mxGetScalar(prhs[nrhsstart]); mysize[1] = mysize[0]; ndims = 2; } else { int n = mxGetNumberOfElements(prhs[nrhsstart]); double *tmp = mxGetPr(prhs[nrhsstart]); mysize = (int*) Mymalloc(n * sizeof(int),&mgc); for (int i = 0; i < n; i++) { mysize[i] = (int) floor(tmp[i]); } ndims = n; } } else { int n = nrhseff; mysize = (int*) Mymalloc(n * sizeof(int),&mgc); for (int i = nrhsstart; i < nrhs; i++) { if (mxGetNumberOfElements(prhs[i]) == 1) { mysize[i-nrhsstart] = (int) mxGetScalar(prhs[i]); } else { mexErrMsgTxt("Input arguments must be scalar."); } } ndims = n; } if (mysize == NULL) mexErrMsgTxt("Unexpected error in GPUtypeNew."); // Check all dimensions different from 0 for (int i = 0; i < ndims; i++) { if (mysize[i] == 0) mexErrMsgTxt("Dimension cannot be zero."); } // remove any one at the end int finalndims = ndims; for (int i = ndims - 1; i > 1; i--) { if (mysize[i] == 1) finalndims--; else break; } ndims = finalndims; GPUtype *r = new GPUtype(type, ndims , mysize, GPUman); mgcobj.setPtr(r); // should delete this pointer r->setSize(ndims, mysize); try { GPUopAllocVector(*r); } catch (GPUexception ex) { mexErrMsgTxt(ex.getError()); } // create output result mgcobj.remPtr(r); return r; }
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) { double *vecA, *vecB, *pA,*pB; double *dist; unsigned int i, ptsA, ptsB, dim, kptsA, kptsB; int *sym; if (nrhs == 0) { mexPrintf("Usage: d = chi2_mex(X,Y);\n"); mexPrintf("where X and Y are matrices of dimension [dim,npts]\n"); mexPrintf("\nExample\n a = rand(2,10);\n b = rand(2,20);\n d = chi2_mex(a,b);\n"); return; } if (nrhs != 3) { mexPrintf("three input arguments expected: A, B, and sym, sym says wether A and B are the same"); return; } if (mxGetNumberOfDimensions(prhs[0]) != 2 || mxGetNumberOfDimensions(prhs[1]) != 2) { mexPrintf("inputs must be two dimensional"); return; } mxClassID the_class = mxGetClassID(prhs[0]); if(the_class != mxDOUBLE_CLASS) { mexErrMsgTxt("Histograms should have double precision!\n"); } vecA = (double *)mxGetPr(prhs[0]); vecB = (double *)mxGetPr(prhs[1]); sym = (int *)mxGetPr(prhs[2]); ptsA = mxGetN(prhs[0]); ptsB = mxGetN(prhs[1]); dim = mxGetM(prhs[0]); if (dim != mxGetM(prhs[1])) { mexPrintf("Dimension mismatch"); return; } const mwSize ndims[2] = {ptsA, ptsB}; mxArray* mxdist = mxCreateNumericArray(2, ndims,the_class,mxREAL); dist = (double *)mxGetData(mxdist); /*plhs[0] = mxCreateDoubleMatrix(ptsA,ptsB,mxREAL);*/ /*dist = (float *)mxGetPr(plhs[0]);*/ /*chi2_distance_float(dim,ptsB,vecB,ptsA,vecA,dist); */ /* printf("get_num_threads: %d\n", omp_get_num_threads()); printf("hello");*/ if(*sym) { chi2sym_distance_double(dim, ptsB, vecB, dist); } else { chi2_distance_double(dim, ptsB, vecB, ptsA, vecA, dist); } plhs[0] = mxdist; return; }
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) { int imgrows, imgcols, numsigmas, numangles, nwedges, maxradius; int i, j, k, anglewedges, plot = 0; enum imgtype type; double *sigmas, *spacing, *dimensions, *angles, *maxclusters, wedgeangle; double maxsigma = -1.0; mxArray **strength = NULL, **orientation = NULL, **uncertainty = NULL; mxArray **abnormality = NULL; void *imgdata; int dims[3]; char buf[20] = "xxxxxxxxxxxxxxxxxxx\0"; /* Before error checking, remove the optional string argument at the end */ if (nrhs > 0 && mxIsChar(prhs[nrhs-1])) { if (mxGetString(prhs[nrhs-1], buf, 20) == 0 && buf[0] == 'p') plot = 1; nrhs--; /* Don't want to process it numerically later on */ } /* Error checking (duh) */ if (nrhs < 2 || nrhs > 7) mexErrMsgTxt("Incorrect number of arguments supplied"); if (nlhs < 1 || nlhs > 4) mexErrMsgTxt("Between 1 and 4 output matrices should be supplied"); if (mxGetNumberOfDimensions(prhs[0]) != 3) mexErrMsgTxt("Image should be M x N x 3"); if (!mxIsUint8(prhs[0]) && !mxIsDouble(prhs[0])) mexErrMsgTxt("Image data should be uint8 or double"); if (mxGetM(prhs[1]) != 1) mexErrMsgTxt("Sigmas must be a scalar or a row vector"); if (mxGetN(prhs[1]) == 0) mexErrMsgTxt("Empty sigma vector is not allowed"); if (nrhs >= 3 && mxGetM(prhs[2]) != 1) mexErrMsgTxt("Spacing must be a scalar or a row vector"); if (nrhs >= 3 && mxGetN(prhs[2]) != 1 && mxGetN(prhs[2]) != mxGetN(prhs[1])) mexErrMsgTxt("Spacing must be a scalar or same length as scale vector"); if (nrhs >= 4 && mxGetM(prhs[3]) != 1) mexErrMsgTxt("Image sub-dimensions must be a scalar or a row vector"); if (nrhs >= 4 && (mxGetN(prhs[3]) == 3 || mxGetN(prhs[3]) > 4)) mexErrMsgTxt("Image sub-dimension vector must have 1, 2, or 4 entries"); if (nrhs >= 5 && mxGetM(prhs[4]) != 1) mexErrMsgTxt("Angles must be a scalar or a row vector"); /* Collect meta-data about each argument */ /* Argument #0: the image */ imgrows = mxGetM(prhs[0]); imgcols = mxGetN(prhs[0]) / 3; /* mxGetN counts over dimensions 2-d */ if (mxIsUint8(prhs[0])) type = RGBImg; else type = LabImg; imgdata = mxGetData(prhs[0]); /* Argument #1: one or more standard deviation values */ /* Modified 31 July 1999 so that standard deviations (sigmas) rather than * radii are specified; also, sigmas can be floating-point values */ numsigmas = mxGetN(prhs[1]); sigmas = mxGetPr(prhs[1]); for (i = 0; i < numsigmas; i++) if (sigmas[i] > maxsigma) maxsigma = sigmas[i]; maxradius = ceil(3 * maxsigma); if (maxsigma * 2 > imgrows || maxsigma * 2 > imgcols) mexErrMsgTxt("Image is too small for maximum scale chosen"); /* Argument #2: the spacing for each application of the operator */ if (nrhs >= 3 && mxGetN(prhs[2]) > 1) spacing = mxGetPr(prhs[2]); else { spacing = (double *)mxCalloc(numsigmas,sizeof(double)); for (i = 0; i < numsigmas; i++) spacing[i] = (nrhs >= 3) ? mxGetScalar(prhs[2]) : 1; } /* Argument #3: Dimensions of the sub-image to find edges over */ if (nrhs >= 4 && mxGetN(prhs[3]) == 4) { dimensions = mxGetPr(prhs[3]); /* Dimensions specified */ if (dimensions[0] < maxradius) { mexWarnMsgTxt("Dimension entry 1 below minimum row"); dimensions[0] = maxradius; } if (dimensions[1] < maxradius) { mexWarnMsgTxt("Dimension entry 2 below minimum column"); dimensions[1] = maxradius; } if (dimensions[2] > imgrows - maxradius) { mexWarnMsgTxt("Dimension entry 3 above maximum row"); dimensions[2] = imgrows - maxradius; } if (dimensions[3] > imgcols - maxradius) { mexWarnMsgTxt("Dimension entry 4 above maximum column"); dimensions[3] = imgcols - maxradius; } if (dimensions[2] < dimensions[0] || dimensions[3] < dimensions[1]) mexErrMsgTxt("Dimensions are [TR LC BR RC] with BR >= TR and RC >= LC"); } else { dimensions = (double *)mxCalloc(4,sizeof(double)); if (nrhs < 4 || mxGetN(prhs[3]) == 1) { /* Whole image */ dimensions[0] = maxradius; dimensions[1] = maxradius; dimensions[2] = imgrows - maxradius; dimensions[3] = imgcols - maxradius; } else { /* One point */ dimensions[0] = mxGetPr(prhs[3])[0]; dimensions[1] = mxGetPr(prhs[3])[1]; dimensions[2] = mxGetPr(prhs[3])[0]; dimensions[3] = mxGetPr(prhs[3])[1]; if (dimensions[0] < maxradius || dimensions[1] < maxradius || dimensions[2] > imgrows - maxradius || dimensions[3] > imgcols - maxradius) mexErrMsgTxt("Point is inoperable by maximum scale"); } } /* Argument #4: Number of angles (alpha values in ICCV99) to compute */ if (nrhs >= 5 && mxGetN(prhs[4]) >= 1) { numangles = mxGetN(prhs[4]); angles = mxGetPr(prhs[4]); for (i = 0; i < numangles; i++) if (angles[i] <= 0 || angles[i] > 180) { mexErrMsgTxt("All angles must be between 0 and 180"); } } else { numangles = 1; angles = (double *)mxCalloc(numangles,sizeof(double)); angles[0] = 180; } /* Argument #5: the number of wedges in one quarter of the circle */ nwedges = (nrhs >= 6) ? mxGetScalar(prhs[5]) : 6; if (nwedges * 2 > MAXWEDGES) mexErrMsgTxt("Too many wedges"); wedgeangle = 90.0 / nwedges; for (i = 0; i < numangles; i++) if (angles[i]/wedgeangle != floor(angles[i]/wedgeangle)) mexErrMsgTxt("Angles chosen not compatible with number of wedges"); /* Argument #6: the maximum number of clusters in a color signature */ if (nrhs >= 7 && mxGetN(prhs[6]) > 1) if (mxGetN(prhs[6]) == numsigmas) maxclusters = mxGetPr(prhs[6]); else mexErrMsgTxt("Maxclusters must be a scalar or equal to # of sigmas"); else { maxclusters = (double *)mxCalloc(numsigmas,sizeof(double)); for (i = 0; i < numsigmas; i++) { maxclusters[i] = (nrhs >= 7) ? mxGetScalar(prhs[6]) : DEFAULTCLUSTERS; if (maxclusters[i] > MAXCLUSTERS) mexErrMsgTxt("Maximum number of clusters greater than allowed"); } } /* Allocate output arguments */ for (i = 0; i < nlhs; i++) { if (i == STRENGTH && plot == 1) { /* Allocate compass plots */ if (numsigmas == 1 && numangles == 1) { dims[0] = (int)(dimensions[2] - dimensions[0])/(int)spacing[0] + 1; dims[1] = (int)(dimensions[3] - dimensions[1])/(int)spacing[0] + 1; dims[2] = (angles[0] == 180) ? 2 * nwedges : 4 * nwedges; plhs[STRENGTH] = mxCreateNumericArray(3, dims, mxDOUBLE_CLASS, mxREAL); } else { /* Create a list of compass plots */ plhs[STRENGTH] = mxCreateCellMatrix(numangles, numsigmas); for (j = 0; j < numsigmas; j++) { dims[0] = (int)(dimensions[2] - dimensions[0])/(int)spacing[j] + 1; dims[1] = (int)(dimensions[3] - dimensions[1])/(int)spacing[j] + 1; for (k = 0; k < numangles; k++) { dims[2] = (angles[k] == 180) ? 2 * nwedges : 4 * nwedges; mxSetCell(plhs[STRENGTH], j * numangles + k, mxCreateNumericArray(3, dims, mxDOUBLE_CLASS, mxREAL)); } } } } else { /* Allow multiple pages for uncertainty and orientation */ dims[2] = (i == STRENGTH || i == ABNORMALITY) ? 1 : MAXRESPONSES; if (numsigmas == 1 && numangles == 1) { /* One matrix per argument */ dims[0] = (int)(dimensions[2] - dimensions[0])/(int)spacing[0] + 1; dims[1] = (int)(dimensions[3] - dimensions[1])/(int)spacing[0] + 1; plhs[i] = mxCreateNumericArray(3, dims, mxDOUBLE_CLASS, mxREAL); } else { /* Create a list for each argument */ plhs[i] = mxCreateCellMatrix(numangles, numsigmas); for (j = 0; j < numsigmas; j++) { dims[0] = (int)(dimensions[2] - dimensions[0])/(int)spacing[j] + 1; dims[1] = (int)(dimensions[3] - dimensions[1])/(int)spacing[j] + 1; for (k = 0; k < numangles; k++) mxSetCell(plhs[i], j * numangles + k, mxCreateNumericArray(3, dims, mxDOUBLE_CLASS, mxREAL)); } } } } switch (nlhs) { /* This has no breaks; be careful when modifying */ case 4: uncertainty = (mxArray **)mxCalloc(numsigmas*numangles,sizeof(mxArray *)); if (numsigmas == 1 && numangles == 1) uncertainty[0] = plhs[UNCERTAINTY]; else for (i = 0; i < numsigmas * numangles; i++) uncertainty[i] = mxGetCell(plhs[UNCERTAINTY],i); case 3: abnormality = (mxArray **)mxCalloc(numsigmas*numangles,sizeof(mxArray *)); if (numsigmas == 1 && numangles == 1) abnormality[0] = plhs[ABNORMALITY]; else for (i = 0; i < numsigmas * numangles; i++) abnormality[i] = mxGetCell(plhs[ABNORMALITY],i); case 2: orientation = (mxArray **)mxCalloc(numsigmas*numangles,sizeof(mxArray *)); if (numsigmas == 1 && numangles == 1) orientation[0] = plhs[ORIENTATION]; else for (i = 0; i < numsigmas * numangles; i++) orientation[i] = mxGetCell(plhs[ORIENTATION],i); case 1: strength = (mxArray **)mxCalloc(numsigmas*numangles,sizeof(mxArray *)); if (numsigmas == 1 && numangles == 1) strength[0] = plhs[STRENGTH]; else for (i = 0; i < numsigmas * numangles; i++) strength[i] = mxGetCell(plhs[STRENGTH],i); } Compass(imgdata, imgrows, imgcols, type, sigmas, numsigmas, maxradius, spacing, dimensions, angles, numangles, nwedges, maxclusters, plot, strength, abnormality, orientation, uncertainty); }
/***********************************************************************//** * \brief mexFunction to append a stack to an existing em-file. **************************************************************************/ void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray*prhs[]) { size_t filename_length = 0; #define __MAX_FILENAME_LENGTH__ ((int)2048) char filename[__MAX_FILENAME_LENGTH__+1]; #define __MAX_S__LENGTH__ (4096) char s[__MAX_S__LENGTH__+1]; #define __BUFFERLENGTH_SYNOPSIS__ 1024 char synopsis[__BUFFERLENGTH_SYNOPSIS__]; size_t i, j, k; const void *w_data; int w_iotype; uint32_t subregion_start[3] = { 0,0,0 }; uint32_t reverse_sampling[3] = { 0,0,0 }; tom_io_em_header header; int allow_conversion = 1; mxArray *plhs_tmp[5] = { NULL, NULL, NULL, NULL, NULL }; void *complexCopy = NULL; uint32_t w_sizex, w_sizey, w_sizez; size_t w_stridex=0, w_stridey=0, w_stridez=0; snprintf(synopsis, __BUFFERLENGTH_SYNOPSIS__, "[size, magic, comment, emdata, userdata] = %s(filename, volume, [subregion_start, reverse_sampling, allow_conversion])", mexFunctionName()); if (nrhs==0 && nlhs==0) { /* Print help */ mexPrintf("SYNOPSIS: %s\n", synopsis); mexPrintf("mex-file compiled from file \"" __FILE__ "\" at " __DATE__ ", " __TIME__ ".\n"); return; } if (nlhs>5 || nrhs<2 || nrhs>5) { snprintf(s, __MAX_S__LENGTH__, "%s: Wrong number of in/output arguments: %s.", mexFunctionName(), synopsis); mexErrMsgTxt(s); } { #define __MAX_UINT32_T__ 0xFFFFFFFF const mxArray *arg; mxArray *tmpArray = NULL; const mwSize *size; double *pdouble; mxClassID type; /* filename */ arg = prhs[0]; if (!mxIsChar(arg) || mxGetNumberOfDimensions(arg)!=2 || mxGetM(arg)!=1 || (filename_length=mxGetN(arg))<1 || filename_length>=__MAX_FILENAME_LENGTH__) { snprintf(s, __MAX_S__LENGTH__, "%s: needs file name as first parameter: %s.", mexFunctionName(), synopsis); mexErrMsgTxt(s); } mxGetString(arg, filename, __MAX_FILENAME_LENGTH__); /* subregion_start */ if (nrhs >= 3) { arg = prhs[2]; i = mxGetM(arg); j = mxGetN(arg); if (!mxIsNumeric(arg) || mxIsComplex(arg) || mxGetNumberOfDimensions(arg)!=2 || !((i==0&&j==0) || (i==1&&j==3) || (i==3&&j==1))) { snprintf(s, __MAX_S__LENGTH__, "%s: The subregion_start must be either [] or a 1x3 vector: %s", mexFunctionName(), synopsis); mexErrMsgTxt(s); } if (i!=0) { if (!(tmpArray=getDoubleArray(arg))) { snprintf(s, __MAX_S__LENGTH__, "%s: Error creating a copy of the subregion_start. Maybe out of memory.", mexFunctionName()); mexErrMsgTxt(s); } pdouble = mxGetPr(tmpArray); for (k=0; k<3; k++) { subregion_start[k] = (uint32_t)pdouble[k]; if (pdouble[k] != subregion_start[k]) { snprintf(s, __MAX_S__LENGTH__, "%s: subregion_start must contain integer values: %s", mexFunctionName(), synopsis); mexErrMsgTxt(s); } } mxDestroyArray(tmpArray); } } /* reverse_sampling */ if (nrhs >= 4) { arg = prhs[3]; i = mxGetM(arg); j = mxGetN(arg); if (!mxIsNumeric(arg) || mxIsComplex(arg) || mxGetNumberOfDimensions(arg)!=2 || !((i==0&&j==0) || (i==1&&j==3) || (i==3&&j==1))) { snprintf(s, __MAX_S__LENGTH__, "%s: The reverse_sampling must be either [] or a 1x3 vector: %s", mexFunctionName(), synopsis); mexErrMsgTxt(s); } if (i!=0) { if (!(tmpArray=getDoubleArray(arg))) { snprintf(s, __MAX_S__LENGTH__, "%s: Error creating a copy of the reverse_sampling. Maybe out of memory.", mexFunctionName()); mexErrMsgTxt(s); } pdouble = mxGetPr(tmpArray); for (k=0; k<3; k++) { reverse_sampling[k] = (uint32_t)pdouble[k]; if (pdouble[k] != reverse_sampling[k]) { snprintf(s, __MAX_S__LENGTH__, "%s: reverse_sampling must contain integer values: %s", mexFunctionName(), synopsis); mexErrMsgTxt(s); } } mxDestroyArray(tmpArray); } } if (reverse_sampling[0] < 1) { reverse_sampling[0] = 1; } if (reverse_sampling[1] < 1) { reverse_sampling[1] = 1; } if (reverse_sampling[2] < 1) { reverse_sampling[2] = 1; } /* allow_conversion */ if (nrhs >= 5) { const mwSize numel = mxGetNumberOfElements(arg = prhs[4]); if (!(mxIsNumeric(arg) || mxIsLogical(arg)) || numel>1) { snprintf(s, __MAX_S__LENGTH__, "%s: allow_conversion must be one of true, false or [].", mexFunctionName(), synopsis); mexErrMsgTxt(s); } if (numel == 1) { allow_conversion = mxGetScalar(arg) != 0; } } { /* Allocate the memory for the ouput, so that in case of successfully writing, no error can happen afterwards in the mexfunction. */ switch (nlhs) { case 5: if (!(plhs_tmp[4] = mxCreateNumericMatrix(1, 256, mxINT8_CLASS, mxREAL))) { mexErrMsgTxt("Error allocating memory"); } case 4: if (!(plhs_tmp[3] = mxCreateNumericMatrix(1, 40, mxINT32_CLASS, mxREAL))) { mexErrMsgTxt("Error allocating memory"); } case 3: if (!(plhs_tmp[2] = mxCreateNumericMatrix(1, 80, mxINT8_CLASS, mxREAL))) { mexErrMsgTxt("Error allocating memory"); } case 2: if (!(plhs_tmp[1] = mxCreateNumericMatrix(1, 4, mxINT8_CLASS, mxREAL))) { mexErrMsgTxt("Error allocating memory"); } case 1: if (!(plhs_tmp[0] = mxCreateNumericMatrix(3, 1, mxUINT32_CLASS, mxREAL))) { mexErrMsgTxt("Error allocating memory"); } } } /* data */ arg = prhs[1]; if (!mxIsNumeric(arg) || mxGetNumberOfDimensions(arg)>3) { snprintf(s, __MAX_S__LENGTH__, "%s: needs a numerical volume as second parameter: %s", mexFunctionName(), synopsis); mexErrMsgTxt(s); } type = mxGetClassID(arg); size = mxGetDimensions(arg); w_sizex = size[0]; w_sizey = size[1]; w_sizez = mxGetNumberOfDimensions(arg)==3 ? size[2] : 1; if (w_sizex!=size[0] || w_sizey!=size[1] || w_sizez!=(mxGetNumberOfDimensions(arg)==3?size[2]:1)) { snprintf(s, __MAX_S__LENGTH__, "%s: The volume is too large to save it as EM.", mexFunctionName(), synopsis); mexErrMsgTxt(s); } if (mxIsComplex(arg)) { const size_t numel = w_sizex * w_sizey * w_sizez; float *pdst; if (!allow_conversion && type!=mxSINGLE_CLASS) { snprintf(s, __MAX_S__LENGTH__, "%s: Can not convert complex volume to single (not allow_conversion).", mexFunctionName()); mexErrMsgTxt(s); } if (!(complexCopy = malloc(numel*2*sizeof(float)))) { snprintf(s, __MAX_S__LENGTH__, "%s: Error allocating memory for temporary copy of complex data.", mexFunctionName()); mexErrMsgTxt(s); } pdst = complexCopy; if (type == mxSINGLE_CLASS) { const float *psrc_re; const float *psrc_im; psrc_re = (float *)mxGetData(arg); psrc_im = (float *)mxGetData(arg); for (i=0; i<numel; i++) { *pdst++ = psrc_re[i]; *pdst++ = psrc_im[i]; } } else if (type == mxDOUBLE_CLASS) { const double *psrc_re, *psrc_im; psrc_re = mxGetPr(arg); psrc_im = mxGetPi(arg); for (i=0; i<numel; i++) { *pdst++ = psrc_re[i]; *pdst++ = psrc_im[i]; } } else { free(complexCopy); complexCopy = NULL; snprintf(s, __MAX_S__LENGTH__, "%s: EM supports only floating point complex data (single).", mexFunctionName(), type); mexErrMsgTxt(s); } w_data = complexCopy; w_iotype = TOM_IO_TYPE_COMPLEX4; } else { w_data = mxGetData(arg); w_iotype = getIOTypeFromMxClassID(type, false); } } { int header_read; int fcn_res = tom_io_em_write_paste(filename, w_data, w_iotype, w_sizex, w_sizey, w_sizez, w_stridex, w_stridey, w_stridez, &header, &header_read, allow_conversion, subregion_start, reverse_sampling); if (fcn_res != TOM_ERR_OK) { if (complexCopy) { free(complexCopy); complexCopy = NULL; } switch (fcn_res) { case TOM_ERR_VOLUME_TOO_LARGE: snprintf(s, __MAX_S__LENGTH__, "%s: The %lux%lux%lu-volume is to large to paste it into the %lux%lux%lu-EM-file (start at %lux%lux%lu, sample %lux%lux%lu).", mexFunctionName(), (unsigned long)w_sizex, (unsigned long)w_sizey, (unsigned long)w_sizez, (unsigned long)header.dims[0], (unsigned long)header.dims[1], (unsigned long)header.dims[2], (unsigned long)subregion_start[0], (unsigned long)subregion_start[1], (unsigned long)subregion_start[2], (unsigned long)reverse_sampling[0], (unsigned long)reverse_sampling[1], (unsigned long)reverse_sampling[2]); break; case TOM_ERR_WRONG_IOTYPE_CONVERSION: snprintf(s, __MAX_S__LENGTH__, "%s: Error converting the volume from type %d to type %d (allow conversion = %s).", mexFunctionName(), (int)w_iotype, (int)tom_io_em_get_iotype(&header), allow_conversion ? "yes" : "no"); break; default: snprintf(s, __MAX_S__LENGTH__, "%s: Unspecified error pasting the volume to file (%d).", mexFunctionName(), fcn_res); break; } mexErrMsgTxt(s); } if (complexCopy) { free(complexCopy); complexCopy = NULL;} } { /* Construct the output. */ void *pdata; switch (nlhs) { case 5: pdata = mxGetData(plhs[4] = plhs_tmp[4]); for (i=0; i<256; i++) { ((int8_t *)pdata)[i] = header.userdata[i]; } case 4: pdata = mxGetData(plhs[3] = plhs_tmp[3]); for (i=0; i<40; i++) { ((int32_t *)pdata)[i] = header.emdata[i]; } case 3: pdata = mxGetData(plhs[2] = plhs_tmp[2]); for (i=0; i<80; i++) { ((int8_t *)pdata)[i] = header.comment[i]; } case 2: pdata = mxGetData(plhs[1] = plhs_tmp[1]); ((int8_t *)pdata)[0] = header.machine; ((int8_t *)pdata)[1] = header.byte2; ((int8_t *)pdata)[2] = header.byte3; ((int8_t *)pdata)[3] = header.type; case 1: pdata = mxGetData(plhs[0] = plhs_tmp[0]); ((uint32_t *)pdata)[0] = header.dims[0]; ((uint32_t *)pdata)[1] = header.dims[1]; ((uint32_t *)pdata)[2] = header.dims[2]; break; case 0: default: break; } } }
void mexFunction(int nlhs, mxArray* plhs[], int nrhs, const mxArray* prhs[]) { //mexPrintf("test A\n"); // Check the number of inputs/outputs if (nlhs == 0) nlhs = 1; if (nrhs != 1) mexErrMsgTxt("Incorrect number of inputs"); else if (nlhs > 2) mexErrMsgTxt("Too many outputs."); // mexPrintf("test A.2\n"); // Setup the set inputs //N int input_N = (int)(mcwrap_size(prhs[1 - 1], 2)); //mexPrintf("test B\n"); // Setup the inputs //samples //Check that we have the correct dimensions! { int numdims = mxGetNumberOfDimensions(prhs[1 - 1]); if (numdims != 2) { mexErrMsgTxt("Incorrect number of dimensions in input: samples"); } const mwSize* dims2 = mxGetDimensions(prhs[1 - 1]); int dims[] = { 1, input_N }; for (long ii = 0; ii < numdims; ii++) { if (dims[ii] != dims2[ii]) { mexErrMsgTxt("Incorrect size of input: samples"); } } } double* input_samples = mxGetPr(prhs[1 - 1]); //mexPrintf("test C\n"); // Setup the outputs //dipscore double* output_dipscore; if (1 <= nlhs) { if ((2 < 1) || (2 > 20)) { mexErrMsgTxt("Bad number of dimensions for my taste: 2"); } { int dims2[] = { 1, 1 }; for (long ii = 0; ii < 2; ii++) { if ((dims2[ii] < 1) || (dims2[ii] > 10000000000.0)) { mexErrMsgTxt("Bad array size for my taste: 1,1"); } } } mwSize dims[] = { 1, 1 }; plhs[1 - 1] = mxCreateNumericArray(2, dims, mxDOUBLE_CLASS, mxREAL); output_dipscore = mxGetPr(plhs[1 - 1]); } //cutpoint double* output_cutpoint; if (2 <= nlhs) { if ((2 < 1) || (2 > 20)) { mexErrMsgTxt("Bad number of dimensions for my taste: 2"); } { int dims2[] = { 1, 1 }; for (long ii = 0; ii < 2; ii++) { if ((dims2[ii] < 1) || (dims2[ii] > 10000000000.0)) { mexErrMsgTxt("Bad array size for my taste: 1,1"); } } } mwSize dims[] = { 1, 1 }; plhs[2 - 1] = mxCreateNumericArray(2, dims, mxDOUBLE_CLASS, mxREAL); output_cutpoint = mxGetPr(plhs[2 - 1]); } //mexPrintf("test D\n"); // Run the subroutine isocut5_mex( output_dipscore, output_cutpoint, input_N, input_samples ); //mexPrintf("test E\n"); // Free the inputs //samples //mexPrintf("test F\n"); // Set the outputs //dipscore //cutpoint //mexPrintf("test G\n"); /**** We are done *******/ }
// inds=mexFunction(data,thrs,fids,child,[nThreads]) void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) { /* Computes the max value in a given patch Sz and return the max-value along each dimension */ int nr,nc,nd,nThreads,sz,stepSz; int b,rNum,cNum; float *im; float *patches,*pool; int *dims; uint32 *loc, *maxLoc; int64_t maxNum,outDim,numPatches; //If mexError is encountered - is probably due to overflow of maxNum - check for it. if (nrhs < 3) mexErrMsgTxt("Atleast 3 input arguments required. patches = pool_vol(im,patchSz,stepSz,nThread)"); if (mxGetClassID(prhs[0])!=mxSINGLE_CLASS) mexErrMsgTxt("Image must be of type single"); if (mxGetNumberOfDimensions(prhs[0])!=3) mexErrMsgTxt("3 dimensional array is expected"); im = (float *) mxGetData(prhs[0]); sz = (int) mxGetScalar(prhs[1]); stepSz = (int) mxGetScalar(prhs[2]); nThreads = (nrhs<4) ? 100000 : (int) mxGetScalar(prhs[3]); nThreads = min2(nThreads,omp_get_max_threads()); //mexPrintf("Location 1 \n"); dims = (int *) mxGetDimensions(prhs[0]); nr = (int) mxGetM(prhs[0]); nc = (int) dims[1]; nd = (int) dims[2]; outDim = sz*sz*nd; //mexPrintf("Size is (%d,%d,%d) and outDim is %d \n",nr,nc,nd,outDim); if (sz % 2==0) mexErrMsgTxt("Patch Size must be an odd number"); if (sz > nr || sz > nc) mexErrMsgTxt("Patch Size should not be bigger than img dims"); b = (sz-1)/2; rNum = (int) (floor(float(nr-1 -2*b)/float(stepSz)) + 1); cNum = (int) (floor(float(nc-1 -2*b)/float(stepSz)) + 1); numPatches = rNum*cNum; //mexPrintf("Location 2 \n"); int rSt[rNum],rEn[rNum],cSt[cNum],cEn[cNum]; for (int i=0; i<rNum; i++){ rSt[i] = i*stepSz; rEn[i] = rSt[i] + sz -1; //mexPrintf("(rSt,rEn): (%d,%d) \n",rSt[i],rEn[i]); } //mexPrintf("Max: (rSt,rEn): (%d,%d) \n",rSt[rNum-1],rEn[rNum-1]); for (int i=0; i<cNum; i++){ cSt[i] = i*stepSz; cEn[i] = cSt[i] + sz - 1; //mexPrintf("(cSt,cEn): (%d,%d) \n",cSt[i],cEn[i]); } //mexPrintf("Max: (cSt,cEn): (%d,%d) \n",cSt[cNum-1],cEn[cNum-1]); //mexPrintf("Location 3 \n"); plhs[0] = mxCreateNumericMatrix(outDim,numPatches,mxSINGLE_CLASS,mxREAL); plhs[1] = mxCreateNumericMatrix(2,numPatches,mxUINT32_CLASS,mxREAL); plhs[2] = mxCreateNumericMatrix(nd,numPatches,mxSINGLE_CLASS,mxREAL); plhs[3] = mxCreateNumericMatrix(2*nd,numPatches,mxUINT32_CLASS,mxREAL); patches = (float *) mxGetPr(plhs[0]); // Store the patches loc = (uint32 *) mxGetPr(plhs[1]); pool = (float *) mxGetPr(plhs[2]); //Store the max-pooled value maxLoc = (uint32 *) mxGetPr(plhs[3]); //Store the location of top-left corner of the patch which produced the maxValue. maxNum = outDim*numPatches - 1; //mexPrintf("Location 4 \n"); int count = 0; int patchCount = 0; int col; float maxVal, val; uint32 *mLoc = new uint32[2]; #pragma omp parallel for num_threads(nThreads) for (int c=0; c<cNum; c++){ for (int r=0; r<rNum; r++){ count = 0; loc[patchCount*2] = rSt[r] + b + 1; //+1 for matlab indexing loc[patchCount*2+1] = cSt[c] + b +1; for (int d=0; d<nd; d++){ col = cSt[c]; maxVal = -std::numeric_limits<float>::max(); mLoc[0] = -1; mLoc[1] = -1; for (int i=0; i<sz; i++){ for (int j=0; j<sz; j++){ val = im[col*nr + rSt[r] + j + d*nr*nc]; patches[count + outDim*patchCount] = val; if (val >maxVal){ //mexPrintf("Yes, val: %f, col: %d",val,col+1); maxVal = val; mLoc[0] = rSt[r] + j + 1; mLoc[1] = col + 1; } count = count + 1; } col = col + 1; } //mexPrintf(" \n"); //mexPrintf("Locs: %d,%d \n",mLoc[0],mLoc[1]); pool[patchCount*nd + d] = maxVal; maxLoc[patchCount*nd*2 + 2*d] = mLoc[0]; maxLoc[patchCount*nd*2 + 2*d + 1] = mLoc[1]; } patchCount = patchCount + 1; } } }
void mexFunction ( /* === Parameters ======================================================= */ int nlhs, /* number of left-hand sides */ mxArray *plhs [], /* left-hand side matrices */ int nrhs, /* number of right--hand sides */ const mxArray *prhs [] /* right-hand side matrices */ ) { Zmat A; ZAMGlevelmat *PRE; ZILUPACKparam *param; integer n; const char **fnames; const mwSize *dims; mxClassID *classIDflags; mxArray *tmp, *fout, *A_input , *b_input, *x0_input, *options_input, *PRE_input, *options_output, *x_output; char *pdata, *input_buf, *output_buf; mwSize ndim,nnz, buflen; mwIndex *irs, *jcs; int ifield, status, nfields, ierr,i,j,k,l,m; size_t mrows, ncols, sizebuf; double dbuf, *A_valuesR, *A_valuesI, *convert, *sr, *pr, *pi; doublecomplex *sol, *rhs; mwIndex *A_ja, /* row indices of input matrix A */ *A_ia; /* column pointers of input matrix A */ if (nrhs != 5) mexErrMsgTxt("five input arguments required."); else if (nlhs !=2) mexErrMsgTxt("Too many output arguments."); else if (!mxIsStruct(prhs[2])) mexErrMsgTxt("Third input must be a structure."); else if (!mxIsNumeric(prhs[0])) mexErrMsgTxt("First input must be a matrix."); /* The first input must be a square matrix.*/ A_input = (mxArray *) prhs [0] ; /* get size of input matrix A */ mrows = mxGetM (A_input) ; ncols = mxGetN (A_input) ; nnz = mxGetNzmax(A_input); if (mrows!=ncols) { mexErrMsgTxt("First input must be a square matrix."); } if (!mxIsSparse (A_input)) { mexErrMsgTxt ("ILUPACK: input matrix must be in sparse format.") ; } /* copy input matrix to sparse row format */ A.nc=A.nr=mrows; A.ia=(integer *) MAlloc((size_t)(A.nc+1)*sizeof(integer),"ZGNLHPDilupacksolver"); A.ja=(integer *) MAlloc((size_t)nnz *sizeof(integer),"ZGNLHPDilupacksolver"); A. a=(doublecomplex *) MAlloc((size_t)nnz *sizeof(doublecomplex), "ZGNLHPDilupacksolver"); A_ja = (mwIndex *)mxGetIr (A_input); A_ia = (mwIndex *)mxGetJc (A_input); A_valuesR = (double *) mxGetPr(A_input); if (mxIsComplex(A_input)) A_valuesI = (double *) mxGetPi(A_input); /* -------------------------------------------------------------------- */ /* .. Convert matrix from 0-based C-notation to Fortran 1-based */ /* notation. */ /* -------------------------------------------------------------------- */ /* for (i = 0 ; i < ncols ; i++) for (j = A_ia[i] ; j < A_ia[i+1] ; j++) printf("i=%d j=%d A.real=%e\n", i+1, A_ja[j]+1, A_valuesR[j]); */ for (i=0; i<=A.nr; i++) A.ia[i]=0; /* remember that MATLAB uses storage by columns and NOT by rows! */ for (i=0; i<A.nr; i++) { for (j=A_ia[i]; j<A_ia[i+1]; j++) { k=A_ja[j]; A.ia[k+1]++; } } /* now we know how many entries are located in every row */ /* switch to pointer structure */ for (i=0; i<A.nr; i++) A.ia[i+1]+=A.ia[i]; if (mxIsComplex(A_input)) { for (i=0; i<ncols; i++) { for (j=A_ia[i]; j<A_ia[i+1]; j++) { /* row index l in C-notation */ l=A_ja[j]; /* where does row l currently start */ k=A.ia[l]; /* column index will be i in FORTRAN notation */ A.ja[k]=i+1; A.a [k].r =A_valuesR[j]; A.a [k++].i=A_valuesI[j]; A.ia[l]=k; } } } else { for (i=0; i<ncols; i++) { for (j=A_ia[i]; j<A_ia[i+1]; j++) { /* row index l in C-notation */ l=A_ja[j]; /* where does row l currently start */ k=A.ia[l]; /* column index will be i in FORTRAN notation */ A.ja[k]=i+1; A.a [k].r =A_valuesR[j]; A.a [k++].i=0; A.ia[l]=k; } } } /* switch to FORTRAN style */ for (i=A.nr; i>0; i--) A.ia[i]=A.ia[i-1]+1; A.ia[0]=1; /* for (i = 0 ; i < A.nr ; i++) for (j = A.ia[i]-1 ; j < A.ia[i+1]-1 ; j++) printf("i=%d j=%d A.real=%e A.imag=%e\n", i+1, A.ja[j], A.a[j].r, A.a[j].i); */ /* import pointer to the preconditioner */ PRE_input = (mxArray*) prhs [1] ; /* get number of levels of input preconditioner structure `PREC' */ /* nlev=mxGetN(PRE_input); */ nfields = mxGetNumberOfFields(PRE_input); /* allocate memory for storing pointers */ fnames = mxCalloc((size_t)nfields, (size_t)sizeof(*fnames)); for (ifield = 0; ifield < nfields; ifield++) { fnames[ifield] = mxGetFieldNameByNumber(PRE_input,ifield); /* check whether `PREC.ptr' exists */ if (!strcmp("ptr",fnames[ifield])) { /* field `ptr' */ tmp = mxGetFieldByNumber(PRE_input,0,ifield); pdata = mxGetData(tmp); memcpy(&PRE, pdata, (size_t)sizeof(size_t)); } else if (!strcmp("param",fnames[ifield])) { /* field `param' */ tmp = mxGetFieldByNumber(PRE_input,0,ifield); pdata = mxGetData(tmp); memcpy(¶m, pdata, (size_t)sizeof(size_t)); } } mxFree(fnames); /* rescale input matrix */ /* obsolete for (i=0; i <A.nr; i++) { for (j=A.ia[i]-1; j<A.ia[i+1]-1; j++) { A.a[j].r*=PRE->rowscal[i].r*PRE->colscal[A.ja[j]-1].r; A.a[j].i*=PRE->rowscal[i].r*PRE->colscal[A.ja[j]-1].r; } } */ /* Get third input argument `options' */ options_input=(mxArray*)prhs[2]; nfields = mxGetNumberOfFields(options_input); /* Allocate memory for storing classIDflags */ classIDflags = (mxClassID *) mxCalloc((size_t)nfields+1, (size_t)sizeof(mxClassID)); /* allocate memory for storing pointers */ fnames = mxCalloc((size_t)nfields+1, (size_t)sizeof(*fnames)); /* Get field name pointers */ j=-1; for (ifield = 0; ifield < nfields; ifield++) { fnames[ifield] = mxGetFieldNameByNumber(options_input,ifield); /* check whether `options.niter' already exists */ if (!strcmp("niter",fnames[ifield])) j=ifield; } if (j==-1) fnames[nfields]="niter"; /* mexPrintf("search for niter completed\n"); fflush(stdout); */ /* import data */ for (ifield = 0; ifield < nfields; ifield++) { /* mexPrintf("%2d\n",ifield+1); fflush(stdout); */ tmp = mxGetFieldByNumber(options_input,0,ifield); classIDflags[ifield] = mxGetClassID(tmp); ndim = mxGetNumberOfDimensions(tmp); dims = mxGetDimensions(tmp); /* Create string/numeric array */ if (classIDflags[ifield] == mxCHAR_CLASS) { /* Get the length of the input string. */ buflen = (mxGetM(tmp) * mxGetN(tmp)) + 1; /* Allocate memory for input and output strings. */ input_buf = (char *) mxCalloc((size_t)buflen, (size_t)sizeof(char)); /* Copy the string data from tmp into a C string input_buf. */ status = mxGetString(tmp, input_buf, buflen); if (!strcmp("amg",fnames[ifield])) { if (strcmp(param->amg,input_buf)) { param->amg=(char *)MAlloc((size_t)buflen*sizeof(char),"ilupacksolver"); strcpy(param->amg,input_buf); } } else if (!strcmp("presmoother",fnames[ifield])) { if (strcmp(param->presmoother,input_buf)) { param->presmoother=(char *)MAlloc((size_t)buflen*sizeof(char), "ilupacksolver"); strcpy(param->presmoother,input_buf); } } else if (!strcmp("postsmoother",fnames[ifield])) { if (strcmp(param->postsmoother,input_buf)) { param->postsmoother=(char *)MAlloc((size_t)buflen*sizeof(char), "ilupacksolver"); strcpy(param->postsmoother,input_buf); } } else if (!strcmp("typecoarse",fnames[ifield])) { if (strcmp(param->typecoarse,input_buf)) { param->typecoarse=(char *)MAlloc((size_t)buflen*sizeof(char), "ilupacksolver"); strcpy(param->typecoarse,input_buf); } } else if (!strcmp("typetv",fnames[ifield])) { if (strcmp(param->typetv,input_buf)) { param->typetv=(char *)MAlloc((size_t)buflen*sizeof(char), "ilupacksolver"); strcpy(param->typetv,input_buf); } } else if (!strcmp("FCpart",fnames[ifield])) { if (strcmp(param->FCpart,input_buf)) { param->FCpart=(char *)MAlloc((size_t)buflen*sizeof(char), "ilupacksolver"); strcpy(param->FCpart,input_buf); } } else if (!strcmp("solver",fnames[ifield])) { if (strcmp(param->solver,input_buf)) { param->solver=(char *)MAlloc((size_t)buflen*sizeof(char), "ilupacksolver"); strcpy(param->solver,input_buf); } } else if (!strcmp("ordering",fnames[ifield])) { if (strcmp(param->ordering,input_buf)) { param->ordering=(char *)MAlloc((size_t)buflen*sizeof(char), "ilupacksolver"); strcpy(param->ordering,input_buf); } } else { /* mexPrintf("%s ignored\n",fnames[ifield]);fflush(stdout); */ } } else { if (!strcmp("elbow",fnames[ifield])) { param->elbow=*mxGetPr(tmp); } else if (!strcmp("lfilS",fnames[ifield])) { param->lfilS=*mxGetPr(tmp); } else if (!strcmp("lfil",fnames[ifield])) { param->lfil=*mxGetPr(tmp); } else if (!strcmp("maxit",fnames[ifield])) { param->maxit=*mxGetPr(tmp); } else if (!strcmp("droptolS",fnames[ifield])) { param->droptolS=*mxGetPr(tmp); } else if (!strcmp("droptol",fnames[ifield])) { param->droptol=*mxGetPr(tmp); } else if (!strcmp("condest",fnames[ifield])) { param->condest=*mxGetPr(tmp); } else if (!strcmp("restol",fnames[ifield])) { param->restol=*mxGetPr(tmp); } else if (!strcmp("npresmoothing",fnames[ifield])) { param->npresmoothing=*mxGetPr(tmp); } else if (!strcmp("npostmoothing",fnames[ifield])) { param->npostsmoothing=*mxGetPr(tmp); } else if (!strcmp("ncoarse",fnames[ifield])) { param->ncoarse=*mxGetPr(tmp); } else if (!strcmp("matching",fnames[ifield])) { param->matching=*mxGetPr(tmp); } else if (!strcmp("nrestart",fnames[ifield])) { param->nrestart=*mxGetPr(tmp); } else if (!strcmp("damping",fnames[ifield])) { param->damping.r=*mxGetPr(tmp); if (mxIsComplex(tmp)) param->damping.i=*mxGetPi(tmp); else param->damping.i=0; } else if (!strcmp("mixedprecision",fnames[ifield])) { param->mixedprecision=*mxGetPr(tmp); } else { /* mexPrintf("%s ignored\n",fnames[ifield]);fflush(stdout); */ } } } /* copy right hand side `b' */ b_input = (mxArray *) prhs [3] ; /* get size of input matrix A */ rhs=(doublecomplex*) MAlloc((size_t)A.nr*sizeof(doublecomplex),"ZGNLHPDilupacksolver:rhs"); pr=mxGetPr(b_input); if (!mxIsComplex(b_input)) { for (i=0; i<A.nr; i++) { rhs[i].r=pr[i]; rhs[i].i=0; } } else { pi=mxGetPi(b_input); for (i=0; i<A.nr; i++) { rhs[i].r=pr[i]; rhs[i].i=pi[i]; } } /* copy initial solution `x0' */ x0_input = (mxArray *) prhs [4] ; /* numerical solution */ sol=(doublecomplex *)MAlloc((size_t)A.nr*sizeof(doublecomplex),"ZGNLHPDilupacksolver:sol"); pr=mxGetPr(x0_input); if (!mxIsComplex(x0_input)) { for (i=0; i<A.nr; i++) { sol[i].r=pr[i]; sol[i].i=0; } } else { pi=mxGetPi(x0_input); for (i=0; i<A.nr; i++) { sol[i].r=pr[i]; sol[i].i=pi[i]; } } ierr=ZGNLHPDAMGsolver(&A, PRE, param, rhs, sol); /* Create a struct matrices for output */ nlhs=2; if (j==-1) plhs[1] = mxCreateStructMatrix((mwSize)1, (mwSize)1, nfields+1, fnames); else plhs[1] = mxCreateStructMatrix((mwSize)1, (mwSize)1, nfields, fnames); if (plhs[1]==NULL) mexErrMsgTxt("Could not create structure mxArray\n"); options_output=plhs[1]; /* export data */ for (ifield = 0; ifield<nfields; ifield++) { tmp = mxGetFieldByNumber(options_input,0,ifield); classIDflags[ifield] = mxGetClassID(tmp); ndim = mxGetNumberOfDimensions(tmp); dims = mxGetDimensions(tmp); /* Create string/numeric array */ if (classIDflags[ifield] == mxCHAR_CLASS) { if (!strcmp("amg",fnames[ifield])) { output_buf = (char *) mxCalloc((size_t)strlen(param->amg)+1, (size_t)sizeof(char)); strcpy(output_buf,param->amg); fout = mxCreateString(output_buf); } else if (!strcmp("presmoother",fnames[ifield])) { output_buf = (char *) mxCalloc((size_t)strlen(param->presmoother)+1, (size_t)sizeof(char)); strcpy(output_buf,param->presmoother); fout = mxCreateString(output_buf); } else if (!strcmp("postsmoother",fnames[ifield])) { output_buf = (char *) mxCalloc((size_t)strlen(param->postsmoother)+1, (size_t)sizeof(char)); strcpy(output_buf,param->postsmoother); fout = mxCreateString(output_buf); } else if (!strcmp("typecoarse",fnames[ifield])) { output_buf = (char *) mxCalloc((size_t)strlen(param->typecoarse)+1, (size_t)sizeof(char)); strcpy(output_buf,param->typecoarse); fout = mxCreateString(output_buf); } else if (!strcmp("typetv",fnames[ifield])) { output_buf = (char *) mxCalloc((size_t)strlen(param->typetv)+1, (size_t)sizeof(char)); strcpy(output_buf,param->typetv); fout = mxCreateString(output_buf); } else if (!strcmp("FCpart",fnames[ifield])) { output_buf = (char *) mxCalloc((size_t)strlen(param->FCpart)+1, (size_t)sizeof(char)); strcpy(output_buf,param->FCpart); fout = mxCreateString(output_buf); } else if (!strcmp("solver",fnames[ifield])) { output_buf = (char *) mxCalloc((size_t)strlen(param->solver)+1, (size_t)sizeof(char)); strcpy(output_buf, param->solver); fout = mxCreateString(output_buf); } else if (!strcmp("ordering",fnames[ifield])) { output_buf = (char *) mxCalloc((size_t)strlen(param->ordering)+1, (size_t)sizeof(char)); strcpy(output_buf, param->ordering); fout = mxCreateString(output_buf); } else { /* Get the length of the input string. */ buflen = (mxGetM(tmp) * mxGetN(tmp)) + 1; /* Allocate memory for input and output strings. */ input_buf = (char *) mxCalloc((size_t)buflen, (size_t)sizeof(char)); output_buf = (char *) mxCalloc((size_t)buflen, (size_t)sizeof(char)); /* Copy the string data from tmp into a C string input_buf. */ status = mxGetString(tmp, input_buf, buflen); sizebuf = (size_t)buflen*sizeof(char); memcpy(output_buf, input_buf, sizebuf); fout = mxCreateString(output_buf); } } else { if (mxGetPi(tmp)==NULL && strcmp("damping",fnames[ifield])) fout = mxCreateNumericArray(ndim, dims, classIDflags[ifield], mxREAL); else { /* complex case */ fout = mxCreateNumericArray(ndim, dims, classIDflags[ifield], mxCOMPLEX); } pdata = mxGetData(fout); sizebuf = mxGetElementSize(tmp); if (!strcmp("elbow",fnames[ifield])) { dbuf=param->elbow; memcpy(pdata, &dbuf, sizebuf); } else if (!strcmp("lfilS",fnames[ifield])) { dbuf=param->lfilS; memcpy(pdata, &dbuf, sizebuf); } else if (!strcmp("lfil",fnames[ifield])) { dbuf=param->lfil; memcpy(pdata, &dbuf, sizebuf); } else if (!strcmp("maxit",fnames[ifield])) { dbuf=param->maxit; memcpy(pdata, &dbuf, sizebuf); } else if (!strcmp("droptolS",fnames[ifield])) { dbuf=param->droptolS; memcpy(pdata, &dbuf, sizebuf); } else if (!strcmp("droptol",fnames[ifield])) { dbuf=param->droptol; memcpy(pdata, &dbuf, sizebuf); } else if (!strcmp("condest",fnames[ifield])) { dbuf=param->condest; memcpy(pdata, &dbuf, sizebuf); } else if (!strcmp("restol",fnames[ifield])) { dbuf=param->restol; memcpy(pdata, &dbuf, sizebuf); } else if (!strcmp("npresmoothing",fnames[ifield])) { dbuf=param->npresmoothing; memcpy(pdata, &dbuf, sizebuf); } else if (!strcmp("npostmoothing",fnames[ifield])) { dbuf=param->npostsmoothing; memcpy(pdata, &dbuf, sizebuf); } else if (!strcmp("ncoarse",fnames[ifield])) { dbuf=param->ncoarse; memcpy(pdata, &dbuf, sizebuf); } else if (!strcmp("matching",fnames[ifield])) { dbuf=param->matching; memcpy(pdata, &dbuf, sizebuf); } else if (!strcmp("nrestart",fnames[ifield])) { dbuf=param->nrestart; memcpy(pdata, &dbuf, sizebuf); } else if (!strcmp("damping",fnames[ifield])) { pr=mxGetPr(fout); pi=mxGetPi(fout); *pr=param->damping.r; *pi=param->damping.i; } else if (!strcmp("mixedprecision",fnames[ifield])) { dbuf=param->mixedprecision; memcpy(pdata, &dbuf, sizebuf); } else { memcpy(pdata, mxGetData(tmp), sizebuf); } } /* Set each field in output structure */ mxSetFieldByNumber(options_output, (mwIndex)0, ifield, fout); } /* store number of iteration steps */ if (j==-1) ifield=nfields; else ifield=j; fout=mxCreateDoubleMatrix((mwSize)1,(mwSize)1, mxREAL); pr=mxGetPr(fout); *pr=param->ipar[26]; /* set each field in output structure */ mxSetFieldByNumber(options_output, (mwIndex)0, ifield, fout); mxFree(fnames); mxFree(classIDflags); /* mexPrintf("options exported\n"); fflush(stdout); */ plhs[0] = mxCreateDoubleMatrix((mwSize)A.nr, (mwSize)1, mxCOMPLEX); x_output=plhs[0]; pr=mxGetPr(x_output); pi=mxGetPi(x_output); for (i=0; i<A.nr; i++) { pr[i]=sol[i].r; pi[i]=sol[i].i; } /* release right hand side */ free(rhs); /* release solution */ free(sol); /* release input matrix */ free(A.ia); free(A.ja); free(A.a); switch (ierr) { case 0: /* perfect! */ break; case -1: /* too many iteration steps */ mexPrintf("!!! ILUPACK Warning !!!\n"); mexPrintf("number of iteration steps exceeded its limit.\nEither increase `options.maxit'\n or recompute ILUPACK preconditioner using a smaller `options.droptol'"); break; case -2: /* weird, should not occur */ mexErrMsgTxt("not enough workspace provided."); plhs[0]=NULL; break; case -3: /* breakdown */ mexErrMsgTxt("iterative solver breaks down.\nMost likely you need to recompute ILUPACK preconditioner using a smaller `options.droptol'"); plhs[0]=NULL; break; default: /* zero pivot encountered at step number ierr */ mexPrintf("iterative solver exited with error code %d",ierr); mexErrMsgTxt("."); plhs[0]=NULL; break; } /* end switch */ return; }
void mexFunction( int nlhs, mxArray *plhs[], int nrhs, const mxArray*prhs[] ) { LSMLIB_REAL *phi_x_plus, *phi_y_plus, *phi_z_plus; LSMLIB_REAL *phi_x_minus, *phi_y_minus, *phi_z_minus; int ilo_grad_phi_gb, ihi_grad_phi_gb; int jlo_grad_phi_gb, jhi_grad_phi_gb; int klo_grad_phi_gb, khi_grad_phi_gb; LSMLIB_REAL *phi; int ilo_phi_gb, ihi_phi_gb, jlo_phi_gb, jhi_phi_gb, klo_phi_gb, khi_phi_gb; LSMLIB_REAL *D1; int ilo_D1_gb, ihi_D1_gb, jlo_D1_gb, jhi_D1_gb, klo_D1_gb, khi_D1_gb; int ilo_fb, ihi_fb, jlo_fb, jhi_fb, klo_fb, khi_fb; double *dX; LSMLIB_REAL dX_meshgrid_order[3]; int ghostcell_width; int num_data_array_dims; const int *data_array_dims_in; int data_array_dims_out[NDIM]; /* Check for proper number of arguments */ if (nrhs != 3) { mexErrMsgTxt("Three required input arguments."); } else if (nlhs > 6) { mexErrMsgTxt("Too many output arguments."); } /* Parameter Checks */ num_data_array_dims = mxGetNumberOfDimensions(PHI); if (num_data_array_dims != 3) { mexErrMsgTxt("phi should be a 3 dimensional array."); } /* Check that the inputs have the correct floating-point precision */ #ifdef LSMLIB_DOUBLE_PRECISION if (!mxIsDouble(PHI)) { mexErrMsgTxt("Incompatible precision: LSMLIB built for double-precision but phi is single-precision"); } #else if (!mxIsSingle(PHI)) { mexErrMsgTxt("Incompatible precision: LSMLIB built for single-precision but phi is double-precision"); } #endif /* Get ghostcell_width */ ghostcell_width = mxGetPr(GHOSTCELL_WIDTH)[0]; /* Get dX */ dX = mxGetPr(DX); /* Change order of dX to be match MATLAB meshgrid() order for grids. */ dX_meshgrid_order[0] = dX[1]; dX_meshgrid_order[1] = dX[0]; dX_meshgrid_order[2] = dX[2]; /* Assign pointers for phi */ phi = (LSMLIB_REAL*) mxGetPr(PHI); /* Get size of phi data */ data_array_dims_in = mxGetDimensions(PHI); ilo_phi_gb = 1; ihi_phi_gb = data_array_dims_in[0]; jlo_phi_gb = 1; jhi_phi_gb = data_array_dims_in[1]; klo_phi_gb = 1; khi_phi_gb = data_array_dims_in[2]; /* Allocate scratch memory for undivided differences */ ilo_D1_gb = ilo_phi_gb; ihi_D1_gb = ihi_phi_gb; jlo_D1_gb = jlo_phi_gb; jhi_D1_gb = jhi_phi_gb; klo_D1_gb = klo_phi_gb; khi_D1_gb = khi_phi_gb; D1 = (LSMLIB_REAL*) mxMalloc( sizeof(LSMLIB_REAL) * (ihi_D1_gb-ilo_D1_gb+1) * (jhi_D1_gb-jlo_D1_gb+1) * (khi_D1_gb-klo_D1_gb+1) ); if (!D1) { if (D1) mxFree(D1); mexErrMsgTxt("Unable to allocate memory for scratch data...aborting...."); } /* Create matrices for plus and minus derivatives */ ilo_grad_phi_gb = ilo_phi_gb; ihi_grad_phi_gb = ihi_phi_gb; jlo_grad_phi_gb = jlo_phi_gb; jhi_grad_phi_gb = jhi_phi_gb; klo_grad_phi_gb = klo_phi_gb; khi_grad_phi_gb = khi_phi_gb; data_array_dims_out[0] = ihi_grad_phi_gb-ilo_grad_phi_gb+1; data_array_dims_out[1] = jhi_grad_phi_gb-jlo_grad_phi_gb+1; data_array_dims_out[2] = khi_grad_phi_gb-klo_grad_phi_gb+1; #ifdef LSMLIB_DOUBLE_PRECISION PHI_X_PLUS = mxCreateNumericArray(NDIM, data_array_dims_out, mxDOUBLE_CLASS, mxREAL); PHI_Y_PLUS = mxCreateNumericArray(NDIM, data_array_dims_out, mxDOUBLE_CLASS, mxREAL); PHI_Z_PLUS = mxCreateNumericArray(NDIM, data_array_dims_out, mxDOUBLE_CLASS, mxREAL); PHI_X_MINUS = mxCreateNumericArray(NDIM, data_array_dims_out, mxDOUBLE_CLASS, mxREAL); PHI_Y_MINUS = mxCreateNumericArray(NDIM, data_array_dims_out, mxDOUBLE_CLASS, mxREAL); PHI_Z_MINUS = mxCreateNumericArray(NDIM, data_array_dims_out, mxDOUBLE_CLASS, mxREAL); #else PHI_X_PLUS = mxCreateNumericArray(NDIM, data_array_dims_out, mxSINGLE_CLASS, mxREAL); PHI_Y_PLUS = mxCreateNumericArray(NDIM, data_array_dims_out, mxSINGLE_CLASS, mxREAL); PHI_Z_PLUS = mxCreateNumericArray(NDIM, data_array_dims_out, mxSINGLE_CLASS, mxREAL); PHI_X_MINUS = mxCreateNumericArray(NDIM, data_array_dims_out, mxSINGLE_CLASS, mxREAL); PHI_Y_MINUS = mxCreateNumericArray(NDIM, data_array_dims_out, mxSINGLE_CLASS, mxREAL); PHI_Z_MINUS = mxCreateNumericArray(NDIM, data_array_dims_out, mxSINGLE_CLASS, mxREAL); #endif phi_x_plus = (LSMLIB_REAL*) mxGetPr(PHI_X_PLUS); phi_y_plus = (LSMLIB_REAL*) mxGetPr(PHI_Y_PLUS); phi_z_plus = (LSMLIB_REAL*) mxGetPr(PHI_Z_PLUS); phi_x_minus = (LSMLIB_REAL*) mxGetPr(PHI_X_MINUS); phi_y_minus = (LSMLIB_REAL*) mxGetPr(PHI_Y_MINUS); phi_z_minus = (LSMLIB_REAL*) mxGetPr(PHI_Z_MINUS); /* Do the actual computations in a Fortran 77 subroutine */ ilo_fb = ilo_phi_gb+ghostcell_width; ihi_fb = ihi_phi_gb-ghostcell_width; jlo_fb = jlo_phi_gb+ghostcell_width; jhi_fb = jhi_phi_gb-ghostcell_width; klo_fb = klo_phi_gb+ghostcell_width; khi_fb = khi_phi_gb-ghostcell_width; /* * NOTE: ordering of data arrays from meshgrid() is (y,x,z), so * order derivative data arrays need to be permuted. */ LSM3D_HJ_ENO1( phi_y_plus, phi_x_plus, phi_z_plus, &ilo_grad_phi_gb, &ihi_grad_phi_gb, &jlo_grad_phi_gb, &jhi_grad_phi_gb, &klo_grad_phi_gb, &khi_grad_phi_gb, phi_y_minus, phi_x_minus, phi_z_minus, &ilo_grad_phi_gb, &ihi_grad_phi_gb, &jlo_grad_phi_gb, &jhi_grad_phi_gb, &klo_grad_phi_gb, &khi_grad_phi_gb, phi, &ilo_phi_gb, &ihi_phi_gb, &jlo_phi_gb, &jhi_phi_gb, &klo_phi_gb, &khi_phi_gb, D1, &ilo_D1_gb, &ihi_D1_gb, &jlo_D1_gb, &jhi_D1_gb, &klo_D1_gb, &khi_D1_gb, &ilo_fb, &ihi_fb, &jlo_fb, &jhi_fb, &klo_fb, &khi_fb, &dX_meshgrid_order[0], &dX_meshgrid_order[1], &dX_meshgrid_order[2]); /* Deallocate scratch memory for undivided differences */ mxFree(D1); return; }
Image Matlab2ViLi(const mxArray *In) { Image Res; int Type; int i, j, k; if (mxIsUint8(In)) { Type = IM_BYTE; } else if (mxIsInt16(In)) { Type = IM_SHORT; } else if (mxIsUint32(In)) { Type = IM_LONG; } else if (mxIsDouble(In)||mxIsSingle(In)) { if (mxIsComplex(In)) { Type = IM_COMPLEX; } else { Type = IM_FLOAT; } } else { mexErrMsgTxt("Array type not supported"); } if (mxGetNumberOfDimensions(In) == 2) { Res = NewImage("from MATLAB", Type, mxGetDimensions(In)[1], mxGetDimensions(In)[0], 1, 1, GRID_RECT); } else if ( (mxGetNumberOfDimensions(In) == 3) && (mxGetDimensions(In)[2] == 3)) { Res = NewImage("from MATLAB", Type, mxGetDimensions(In)[1], mxGetDimensions(In)[0], 1, mxGetDimensions(In)[2], GRID_RECT); } else if ( (mxGetNumberOfDimensions(In) == 3) && (mxGetDimensions(In)[2] != 3)) { Res = NewImage("from MATLAB", Type, mxGetDimensions(In)[1], mxGetDimensions(In)[0], mxGetDimensions(In)[2], 1, GRID_RECT); } else if (mxGetNumberOfDimensions(In) == 4) { Res = NewImage("from MATLAB", Type, mxGetDimensions(In)[1], mxGetDimensions(In)[0], mxGetDimensions(In)[2], mxGetDimensions(In)[3], GRID_RECT); } else { mexErrMsgTxt("Dimensions not supported"); } switch(Type) { case IM_BYTE: { unsigned char *pIn, *pRes; pRes = (unsigned char *) Res->Data; pIn = (unsigned char *) mxGetData(In); /* Copia transponiendo filas y columnas */ for (k=0; k<Res->NPlanes * Res->NChannels; k++) { for (j=0; j<Res->NCol; j++) { for (i=0; i<Res->NLin; i++) { pRes[ j + i * Res->NCol + k * Res->NCol * Res->NLin] = pIn[ i + j * Res->NLin + k * Res->NCol * Res->NLin]; } } } } break; case IM_SHORT: { short *pIn, *pRes; pRes = (short *) Res->Data; pIn = (short *) mxGetData(In); /* Copia transponiendo filas y columnas */ for (k=0; k<Res->NPlanes * Res->NChannels; k++) { for (j=0; j<Res->NCol; j++) { for (i=0; i<Res->NLin; i++) { pRes[ j + i * Res->NCol + k * Res->NCol * Res->NLin] = pIn[ i + j * Res->NLin + k * Res->NCol * Res->NLin]; } } } } break; case IM_LONG: { unsigned long *pIn, *pRes; pRes = (unsigned long *) Res->Data; pIn = (unsigned long *) mxGetData(In); /* Copia transponiendo filas y columnas */ for (k=0; k<Res->NPlanes * Res->NChannels; k++) { for (j=0; j<Res->NCol; j++) { for (i=0; i<Res->NLin; i++) { pRes[ j + i * Res->NCol + k * Res->NCol * Res->NLin] = pIn[ i + j * Res->NLin + k * Res->NCol * Res->NLin]; } } } } break; case IM_FLOAT: { float *pRes; pRes = (float *) Res->Data; if (mxIsSingle(In)){ float *pIn; pIn = (float *) mxGetData(In); /* Copia transponiendo filas y columnas */ for (k=0; k<Res->NPlanes * Res->NChannels; k++) { for (j=0; j<Res->NCol; j++) { for (i=0; i<Res->NLin; i++) { pRes[ j + i * Res->NCol + k * Res->NCol * Res->NLin] = (float) pIn[ i + j * Res->NLin + k * Res->NCol * Res->NLin]; } } } } else { double *pIn; pIn = (double *) mxGetData(In); /* Copia transponiendo filas y columnas */ for (k=0; k<Res->NPlanes * Res->NChannels; k++) { for (j=0; j<Res->NCol; j++) { for (i=0; i<Res->NLin; i++) { pRes[ j + i * Res->NCol + k * Res->NCol * Res->NLin] = (float) pIn[ i + j * Res->NLin + k * Res->NCol * Res->NLin]; } } } } } break; case IM_COMPLEX: { Complex *pRes; pRes = (Complex *) Res->Data; if (mxIsSingle(In)){ float *pInR, *pInI; pInR = mxGetPr(In); pInI = mxGetPi(In); /* Copia transponiendo filas y columnas */ for (k=0; k<Res->NPlanes * Res->NChannels; k++) { for (j=0; j<Res->NCol; j++) { for (i=0; i<Res->NLin; i++) { pRes[ j + i * Res->NCol + k * Res->NCol * Res->NLin].Re = (float) pInR[ i + j * Res->NLin + k * Res->NCol * Res->NLin]; pRes[ j + i * Res->NCol + k * Res->NCol * Res->NLin].Im = (float) pInI[ i + j * Res->NLin + k * Res->NCol * Res->NLin]; } } } } else { double *pInR, *pInI; pInR = mxGetPr(In); pInI = mxGetPi(In); /* Copia transponiendo filas y columnas */ for (k=0; k<Res->NPlanes * Res->NChannels; k++) { for (j=0; j<Res->NCol; j++) { for (i=0; i<Res->NLin; i++) { pRes[ j + i * Res->NCol + k * Res->NCol * Res->NLin].Re = (float) pInR[ i + j * Res->NLin + k * Res->NCol * Res->NLin]; pRes[ j + i * Res->NCol + k * Res->NCol * Res->NLin].Im = (float) pInI[ i + j * Res->NLin + k * Res->NCol * Res->NLin]; } } } } } break; } return Res; }
void mexFunction( int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[] ) { /* Requires 5 arguments in this order: 1. Cell array of hierarhcially coarsened density 2. Cell array of hierarchially coarsened mass centers 3. Realspace locations to sum at (9x1 vector) 4. Coarsening algorithm's constant %% NOT ANYMORE 5. Mean cell distance from center (1/8 length of line to opposite corners of cell) */ /* Check for proper number of arguments. */ if(nrhs!=4) { mexErrMsgTxt("four inputs required."); } else if(nlhs>1) { mexErrMsgTxt("One return value required."); } /* Get number of argument and allocate memory */ int nLevels = mxGetNumberOfElements(prhs[0]); int *arraydims = malloc(3*nLevels * sizeof(int)); double **rhoptr = malloc(nLevels * sizeof(double*)); double **posptr = malloc(nLevels * sizeof(double*)); rconst = *mxGetPr(prhs[3]); int j; /* Build arrays of the size of every level and *s to them */ for(j = 0; j < nLevels; j++) { mxArray *rhos = mxGetCell(prhs[0], j); mxArray *poss = mxGetCell(prhs[1], j); mwSize d = mxGetNumberOfDimensions(rhos); mwSize *s = mxGetDimensions(rhos); if(d == 2) { /* 2-D */ arraydims[3*j] = (int)s[0]; arraydims[3*j+1]=(int)s[1]; arraydims[3*j+2]= 1; } else { /* 3-D, it better not be higher-dimensional */ arraydims[3*j] = (int)s[0]; arraydims[3*j+1]=(int)s[1]; arraydims[3*j+2]=(int)s[2]; } rhoptr[j] = mxGetPr(rhos); posptr[j] = mxGetPr(poss); } /*double *cmr = mxGetPr(prhs[4]); */ /* At some point this will get broken up into a parallel operation, then a CUDA operation. */ int sumvol[6] = {0, 0, 0, arraydims[0], arraydims[1], arraydims[2]}; /* 9x1 - [ [startxyz] [endxyz] [npointsxyz] ] */ double *vin = mxGetPr(prhs[2]); double r0[3] = {vin[0], vin[1], vin[2]}; double dr[3] = { (vin[3]-vin[0])/vin[6], (vin[4]-vin[1])/vin[7], (vin[5]-vin[2])/vin[8] }; for(j = 0; j < 3; j++) if(vin[6+j] == 0) dr[j] = 0; /* Prevent divide by zero */ int ctx, cty, ctz; int maxid[3] = { (int)vin[6]+1, (int)vin[7]+1, (int)vin[8]+1 }; mwSize retdims[3] = { maxid[0], maxid[1], maxid[2] }; plhs[0] = mxCreateNumericArray(3, retdims, mxDOUBLE_CLASS, mxREAL); double *phi = mxGetPr(plhs[0]); double rp[3]; lvlMax = nLevels; for(ctx = 0; ctx < maxid[0]; ctx++) for(cty = 0; cty < maxid[1]; cty++) for(ctz = 0; ctz < maxid[2]; ctz++) { rp[0] = r0[0] + ctx*dr[0]; rp[1] = r0[1] + cty*dr[1]; rp[2] = r0[2] + ctz*dr[2]; phi[ctx + maxid[0]*cty + maxid[0]*maxid[1]*ctz] = sumLevel(rhoptr, posptr, rp, 0, arraydims, sumvol); } free(arraydims); free(rhoptr); free(posptr); return; }
// Main function =============================================================== void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) { double *a, *b, *Z, *X, *Y, a0; float *Xf, *Yf; mwSize na, nb, order, nParam, MX, NX, Xndims, Zdims[MAX_NDIMS]; bool allocate_ba = false, allocate_Z = false, forward = true, hasZInput; char Rev[2]; const mwSize *Xdims; // Check number of inputs and outputs: if (nrhs < 3 || nrhs > 5) { mexErrMsgIdAndTxt(ERR_ID "BadNInput", ERR_HEAD "3 to 5 inputs required."); } if (nlhs > 2) { mexErrMsgIdAndTxt(ERR_ID "BadNOutput", ERR_HEAD "2 outputs allowed."); } // Check type of inputs: if (!mxIsDouble(b_in) || !mxIsDouble(a_in)) { mexErrMsgIdAndTxt(ERR_ID "BadTypeInput1_2", ERR_HEAD "Filter parameters must be DOUBLES."); } // Get dimensions of inputs: nb = mxGetNumberOfElements(b_in); na = mxGetNumberOfElements(a_in); MX = mxGetM(X_in); // First dimension NX = mxGetN(X_in); // Product of trailing dimensions // Reply empty array if the parameters or the signal is empty: if (na * nb * MX * NX == 0) { plhs[0] = mxCreateDoubleMatrix(0, 0, mxREAL); if (nrhs == 2) { plhs[1] = mxCreateDoubleMatrix(0, 0, mxREAL); } return; } // Get a and b as vectors of the same length: if (na == nb) { // Use input vectors directly, if possible: b = mxGetPr(b_in); a = mxGetPr(a_in); nParam = nb; allocate_ba = (bool) (a[0] != 1.0); // Normalization is needed } else { // na differs from nb: nParam = na > nb ? na : nb; allocate_ba = true; } order = nParam - 1; if (allocate_ba) { // Create local copy of expanded [b] and [a]: // It is slightly cheaper to allocate one array only: if ((b = mxCalloc(2 * nParam, sizeof(double))) == NULL) { mexErrMsgIdAndTxt(ERR_ID "NoMemory", ERR_HEAD "Cannot get memory for parameters."); } a = b + nParam; // Use 2nd half of vector [b] as [a] memcpy(b, mxGetPr(b_in), nb * sizeof(double)); memcpy(a, mxGetPr(a_in), na * sizeof(double)); // Normalize if 1st element of [a] does not equal 1.0: if (a[0] != 1.0) { NormalizeBA(b, nParam); } } // Create array for final conditions, insert value of initial conditions: Xndims = mxGetNumberOfDimensions(X_in); Xdims = mxGetDimensions(X_in); if (Xndims > MAX_NDIMS) { mexErrMsgIdAndTxt(ERR_ID "BadSizeSignal", ERR_HEAD "Signal cannot have more than %d dimensions.", MAX_NDIMS); } // Z has dimensions [order, DIMS(X, 2:end)]: memcpy(Zdims, Xdims, Xndims * sizeof(mwSize)); Zdims[0] = order; // 4th input is existing and not empty: hasZInput = false; if (nrhs >= 4) { hasZInput = (bool) (!mxIsEmpty(Z_in)); } if (hasZInput) { // Initial conditions provided as input: // Check dimensions of Z: if (mxGetM(Z_in) != order || mxGetN(Z_in) != NX) { mexErrMsgIdAndTxt(ERR_ID "BadSizeZ", ERR_HEAD "Dimensions of initial conditions do not match the signal."); } if (nlhs == 2) { // Final conditions wanted: Z_out = mxCreateNumericArray(Xndims, Zdims, mxDOUBLE_CLASS, mxREAL); Z = mxGetPr(Z_out); } else { // Final conditions not caught in the caller: allocate_Z = true; if ((Z = mxCalloc(order * NX, sizeof(double))) == NULL) { mexErrMsgIdAndTxt(ERR_ID "NoMemory", ERR_HEAD "No memory for initial conditions."); } } // Copy value from input with a conversion to DOUBLE on demand: if (mxIsDouble(Z_in)) { memcpy(Z, mxGetPr(Z_in), order * NX * sizeof(double)); } else if (mxIsSingle(Z_in)) { CopySingleToDouble(Z, (float *) mxGetData(Z_in), order * NX); } else { mexErrMsgIdAndTxt(ERR_ID "BadTypeInput4", ERR_HEAD "Initial conditions must be a DOUBLE or SINGLE array."); } } else { // Initial conditions not provided: if (nlhs == 2) { // Final conditions wanted: Z_out = mxCreateNumericArray(Xndims, Zdims, mxDOUBLE_CLASS, mxREAL); Z = mxGetPr(Z_out); } else { // Cheaper to to use malloc than creating a Matlab array: allocate_Z = true; if ((Z = mxCalloc(order * NX, sizeof(double))) == NULL) { mexErrMsgIdAndTxt(ERR_ID "NoMemory", ERR_HEAD "No memory for initial conditions."); } } } // Flag for forward processing: ---------------------------------------------- // 'Reverse', 1, TRUE: Process signal in reverse order: if (nrhs == 5) { if (!mxIsEmpty(Rev_in)) { if (mxIsChar(Rev_in)) { mxGetString(Rev_in, Rev, 2); forward = (bool) ((*Rev != 'r') && (*Rev != 'R')); } else if (mxIsLogical(Rev_in)) { forward = (bool) (mxGetScalar(Rev_in) == 0); } } else { // Most likely the user tries to define the dimension as in FILTER: mexErrMsgIdAndTxt(ERR_ID "BadTypeInput5", ERR_HEAD "Reverse flag must be a string or LOGICAL."); } } // Call the calulator: ------------------------------------------------------- if (mxIsDouble(X_in)) { // Create the output array: Y_out = mxCreateNumericArray(Xndims, Xdims, mxDOUBLE_CLASS, mxREAL); Y = mxGetPr(Y_out); X = mxGetPr(X_in); if (forward) { # if defined(__BORLAND__) // BCC 5.5 runs the unrolled loops with the half speed! CoreDoubleN(X, MX, NX, a, b, order, Z, Y); # else // Unrolled loops for common filter lengths: switch (order) { case 1: CoreDouble2(X, MX, NX, a, b, Z, Y); break; case 2: CoreDouble3(X, MX, NX, a, b, Z, Y); break; case 3: CoreDouble4(X, MX, NX, a, b, Z, Y); break; case 4: CoreDouble5(X, MX, NX, a, b, Z, Y); break; case 5: CoreDouble6(X, MX, NX, a, b, Z, Y); break; case 6: CoreDouble7(X, MX, NX, a, b, Z, Y); break; default: CoreDoubleN(X, MX, NX, a, b, order, Z, Y); } # endif } else { // Reverse order: CoreDoubleNR(X, MX, NX, a, b, order, Z, Y); } } else if (mxIsSingle(X_in)) { // Create the output array: Y_out = mxCreateNumericArray(Xndims, Xdims, mxSINGLE_CLASS, mxREAL); Yf = (float *) mxGetData(Y_out); Xf = (float *) mxGetData(X_in); if (forward) { # if defined(__BORLAND__) // BCC 5.5 runs the unrolled loops with the half speed! CoreSingleN(X, MX, NX, a, b, order, Z, Y); # else // Unrolled loops for common filter lengths: switch (order) { case 1: CoreSingle2(Xf, MX, NX, a, b, Z, Yf); break; case 2: CoreSingle3(Xf, MX, NX, a, b, Z, Yf); break; case 3: CoreSingle4(Xf, MX, NX, a, b, Z, Yf); break; case 4: CoreSingle5(Xf, MX, NX, a, b, Z, Yf); break; case 5: CoreSingle6(Xf, MX, NX, a, b, Z, Yf); break; case 6: CoreSingle7(Xf, MX, NX, a, b, Z, Yf); break; default: CoreSingleN(Xf, MX, NX, a, b, order, Z, Yf); } # endif } else { // Reverse order: CoreSingleNR(Xf, MX, NX, a, b, order, Z, Yf); } } else { // Signal is neither a DOUBLE nor a SINGLE: mexErrMsgIdAndTxt(ERR_ID "BadTypeInput3", ERR_HEAD "Signal must be a DOUBLE or SINGLE array."); } // Cleanup: if (allocate_Z) { mxFree(Z); } if (allocate_ba) { mxFree(b); // Frees [a] implicitely! } return; }
void mexFunction ( int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[] ) { Response *response; double *real_ptr, *imag_ptr; double *omega_ptr; int M, N; int nelements; int rc; int i; if( nlhs > 1 ) { antelope_mexUsageMsgTxt ( USAGE ); return; } if( nrhs != 2 ) { antelope_mexUsageMsgTxt ( USAGE ); return; } else if( ! mtlb_get_response( prhs[0], &response ) ) { antelope_mexUsageMsgTxt ( USAGE ); return; } else if( mxGetClassID( prhs[1] ) != mxDOUBLE_CLASS ) { antelope_mexUsageMsgTxt ( USAGE ); return; } else if( mxGetNumberOfDimensions( prhs[1] ) != 2 ) { antelope_mexUsageMsgTxt ( USAGE ); return; } M = mxGetM( prhs[1] ); N = mxGetN( prhs[1] ); plhs[0] = mxCreateDoubleMatrix( M, N, mxCOMPLEX ); nelements = M * N; omega_ptr = (double *) mxGetPr( prhs[1] ); real_ptr = (double *) mxGetPr( plhs[0] ); imag_ptr = (double *) mxGetPi( plhs[0] ); for( i = 0; i < nelements; i++ ) { rc = eval_response( *omega_ptr++, response, real_ptr++, imag_ptr++ ); if( rc ) { mxDestroyArray( plhs[0] ); antelope_mex_clear_register( 1 ); mexErrMsgTxt( "eval_response failed" ); } } }
void mexFunction(int nlhs, /* No. of output arguments */ mxArray *plhs[], /* Output arguments. */ int nrhs, /* No. of input arguments. */ const mxArray *prhs[]) /* Input arguments. */ { int i=0; int ndim=0, lima_ndim=0; int nc=0, nr=0, ni=0; const int *cdim=NULL, *lima_cdim=NULL; unsigned int dim[3]; int *nn=NULL; int *rs=NULL; int *rw=NULL; int *lima=NULL; double *pp=NULL; double *pm=NULL; double *d_tmp=NULL; double *opm=NULL; if (nrhs == 0) mexErrMsgTxt("usage: pm = pm_merge_regions(pm,lima,i,j,n,p,rs)"); if (nrhs != 7) mexErrMsgTxt("pm_merge_regions: 7 input arguments required"); /* if (nlhs != 1) mexErrMsgTxt("pm_merge_regions: 1 output argument required"); */ /* Get phase map. */ if (!mxIsNumeric(prhs[0]) || mxIsComplex(prhs[0]) || mxIsSparse(prhs[0]) || !mxIsDouble(prhs[0])) { mexErrMsgTxt("pm_merge_regions: pm must be numeric, real, full and double"); } ndim = mxGetNumberOfDimensions(prhs[0]); if ((ndim < 2) | (ndim > 3)) { mexErrMsgTxt("pm_merge_regions: pm must be 2 or 3-dimensional"); } cdim = mxGetDimensions(prhs[0]); pm = mxGetPr(prhs[0]); /* Get image of labels. */ if (!mxIsNumeric(prhs[1]) || mxIsComplex(prhs[1]) || mxIsSparse(prhs[1]) || !mxIsDouble(prhs[1])) { mexErrMsgTxt("pm_merge_regions: lima must be numeric, real, full and double"); } lima_ndim = mxGetNumberOfDimensions(prhs[1]); if (lima_ndim != ndim) { mexErrMsgTxt("pm_merge_regions: pm and lima must have same dimensionality"); } lima_cdim = mxGetDimensions(prhs[1]); for (i=0; i<ndim; i++) { if (cdim[i] != lima_cdim[i]) { mexErrMsgTxt("pm_merge_regions: pm and lima must have same size"); } } d_tmp = mxGetPr(prhs[1]); /* Fix dimensions to allow for 2D and 3D data. */ dim[0]=cdim[0]; dim[1]=cdim[1]; if (ndim==2) {dim[2]=1; ndim=3;} else {dim[2]=cdim[2];} for (i=0, ni=1; i<ndim; i++) { ni *= dim[i]; } /* Convert double representation of lima into int's. */ lima = (int *) mxCalloc(ni,sizeof(int)); for (i=0; i<ni; i++) {lima[i] = ((int) (d_tmp[i]+0.1));} /* Get vector of row indicies into connectogram matrix */ if (!mxIsNumeric(prhs[2]) || mxIsComplex(prhs[2]) || mxIsSparse(prhs[2]) || !mxIsDouble(prhs[2])) { mexErrMsgTxt("pm_merge_regions: i must be numeric, real, full and double"); } nc = mxGetM(prhs[2]); d_tmp = mxGetPr(prhs[2]); if (mxGetN(prhs[2]) != 1) { mexErrMsgTxt("pm_merge_regions: i must be a column matrix"); } ii = (int *) mxCalloc(nc,sizeof(int)); for (i=0; i<nc; i++) {ii[i] = ((int) (d_tmp[i]+0.1));} /* Get vector of column indicies into connectogram matrix */ if (!mxIsNumeric(prhs[3]) || mxIsComplex(prhs[3]) || mxIsSparse(prhs[3]) || !mxIsDouble(prhs[3])) { mexErrMsgTxt("pm_merge_regions: j must be numeric, real, full and double"); } if (mxGetM(prhs[3]) != nc || mxGetN(prhs[3]) != 1) { mexErrMsgTxt("pm_merge_regions: j must be a column matrix of same size as i"); } d_tmp = mxGetPr(prhs[3]); jj = (int *) mxCalloc(nc,sizeof(int)); for (i=0; i<nc; i++) {jj[i] = ((int) (d_tmp[i]+0.1));} /* Get entrys for first connectogram matrix (containing border sizes). */ if (!mxIsNumeric(prhs[4]) || mxIsComplex(prhs[4]) || mxIsSparse(prhs[4]) || !mxIsDouble(prhs[4])) { mexErrMsgTxt("pm_merge_regions: n must be numeric, real, full and double"); } if (mxGetM(prhs[4]) != nc || mxGetN(prhs[4]) != 1) { mexErrMsgTxt("pm_merge_regions: n must be a column matrix of same size as i"); } d_tmp = mxGetPr(prhs[4]); nn = (int *) mxCalloc(nc,sizeof(int)); for (i=0; i<nc; i++) {nn[i] = ((int) (d_tmp[i]+0.1));} /* Get entrys for second connectogram matrix (containing phase differences along borders). */ if (!mxIsNumeric(prhs[5]) || mxIsComplex(prhs[5]) || mxIsSparse(prhs[5]) || !mxIsDouble(prhs[5])) { mexErrMsgTxt("pm_merge_regions: p must be numeric, real, full and double"); } if (mxGetM(prhs[5]) != nc || mxGetN(prhs[5]) != 1) { mexErrMsgTxt("pm_merge_regions: p must be a column matrix of same size as i"); } d_tmp = mxGetPr(prhs[5]); pp = (double *) mxCalloc(nc,sizeof(double)); /* Use local copy to avoid side effects. */ memcpy(pp,d_tmp,nc*sizeof(double)); /* Get vector of region sizes (in voxels) */ if (!mxIsNumeric(prhs[6]) || mxIsComplex(prhs[6]) || mxIsSparse(prhs[6]) || !mxIsDouble(prhs[6])) { mexErrMsgTxt("pm_merge_regions: rs must be numeric, real, full and double"); } nr = mxGetM(prhs[6]); d_tmp = mxGetPr(prhs[6]); if (mxGetN(prhs[6]) != 1) { mexErrMsgTxt("pm_merge_regions: rs must be a column matrix"); } rs = (int *) mxCalloc(nr,sizeof(int)); for (i=0; i<nr; i++) {rs[i] = ((int) (d_tmp[i]+0.1));} /* Allocate mem for unwrapped output phasemap. */ plhs[0] = mxCreateNumericArray(mxGetNumberOfDimensions(prhs[0]), mxGetDimensions(prhs[0]),mxDOUBLE_CLASS,mxREAL); opm = mxGetPr(plhs[0]); rw = (int *) mxCalloc(nr,sizeof(int)); merge_regions(nn,pp,nc,rs,nr,rw); for (i=0; i<ni; i++) { if (lima[i]) {opm[i] = pm[i] + 2.0*PI*rw[lima[i]-1];} else {opm[i] = pm[i];} } mxFree(lima); mxFree(ii); mxFree(jj); mxFree(nn); mxFree(pp); mxFree(rs); return; }
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) { const mwSize* dims; char* CtC_err, *Ctd_err; nargout = nlhs; mxAssert(nrhs==4,"Expects four input arguments.\n"); mxAssert(mxIsDouble(prhs[0]), "CtC_all must be a double array.\n"); CtC_err = "CtC must be num_bases x num_bases x patch_M x patch_N.\n"; CtC_all = prhs[0]; dims = mxGetDimensions(CtC_all); num_bases = inv_tri(dims[0]); patch_M = 2*(dims[1]-1); if (mxGetNumberOfDimensions(CtC_all)==3){ patch_N = dims[2]; } else { patch_N = 1; } CtC_allr = mxGetPr(CtC_all); if (mxIsComplex(CtC_all)){ CtC_alli = mxGetPi(CtC_all); } mxAssert(mxIsDouble(prhs[1]), "Ctd must be a double array.\n"); Ctd_err = "Ctd must be num_bases x num_channels x patch_M x patch_N.\n"; Ctd_all = prhs[1]; dims = mxGetDimensions(Ctd_all); mxAssert(dims[0] == num_bases, Ctd_err); num_channels = dims[1]; mxAssert(dims[2] == patch_M/2+1, Ctd_err); if (mxGetNumberOfDimensions(Ctd_all)==4){ mxAssert(dims[3] == patch_N, Ctd_err); } else { mxAssert(1 == patch_N, Ctd_err); } Ctd_allr = mxGetPr(Ctd_all); if (mxIsComplex(Ctd_all)){ Ctd_alli = mxGetPi(Ctd_all); } mxAssert(mxIsDouble(prhs[2]), "lambda must be a double array.\n"); mxAssert(mxGetM(prhs[2])==num_bases && mxGetN(prhs[2])==1,"lambda must be num_bases x 1.\n"); lambda = mxGetPr(prhs[2]); c = mxGetScalar(prhs[3]); plhs[0] = mxCreateDoubleScalar(0); obj = mxGetPr(plhs[0]); if (nargout >= 2){ plhs[1] = mxCreateDoubleMatrix(num_bases,1,mxREAL); grad = mxGetPr(plhs[1]); } if (nargout >= 3){ plhs[2] = mxCreateDoubleMatrix(num_bases,num_bases,mxREAL); hessian = mxGetPr(plhs[2]); } get_objective(); }
//================================================================================= // mexFunction // // Main entry function // // Takes as input // - an image stack (color or grayscale) and // - the number of supervoxels requried // // Generates output: // - supervoxel label volume (same indexing order as input stack) // - number of generated supervoxels (which could differ from the input number) //================================================================================= void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) { if (nrhs < 1) { mexErrMsgTxt("At least one argument is required.") ; } else if(nrhs > 3) { mexErrMsgTxt("Too many input arguments."); } if(nlhs!=2) { mexErrMsgIdAndTxt("SLIC:nlhs","Two outputs required, a labels and the number of labels, i.e supervoxels."); } //--------------------------- // Variable declarations //--------------------------- int numReqdSupervoxels = 200;//default value double compactness = 10;//default value int width; int height; int depth; int colors; int sz2; int sz3; int sz4; int i, ii; int x, y, z; unsigned char* rin; unsigned char* gin; unsigned char* bin; int* klabels; int* clabels; double* lvec; double* avec; double* bvec; int step; int* seedIndices; int numseeds; double* kseedsx;double* kseedsy;double* kseedsz; double* kseedsl;double* kseedsa;double* kseedsb; int k; const mwSize* dims;//int* dims; int* outputNumSuperpixels; int* outlabels; int finalNumberOfLabels; unsigned char* imgbytes; int testcount; //--------------------------- size_t numelements = mxGetNumberOfElements(prhs[0]) ;// returns number of bytes mwSize numdims = mxGetNumberOfDimensions(prhs[0]) ; dims = mxGetDimensions(prhs[0]) ; imgbytes = (unsigned char*)mxGetData(prhs[0]) ;//mxGetData returns a void pointer, so cast it if(3 == numdims) { depth = dims[2]; width = dims[1]; height = dims[0]; } else if(4 == numdims) { depth = dims[3]; colors = dims[2]; width = dims[1]; height = dims[0]; } else return; sz2 = width*height; sz3 = width*height*depth; sz4 = width*height*depth*colors; //--------------------------- numReqdSupervoxels = mxGetScalar(prhs[1]); compactness = mxGetScalar(prhs[2]); //--------------------------- // Allocate memory //--------------------------- rin = mxMalloc( sizeof(unsigned char) * sz3 ) ; gin = mxMalloc( sizeof(unsigned char) * sz3 ) ; bin = mxMalloc( sizeof(unsigned char) * sz3 ) ; lvec = mxMalloc( sizeof(double) * sz3 ) ; avec = mxMalloc( sizeof(double) * sz3 ) ; bvec = mxMalloc( sizeof(double) * sz3 ) ; klabels = mxMalloc( sizeof(int) * sz3 );//original k-means labels clabels = mxMalloc( sizeof(int) * sz3 );//corrected labels after enforcing connectivity seedIndices = mxMalloc( sizeof(int) * sz3 ); //--------------------------- // Perform color conversion //--------------------------- //if(2 == numdims) if(numelements/sz3 == 1)//if it is a grayscale image, copy the values directly into the lab vectors { for(z = 0, ii = 0; z < depth; z++) { for(x = 0; x < width; x++)//reading data from column-major MATLAB matrics to row-major C matrices (i.e perform transpose) { for(y = 0; y < height; y++) { i = z*sz2 + y*width+x; lvec[i] = avec[i] = bvec[i] = imgbytes[ii]; ii++; } } } } else//else covert from rgb to lab { for(z = 0; z < depth; z++) { ii = z*sz2*3; for(x = 0; x < width; x++)//reading data from column-major MATLAB matrics to row-major C matrices (i.e perform transpose) { for(y = 0; y < height; y++) { i = z*sz2 + y*width + x; rin[i] = imgbytes[ii]; gin[i] = imgbytes[ii+sz2]; bin[i] = imgbytes[ii+sz2+sz2]; ii++; } } } rgbtolab(rin,gin,bin,sz3,lvec,avec,bvec); } //--------------------------- // Find seeds //--------------------------- step = pow((double)(sz3)/(double)(numReqdSupervoxels), 1.0/3.0) + 0.5;//step size is the cube-root of the average area of a supervoxel getLABXYZSeeds(width,height,depth,numReqdSupervoxels,step,seedIndices,&numseeds); kseedsx = mxMalloc( sizeof(double) * numseeds ) ; kseedsy = mxMalloc( sizeof(double) * numseeds ) ; kseedsz = mxMalloc( sizeof(double) * numseeds ) ; kseedsl = mxMalloc( sizeof(double) * numseeds ) ; kseedsa = mxMalloc( sizeof(double) * numseeds ) ; kseedsb = mxMalloc( sizeof(double) * numseeds ) ; testcount = 0; for(k = 0; k < numseeds; k++) { if(seedIndices[k] >= 0) { kseedsz[k] = (int)(seedIndices[k]/sz2); kseedsy[k] = (int)((seedIndices[k]-kseedsz[k]*sz2)/width); kseedsx[k] = (int)(seedIndices[k]-kseedsz[k]*sz2)%width; //kseedsx[k] = (int)(seedIndices[k]-kseedsz[k]*sz2-kseedsy[k]*width); kseedsl[k] = lvec[seedIndices[k]]; kseedsa[k] = avec[seedIndices[k]]; kseedsb[k] = bvec[seedIndices[k]]; testcount++; } } //--------------------------- // Compute superpixels //--------------------------- PerformSupervoxelSLIC(lvec, avec, bvec, kseedsl,kseedsa,kseedsb,kseedsx,kseedsy,kseedsz,width,height,depth,numseeds,klabels,step,compactness); //--------------------------- // Enforce connectivity //--------------------------- EnforceSupervoxelConnectivity(klabels,width,height,depth,numReqdSupervoxels,clabels,&finalNumberOfLabels); //--------------------------- // Assign output labels //--------------------------- //plhs[0] = mxCreateNumericMatrix(height,width,mxINT32_CLASS,mxREAL); mwSize ndims[3]; ndims[0] = height; ndims[1] = width; ndims[2] = depth; plhs[0] = mxCreateNumericArray(3,ndims,mxINT32_CLASS,mxREAL); outlabels = mxGetData(plhs[0]); for(z = 0, ii = 0; z < depth; z++) { for(x = 0; x < width; x++)//copying data from row-major C matrix to column-major MATLAB matrix (i.e. perform transpose) { for(y = 0; y < height; y++) { i = z*sz2 + y*width + x; outlabels[ii] = clabels[i]; ii++; } } } //--------------------------- // Assign number of labels/seeds //--------------------------- plhs[1] = mxCreateNumericMatrix(1,1,mxINT32_CLASS,mxREAL); outputNumSuperpixels = (int*)mxGetData(plhs[1]);//gives a void*, cast it to int* *outputNumSuperpixels = finalNumberOfLabels; //--------------------------- // Deallocate memory //--------------------------- mxFree(kseedsx); mxFree(kseedsy); mxFree(kseedsz); mxFree(kseedsl); mxFree(kseedsa); mxFree(kseedsb); mxFree(rin); mxFree(gin); mxFree(bin); mxFree(lvec); mxFree(avec); mxFree(bvec); mxFree(klabels); mxFree(clabels); mxFree(seedIndices); }
void mexFunction( int nlhs, mxArray *plhs[], int nrhs, const mxArray*prhs[] ) { LSMLIB_REAL *phi_x, *phi_y, *phi_z; int ilo_grad_phi_gb, ihi_grad_phi_gb; int jlo_grad_phi_gb, jhi_grad_phi_gb; int klo_grad_phi_gb, khi_grad_phi_gb; LSMLIB_REAL *phi; int ilo_phi_gb, ihi_phi_gb, jlo_phi_gb, jhi_phi_gb, klo_phi_gb, khi_phi_gb; LSMLIB_REAL *vel_x, *vel_y, *vel_z; int ilo_vel_gb, ihi_vel_gb, jlo_vel_gb, jhi_vel_gb, klo_vel_gb, khi_vel_gb; LSMLIB_REAL *D1; int ilo_D1_gb, ihi_D1_gb, jlo_D1_gb, jhi_D1_gb, klo_D1_gb, khi_D1_gb; int ilo_fb, ihi_fb, jlo_fb, jhi_fb, klo_fb, khi_fb; double *dX; LSMLIB_REAL dX_meshgrid_order[3]; int ghostcell_width; int num_data_array_dims; const int *data_array_dims_in; int data_array_dims_out[NDIM]; /* Check for proper number of arguments */ if (nrhs != 6) { mexErrMsgTxt("Six required input arguments."); } else if (nlhs > 3) { mexErrMsgTxt("Too many output arguments."); } /* Parameter Checks */ num_data_array_dims = mxGetNumberOfDimensions(PHI); if (num_data_array_dims != 3) { mexErrMsgTxt("phi should be a 3 dimensional array."); } num_data_array_dims = mxGetNumberOfDimensions(VEL_X); if (num_data_array_dims != 3) { mexErrMsgTxt("vel_x should be a 3 dimensional array."); } num_data_array_dims = mxGetNumberOfDimensions(VEL_Y); if (num_data_array_dims != 3) { mexErrMsgTxt("vel_y should be a 3 dimensional array."); } num_data_array_dims = mxGetNumberOfDimensions(VEL_Z); if (num_data_array_dims != 3) { mexErrMsgTxt("vel_z should be a 3 dimensional array."); } /* Check that the inputs have the correct floating-point precision */ #ifdef LSMLIB_DOUBLE_PRECISION if (!mxIsDouble(PHI)) { mexErrMsgTxt("Incompatible precision: LSMLIB built for double-precision but phi is single-precision"); } if (!mxIsDouble(VEL_X)) { mexErrMsgTxt("Incompatible precision: LSMLIB built for double-precision but vel_x is single-precision"); } if (!mxIsDouble(VEL_Y)) { mexErrMsgTxt("Incompatible precision: LSMLIB built for double-precision but vel_y is single-precision"); } if (!mxIsDouble(VEL_Z)) { mexErrMsgTxt("Incompatible precision: LSMLIB built for double-precision but vel_z is single-precision"); } #else if (!mxIsSingle(PHI)) { mexErrMsgTxt("Incompatible precision: LSMLIB built for single-precision but phi is double-precision"); } if (!mxIsSingle(VEL_X)) { mexErrMsgTxt("Incompatible precision: LSMLIB built for single-precision but vel_x is double-precision"); } if (!mxIsSingle(VEL_Y)) { mexErrMsgTxt("Incompatible precision: LSMLIB built for single-precision but vel_y is double-precision"); } if (!mxIsSingle(VEL_Z)) { mexErrMsgTxt("Incompatible precision: LSMLIB built for single-precision but vel_z is double-precision"); } #endif /* Get ghostcell_width */ ghostcell_width = mxGetPr(GHOSTCELL_WIDTH)[0]; /* Get dX */ dX = mxGetPr(DX); /* Change order of dX to be match MATLAB meshgrid() order for grids. */ dX_meshgrid_order[0] = dX[1]; dX_meshgrid_order[1] = dX[0]; dX_meshgrid_order[2] = dX[2]; /* Assign pointers for phi and velocities */ phi = (LSMLIB_REAL*) mxGetPr(PHI); vel_x = (LSMLIB_REAL*) mxGetPr(VEL_X); vel_y = (LSMLIB_REAL*) mxGetPr(VEL_Y); vel_z = (LSMLIB_REAL*) mxGetPr(VEL_Z); /* Get size of phi data */ data_array_dims_in = mxGetDimensions(PHI); ilo_phi_gb = 1; ihi_phi_gb = data_array_dims_in[0]; jlo_phi_gb = 1; jhi_phi_gb = data_array_dims_in[1]; klo_phi_gb = 1; khi_phi_gb = data_array_dims_in[2]; /* Get size of velocity data */ /* (assume vel_x, vel_y, and vel_z have same size) */ data_array_dims_in = mxGetDimensions(VEL_X); ilo_vel_gb = 1; ihi_vel_gb = data_array_dims_in[0]; jlo_vel_gb = 1; jhi_vel_gb = data_array_dims_in[1]; klo_vel_gb = 1; khi_vel_gb = data_array_dims_in[2]; /* if necessary, shift ghostbox for velocity to be */ /* centered with respect to the ghostbox for phi. */ if (ihi_vel_gb != ihi_phi_gb) { int shift = (ihi_phi_gb-ihi_vel_gb)/2; ilo_vel_gb += shift; ihi_vel_gb += shift; } if (jhi_vel_gb != jhi_phi_gb) { int shift = (jhi_phi_gb-jhi_vel_gb)/2; jlo_vel_gb += shift; jhi_vel_gb += shift; } if (khi_vel_gb != khi_phi_gb) { int shift = (khi_phi_gb-khi_vel_gb)/2; klo_vel_gb += shift; khi_vel_gb += shift; } /* Allocate scratch memory for undivided differences */ ilo_D1_gb = ilo_phi_gb; ihi_D1_gb = ihi_phi_gb; jlo_D1_gb = jlo_phi_gb; jhi_D1_gb = jhi_phi_gb; klo_D1_gb = klo_phi_gb; khi_D1_gb = khi_phi_gb; D1 = (LSMLIB_REAL*) mxMalloc( sizeof(LSMLIB_REAL) * (ihi_D1_gb-ilo_D1_gb+1) * (jhi_D1_gb-jlo_D1_gb+1) * (khi_D1_gb-klo_D1_gb+1) ); if (!D1) { if (D1) mxFree(D1); mexErrMsgTxt("Unable to allocate memory for scratch data...aborting...."); } /* Create matrices for upwind derivatives (i.e. phi_x, phi_y, phi_z) */ ilo_grad_phi_gb = ilo_phi_gb; ihi_grad_phi_gb = ihi_phi_gb; jlo_grad_phi_gb = jlo_phi_gb; jhi_grad_phi_gb = jhi_phi_gb; klo_grad_phi_gb = klo_phi_gb; khi_grad_phi_gb = khi_phi_gb; data_array_dims_out[0] = ihi_grad_phi_gb-ilo_grad_phi_gb+1; data_array_dims_out[1] = jhi_grad_phi_gb-jlo_grad_phi_gb+1; data_array_dims_out[2] = khi_grad_phi_gb-klo_grad_phi_gb+1; #ifdef LSMLIB_DOUBLE_PRECISION PHI_X = mxCreateNumericArray(NDIM, data_array_dims_out, mxDOUBLE_CLASS, mxREAL); PHI_Y = mxCreateNumericArray(NDIM, data_array_dims_out, mxDOUBLE_CLASS, mxREAL); PHI_Z = mxCreateNumericArray(NDIM, data_array_dims_out, mxDOUBLE_CLASS, mxREAL); #else PHI_X = mxCreateNumericArray(NDIM, data_array_dims_out, mxSINGLE_CLASS, mxREAL); PHI_Y = mxCreateNumericArray(NDIM, data_array_dims_out, mxSINGLE_CLASS, mxREAL); PHI_Z = mxCreateNumericArray(NDIM, data_array_dims_out, mxSINGLE_CLASS, mxREAL); #endif phi_x = (LSMLIB_REAL*) mxGetPr(PHI_X); phi_y = (LSMLIB_REAL*) mxGetPr(PHI_Y); phi_z = (LSMLIB_REAL*) mxGetPr(PHI_Z); /* Do the actual computations in a Fortran 77 subroutine */ ilo_fb = ilo_phi_gb+ghostcell_width; ihi_fb = ihi_phi_gb-ghostcell_width; jlo_fb = jlo_phi_gb+ghostcell_width; jhi_fb = jhi_phi_gb-ghostcell_width; klo_fb = klo_phi_gb+ghostcell_width; khi_fb = khi_phi_gb-ghostcell_width; /* * NOTE: ordering of data arrays from meshgrid() is (y,x,z), so * order derivative and velocity data arrays need to be permuted. */ LSM3D_UPWIND_HJ_ENO1( phi_y, phi_x, phi_z, &ilo_grad_phi_gb, &ihi_grad_phi_gb, &jlo_grad_phi_gb, &jhi_grad_phi_gb, &klo_grad_phi_gb, &khi_grad_phi_gb, phi, &ilo_phi_gb, &ihi_phi_gb, &jlo_phi_gb, &jhi_phi_gb, &klo_phi_gb, &khi_phi_gb, vel_y, vel_x, vel_z, &ilo_vel_gb, &ihi_vel_gb, &jlo_vel_gb, &jhi_vel_gb, &klo_vel_gb, &khi_vel_gb, D1, &ilo_D1_gb, &ihi_D1_gb, &jlo_D1_gb, &jhi_D1_gb, &klo_D1_gb, &khi_D1_gb, &ilo_fb, &ihi_fb, &jlo_fb, &jhi_fb, &klo_fb, &khi_fb, &dX_meshgrid_order[0], &dX_meshgrid_order[1], &dX_meshgrid_order[2]); /* Deallocate scratch memory for undivided differences */ mxFree(D1); return; }
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) { // Check inputs if (nlhs == 0) return; if (nrhs != 3) mexErrMsgTxt("Should be three inputs"); if (!mxIsUint8(prhs[0])) mexErrMsgTxt("Intput should be a UINT8 matrix"); if (mxGetNumberOfDimensions(prhs[0]) != 2) mexErrMsgTxt("Intput should be a 2D matrix"); try { std::vector<double> glcm(n*n); int w = mxGetN(prhs[0]); int h = mxGetM(prhs[0]); unsigned char* im = (unsigned char*) mxGetData(prhs[0]); int offset_x = mxGetScalar(prhs[2]); int offset_y = mxGetScalar(prhs[1]); int n_px = 0; // Compute GLCM for (int y=0; y<h; y++) { for(int x=0; x<w; x++) { int xo = x + offset_x; int yo = y + offset_y; if ((xo >= 0) && (yo >= 0) && (xo < w) && (yo < h)) { unsigned char a = im[x + y * w]; unsigned char b = im[xo + yo * w]; glcm[a + b * n]++; n_px++; } } } double correlation = 0.0; double contrast = 0.0; double energy = 0.0; double homogeneity = 0.0; double pa = 0; double pb = 0; double stdeva = 0.0; double stdevb = 0.0; // Compute means for (int b=0; b<n; b++) for (int a=0; a<n; a++) { pa += a * glcm[a+b*n]; pb += b * glcm[a+b*n]; } pa /= n_px; pb /= n_px; // Compute standard deviations for (int b=0; b<n; b++) for (int a=0; a<n; a++) { stdeva += (a - pa) * (a - pa) * glcm[a+b*n]; stdevb += (b - pb) * (b - pb) * glcm[a+b*n]; } stdeva = sqrt(stdeva/n_px); stdevb = sqrt(stdevb/n_px); // Compute correlation parameter for (int b=0; b<n; b++) for (int a=0; a<n; a++) { double g = glcm[a+b*n]; correlation += (a - pa) * (b - pb) * g; contrast += (a-b)*(a-b) * g; energy += g * g; homogeneity += g / (1 + std::abs(a-b)); } correlation /= (stdeva * stdevb * n_px); if (nlhs >= 0) plhs[0] = mxCreateDoubleScalar(correlation); if (nlhs >= 1) plhs[1] = mxCreateDoubleScalar(contrast); if (nlhs >= 2) plhs[2] = mxCreateDoubleScalar(energy); if (nlhs >= 3) plhs[3] = mxCreateDoubleScalar(homogeneity); } catch(std::exception e) { mexErrMsgTxt(e.what()); } }
/* main function */ void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) { if (nrhs<1) mexErrMsgTxt("ERROR:eikonal3: not enough input elements\n"); if (nrhs>2) mexErrMsgTxt("ERROR:eikonal3: too many input elements.\n"); if (nlhs>2) mexErrMsgTxt("ERROR:eikonal3: too many output elements.\n"); if (mxIsSingle(prhs[0])==0) mexErrMsgTxt("ERROR:eikonal3: first input must be an 3d single matrix\n"); if (nrhs==2 && mxIsDouble(prhs[1])==0) mexErrMsgTxt("ERROR:eikonal3: second input must be an double matrix\n"); if (nrhs==2 && mxGetNumberOfElements(prhs[1])!=3) mexErrMsgTxt("ERROR:eikonal3: second input must have 3 Elements"); int i, j, k, n, ind, x, y, z; int ni, kll=0; float diff, maxdiffi, maxdiff=1, Dio, DNi; float TH=0.01; /* main informations about input data (size, dimensions, ...) */ const mwSize *sL = mxGetDimensions(prhs[0]); const int dL = mxGetNumberOfDimensions(prhs[0]); const int nL = (int)mxGetNumberOfElements(prhs[0]); const int sS[] = {1,3}; mxArray *SS = mxCreateNumericArray(2,sS,mxDOUBLE_CLASS,mxREAL); double *S = mxGetPr(SS); if (nrhs<2) {S[0]=1; S[1]=1; S[2]=1;} else {S = mxGetPr(prhs[1]);} float s1 = abs2((float)S[0]),s2 = abs2((float)S[1]),s3 = abs2((float)S[2]); const float s12 = sqrt( s1*s1 + s2*s2); /* xy - voxel size */ const float s13 = sqrt( s1*s1 + s3*s3); /* xz - voxel size */ const float s23 = sqrt( s2*s2 + s3*s3); /* yz - voxel size */ const float s123 = sqrt(s12*s12 + s3*s3); /* xyz - voxel size */ /* indices of the euclidean distance NW */ const float ND[] = {s123, s12, s123, s13, s1, s13, s123, s12, s123, s23, s2, s23, s3, 0.0, s3, s23, s2, s23, s123, s12, s123, s13, s1, s13, s123, s12, s123}; /* main volumes - actual without memory optimation ... */ plhs[0] = mxCreateNumericArray(dL,sL,mxSINGLE_CLASS,mxREAL); plhs[1] = mxCreateNumericArray(dL,sL,mxSINGLE_CLASS,mxREAL); float *D = (float *)mxGetPr(plhs[0]); float *L = (float *)mxGetPr(plhs[1]); /* input variables */ float *SEG = (float *)mxGetPr(prhs[0]); if ( TH>=0.5 || TH<0.0001 ) mexErrMsgTxt("ERROR:eikonal3: threshhold must be >0.0001 and smaller than 0.5\n"); /* intitialisiation */ for (i=0;i<nL;i++) { if ( SEG[i]<0 ) {D[i]=0; L[i]=SEG[i];} else {D[i]=FLT_MAX; L[i]=0;} } while ( ( maxdiff > TH ) && kll<2000 ) { maxdiffi=0; kll++; for (z=0;z<sL[2];z++) for (y=0;y<sL[1];y++) for (x=0;x<sL[0];x++) { ind = index(x,y,z,sL); if ( SEG[ind]>0 && SEG[ind]<FLT_MAX) { /* read neighbor values */ Dio = D[ind]; n = 0; /* go through all elements in a 3x3x3 box */ for (i=-1;i<=1;i++) for (j=-1;j<=1;j++) for (k=-1;k<=1;k++) { ni = index(x+i,y+j,z+k,sL); if ( SEG[ind]!=FLT_MAX ) { if ( ((x+i)>=0) && ((x+i)<sL[0]) && ((y+j)>=0) && ((y+j)<sL[1]) && ((z+k)>=0) && ((z+k)<sL[2]) ) { DNi = D[ni] + ND[n]*SEG[ind]; if ( DNi<D[ind] ) {D[ind]=DNi; L[ind]=L[ni]; } } } n++; } diff = abs2( Dio - D[ind] ); if ( maxdiffi<diff ) maxdiffi=diff; } } for (z=sL[2]-1;z>=0;z--) for (y=sL[1]-1;y>=0;y--) for (x=sL[0]-1;x>=0;x--) { ind = index(x,y,z,sL); if ( SEG[ind]>0 && SEG[ind]<FLT_MAX) { /* read neighbor values */ Dio = D[ind]; n = 0; /* go through all elements in a 3x3x3 box */ for (i=-1;i<=1;i++) for (j=-1;j<=1;j++) for (k=-1;k<=1;k++) { ni = index(x+i,y+j,z+k,sL); if ( SEG[ind]!=FLT_MAX ) { if ( ((x+i)>=0) && ((x+i)<sL[0]) && ((y+j)>=0) && ((y+j)<sL[1]) && ((z+k)>=0) && ((z+k)<sL[2]) ) { DNi = D[ni] + ND[n]*SEG[ind]; if ( DNi<D[ind] ) {D[ind]=DNi; L[ind]=L[ni]; } } } n++; } diff = abs2( Dio - D[ind] ); if ( maxdiffi<diff ) maxdiffi=diff; } } maxdiff = maxdiffi; } }
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) { const mxArray *udata, *wdata; mxArray *ptr_shape, *ptr_data, *ptr_obj; double *umat, *vmat, *wmat; int i, j, k, l; int wdimm, wdimn, vdimm, vdimn, udimm, udimn, n, nmat; int nd_u, nd_v, wdim[2]; const int *udim, *vdim; const int nod = 2; nd_u = mxGetNumberOfDimensions(prhs[0]); nd_v = mxGetNumberOfDimensions(prhs[1]); if ((nd_u > 2) || (nd_v > 2)) mexErrMsgTxt("Function does not support number-of-dims > 2!"); /* Make sure that multiplication is done correctly!! */ if (mxGetN(prhs[0]) == mxGetM(prhs[1])) { if (mxIsDouble(prhs[1])) { vmat = mxGetPr(prhs[1]); udata = prhs[0]; vdim = mxGetDimensions(prhs[1]); udim = mxGetDimensions(prhs[0]); wdim[0] = udim[0]; wdim[1] = vdim[1]; wdimm = wdim[0]; wdimn = wdim[1]; vdimm = vdim[0]; vdimn = vdim[1]; udimm = udim[0]; udimn = udim[1]; plhs[0] = mxDuplicateArray(udata); /* This is OUTPUT object array */ mxSetDimensions(plhs[0],wdim,nod); /* Reshape OUTPUT object array */ n = wdimm*wdimn; /* Total number of objects */ nmat = mxGetNumberOfElements(mxGetField(prhs[0],0,"data")); /* Initializing all matrices in all the objects in the OUTPUT array to zero */ ptr_shape = mxGetFieldByNumber(plhs[0],0,0); ptr_data = mxGetFieldByNumber(plhs[0],0,1); ptr_obj = mxGetFieldByNumber(plhs[0],0,2); /* Initializing the matrix data of the object to zero */ wmat = mxGetPr(ptr_data); for (j = 0; j < nmat; j++) wmat[j] = 0.0; for (i = 0; i < n; i++) { mxSetFieldByNumber(plhs[0],i,0,mxDuplicateArray(ptr_shape)); mxSetFieldByNumber(plhs[0],i,1,mxDuplicateArray(ptr_data)); mxSetFieldByNumber(plhs[0],i,2,mxDuplicateArray(ptr_obj)); } for (k = 0; k < wdimm; k++) { for (l = 0; l < wdimn; l++) { wdata = mxGetField(plhs[0],k+l*wdimm,"data"); wmat = mxGetPr(wdata); for (i = 0; i < udimn; i++) { umat = mxGetPr(mxGetField(udata,k + i*udimm,"data")); if (umat) { for (j = 0; j < nmat; j++) wmat[j] += vmat[i+l*vdimm] * umat[j]; } else { mexPrintf("mtimes.c: line ~ 80: Ptr corrupt!\n");} } } } } else if (mxIsDouble(prhs[0])) { /* double-matrise X obj-matrise */ vmat = mxGetPr(prhs[0]); udata = prhs[1]; vdim = mxGetDimensions(prhs[0]); udim = mxGetDimensions(prhs[1]); wdim[0] = vdim[0]; wdim[1] = udim[1]; wdimm = wdim[0]; wdimn = wdim[1]; vdimm = vdim[0]; vdimn = vdim[1]; udimm = udim[0]; udimn = udim[1]; plhs[0] = mxDuplicateArray(udata); /* This is OUTPUT object array */ mxSetDimensions(plhs[0],wdim,nod); /* Reshape OUTPUT object array */ n = wdimm*wdimn; /* Total number of objects */ nmat = mxGetNumberOfElements(mxGetField(prhs[1],0,"data")); /* Initializing all matrices in all the object in the OUTPUT array to zero */ ptr_shape = mxGetFieldByNumber(plhs[0],0,0); ptr_data = mxGetFieldByNumber(plhs[0],0,1); ptr_obj = mxGetFieldByNumber(plhs[0],0,2); /* Initializing the matrix data of the object to zero */ wmat = mxGetPr(ptr_data); for (j = 0; j < nmat; j++) wmat[j] = 0.0; for (i = 0; i < n; i++) { mxSetFieldByNumber(plhs[0],i,0,mxDuplicateArray(ptr_shape)); mxSetFieldByNumber(plhs[0],i,1,mxDuplicateArray(ptr_data)); mxSetFieldByNumber(plhs[0],i,2,mxDuplicateArray(ptr_obj)); } for (k = 0; k < wdimm; k++) { for (l = 0; l < wdimn; l++) { wdata = mxGetField(plhs[0],k+l*wdimm,"data"); wmat = mxGetPr(wdata); for (i = 0; i < vdimn; i++) { umat = mxGetPr(mxGetField(udata,i + l*udimm,"data")); if (umat) { for (j = 0; j < nmat; j++) wmat[j] += vmat[k+i*vdimm] * umat[j]; } else { mexPrintf("mtimes.c: line ~ 130: Ptr corrupt!\n");} } } } } return; } else { mexErrMsgTxt("Check sizes: columns(left matrix) != rows(right matrix)!"); } }
void mexFunction ( int nargout, mxArray *pargout [ ], int nargin, const mxArray *pargin [ ] ) { UF_long i, m, n, *Ap, *Ai, *P, nc, result, spumoni, full ; double *Pout, *InfoOut, Control [AMD_CONTROL], Info [AMD_INFO], *ControlIn ; mxArray *A ; /* --------------------------------------------------------------------- */ /* get control parameters */ /* --------------------------------------------------------------------- */ amd_malloc = mxMalloc ; amd_free = mxFree ; amd_calloc = mxCalloc ; amd_realloc = mxRealloc ; amd_printf = mexPrintf ; spumoni = 0 ; if (nargin == 0) { /* get the default control parameters, and return */ pargout [0] = mxCreateDoubleMatrix (AMD_CONTROL, 1, mxREAL) ; amd_l_defaults (mxGetPr (pargout [0])) ; if (nargout == 0) { amd_l_control (mxGetPr (pargout [0])) ; } return ; } amd_l_defaults (Control) ; if (nargin > 1) { ControlIn = mxGetPr (pargin [1]) ; nc = mxGetM (pargin [1]) * mxGetN (pargin [1]) ; Control [AMD_DENSE] = (nc > 0) ? ControlIn [AMD_DENSE] : AMD_DEFAULT_DENSE ; Control [AMD_AGGRESSIVE] = (nc > 1) ? ControlIn [AMD_AGGRESSIVE] : AMD_DEFAULT_AGGRESSIVE ; spumoni = (nc > 2) ? (ControlIn [2] != 0) : 0 ; } if (spumoni > 0) { amd_l_control (Control) ; } /* --------------------------------------------------------------------- */ /* get inputs */ /* --------------------------------------------------------------------- */ if (nargout > 2 || nargin > 2) { mexErrMsgTxt ("Usage: p = amd (A)\nor [p, Info] = amd (A, Control)") ; } A = (mxArray *) pargin [0] ; n = mxGetN (A) ; m = mxGetM (A) ; if (spumoni > 0) { mexPrintf (" input matrix A is %d-by-%d\n", m, n) ; } if (mxGetNumberOfDimensions (A) != 2) { mexErrMsgTxt ("amd: A must be 2-dimensional") ; } if (m != n) { mexErrMsgTxt ("amd: A must be square") ; } /* --------------------------------------------------------------------- */ /* allocate workspace for output permutation */ /* --------------------------------------------------------------------- */ P = mxMalloc ((n+1) * sizeof (UF_long)) ; /* --------------------------------------------------------------------- */ /* if A is full, convert to a sparse matrix */ /* --------------------------------------------------------------------- */ full = !mxIsSparse (A) ; if (full) { if (spumoni > 0) { mexPrintf ( " input matrix A is full (sparse copy of A will be created)\n"); } mexCallMATLAB (1, &A, 1, (mxArray **) pargin, "sparse") ; } Ap = (UF_long *) mxGetJc (A) ; Ai = (UF_long *) mxGetIr (A) ; if (spumoni > 0) { mexPrintf (" input matrix A has %d nonzero entries\n", Ap [n]) ; } /* --------------------------------------------------------------------- */ /* order the matrix */ /* --------------------------------------------------------------------- */ result = amd_l_order (n, Ap, Ai, P, Control, Info) ; /* --------------------------------------------------------------------- */ /* if A is full, free the sparse copy of A */ /* --------------------------------------------------------------------- */ if (full) { mxDestroyArray (A) ; } /* --------------------------------------------------------------------- */ /* print results (including return value) */ /* --------------------------------------------------------------------- */ if (spumoni > 0) { amd_l_info (Info) ; } /* --------------------------------------------------------------------- */ /* check error conditions */ /* --------------------------------------------------------------------- */ if (result == AMD_OUT_OF_MEMORY) { mexErrMsgTxt ("amd: out of memory") ; } else if (result == AMD_INVALID) { mexErrMsgTxt ("amd: input matrix A is corrupted") ; } /* --------------------------------------------------------------------- */ /* copy the outputs to MATLAB */ /* --------------------------------------------------------------------- */ /* output permutation, P */ pargout [0] = mxCreateDoubleMatrix (1, n, mxREAL) ; Pout = mxGetPr (pargout [0]) ; for (i = 0 ; i < n ; i++) { Pout [i] = P [i] + 1 ; /* change to 1-based indexing for MATLAB */ } mxFree (P) ; /* Info */ if (nargout > 1) { pargout [1] = mxCreateDoubleMatrix (AMD_INFO, 1, mxREAL) ; InfoOut = mxGetPr (pargout [1]) ; for (i = 0 ; i < AMD_INFO ; i++) { InfoOut [i] = Info [i] ; } } }
void mexFunction(int nlhs, /* No. of output arguments */ mxArray *plhs[], /* Output arguments. */ int nrhs, /* No. of input arguments. */ const mxArray *prhs[]) /* Input arguments. */ { int ndim, pm_ndim; int n, i; const int *cdim = NULL, *pm_cdim = NULL; unsigned int dim[3]; unsigned int nnz = 0; double *rima = NULL; double *pm = NULL; double *ii = NULL, *jj = NULL; double *nn = NULL, *pp = NULL; double *tmp = NULL; if (nrhs == 0) mexErrMsgTxt("usage: [i,j,n,p]=pm_create_connectogram_dtj(rima,pm)"); if (nrhs != 2) mexErrMsgTxt("pm_create_connectogram_dtj: 2 input arguments required"); if (nlhs != 4) mexErrMsgTxt("pm_create_connectogram_dtj: 4 output argument required"); /* Get connected components map. */ if (!mxIsNumeric(prhs[0]) || mxIsComplex(prhs[0]) || mxIsSparse(prhs[0]) || !mxIsDouble(prhs[0])) { mexErrMsgTxt("pm_bwlabel_dtj: rima must be numeric, real, full and double"); } ndim = mxGetNumberOfDimensions(prhs[0]); if ((ndim < 2) | (ndim > 3)) { mexErrMsgTxt("pm_bwlabel_dtj: rima must be 2 or 3-dimensional"); } cdim = mxGetDimensions(prhs[0]); rima = mxGetPr(prhs[0]); /* Get phase-map. */ if (!mxIsNumeric(prhs[1]) || mxIsComplex(prhs[1]) || mxIsSparse(prhs[1]) || !mxIsDouble(prhs[1])) { mexErrMsgTxt("pm_bwlabel_dtj: pm must be numeric, real, full and double"); } pm_ndim = mxGetNumberOfDimensions(prhs[1]); if (pm_ndim != ndim) { mexErrMsgTxt("pm_bwlabel_dtj: rima and pm must have same dimensionality"); } pm_cdim = mxGetDimensions(prhs[1]); for (i=0; i<ndim; i++) { if (cdim[i] != pm_cdim[i]) { mexErrMsgTxt("pm_bwlabel_dtj: rima and pm must have same size"); } } pm = mxGetPr(prhs[1]); /* Fix dimensions to allow for 2D and 3D data. */ dim[0]=cdim[0]; dim[1]=cdim[1]; if (ndim==2) {dim[2]=1; ndim=3;} else {dim[2]=cdim[2];} for (i=0, n=1; i<ndim; i++) { n *= dim[i]; } /* Create ii, jj, and nn and pp vectors for subsequent use by the matlab sparse function such that N = sparse(ii,jj,nn,nnz) generates a matrix where each non-zero entry signifies the no. of voxels along the border of the corresponding regions. */ nnz = make_vectors(rima,pm,dim,&ii,&jj,&nn,&pp); /* Allocate memory for output. */ plhs[0] = mxCreateDoubleMatrix(nnz,1,mxREAL); tmp = mxGetPr(plhs[0]); memcpy(tmp,ii,nnz*sizeof(double)); plhs[1] = mxCreateDoubleMatrix(nnz,1,mxREAL); tmp = mxGetPr(plhs[1]); memcpy(tmp,jj,nnz*sizeof(double)); plhs[2] = mxCreateDoubleMatrix(nnz,1,mxREAL); tmp = mxGetPr(plhs[2]); memcpy(tmp,nn,nnz*sizeof(double)); plhs[3] = mxCreateDoubleMatrix(nnz,1,mxREAL); tmp = mxGetPr(plhs[3]); memcpy(tmp,pp,nnz*sizeof(double)); /* Clean up a bit. */ mxFree(ii); mxFree(jj); mxFree(nn); mxFree(pp); return; }
void mexFunction(int nout, mxArray *pout[], int nin, const mxArray *pin[]) { FILE *f = fopen("log.txt", "wt"); fclose(f); if (nin < 2) { mexErrMsgTxt("nnmex called with < 2 input arguments"); } const mxArray *A = pin[0], *B = pin[1]; const mxArray *ANN_PREV = NULL, *ANN_WINDOW = NULL, *AWINSIZE = NULL; int aw = -1, ah = -1, bw = -1, bh = -1; BITMAP *a = NULL, *b = NULL, *ann_prev = NULL, *ann_window = NULL, *awinsize = NULL; VECBITMAP<unsigned char> *ab = NULL, *bb = NULL; VECBITMAP<float> *af = NULL, *bf = NULL; if (mxGetNumberOfDimensions(A) != 3 || mxGetNumberOfDimensions(B) != 3) { mexErrMsgTxt("dims != 3"); } if (mxGetDimensions(A)[2] != mxGetDimensions(B)[2]) { mexErrMsgTxt("3rd dimension not same size"); } int mode = MODE_IMAGE; if (mxGetDimensions(A)[2] != 3) { // a discriptor rather than rgb if (mxIsUint8(A) && mxIsUint8(B)) { mode = MODE_VECB; } else if (is_float(A) && is_float(B)) { mode = MODE_VECF; } else { mexErrMsgTxt("input not uint8, single, or double"); } } Params *p = new Params(); RecomposeParams *rp = new RecomposeParams(); BITMAP *borig = NULL; if (mode == MODE_IMAGE) { a = convert_bitmap(A); b = convert_bitmap(B); borig = b; aw = a->w; ah = a->h; bw = b->w; bh = b->h; } else if (mode == MODE_VECB) { ab = convert_vecbitmap<unsigned char>(A); bb = convert_vecbitmap<unsigned char>(B); if (ab->n != bb->n) { mexErrMsgTxt("3rd dimension differs"); } aw = ab->w; ah = ab->h; bw = bb->w; bh = bb->h; p->vec_len = ab->n; } else if (mode == MODE_VECF) { af = convert_vecbitmap<float>(A); bf = convert_vecbitmap<float>(B); if (af->n != bf->n) { mexErrMsgTxt("3rd dimension differs"); } aw = af->w; ah = af->h; bw = bf->w; bh = bf->h; p->vec_len = af->n; } double *win_size = NULL; BITMAP *amask = NULL, *bmask = NULL; double scalemin = 0.5, scalemax = 2.0; // The product of these must be one. /* parse parameters */ int i = 2; int sim_mode = 0; int knn_chosen = -1; p->algo = ALGO_CPU; int enrich_mode = 0; if (nin > i && !mxIsEmpty(pin[i])) { if (mxStringEquals(pin[i], "cpu")) { p->algo = ALGO_CPU; } else if (mxStringEquals(pin[i], "gpucpu")) { p->algo = ALGO_GPUCPU; } else if (mxStringEquals(pin[i], "cputiled")) { p->algo = ALGO_CPUTILED; } else if (mxStringEquals(pin[i], "rotscale")) { sim_mode = 1; } else if (mxStringEquals(pin[i], "enrich")) { p->algo = ALGO_CPUTILED; enrich_mode = 1; } else { mexErrMsgTxt("Unknown algorithm"); } } i++; if (nin > i && !mxIsEmpty(pin[i])) { p->patch_w = int(mxGetScalar(pin[i])); } i++; if (nin > i && !mxIsEmpty(pin[i])) { p->nn_iters = int(mxGetScalar(pin[i])); } i++; if (nin > i && !mxIsEmpty(pin[i])) { p->rs_max = int(mxGetScalar(pin[i])); } i++; if (nin > i && !mxIsEmpty(pin[i])) { p->rs_min = int(mxGetScalar(pin[i])); } i++; if (nin > i && !mxIsEmpty(pin[i])) { p->rs_ratio = mxGetScalar(pin[i]); } i++; if (nin > i && !mxIsEmpty(pin[i])) { p->rs_iters = mxGetScalar(pin[i]); } i++; if (nin > i && !mxIsEmpty(pin[i])) { p->cores = int(mxGetScalar(pin[i])); } i++; if (nin > i && !mxIsEmpty(pin[i])) { bmask = convert_bitmap(pin[i]); } i++; // XC+ if (nin > i && !mxIsEmpty(pin[i])) { if (!mxIsDouble(pin[i])) { mexErrMsgTxt("\nwin_size should be of type double."); } win_size = (double*)mxGetData(pin[i]); if (mxGetNumberOfElements(pin[i])==1) { p->window_h = p->window_w = int(win_size[0]); } else if (mxGetNumberOfElements(pin[i])==2) { p->window_h = int(win_size[0]); p->window_w = int(win_size[1]); } else { mexErrMsgTxt("\nwin_size should be a scalar for square window or [h w] for a rectangular one."); } } i++; /* continue parsing parameters */ // [ann_prev=NULL], [ann_window=NULL], [awinsize=NULL], if (nin > i && !mxIsEmpty(pin[i])) { ANN_PREV = pin[i]; int clip_count = 0; ann_prev = convert_field(p, ANN_PREV, bw, bh, clip_count); // Bug fixed by Connelly } i++; if (nin > i && !mxIsEmpty(pin[i])) { ANN_WINDOW = pin[i]; int clip_count = 0; ann_window = convert_field(p, ANN_WINDOW, bw, bh, clip_count); } i++; if (nin > i && !mxIsEmpty(pin[i])) { AWINSIZE = pin[i]; awinsize = convert_winsize_field(p, AWINSIZE, aw, ah); if (p->window_w==INT_MAX||p->window_h==INT_MAX) { p->window_w = -1; p->window_h = -1; } } i++; if (nin > i && !mxIsEmpty(pin[i])) { knn_chosen = int(mxGetScalar(pin[i])); if (knn_chosen == 1) { knn_chosen = -1; } if (knn_chosen <= 0) { mexErrMsgTxt("\nknn is less than zero"); } } i++; if (nin > i && !mxIsEmpty(pin[i])) { scalemax = mxGetScalar(pin[i]); if (scalemax <= 0) { mexErrMsgTxt("\nscalerange is less than zero"); } scalemin = 1.0/scalemax; if (scalemax < scalemin) { double temp = scalemax; scalemax = scalemin; scalemin = temp; } } i++; if (ann_window&&!awinsize&&!win_size) { mexErrMsgTxt("\nUsing ann_window - either awinsize or win_size should be defined.\n"); } if (enrich_mode) { int nn_iters = p->nn_iters; p->enrich_iters = nn_iters/2; p->nn_iters = 2; if (A != B) { mexErrMsgTxt("\nOur implementation of enrichment requires that image A = image B.\n"); } if (mode == MODE_IMAGE) { b = a; } else { mexErrMsgTxt("\nEnrichment only implemented for 3 channel uint8 inputs.\n"); } } init_params(p); if (sim_mode) { init_xform_tables(scalemin, scalemax, 1); } RegionMasks *amaskm = amask ? new RegionMasks(p, amask): NULL; BITMAP *ann = NULL; // NN field BITMAP *annd_final = NULL; // NN patch distance field BITMAP *ann_sim_final = NULL; VBMP *vann_sim = NULL; VBMP *vann = NULL; VBMP *vannd = NULL; if (mode == MODE_IMAGE) { // input as RGB image if (!a || !b) { mexErrMsgTxt("internal error: no a or b image"); } if (knn_chosen > 1) { p->knn = knn_chosen; if (sim_mode) { mexErrMsgTxt("rotating+scaling patches not implemented with knn (actually it is implemented it is not exposed by the wrapper)"); } PRINCIPAL_ANGLE *pa = NULL; vann_sim = NULL; vann = knn_init_nn(p, a, b, vann_sim, pa); vannd = knn_init_dist(p, a, b, vann, vann_sim); knn(p, a, b, vann, vann_sim, vannd, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, pa); // sort_knn(p, vann, vann_sim, vannd); } else if (sim_mode) { BITMAP *ann_sim = NULL; ann = sim_init_nn(p, a, b, ann_sim); BITMAP *annd = sim_init_dist(p, a, b, ann, ann_sim); sim_nn(p, a, b, ann, ann_sim, annd); if (ann_prev) { mexErrMsgTxt("when searching over rotations+scales, previous guess is not supported"); } annd_final = annd; ann_sim_final = ann_sim; } else { ann = init_nn(p, a, b, bmask, NULL, amaskm, 1, ann_window, awinsize); BITMAP *annd = init_dist(p, a, b, ann, bmask, NULL, amaskm); nn(p, a, b, ann, annd, amaskm, bmask, 0, 0, rp, 0, 0, 0, NULL, p->cores, ann_window, awinsize); if (ann_prev) minnn(p, a, b, ann, annd, ann_prev, bmask, 0, 0, rp, NULL, amaskm, p->cores); annd_final = annd; } } /* else if (mode == MODE_VECB) { // mexPrintf("mode vecb %dx%dx%d, %dx%dx%d\n", ab->w, ab->h, ab->n, bb->w, bb->h, bb->n); // mexPrintf(" %d %d %d %d\n", ab->get(0,0)[0], ab->get(1,0)[0], ab->get(0,1)[0], ab->get(0,0)[1]); if (!ab || !bb) { mexErrMsgTxt("internal error: no a or b image"); } ann = vec_init_nn<unsigned char>(p, ab, bb, bmask, NULL, amaskm); VECBITMAP<int> *annd = vec_init_dist<unsigned char, int>(p, ab, bb, ann, bmask, NULL, amaskm); // mexPrintf(" %d %d %d %p %p\n", annd->get(0,0)[0], annd->get(1,0)[0], annd->get(0,1)[0], amaskm, bmask); vec_nn<unsigned char, int>(p, ab, bb, ann, annd, amaskm, bmask, 0, 0, rp, 0, 0, 0, NULL, p->cores); if (ann_prev) vec_minnn<unsigned char, int>(p, ab, bb, ann, annd, ann_prev, bmask, 0, 0, rp, NULL, amaskm, p->cores); annd_final = vecbitmap_to_bitmap(annd); delete annd; } else if (mode == MODE_VECF) { // mexPrintf("mode vecf %dx%dx%d, %dx%dx%d\n", af->w, af->h, af->n, bf->w, bf->h, bf->n); // mexPrintf(" %f %f %f %f\n", af->get(0,0)[0], af->get(1,0)[0], af->get(0,1)[0], af->get(0,0)[1]); if (!af || !bf) { mexErrMsgTxt("internal error: no a or b image"); } ann = vec_init_nn<float>(p, af, bf, bmask, NULL, amaskm); VECBITMAP<float> *annd = vec_init_dist<float, float>(p, af, bf, ann, bmask, NULL, amaskm); vec_nn<float, float>(p, af, bf, ann, annd, amaskm, bmask, 0, 0, rp, 0, 0, 0, NULL, p->cores); if (ann_prev) vec_minnn<float, float>(p, af, bf, ann, annd, ann_prev, bmask, 0, 0, rp, NULL, amaskm, p->cores); annd_final = create_bitmap(annd->w, annd->h); clear(annd_final); delete annd; } */ else if(mode == MODE_VECB) { if (sim_mode) { mexErrMsgTxt("internal error: rotation+scales not implemented with descriptor mode"); } if (knn_chosen > 1) { mexErrMsgTxt("internal error: kNN not implemented with descriptor mode"); } // mexPrintf("mode vecb_xc %dx%dx%d, %dx%dx%d\n", ab->w, ab->h, ab->n, bb->w, bb->h, bb->n); // input as uint8 discriptors per pixel if (!ab || !bb) { mexErrMsgTxt("internal error: no a or b image"); } ann = XCvec_init_nn<unsigned char>(p, ab, bb, bmask, NULL, amaskm); VECBITMAP<int> *annd = XCvec_init_dist<unsigned char, int>(p, ab, bb, ann, bmask, NULL, amaskm); XCvec_nn<unsigned char, int>(p, ab, bb, ann, annd, amaskm, bmask, 0, 0, rp, 0, 0, 0, NULL, p->cores); if (ann_prev) XCvec_minnn<unsigned char, int>(p, ab, bb, ann, annd, ann_prev, bmask, 0, 0, rp, NULL, amaskm, p->cores); annd_final = vecbitmap_to_bitmap(annd); delete annd; } else if(mode == MODE_VECF) { if (sim_mode) { mexErrMsgTxt("internal error: rotation+scales not implemented with descriptor mode"); } if (knn_chosen > 1) { mexErrMsgTxt("internal error: kNN not implemented with descriptor mode"); } // input as float/double discriptors per pixel if (!af || !bf) { mexErrMsgTxt("internal error: no a or b image"); } ann = XCvec_init_nn<float>(p, af, bf, bmask, NULL, amaskm); VECBITMAP<float> *annd = XCvec_init_dist<float, float>(p, af, bf, ann, bmask, NULL, amaskm); XCvec_nn<float, float>(p, af, bf, ann, annd, amaskm, bmask, 0, 0, rp, 0, 0, 0, NULL, p->cores); if (ann_prev) XCvec_minnn<float, float>(p, af, bf, ann, annd, ann_prev, bmask, 0, 0, rp, NULL, amaskm, p->cores); annd_final = create_bitmap(annd->w, annd->h); clear(annd_final); delete annd; } destroy_region_masks(amaskm); // output ann: x | y | patch_distance if(nout >= 1) { mxArray *ans = NULL; if (knn_chosen > 1) { if (sim_mode) { mexErrMsgTxt("rotating+scaling patches return value not implemented with knn"); } mwSize dims[4] = { ah, aw, 3, knn_chosen }; ans = mxCreateNumericArray(4, dims, mxINT32_CLASS, mxREAL); int *data = (int *) mxGetData(ans); for (int kval = 0; kval < knn_chosen; kval++) { int *xchan = &data[aw*ah*3*kval+0]; int *ychan = &data[aw*ah*3*kval+aw*ah]; int *dchan = &data[aw*ah*3*kval+2*aw*ah]; for (int y = 0; y < ah; y++) { // int *ann_row = (int *) ann->line[y]; // int *annd_row = (int *) annd_final->line[y]; for (int x = 0; x < aw; x++) { // int pp = ann_row[x]; int pp = vann->get(x, y)[kval]; int pos = y + x * ah; xchan[pos] = INT_TO_X(pp); ychan[pos] = INT_TO_Y(pp); dchan[pos] = vannd->get(x, y)[kval]; } } } } else if (ann_sim_final) { mwSize dims[3] = { ah, aw, 5 }; ans = mxCreateNumericArray(3, dims, mxSINGLE_CLASS, mxREAL); float *data = (float *) mxGetData(ans); float *xchan = &data[0]; float *ychan = &data[aw*ah]; float *dchan = &data[2*aw*ah]; float *tchan = &data[3*aw*ah]; float *schan = &data[4*aw*ah]; double angle_scale = 2.0*M_PI/NUM_ANGLES; for (int y = 0; y < ah; y++) { int *ann_row = (int *) ann->line[y]; int *annd_row = (int *) annd_final->line[y]; int *ann_sim_row = ann_sim_final ? (int *) ann_sim_final->line[y]: NULL; for (int x = 0; x < aw; x++) { int pp = ann_row[x]; int pos = y + x * ah; xchan[pos] = INT_TO_X(pp); ychan[pos] = INT_TO_Y(pp); dchan[pos] = annd_row[x]; if (ann_sim_final) { int v = ann_sim_row[x]; int tval = INT_TO_Y(v)&(NUM_ANGLES-1); int sval = INT_TO_X(v); tchan[pos] = tval*angle_scale; schan[pos] = xform_scale_table[sval]*(1.0/65536.0); } } } } else { mwSize dims[3] = { ah, aw, 3 }; ans = mxCreateNumericArray(3, dims, mxINT32_CLASS, mxREAL); int *data = (int *) mxGetData(ans); int *xchan = &data[0]; int *ychan = &data[aw*ah]; int *dchan = &data[2*aw*ah]; for (int y = 0; y < ah; y++) { int *ann_row = (int *) ann->line[y]; int *annd_row = (int *) annd_final->line[y]; for (int x = 0; x < aw; x++) { int pp = ann_row[x]; int pos = y + x * ah; xchan[pos] = INT_TO_X(pp); ychan[pos] = INT_TO_Y(pp); dchan[pos] = annd_row[x]; } } } pout[0] = ans; } // clean up delete vann; delete vann_sim; delete vannd; delete p; delete rp; destroy_bitmap(a); destroy_bitmap(borig); delete ab; delete bb; delete af; delete bf; destroy_bitmap(ann); destroy_bitmap(annd_final); destroy_bitmap(ann_sim_final); if (ann_prev) destroy_bitmap(ann_prev); if (ann_window) destroy_bitmap(ann_window); if (awinsize) destroy_bitmap(awinsize); }
/** @brief MATLAB Driver. **/ void mexFunction(int nout, mxArray *out[], int nin, const mxArray *in[]) { int M,N,S=0,smin=0,K,num_levels=0 ; const int* dimensions ; const double* P_pt ; const double* G_pt ; float* descr_pt ; float* buffer_pt ; float sigma0 ; float magnif = 3.0f ; /* Spatial bin extension factor. */ int NBP = 4 ; /* Number of bins for one spatial direction (even). */ int NBO = 8 ; /* Number of bins for the ortientation. */ int mode = NOSCALESPACE ; int buffer_size=0; enum {IN_G=0,IN_P,IN_SIGMA0,IN_S,IN_SMIN} ; enum {OUT_L=0} ; /* ------------------------------------------------------------------ ** Check the arguments ** --------------------------------------------------------------- */ if (nin < 3) { mexErrMsgTxt("At least three arguments are required") ; } else if (nout > 1) { mexErrMsgTxt("Too many output arguments."); } if( !uIsRealScalar(in[IN_SIGMA0]) ) { mexErrMsgTxt("SIGMA0 should be a real scalar") ; } if(!mxIsDouble(in[IN_G]) || mxGetNumberOfDimensions(in[IN_G]) > 3) { mexErrMsgTxt("G should be a real matrix or 3-D array") ; } sigma0 = (float) *mxGetPr(in[IN_SIGMA0]) ; dimensions = mxGetDimensions(in[IN_G]) ; M = dimensions[0] ; N = dimensions[1] ; G_pt = mxGetPr(in[IN_G]) ; P_pt = mxGetPr(in[IN_P]) ; K = mxGetN(in[IN_P]) ; if( !uIsRealMatrix(in[IN_P],-1,-1)) { mexErrMsgTxt("P should be a real matrix") ; } if ( mxGetM(in[IN_P]) == 4) { /* Standard (scale space) mode */ mode = SCALESPACE ; num_levels = dimensions[2] ; if(nin < 5) { mexErrMsgTxt("Five arguments are required in standard mode") ; } if( !uIsRealScalar(in[IN_S]) ) { mexErrMsgTxt("S should be a real scalar") ; } if( !uIsRealScalar(in[IN_SMIN]) ) { mexErrMsgTxt("SMIN should be a real scalar") ; } if( !uIsRealMatrix(in[IN_P],4,-1)) { mexErrMsgTxt("When the e mode P should be a 4xK matrix.") ; } S = (int)(*mxGetPr(in[IN_S])) ; smin = (int)(*mxGetPr(in[IN_SMIN])) ; } else if ( mxGetM(in[IN_P]) == 3 ) { mode = NOSCALESPACE ; num_levels = 1 ; S = 1 ; smin = 0 ; } else { mexErrMsgTxt("P should be either a 3xK or a 4xK matrix.") ; } /* Parse the property-value pairs */ { char str [80] ; int arg = (mode == SCALESPACE) ? IN_SMIN + 1 : IN_SIGMA0 + 1 ; while(arg < nin) { int k ; if( !uIsString(in[arg],-1) ) { mexErrMsgTxt("The first argument in a property-value pair" " should be a string") ; } mxGetString(in[arg], str, 80) ; #ifdef WINDOWS for(k = 0 ; properties[k] && strcmpi(str, properties[k]) ; ++k) ; #else for(k = 0 ; properties[k] && strcasecmp(str, properties[k]) ; ++k) ; #endif switch (k) { case PROP_NBP: if( !uIsRealScalar(in[arg+1]) ) { mexErrMsgTxt("'NumSpatialBins' should be real scalar") ; } NBP = (int) *mxGetPr(in[arg+1]) ; if( NBP <= 0 || (NBP & 0x1) ) { mexErrMsgTxt("'NumSpatialBins' must be positive and even") ; } break ; case PROP_NBO: if( !uIsRealScalar(in[arg+1]) ) { mexErrMsgTxt("'NumOrientBins' should be a real scalar") ; } NBO = (int) *mxGetPr(in[arg+1]) ; if( NBO <= 0 ) { mexErrMsgTxt("'NumOrientlBins' must be positive") ; } break ; case PROP_MAGNIF: if( !uIsRealScalar(in[arg+1]) ) { mexErrMsgTxt("'Magnif' should be a real scalar") ; } magnif = (float) *mxGetPr(in[arg+1]) ; if( magnif <= 0 ) { mexErrMsgTxt("'Magnif' must be positive") ; } break ; case PROP_UNKNOWN: mexErrMsgTxt("Property unknown.") ; break ; } arg += 2 ; } } /* ----------------------------------------------------------------- * Pre-compute gradient and angles * -------------------------------------------------------------- */ /* Alloc two buffers and make sure their size is multiple of 128 for * better alignment (used also by the Altivec code below.) */ buffer_size = (M*N*num_levels + 0x7f) & (~ 0x7f) ; buffer_pt = (float*) mxMalloc( sizeof(float) * 2 * buffer_size ) ; descr_pt = (float*) mxCalloc( NBP*NBP*NBO*K, sizeof(float) ) ; { /* Offsets to move in the scale space. */ const int yo = 1 ; const int xo = M ; const int so = M*N ; int x,y,s ; #define at(x,y) (*(pt + (x)*xo + (y)*yo)) /* Compute the gradient */ for(s = 0 ; s < num_levels ; ++s) { const double* pt = G_pt + s*so ; for(x = 1 ; x < N-1 ; ++x) { for(y = 1 ; y < M-1 ; ++y) { float Dx = 0.5 * ( at(x+1,y) - at(x-1,y) ) ; float Dy = 0.5 * ( at(x,y+1) - at(x,y-1) ) ; buffer_pt[(x*xo+y*yo+s*so) + 0 ] = Dx ; buffer_pt[(x*xo+y*yo+s*so) + buffer_size] = Dy ; } } } /* Compute angles and modules */ { float* pt = buffer_pt ; int j = 0 ; while (j < N*M*num_levels) { #if defined( MACOSX ) && defined( __ALTIVEC__ ) if( ((unsigned int)pt & 0x7) == 0 && j+3 < N*M*num_levels ) { /* If aligned to 128 bit and there are at least 4 pixels left */ float4 a, b, c, d ; a.vec = vec_ld(0,(vector float*)(pt )) ; b.vec = vec_ld(0,(vector float*)(pt + buffer_size)) ; c.vec = vatan2f(b.vec,a.vec) ; a.x[0] = a.x[0]*a.x[0]+b.x[0]*b.x[0] ; a.x[1] = a.x[1]*a.x[1]+b.x[1]*b.x[1] ; a.x[2] = a.x[2]*a.x[2]+b.x[2]*b.x[2] ; a.x[3] = a.x[3]*a.x[3]+b.x[3]*b.x[3] ; d.vec = vsqrtf(a.vec) ; vec_st(c.vec,0,(vector float*)(pt + buffer_size)) ; vec_st(d.vec,0,(vector float*)(pt )) ; j += 4 ; pt += 4 ; } else { #endif float Dx = *(pt ) ; float Dy = *(pt + buffer_size) ; *(pt ) = sqrtf(Dx*Dx + Dy*Dy) ; *(pt + buffer_size) = atan2f(Dy, Dx) ; j += 1 ; pt += 1 ; #if defined( MACOSX ) && defined( __ALTIVEC__ ) } #endif } } } /* ----------------------------------------------------------------- * Do the job * -------------------------------------------------------------- */ if(K > 0) { int p ; /* Offsets to move in the buffer */ const int yo = 1 ; const int xo = M ; const int so = M*N ; /* Offsets to move in the descriptor. */ /* Use Lowe's convention. */ const int binto = 1 ; const int binyo = NBO * NBP ; const int binxo = NBO ; const int bino = NBO * NBP * NBP ; for(p = 0 ; p < K ; ++p, descr_pt += bino) { /* The SIFT descriptor is a three dimensional histogram of the position * and orientation of the gradient. There are NBP bins for each spatial * dimesions and NBO bins for the orientation dimesion, for a total of * NBP x NBP x NBO bins. * * The support of each spatial bin has an extension of SBP = 3sigma * pixels, where sigma is the scale of the keypoint. Thus all the bins * together have a support SBP x NBP pixels wide . Since weighting and * interpolation of pixel is used, another half bin is needed at both * ends of the extension. Therefore, we need a square window of SBP x * (NBP + 1) pixels. Finally, since the patch can be arbitrarly rotated, * we need to consider a window 2W += sqrt(2) x SBP x (NBP + 1) pixels * wide. */ const float x = (float) *P_pt++ ; const float y = (float) *P_pt++ ; const float s = (float) (mode == SCALESPACE) ? (*P_pt++) : 0.0 ; const float theta0 = (float) *P_pt++ ; const float st0 = sinf(theta0) ; const float ct0 = cosf(theta0) ; const int xi = (int) floor(x+0.5) ; /* Round-off */ const int yi = (int) floor(y+0.5) ; const int si = (int) floor(s+0.5) - smin ; const float sigma = sigma0 * powf(2, s / S) ; const float SBP = magnif * sigma ; const int W = (int) floor( sqrt(2.0) * SBP * (NBP + 1) / 2.0 + 0.5) ; int bin ; int dxi ; int dyi ; const float* pt ; float* dpt ; /* Check that keypoints are within bounds . */ if(xi < 0 || xi > N-1 || yi < 0 || yi > M-1 || ((mode==SCALESPACE) && (si < 0 || si > dimensions[2]-1) ) ) continue ; /* Center the scale space and the descriptor on the current keypoint. * Note that dpt is pointing to the bin of center (SBP/2,SBP/2,0). */ pt = buffer_pt + xi*xo + yi*yo + si*so ; dpt = descr_pt + (NBP/2) * binyo + (NBP/2) * binxo ; #define atd(dbinx,dbiny,dbint) (*(dpt + (dbint)*binto + (dbiny)*binyo + (dbinx)*binxo)) /* * Process each pixel in the window and in the (1,1)-(M-1,N-1) * rectangle. */ for(dxi = max(-W, 1-xi) ; dxi <= min(+W, N-2-xi) ; ++dxi) { for(dyi = max(-W, 1-yi) ; dyi <= min(+W, M-2-yi) ; ++dyi) { /* Compute the gradient. */ float mod = *(pt + dxi*xo + dyi*yo + 0 ) ; float angle = *(pt + dxi*xo + dyi*yo + buffer_size ) ; #ifdef LOWE_COMPATIBLE float theta = fast_mod(-angle + theta0) ; #else float theta = fast_mod(angle - theta0) ; #endif /* Get the fractional displacement. */ float dx = ((float)(xi+dxi)) - x; float dy = ((float)(yi+dyi)) - y; /* Get the displacement normalized w.r.t. the keypoint orientation * and extension. */ float nx = ( ct0 * dx + st0 * dy) / SBP ; float ny = (-st0 * dx + ct0 * dy) / SBP ; float nt = NBO * theta / (2*M_PI) ; /* Get the gaussian weight of the sample. The gaussian window * has a standard deviation of NBP/2. Note that dx and dy are in * the normalized frame, so that -NBP/2 <= dx <= NBP/2. */ const float wsigma = NBP/2 ; float win = expf(-(nx*nx + ny*ny)/(2.0 * wsigma * wsigma)) ; /* The sample will be distributed in 8 adijacient bins. * Now we get the ``lower-left'' bin. */ int binx = fast_floor( nx - 0.5 ) ; int biny = fast_floor( ny - 0.5 ) ; int bint = fast_floor( nt ) ; float rbinx = nx - (binx+0.5) ; float rbiny = ny - (biny+0.5) ; float rbint = nt - bint ; int dbinx ; int dbiny ; int dbint ; /* Distribute the current sample into the 8 adijacient bins. */ for(dbinx = 0 ; dbinx < 2 ; ++dbinx) { for(dbiny = 0 ; dbiny < 2 ; ++dbiny) { for(dbint = 0 ; dbint < 2 ; ++dbint) { if( binx+dbinx >= -(NBP/2) && binx+dbinx < (NBP/2) && biny+dbiny >= -(NBP/2) && biny+dbiny < (NBP/2) ) { float weight = win * mod * fabsf(1 - dbinx - rbinx) * fabsf(1 - dbiny - rbiny) * fabsf(1 - dbint - rbint) ; atd(binx+dbinx, biny+dbiny, (bint+dbint) % NBO) += weight ; } } } } } } { /* Normalize the histogram to L2 unit length. */ normalize_histogram(descr_pt, descr_pt + NBO*NBP*NBP) ; /* Truncate at 0.2. */ for(bin = 0; bin < NBO*NBP*NBP ; ++bin) { if (descr_pt[bin] > 0.2) descr_pt[bin] = 0.2; } /* Normalize again. */ normalize_histogram(descr_pt, descr_pt + NBO*NBP*NBP) ; } } } /* Restore pointer to the beginning of the descriptors. */ descr_pt -= NBO*NBP*NBP*K ; { int k ; double* L_pt ; out[OUT_L] = mxCreateDoubleMatrix(NBP*NBP*NBO, K, mxREAL) ; L_pt = mxGetPr(out[OUT_L]) ; for(k = 0 ; k < NBP*NBP*NBO*K ; ++k) { L_pt[k] = descr_pt[k] ; } } mxFree(descr_pt) ; mxFree(buffer_pt) ; }