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);
						}
					}
				}
			}
		}
	}
}
Example #3
0
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;
}
Example #4
0
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 */
}
Example #5
0
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
      );
  }
}
Example #6
0
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);
	}
}
Example #7
0
/*-------------------------------------------------------------------------------------------------------------- */
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];	
		}
	}
}
Example #8
0
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;

}
Example #9
0
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;
}
Example #10
0
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);
}
Example #11
0
/***********************************************************************//**
 * \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;
        }
    }


}
Example #12
0
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 *******/
}
Example #13
0
// 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;
	}
  }
 
}
Example #14
0
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(&param, 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;
}
Example #15
0
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;
}
Example #17
0
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;
}
Example #18
0
// 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" );

		}
	}
}
Example #20
0
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;
}
Example #21
0
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);
}
Example #23
0
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;   
  }
}
Example #26
0
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)!");
  }
}
Example #27
0
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] ;
	}
    }
}
Example #28
0
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;
}
Example #29
0
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);
}
Example #30
0
/** @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) ;
}