Esempio n. 1
0
void mexFunction(int nlhs,   /* number of arguments on lhs */
		 mxArray	*plhs[],   			/* Matrices on lhs      */
		 int nrhs,	   						/* no. of mat on rhs    */
		 const mxArray	*prhs[]   /* Matrices on rhs      */
		 )
{
  register const double *data;     /* pointer to input data */
  mxArray *xArray;  								/* pointer to output x */
  register double *h, *x;					/* pointers to histogram and intensity values */
  register int npoints;      				/* number of points in the input array */
  int Nbins;        								/* number of bins in the histogram */
  double *NbinsPtr; 								/* pointer to the number of bins input argument */
  int Outdims[2];   								/* dimensions of the output arrays */

  /* Check for proper number of arguments */
  if (nrhs<1) { /* help */
   printf("[h, x] = regHistogram(A, <Nbins>);\n");
   printf("    Computes the histogram of a N-dimensional array (A), \n");
   printf("    using Nbins intervals (default = 256). \n");
  }

  /* reading input parameters */
  data = mxGetPr(prhs[0]);
  npoints = mxGetNumberOfElements(prhs[0]);
  if (nrhs==2) {
    NbinsPtr = mxGetPr(prhs[1]);
    Nbins = (int)(*NbinsPtr);}
  else {
    Nbins = 256;}

  /* creating output array for histogram and intensity values, with
     room for one more value (corresponding to Max */
  Outdims[0] = 1; Outdims[1] = Nbins+1;
  plhs[0] = mxCreateNumericArray(2, Outdims, mxDOUBLE_CLASS, mxREAL);
  xArray = mxCreateNumericArray(2, Outdims, mxDOUBLE_CLASS, mxREAL);
  h = mxGetPr(plhs[0]);
  x = mxGetPr(xArray);

  /* main routine */
  histogram(data, npoints, h, x, Nbins);

  /* returning arrays with the actual number of bins */
  Outdims[0] = 1; Outdims[1] = Nbins;
  mxSetDimensions(plhs[0], Outdims, 2);
  mxSetDimensions(xArray, Outdims, 2);

  /* returning bin centers if requested */
  if (nlhs == 2) {
    plhs[1] = xArray;
  }
}
void mexFunction(int nlhs, mxArray* plhs[], int nrhs, const mxArray* prhs[])
{	
	if (nlhs > 1) {
        mexErrMsgTxt("Too many output arguments.");
    }
	switch(nrhs) {
    default: {
    	mexErrMsgTxt("Incorrect number of arguments.");
        }
    case 0: {
        mexPrintf("\nColumnwise dot-product matrix with vector.\n\n");
        break;
        }
	case 2: {
		int m=mxGetN(Vec);
		int n=mxGetN(Mat);
		Out=mxCreateDoubleMatrix(0,0,mxREAL);
		if (m == 1 && n > 0) {
            int i, j, k=0;
			const int* e=mxGetDimensions(Mat);
			double* or;
            double* inMat=mxGetPr(Mat);
            double* inVec=mxGetPr(Vec);
            mxSetDimensions(Out,e,2);
    		mxSetPr(Out,or=(double*) mxMalloc(e[0]*e[1]*sizeof(double)));
            for (i=0; i<e[1]; i++) {
                for (j=0; j<e[0]; j++) {
                    or[k] = inMat[k]*inVec[j];
                    k++;
                }
            }
		}
        }
	}
}
Esempio n. 3
0
//================================================================
void mexFunction(	int nlhs, mxArray *plhs[], 
					int nrhs, const mxArray*prhs[] ) 
//================================================================                    
{
	//------------------------------------------------------------------
	/* retrive arguments */
	//------------------------------------------------------------------
	if( (nrhs!=2)  )
    {
		mexErrMsgTxt("2 arguments are required.");
    }
	//------------------------------------------------------------------
	// first argument : Set of points
    if( (mxGetClassID(prhs[0]) != mxDOUBLE_CLASS) || (mxGetNumberOfDimensions(prhs[0])!= 2) 
		||    mxGetDimensions(prhs[0])[0] != 2 ) 
	{
			mexErrMsgTxt("tforth input shoud be an array containing the [mean_i, std_i] intensities of the nuclei regions") ;
	}
    
    POINTS = mxGetPr(prhs[0]);
    number_of_points = mxGetDimensions(prhs[0])[1];
	//------------------------------------------------------------------
	// Second argument : Distance map for the back propagation
    if( (mxGetClassID(prhs[1]) != mxDOUBLE_CLASS) || (mxGetNumberOfDimensions(prhs[1])!= 2) ) 
    {
        mexErrMsgTxt("Distance map for the back propagation must be a 2D double array AND \n must be of class double") ;
    }
    
	UU = (double*)mxGetPr(prhs[1]);
    nx = mxGetDimensions(prhs[1])[0];
	ny = mxGetDimensions(prhs[1])[1];
	Nx = nx+2; Ny = ny+2;
	size = Nx*Ny;
	//------------------------------------------------------------------
    //==================================================================
	// Outputs
	mwSize dims[2] = {Nx,Ny};
	// First output : minimal action map
	plhs[0] = mxCreateNumericArray(2, dims, mxLOGICAL_CLASS, mxREAL );
	Filaments = (bool*) mxGetPr(plhs[0]);
	//==================================================================
	InitializeNeighborhoods();
    //------------------------------------------------------------------
	InitializeArrays();
    	//------------------------------------------------------------------
 	BackPropagate();
	//==================================================================
	resize();
	dims[0] = Nx-2; dims[1] = Ny-2;
	mxSetDimensions(plhs[0], dims, 2);
	//==================================================================
    mxFree(U);
    mxFree(NeighborhoodLarge);
    mxFree(END_POINTS);
    return;
}
Esempio n. 4
0
// Create [hxwxd] mxArray array, initialize to 0 if c=true
mxArray* mxCreateMatrix3( int h, int w, int d, mxClassID id, bool c, void **I ){
  const int dims[3]={h,w,d}, n=h*w*d; int b; mxArray* M;
  if( id==mxINT32_CLASS ) b=sizeof(int);
  else if( id==mxDOUBLE_CLASS ) b=sizeof(double);
  else if( id==mxSINGLE_CLASS ) b=sizeof(float);
  else mexErrMsgTxt("Unknown mxClassID.");
  *I = c ? mxCalloc(n,b) : mxMalloc(n*b);
  M = mxCreateNumericMatrix(0,0,id,mxREAL);
  mxSetData(M,*I); mxSetDimensions(M,dims,3); return M;
}
Esempio n. 5
0
void permute_data(mxArray *data, int p, int N, int n)
{
    int dims[3];
    
    if(N > 1) {
        int i;
        double *pdata   = mxGetPr(data);
        double *temp    = (double *)mxCalloc(p*n*N, sizeof(double));
        
        permute(p, N, n, pdata, temp);
        for(i=0; i<p*n*N; i++) pdata[i] = temp[i];
        mxFree(temp);
        
        dims[0] = p; dims[1] = n; dims[2] = N;
        mxSetDimensions(data, dims, 3);
    }
    else {
        dims[0] = p; dims[1] = n;
        mxSetDimensions(data, dims, 2);
    }
}
static const mxArray *emlrt_marshallOut(emxArray_real_T *u)
{
  const mxArray *y;
  static const int32_T iv2[2] = { 0, 0 };

  const mxArray *m2;
  y = NULL;
  m2 = mxCreateNumericArray(2, (int32_T *)&iv2, mxDOUBLE_CLASS, mxREAL);
  mxSetData((mxArray *)m2, (void *)u->data);
  mxSetDimensions((mxArray *)m2, u->size, 2);
  emlrtAssign(&y, m2);
  return y;
}
Esempio n. 7
0
void mexFunction( int nlhs, mxArray* plhs[], int nrhs, const mxArray* prhs[] ) {
  int *ns, ms[3], nDims, d, m, r, s; float *A, *B, p;
  mxClassID id; char type[1024];

  // error checking on arguments
  if(nrhs!=4) mexErrMsgTxt("Four inputs required.");
  if(nlhs > 1) mexErrMsgTxt("One output expected.");
  nDims = mxGetNumberOfDimensions(prhs[1]);
  id = mxGetClassID(prhs[1]);
  ns = (int*) mxGetDimensions(prhs[1]);
  d = (nDims == 3) ? ns[2] : 1;
  m = (ns[0] < ns[1]) ? ns[0] : ns[1];
  if( (nDims!=2 && nDims!=3) || id!=mxSINGLE_CLASS || m<4 )
    mexErrMsgTxt("A must be a 4x4 or bigger 2D or 3D float array.");

  // extract inputs
  if(mxGetString(prhs[0],type,1024))
    mexErrMsgTxt("Failed to get type.");
  A = (float*) mxGetData(prhs[1]);
  p = (float) mxGetScalar(prhs[2]);
  r = (int) mxGetScalar(prhs[2]);
  s = (int) mxGetScalar(prhs[3]);
  if( s<1 ) mexErrMsgTxt("Invalid sampling value s");
  if( r<0 ) mexErrMsgTxt("Invalid radius r");

  // create output array (w/o initializing to 0)
  ms[0]=ns[0]/s; ms[1]=ns[1]/s; ms[2]=d;
  B = (float*) mxMalloc(ms[0]*ms[1]*d*sizeof(float));
  plhs[0] = mxCreateNumericMatrix(0, 0, mxSINGLE_CLASS, mxREAL);
  mxSetData(plhs[0], B); mxSetDimensions(plhs[0],(mwSize*)ms,nDims);

  // perform appropriate type of convolution
  if(!strcmp(type,"convBox")) {
    if(r>=m/2) mexErrMsgTxt("mask larger than image (r too large)");
    convBox( A, B, ns[0], ns[1], d, r, s );
  } else if(!strcmp(type,"convTri")) {
    if(r>=m/2) mexErrMsgTxt("mask larger than image (r too large)");
    convTri( A, B, ns[0], ns[1], d, r, s );
  } else if(!strcmp(type,"conv11")) {
    if( s>2 ) mexErrMsgTxt("conv11 can sample by at most s=2");
    conv11( A, B, ns[0], ns[1], d, r, s );
  } else if(!strcmp(type,"convTri1")) {
    if( s>2 ) mexErrMsgTxt("convTri1 can sample by at most s=2");
    convTri1( A, B, ns[0], ns[1], d, p, s );
  } else if(!strcmp(type,"convMax")) {
    if( s>1 ) mexErrMsgTxt("convMax cannot sample");
    convMax( A, B, ns[0], ns[1], d, r );
  } else {
    mexErrMsgTxt("Invalid type.");
  }
}
Esempio n. 8
0
void mexFunction(int nlhs, mxArray *plhs[], /* Output variables */ 
				 int nrhs, const mxArray *prhs[] /* Input variables */){
	
	//OUTPUT/INPUT PARAMETERS
	#define HIST_OUT plhs[0]
	#define IMG_IN prhs[0]
	#define ROW_IN prhs[1]
	#define COL_IN prhs[2]
	#define BIN_IN prhs[3]
	
	//POINTER VARIABLES
	double *imgBins, *intHist;
	int r, c, b, Row, Col, Bin, intHistDims[3];
	
	//INPUT: Pointers
	imgBins = mxGetPr(IMG_IN);    
	Row = (int)mxGetScalar(ROW_IN);
	Col = (int)mxGetScalar(COL_IN);
	Bin = (int)mxGetScalar(BIN_IN);
	
	intHistDims[0] = Row;
	intHistDims[1] = Col;
	intHistDims[2] = Bin;
	
	//OUTPUT: Pointers
	HIST_OUT = mxCreateDoubleMatrix(Row*Col*Bin, 1, mxREAL);
	intHist = mxGetPr(HIST_OUT);
	mxSetDimensions(HIST_OUT, intHistDims, 3);
	//memset(intHist, 0, sizeof(double)*Row*Col*Bin);
	
	/* IMAGE INTEGRAL HISTOGRAM */
	
	for(r=0; r<Row; r++){
		for(c=0; c<Col; c++){
			//INITIALIZE
			for(b=0; b<Bin; b++) intHist[index3D(r,c,b,Row,Col,Bin)] = 0;
			
			//CHECK IF IMG_IN_BINs == BIN_IN
			b = imgBins[index2D(r,c,Row,Col)];
			if (b > Bin) mexErrMsgTxt("IMG_IN Beans exceed BIN_IN");
			
			intHist[index3D(r,c,b-1,Row,Col,Bin)] = 1;
			for(b=0; b<Bin; b++){
				if (r > 0) 			intHist[index3D(r,c,b,Row,Col,Bin)] += intHist[index3D(r-1,c  ,b,Row,Col,Bin)];
				if (c > 0) 			intHist[index3D(r,c,b,Row,Col,Bin)] += intHist[index3D(r  ,c-1,b,Row,Col,Bin)];
				if (r > 0 && c > 0) intHist[index3D(r,c,b,Row,Col,Bin)] -= intHist[index3D(r-1,c-1,b,Row,Col,Bin)];
			}
		}
	}
}
Esempio n. 9
0
static
mxArray* AllocateOutputArray(const mxArray* In, int OutputChannels)
{       
 
	mxArray*	Out			  = mxDuplicateArray(In);   // Make a "deep copy" of Input array 
    int         nDimensions   = mxGetNumberOfDimensions(In);    
    const int*	Dimensions    = mxGetDimensions(In);
    int         InputChannels = Dimensions[nDimensions-1];


    // Modify pixel size only if needed

    if (InputChannels != OutputChannels) {
    
		
        int i, NewSize;
        int *ModifiedDimensions = (int*) mxMalloc(nDimensions * sizeof(int));
	

        CopyMemory(ModifiedDimensions, Dimensions, nDimensions * sizeof(int));
        ModifiedDimensions[nDimensions - 1] = OutputChannels;
        
		switch (mxGetClassID(In))  {

		case mxINT8_CLASS:   NewSize = sizeof(char); break;
		case mxUINT8_CLASS:  NewSize = sizeof(unsigned char); break;
		case mxINT16_CLASS:  NewSize = sizeof(short); break;
		case mxUINT16_CLASS: NewSize = sizeof(unsigned short); break;

		default:
		case mxDOUBLE_CLASS: NewSize = sizeof(double); break;
		}
 

        // NewSize = 1;
        for (i=0; i < nDimensions; i++)
            NewSize *= ModifiedDimensions[i];
        

        mxSetDimensions(Out, ModifiedDimensions, nDimensions);
        mxFree(ModifiedDimensions);
        
        mxSetPr(Out, mxRealloc(mxGetPr(Out), NewSize));             

    }


    return Out;
}
Esempio n. 10
0
void mexFunction(int nlhs, mxArray *plhs[], /* Output variables */ 
				 int nrhs, const mxArray *prhs[] /* Input variables */){
	
	//OUTPUT/INPUT PARAMETERS
	#define HIST_OUT plhs[0]
	#define INT_HIST_IN prhs[0]
	#define ROW_IN prhs[1]
	#define COL_IN prhs[2]
	#define BIN_IN prhs[3]
	#define X1_IN prhs[4]
	#define Y1_IN prhs[5]
	#define X2_IN prhs[6]
	#define Y2_IN prhs[7]
	
	//POINTER VARIABLES
	double *intHist, *hist;
	int i, j, k, x1, y1, x2, y2, Row, Col, Bin, histDims[3];

	//INPUT: Pointers
	intHist = mxGetPr(INT_HIST_IN); 
	Bin = (int)mxGetScalar(BIN_IN);
	Row = (int)mxGetScalar(ROW_IN);
	Col = (int)mxGetScalar(COL_IN);
	x1 = (int)mxGetScalar(X1_IN)-1;
	y1 = (int)mxGetScalar(Y1_IN)-1;
	x2 = (int)mxGetScalar(X2_IN)-1;
	y2 = (int)mxGetScalar(Y2_IN)-1;

	histDims[0] = Bin;
	histDims[1] = Bin;
	histDims[2] = Bin;
	
	//OUTPUT: Pointers
	HIST_OUT = mxCreateDoubleMatrix(Bin*Bin*Bin, 1, mxREAL);
	hist = mxGetPr(HIST_OUT);
	mxSetDimensions(HIST_OUT, histDims, 3);
	
	for(i=0; i<Bin; i++)
		for(j=0; j<Bin; j++)
			for(k=0; k<Bin; k++){
				hist[index3D(i,j,k,Bin,Bin,Bin)] = intHist[index5D(y2,x2,i,j,k,Row,Col,Bin,Bin,Bin)];
				if (y1-1 > 0) hist[index3D(i,j,k,Bin,Bin,Bin)] -= intHist[index5D(y1-1,x2,i,j,k,Row,Col,Bin,Bin,Bin)];
				if (x1-1 > 0) hist[index3D(i,j,k,Bin,Bin,Bin)] -= intHist[index5D(y2,x1-1,i,j,k,Row,Col,Bin,Bin,Bin)];
				if (y1-1 > 0 && x1-1 > 0) hist[index3D(i,j,k,Bin,Bin,Bin)] += intHist[index5D(y1-1,x1-1,i,j,k,Row,Col,Bin,Bin,Bin)];
			}
}
Esempio n. 11
0
void applyTransform(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) {
  /* J=applyTransform(I,rs,cs,is,flag); */
  int flag, *nsI, nsJ[3], areaJ, areaI, nDims, i, k, id, *is;
  double *I, *J, *I1, *J1, *rs, *cs, wr, wc, wrc, r, c;

  /* extract inputs */
  I   = (double*) mxGetData(prhs[0]);
  rs  = (double*) mxGetData(prhs[1]);
  cs  = (double*) mxGetData(prhs[2]);
  is  = (int*) mxGetData(prhs[3]);
  flag = (int) mxGetScalar(prhs[4]);

  /* get dimensions */
  nDims = mxGetNumberOfDimensions(prhs[0]);
  nsI = (int*) mxGetDimensions(prhs[0]);
  nsJ[0]=(int)mxGetM(prhs[1]); nsJ[1]=(int)mxGetN(prhs[1]);
  nsJ[2]=(nDims==2) ? 1 : nsI[2];
  areaJ=nsJ[0]*nsJ[1]; areaI=nsI[0]*nsI[1];

  /* Perform interpolation */
  J = mxMalloc(sizeof(double)*areaJ*nsJ[2]);
  if( flag==1 ) { /* nearest neighbor */
    for( k=0; k<nsJ[2]; k++ ) {
      J1=J+areaJ*k; I1=I+areaI*k;
      for( i=0; i<areaJ; i++ ) J1[i]=I1[is[i]];
    }
  } else if( flag==2 ) { /* bilinear */
    for( k=0; k<nsJ[2]; k++ ) {
      J1=J+areaJ*k; I1=I+areaI*k;
      for( i=0; i<areaJ; i++ ) {
        id=is[i]; wr=rs[i]; wc=cs[i]; wrc=wr*wc;
        J1[i]=I1[id]*(1-wr-wc+wrc) + I1[id+1]*(wr-wrc)
          + I1[id+nsI[0]]*(wc-wrc) + I1[id+nsI[0]+1]*wrc;
      }
    }
  }

  /* create output array */
  plhs[0] = mxCreateNumericMatrix(0,0,mxDOUBLE_CLASS,mxREAL);
  mxSetData(plhs[0],J); mxSetDimensions(plhs[0],nsJ,3);
}
Esempio n. 12
0
mxArray *mxCreateNumericArrayE(mwSize ndim, const mwSize *dims, 
         mxClassID classid, mxComplexity ComplexFlag)
{
  mxArray *a;
  mwSize i;
  mwSize *dims1 = mxMalloc(ndim*sizeof(mwSize));
  mwSize sz = 1;
  for(i=0;i<ndim;i++) {
    sz *= dims[i];
    dims1[i] = 1;
  }
  a = mxCreateNumericArray(ndim,dims1,classid,ComplexFlag);
  sz *= mxGetElementSize(a);
  mxSetDimensions(a, dims, ndim);
  mxFree(dims1);
  mxSetData(a, mxRealloc(mxGetData(a), sz));
  if(ComplexFlag == mxCOMPLEX) {
    mxSetPi(a, mxRealloc(mxGetPi(a),sz));
  }
  return a;
}
static void emlrt_marshallOut(emxArray_real_T *u, const mxArray *y)
{
  mxSetData((mxArray *)y, (void *)u->data);
  mxSetDimensions((mxArray *)y, u->size, 2);
}
Esempio n. 14
0
void mexFunction(int nlhs, mxArray* plhs[], int nrhs, const mxArray* prhs[])
{
    OID ID;

    /* OMEIS data structures */
    omeis* is;
    pixHeader* head;
    void* pixels;

    /* MATLAB data structueres */
    mxArray *m_url, *m_sessionkey;
    mxArray *permute_inputs[2];
    int result;

    char* url, *sessionkey;

    if (nrhs != 12)
        mexErrMsgTxt("\n [pixels] = getROI (is, ID, row0 (OME:y0), column0 (OME:x0), z0, c0, t0, row1 (OME:y1), column1 (OME:x1), z1, c1, t1)");

    if (!mxIsStruct(prhs[0]))
        mexErrMsgTxt("getROI requires the first input to be the struct outputed"
                     " from openConnectionOMEIS\n");

    if (!(m_url = mxGetField(prhs[0], 0, "url")))
        mexErrMsgTxt("getROI requires the first input, OMEIS struct, to have field: url");
    if (!(m_sessionkey = mxGetField(prhs[0], 0, "sessionkey")))
        mexErrMsgTxt("getROI requires the first input, OMEIS struct, to have field: sessionkey");

    if (!mxIsChar(m_url) || !mxIsChar(m_sessionkey))
        mexErrMsgTxt("OMEIS field aren't character array.\n");

    if (!mxIsNumeric(prhs[1]))
        mexErrMsgTxt("getROI requires the second input to be the PixelsID\n") ;

    ID = (OID) mxGetScalar(prhs[1]) ;

    /* get ROI */
    /* NB x0/y0 and x1/y1 are switched on purpose because of the different orientations
     used in MATLAB and OME. See note below */
    int y0 = (int) mxGetScalar(prhs[2]); /* switched */
    int x0 = (int) mxGetScalar(prhs[3]); /* switched */
    int z0 = (int) mxGetScalar(prhs[4]);
    int c0 = (int) mxGetScalar(prhs[5]);
    int t0 = (int) mxGetScalar(prhs[6]);
    int y1 = (int) mxGetScalar(prhs[7]); /* switched */
    int x1 = (int) mxGetScalar(prhs[8]); /* switched */
    int z1 = (int) mxGetScalar(prhs[9]);
    int c1 = (int) mxGetScalar(prhs[10]);
    int t1 = (int) mxGetScalar(prhs[11]);

    url = mxArrayToString(m_url);
    sessionkey = mxArrayToString(m_sessionkey);

    is = openConnectionOMEIS (url, sessionkey);
    if (!(head = pixelsInfo (is, ID))) {
        char err_str[128];
        sprintf(err_str, "PixelsID %llu or OMEIS URL '%s' is probably wrong\n", ID, is->url);

        /* clean up */
        mxFree(url);
        mxFree(sessionkey);
        mxFree(is);

        mexErrMsgTxt(err_str);
    }

    if (!(pixels = getROI (is, ID, x0, y0, z0, c0, t0, x1, y1, z1, c1, t1))) {
        /* clean up */
        mxFree(url);
        mxFree(sessionkey);
        mxFree(head);
        mxFree(is);

        char err_str[128];
        sprintf(err_str, "Couldn't load ROI from pixelsID %llu. ROI dims are probably wrong.\n", ID);
        mexErrMsgTxt(err_str);
    }

    /* convert ROI to dims */
    mwSize dims[5];
    dims[0] = (mwSize) (x1-x0+1);
    dims[1] = (mwSize) (y1-y0+1);
    dims[2] = (mwSize) (z1-z0+1);
    dims[3] = (mwSize) (c1-c0+1);
    dims[4] = (mwSize) (t1-t0+1);

    /* attach pixels from OMEIS to MATLAB array */
    mwSize tmp_dims[2] = {1,1};
    plhs[0] = mxCreateNumericArray (2, tmp_dims, OMEIStoMATLABDatatype(head), mxREAL);

    mxSetData (plhs[0], pixels);
    mxSetDimensions (plhs[0], dims, 5);

    /*
    	In OMEIS Size_X corresponds to columns and Size_Y corresponds to rows.
    	This is diametrically opposite to MATLAB's assumptions.
    	hence we do
    	"$matlab_var_name = permute($matlab_var_name, [2 1 3 4 5]);"
    	the hard way (groan)
    */
    permute_inputs[0] = plhs[0];
    permute_inputs[1] = mxCreateDoubleMatrix(1, 5, mxREAL);
    mxGetPr(permute_inputs[1])[0] = 2;
    mxGetPr(permute_inputs[1])[1] = 1;
    mxGetPr(permute_inputs[1])[2] = 3;
    mxGetPr(permute_inputs[1])[3] = 4;
    mxGetPr(permute_inputs[1])[4] = 5;
    /* returns 0 if successful */
    result = mexCallMATLAB(1, plhs, 2, permute_inputs, "permute");

    /* clean up */
    mxFree(url);
    mxFree(sessionkey);
    mxFree(head);
    mxFree(is);
    mxDestroyArray(permute_inputs[1]);

    if (result) {
        char err_str[128];
        sprintf(err_str, "Couldn't permute the pixels to get them in MATLAB orientation");
        mexErrMsgTxt(err_str);
    }
}
Esempio n. 15
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
      );
  }
}
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_frames :
      if (!vlmxIsMatrix(optarg, 4, -1)) {
        mexErrMsgTxt("'Frames' must be a 4 x N matrix.") ;
      }
      ikeys_array = mxDuplicateArray (optarg) ;
      nikeys      = mxGetN (optarg) ;
      ikeys       = mxGetPr (ikeys_array) ;
      if (! check_sorted (ikeys, nikeys)) {
        qsort (ikeys, nikeys, 4 * sizeof(double), korder) ;
      }
      break ;

    default :
		mexPrintf("F**k you!");
      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) ;

	//mexPrintf("%f %f %f \n%f %f %f %f %f\n",(float)O,(float)S,(float)o_min,(float)peak_thresh
	//	,(float)edge_thresh,(float)norm_thresh,(float)magnif,(float)window_size);


    /* ...............................................................
     *                                             Process each octave
     * ............................................................ */
    i     = 0 ;
    first = 1 ;
    while (first == 1) {
      int                   err ;
      VlSiftKeypoint const *keys  = 0 ;
      int                   nkeys = 0 ;


        err   = vl_sift_process_first_octave (filt, data) ;
        first = 0 ;

      if (err) break ;

      /* Run detector ............................................. */
        nkeys = nikeys ;

	  //mexPrintf("Zhu: entering sweeping nkeys, nkeys = %d, i = %d \n", nkeys, i);

      /* For each keypoint ........................................ */
		for (; i < nkeys ; ++i) {
			int h;
			vl_sift_pix  buf[128];
			vl_sift_pix rbuf[128];
        double                angle;
        VlSiftKeypoint        ik ;
        VlSiftKeypoint const *k ;

        /* Obtain keypoint orientations ........................... */
          vl_sift_keypoint_init (filt, &ik,
                                 ikeys [4 * i + 1] - 1,
                                 ikeys [4 * i + 0] - 1,
                                 ikeys [4 * i + 2]) ;
		  //mexPrintf("ikeys: [%f, %f, %f]\n", (float)(ikeys [4 * i + 1] - 1), (float)(ikeys [4 * i + 0] - 1), (float)(ikeys [4 * i + 2]) );

          k = &ik ;

          /* optionally compute orientations too */
            angle = VL_PI / 2 - ikeys [4 * i + 3] ;
			q = 0;

		  
		  /* compute descriptor (if necessary) */
		  //int h;
		  //mexPrintf("M = %d, N = %d.\n",M,N);
		  //for (h = 0; h < 300; h++) 
		  //{
			//  mexPrintf("%f ",data[h]);
			//  if (h % 8 == 7) mexPrintf("\n");
		  //}
          if (nout > 1) {
			  //mexPrintf("angles = %f, x = %f(%d), y = %f(%d), s = %f(%d), o = %d, sigma = %f.\n buf = [", 
				  //angle,k->x,k->ix,k->y,k->iy,k->s,k->is,k->o,k->sigma);
			  vl_sift_calc_keypoint_descriptor (filt, buf, k, angle) ;
			  //for (h = 0; h < 128; h++) 
			  //{
				//  mexPrintf("%f ",(float)buf[h]);
				//  if (h % 8 == 7) mexPrintf("\n");
			  //}
			  //mexPrintf("...].\nrbuf = [");
			  transpose_descriptor (rbuf, buf) ;
			  //for (h = 0; h < 128; h++) 
			  //{
				//  mexPrintf("%f ",(float)rbuf[h]);
				//  if (h % 8 == 7) mexPrintf("\n");
			  //}
			  //mexPrintf("...].\n");
          }

          /* 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 - angle;

		  //mexPrintf("Zhu: %d\n", nframes);
          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 */
	  //break;
	  //mexPrintf("Zhu: skip subsequent octave\n");
    } /* next octave */

	//mexPrintf("nframes_tot = %d\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 */
}
Esempio n. 17
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)!");
  }
}
Esempio n. 18
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 */
}
Esempio n. 19
0
void mexFunction( int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[] )
{
  // get inputs
  float *chns = (float*) mxGetData(prhs[0]);
  float *chnsSs = (float*) mxGetData(prhs[1]);
  float *thrs = (float*) mxGetData(prhs[2]);
  uint32 *fids = (uint32*) mxGetData(prhs[3]);
  uint32 *child = (uint32*) mxGetData(prhs[4]);
  float *distr = (float*) mxGetData(prhs[5]);//
  uint32 *cids1 =  (uint32*) mxGetData(prhs[6]);
  uint32 *cids2 =  (uint32*) mxGetData(prhs[7]);
  const int stride = (int) mxGetScalar(prhs[8]);// 2
  const int rad = (int) mxGetScalar(prhs[9]);//17
  const int nChnFtrs = (int) mxGetScalar(prhs[10]);//17150

  // get dimensions and constants
  const mwSize *chnsSize = mxGetDimensions(prhs[0]);
  const int height = (int) chnsSize[0];//634
  const int width = (int) chnsSize[1];//434
  const mwSize *distrSize = mxGetDimensions(prhs[5]);
  const int nTokens = (int) distrSize[0];//
  const int nTreeNodes = (int) distrSize[1];//
  const int nTrees = (int) distrSize[2];//
  const int heightOut = (int) ceil((height-rad*2.0)/stride);
  const int widthOut = (int) ceil((width-rad*2.0)/stride);

  // create output
  const int outDims[3]={nTokens,heightOut,widthOut};
  float *S = (float*) mxCalloc(nTokens*heightOut*widthOut,sizeof(float));
  plhs[0] = mxCreateNumericMatrix(0,0,mxSINGLE_CLASS,mxREAL);
  mxSetData(plhs[0],S);
  mxSetDimensions(plhs[0],outDims,3);

  // apply forest to each patch
  #pragma omp parallel for
  for( int c=0; c<widthOut; c++ ) {
      for( int r=0; r<heightOut; r++ ) {
        // classify a single patch using all trees
        float *chns1 = chns + (r*stride) + (c*stride)*height;
        float *chnsSs1 = chnsSs + (r*stride) + (c*stride)*height;
        
        for( int t = 0; t < nTrees; t++ ) {
            uint32 k = t*nTreeNodes, res;
            
            while( child[k] ) {
                // compute feature (either lookup in channel or self-similarity feature)
                uint32 f = fids[k], cid1 = cids1[f], cid2 = cids2[f];
                float ftr;
                
                if( f<nChnFtrs )
                    ftr = chns1[cid1];
                else
                    ftr = chnsSs1[cid1] - chnsSs1[cid2];
                
                // compare ftr to threshold and move left or right accordingly
                if( ftr < thrs[k] )
                    k = child[k]-1;
                else
                    k = child[k];
                
                res = k;
                k += t*nTreeNodes;
            }
            
            // lookup probability and store results
            for( int i = 0; i < nTokens; i++ ) {
                S[r*nTokens + c*heightOut*nTokens + i] += distr[t*nTreeNodes*nTokens + res*nTokens + i];
            }
        }
      }
  }
}
/*
 * Main Documentation:
 * http://www.libjpeg-turbo.org/Documentation/Documentation
 * See C API
 *
 *
 *  Functions Used:
 *  tjDecompressHeader2
 *  tjDecompress2
 */
void mexFunction( int nlhs, mxArray *plhs[], int nrhs, const mxArray*prhs[] )
{
    
    //Calling form:
    //img_data = readJPG(uncompressed_image_data);
    //
    //  INPUTS
    //  ------------------------------------------------
    //  uncompressed_image_data: (uint8 array)
    //
    //
    //  Documentation
    //  http://libjpeg-turbo.sourceforge.net/ljtdoc.branches_1.3.x/turbojpeg-c/group___turbo_j_p_e_g.html
    
    uint8_T* buffer;
    
    unsigned char* compressed_image;
    int compressed_image_size;
    
    mwSize dims[3] = {0,0,0};
    int width;
    int height;
    int pixel_format;
    int flags;
    int is_3d;
    int option;
    int jpeg_subsamp;
    tjhandle jpeg_decompressor;
    
    //Input Checking
    //---------------------------------------------------------------------
    if (nrhs != 2) {
        mexErrMsgTxt("2 inputs needed, readJPGHelper(u8_data,option)");
    }else if (!mxIsUint8(prhs[0])) {
        mexErrMsgTxt("Input data type must be uint8");
    }
    
    //Input Retrieval
    //---------------------------------------------------------------------
    compressed_image      = (unsigned char *)mxGetData(prhs[0]);
    compressed_image_size = (int)mxGetNumberOfElements(prhs[0]);
    option                = (int)mxGetScalar(prhs[1]);
        
    switch (option) {
        case 1:
            //fast RGB
            flags = TJFLAG_FASTDCT;
            pixel_format = TJPF_RGB;
            is_3d = 1;
            break;
        case 2:
            //slow RGB
            flags = 0;
            pixel_format = TJPF_RGB;
            is_3d = 1;
            break;
        case 3:
            //fast gray
            flags = TJFLAG_FASTDCT;
            pixel_format = TJPF_GRAY;
            is_3d = 0;
            break;
        case 4:
            //slow gray
            flags = 0;
            pixel_format = TJPF_GRAY;
            is_3d = 0;
            break;
        default:
            mexErrMsgTxt("Invalid input option");
            break;   
    }
    
    
    jpeg_decompressor = tjInitDecompress();
    
    //Retrieve image information, namely width and height
    //tjhandle handle, unsigned char *jpegBuf, unsigned long jpegSize, int *width, int *height, int *jpegSubsamp
    //
    // NOTE: This might change for 1.4 ... to tjDecompressHeader3 with color type included
    tjDecompressHeader2(jpeg_decompressor, compressed_image, compressed_image_size, &width, &height, &jpeg_subsamp);
    
    //NOTE, this might eventually change based on what we want out
    //--------------------------------------------
    if (is_3d) {
        buffer = mxMalloc((width)*(height)*3); //*3 implies RGB
    }else{
        buffer = mxMalloc((width)*(height));
    }
    
    //mexPrintf("Width: %d\n",width);
    //mexPrintf("Height: %d\n",height);
    //mexPrintf("sub_samp: %d\n",jpeg_subsamp);
    
    
    //Last two inputs are flags and options
    //I'm not sure how to distinguish them, but the inputs are very different
    //After height:
    //1) pixel_format
    //2) flags
    //
    //Pixel Formats
    //---------------------------------------------------------------------
    //TJPF_RGB - RGB
    //TJPF_GRAY
    //
    //Flags
    //---------------------------------------------------------------------
    //TJFLAG_FASTDCT - used fastest IDCT algorithm
    //TJFLAG_FASTUPSAMPLE - not exposed
    //
    //TJXOPT_GRAY - discard color, produce gray
    
    tjDecompress2(jpeg_decompressor, compressed_image, compressed_image_size, buffer, width, 0, height, pixel_format, flags);
    
    //For gray, do I need to convery to YUV then grab
    
    tjDestroy(jpeg_decompressor);
    
    //Setup Output
    //------------------------------------------------------------------
    
    if (is_3d) {
        plhs[0] = mxCreateNumericArray(3,&dims[0], mxUINT8_CLASS, mxREAL);
        
        mxSetData(plhs[0], buffer);
        
        dims[0] = 3;
        dims[1] = width;
        dims[2] = height;
        mxSetDimensions(plhs[0],&dims[0], 3);
    } else {
        plhs[0] = mxCreateNumericMatrix(0, 0, mxUINT8_CLASS, mxREAL);
        mxSetData(plhs[0], buffer);
        mxSetM(plhs[0], width);
        mxSetN(plhs[0], height);
    }

    
    
    
    //OLD, single dimension only
    //-------------------------------
    //plhs[0] = mxCreateNumericMatrix(0, 0, mxUINT8_CLASS, mxREAL);
    //mxSetM(plhs[0], width*height*3);
    //mxSetN(plhs[0], 1);
    
}
Esempio n. 21
0
void mexFunction(int nlhs, mxArray* plhs[], int nrhs, const mxArray* prhs[])
{
	OID ID;
	
	/* OMEIS data structures */
	omeis* is;
	pixHeader* head;
	void* pixels;
	
	/* MATLAB data structueres */
	mxArray *m_url, *m_sessionkey;
	mxArray *permute_inputs[2];
	int result;
	
	char* url, *sessionkey;

	if (nrhs != 2)
		mexErrMsgTxt("\n [pixels] = getPixels (is, ID)");
		
	if (!mxIsStruct(prhs[0]))
		mexErrMsgTxt("getPixels requires the first input to be the struct outputed"
					 " from openConnectionOMEIS\n");
					 
	if (!(m_url = mxGetField(prhs[0], 0, "url")))
		mexErrMsgTxt("getPixels requires the first input, OMEIS struct, to have field: url");
	if (!(m_sessionkey = mxGetField(prhs[0], 0, "sessionkey")))
		mexErrMsgTxt("getPixels requires the first input, OMEIS struct, to have field: sessionkey");
		
	if (!mxIsChar(m_url) || !mxIsChar(m_sessionkey))
		mexErrMsgTxt("OMEIS field aren't character array.\n");		
	
	if (!mxIsNumeric(prhs[1]))
		mexErrMsgTxt("getPixels requires the second input to be the PixelsID\n") ;
		
	ID = (OID) mxGetScalar(prhs[1]) ;
	
	url = mxArrayToString(m_url);
	sessionkey = mxArrayToString(m_sessionkey);
	
	is = openConnectionOMEIS (url, sessionkey);
	if (!(head = pixelsInfo (is, ID))) {
		char err_str[128];
		sprintf(err_str, "PixelsID %llu or OMEIS URL '%s' is probably wrong\n", ID, is->url);
		
		/* clean up */
		mxFree(url);
		mxFree(sessionkey);
		mxFree(is);
		
		mexErrMsgTxt(err_str);
	}
	
	/* figure out dimensions */
	mwSize dims[5]; dims[0] = (mwSize) head->dx; dims[1] = (mwSize) head->dy;
		dims[2] = (mwSize) head->dz; dims[3] = (mwSize) head->dc; dims[4] = (mwSize) head->dt;
		
	if (!(pixels = getPixels (is, ID))) {
		/* clean up */
		mxFree(url);
		mxFree(sessionkey);
		mxFree(head);
		mxFree(is);
		
		char err_str[128];
		sprintf(err_str, "Couldn't load pixelsID %llu\n", ID);
		mexErrMsgTxt(err_str);
	}
	
	/* attach pixels from OMEIS to MATLAB array */
	mwSize tmp_dims[2] = {1,1};
	plhs[0] = mxCreateNumericArray (2, tmp_dims, OMEIStoMATLABDatatype(head), mxREAL);
	
	mxSetData (plhs[0], pixels);
	mxSetDimensions (plhs[0], dims, 5);
	
	/*
		In OMEIS Size_X corresponds to columns and Size_Y corresponds to rows.
		This is diametrically opposite to MATLAB's assumptions.
		hence we do
		"$matlab_var_name = permute($matlab_var_name, [2 1 3 4 5]);" 
		the hard way (groan)
	*/
	permute_inputs[0] = plhs[0];
	permute_inputs[1] = mxCreateDoubleMatrix(1, 5, mxREAL);
	mxGetPr(permute_inputs[1])[0] = 2;
	mxGetPr(permute_inputs[1])[1] = 1;
	mxGetPr(permute_inputs[1])[2] = 3;
	mxGetPr(permute_inputs[1])[3] = 4;
	mxGetPr(permute_inputs[1])[4] = 5;
	/* returns 0 if successful */
	result = mexCallMATLAB(1, plhs, 2, permute_inputs, "permute"); 
	
	/* clean up */
	mxFree(url);
	mxFree(sessionkey);
	mxFree(head);
	mxFree(is);
	mxDestroyArray(permute_inputs[1]);
	
	/* If the flip failed write a message, we are doing it after cleanup */
	if (result) {
		char err_str[128];
		sprintf(err_str, "Couldn't permute the pixels to get them in MATLAB orientation");
		mexErrMsgTxt(err_str);
	}
}
Esempio n. 22
0
/** @brief MEX gateway */
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray*prhs[])
{
    #define	S_IN	     prhs[0]
    #define	A_IN	     prhs[1]
    #define	B_OUT	     plhs[0]
#define IS_REAL_FULL_DOUBLE(P) (!mxIsComplex(P) \
&& !mxIsSparse(P) && mxIsDouble(P))
	num *A, *B;
	char *SBuf;
	const int *Size;
	colortransform Trans;
	int SBufLen, NumPixels, Channel, Channel2;


    /* Parse the input arguments */
    if(nrhs != 2)
        mexErrMsgTxt("Two input arguments required.");
    else if(nlhs > 1)
        mexErrMsgTxt("Too many output arguments.");

	if(!mxIsChar(S_IN))
		mexErrMsgTxt("First argument should be a string.");
    if(!IS_REAL_FULL_DOUBLE(A_IN))
        mexErrMsgTxt("Second argument should be a real full double array.");

	Size = mxGetDimensions(A_IN);

	if(mxGetNumberOfDimensions(A_IN) > 3
		|| Size[mxGetNumberOfDimensions(A_IN) - 1] != 3)
		mexErrMsgTxt("Second argument should be an Mx3 or MxNx3 array.");

	/* Read the color transform from S */
	SBufLen = mxGetNumberOfElements(S_IN)*sizeof(mxChar) + 1;
	SBuf = mxMalloc(SBufLen);
	mxGetString(S_IN, SBuf, SBufLen);

	if(!(GetColorTransform(&Trans, SBuf)))
		mexErrMsgTxt("Invalid syntax or unknown color space.");

	mxFree(SBuf);

	A = (num *)mxGetData(A_IN);
	NumPixels = mxGetNumberOfElements(A_IN)/3;

	/* Create the output image */
	B_OUT = mxCreateDoubleMatrix(0, 0, mxREAL);
	mxSetDimensions(B_OUT, Size, mxGetNumberOfDimensions(A_IN));
	mxSetData(B_OUT, B = mxMalloc(sizeof(num)*mxGetNumberOfElements(A_IN)));

	Channel = NumPixels;
	Channel2 = NumPixels*2;

	/* Apply the color transform */
	while(NumPixels--)
	{
		ApplyColorTransform(Trans, B, B + Channel, B + Channel2,
			A[0], A[Channel], A[Channel2]);
		A++;
		B++;
	}

    return;
}
Esempio n. 23
0
/*
  This function computes the generalised matrix products.  Basicially it
  works by spliting the input X and Y matrices into 2 *virtual* sub-matrices,
  one for the "outer" product dimensions (x/y rest) (over which the cartesian
  product is computed) and one for the "inner" product matrices (over which
  the inner product - or multiply accumulate - is computed).  Once these 2
  matrices have been computed the result is simply an outer product in
  tprod and inner product in macc */
void mexFunction(const int nlhs, mxArray *plhs[], 
                 const int nrhs, const mxArray *prhs[]) {
  char msgTxt[256];
  int i, j, maccnd=0, seqnd=0, BLKSZ=DEFAULTBLKSZ, indtype, retVal;
  const int xarg=0, ydimspecarg=3;
  int xdimspecarg=0, yarg=0; /* possibly other way round? */
  bool useMATLAB=true;
  int callType=0;
  MxInfo xinfo, yinfo, zinfo;
  MxInfo xmacc, ymacc, zrest, xrest, yrest;
  int znd, xnidx=0, ynidx=0;
  int *x2yIdx=0;
  if (nrhs < 4 || nrhs >6)	 ERROR("tprod: Incorrect number of inputs.");
  if (nlhs > 1)	 ERROR("tprod: Too many output arguments.");
  if ( mxGetNumberOfDimensions(prhs[ydimspecarg]) > 2 )
	 ERROR("tprod: ydimspec must be a vector");
  /* parse the tprod options list */
  if( nrhs >= 5 && mxIsChar(prhs[4]) ) {
	 char *opnmStr=mxArrayToString(prhs[4]);
	 for (i=0 ; opnmStr[i] != 0; i++ ) {
		switch ( opnmStr[i] ) {
		case 'm': case 'M':   useMATLAB=false;  break;
		case 'n': case 'N':   callType=1;    break; /* new call type */
		case 'o': case 'O':   callType=-1;   break; /* old call type */
		default: 
		  WARNING("tprod: Unrecognised tprod option");
		}
	 }
	 mxFree(opnmStr); opnmStr=0;
  }

  if ( nrhs==6 && mxGetNumberOfElements(prhs[5])==1 ){
	 BLKSZ=(int)mxGetScalar(prhs[5]);
  }

  /* Get X */
  xinfo = mkmxInfo(prhs[xarg],0);
  /* remove trailing singlenton dimensions from x and y */
  for( i=xinfo.nd; i>1; i-- ) if ( xinfo.sz[i-1]!=1 ) break;  xinfo.nd=i;

  /*----------------------------------------------------------------------*/
  /* Identify the calling convention used */
  if ( callType == 0 ) {

	 /* Try and identify the calling convention used, i.e. 
		 X,Y,xdimspec,ydimspec, or X,xdimspec,Y,ydimspec (deprecated) */
	 if ( mxGetNumberOfDimensions(prhs[1])==2 &&		
			( (mxGetN(prhs[1])==1 && mxGetM(prhs[1])>=xinfo.nd) /* Xdimspec OK */
			  || (mxGetN(prhs[1])>=xinfo.nd && mxGetM(prhs[1])==1) ) ) {
		yarg  = 2; /* start by trying new call type */
		int ynd = mxGetNumberOfDimensions(prhs[yarg]);
		const int *ysz = mxGetDimensions(prhs[yarg]); /* size of poss Y*/
		for( i=ynd; i>1; i-- ) if ( ysz[i-1]!=1 ) break; ynd=i; 
		if( mxGetNumberOfElements(prhs[ydimspecarg]) >= ynd ){/*Ydimspec OK*/
		  callType = 1 ;  /* new call type */
		}
	 }
	 if( mxGetNumberOfDimensions(prhs[2])==2 &&
		  ((mxGetN(prhs[2])==1 && mxGetM(prhs[2])>=xinfo.nd)/* xdimspec OK */
			|| (mxGetN(prhs[2])>=xinfo.nd && mxGetM(prhs[2])==1) ) ) {
		/* Consitent so far, check the ydimspec is OK */
		yarg  = 1; /* start by trying new call type */
		int ynd = mxGetNumberOfDimensions(prhs[yarg]);
		const int *ysz = mxGetDimensions(prhs[yarg]); /* size of poss Y*/
		for( i=ynd; i>1; i-- ) if ( ysz[i-1]!=1 ) break; ynd=i; 
		if ( mxGetNumberOfElements(prhs[ydimspecarg]) >= ynd ) {
		  
		  if ( callType == 0 ) { /* argument 3 is CONSISTENT, and 2 *WASN'T* */
			 callType = -1; 
			 
		  } else { /* argument 2 consistent ALSO */
			 /* of one of them matches exactly and the other doesn't */
			 int xnd = mxGetNumberOfDimensions(prhs[xarg]); /* num input X dims */
			 if ( xnd==2 && xinfo.nd == 1 ) xnd=1; /* col vec is special case*/
			 if ( xnd == mxGetNumberOfElements(prhs[1]) /* 1 matches *exactly* */
					&& xnd != mxGetNumberOfElements(prhs[2]) ) { /* 2 doesn't */
				callType = 1;
			 } else if( xnd == mxGetNumberOfElements(prhs[2])/* 2 *exact* match */
							&& xnd != mxGetNumberOfElements(prhs[1]) ){/* 1 doesn't */
				callType = -1;
			 } else { /* neither or both match exactly */
				callType = 1;
				WARNING("tprod: Could not unambigiously determine calling convention, tprod(X,xdimspec,Y,ydimspec) assumed. Use 'n' or 'o' to force new/old convention.");
			 }
		  }
		}
	 } 
  }
  switch ( callType ) {
  case 1:  xdimspecarg=1; yarg=2; break;/* new type: X,xdimspec,Y,xdimspec */
  case -1: xdimspecarg=2; yarg=1; break;/* old type: X,Y,xdimspec,xdimspec */
  default: ERROR("tprod: Couldnt identify calling convention.");
  }

  /* Now we know where the Y is we can get it too! */
  yinfo = mkmxInfo(prhs[yarg],0); 
  /* empty set as input for y means make it copy of x */
  if ( yinfo.numel==0 && yinfo.nd==2 && yinfo.sz[0]==0 && yinfo.sz[1]==0 ) { 
	 yinfo=copymxInfo(xinfo); 
  }
  /* remove trailing singlenton dimensions from x and y */
  for( i=yinfo.nd; i>1; i-- ) if ( yinfo.sz[i-1]!=1 ) break;  yinfo.nd=i;

  /* check the types are what we can use */
  if ( !(xinfo.dtype == DOUBLE_DTYPE || xinfo.dtype == SINGLE_DTYPE ) ){
	 ERROR("tprod: X type unsuppored: only double, single");
  }
  if ( !(yinfo.dtype == DOUBLE_DTYPE || yinfo.dtype == SINGLE_DTYPE ) ){
	 ERROR("tprod: Y type unsuppored: only double, single");
  }
     
  /*-------------------------------------------------------------------------
   * Initialise x2yIdx which maps from input dimensions to the type of output
	* we want.  The format of x2yIdx is:
	*   [Xdimlabels Ydimlabels] 
	* so it reflects the order of the dimensions in the output Z.
   * The value and sign of the integer label tells us what type of
   * operation to perform on this dimension.
	*    0   this is a squeezed dim which must be singlenton
	*   -ve  this is the index in X/Y of the matching dim to be accumulated
	*   +ve  this number is the position of the dimension at this location in
   *        the output matrix.
	*-------------------------------------------------------------------------*/
  znd=0; /* xnidx, ynidx; */
  double *xip, *yip;
  /* fill in the x2yIdx for the new type of indicies */
  maccnd=0;
  xnidx=mxGetNumberOfElements(prhs[xdimspecarg]);
  if( xnidx<xinfo.nd ) ERROR("tprod:Less X indicies than dimensions");
  ynidx=mxGetNumberOfElements(prhs[ydimspecarg]);
  if( ynidx<yinfo.nd ) ERROR("tprod:Less Y indicies than dimensions");

  x2yIdx=(int*)mxCalloc(xnidx+ynidx,sizeof(int));  	 
  xip=mxGetPr(prhs[xdimspecarg]); yip=mxGetPr(prhs[ydimspecarg]);

  /* find the max value of xip, this is num output dims */
  /* also check for non multiple instances of acc dims labels */
  znd=MAX((int)xip[0],0);
  for( i=1; i<xnidx; i++){
	 if ( xip[i] < .0 ) {
		for( j=0; j<i; j++)
		  if(xip[i]==xip[j]) ERROR("tprod: Duplicate x-dim label");
	 } else if ( xip[i] > .0 ) {
		znd=MAX(znd,(int)xip[i]); /* find the largest target dim */
	 } else if ( sz(xinfo,i)!=1 ) 
		ERROR("tprod: Ignored dims *MUST* have size 1");
  }
  /* same for yip */
  /* but also check that we always have matching x label to accumulate */
  znd=MAX(znd,(int)yip[0]); 
  for( i=1; i<ynidx; i++){
	 if ( yip[i] < .0 ) {
		for( j=0; j<i; j++)
		  if(yip[i]==yip[j]) ERROR("tprod: Duplicate y-dim label");
		for( j=0; j<xnidx; j++) if( yip[i]==xip[j] ) break;
		if( j==xnidx ) {
		  sprintf(msgTxt,"tprod: Couldn't find a matching negative x-label for the y-label=%d",(int)yip[i]);
		  ERROR(msgTxt);
		}
	 } else if ( yip[i] > .0 ) {
		znd=MAX(znd,(int)yip[i]); /* find the largest target dim */
	 } else if ( sz(yinfo,i)!=1 ) 
		ERROR("tprod: Ignored dims *MUST* have size 1");
  }

  /* compute the x->y mapping */
  for( i=0; i<xnidx; i++){
	 if ( xip[i] < .0 ) {
		/* search for the matching y */
		for( j=0; j<ynidx; j++) {
		  if ( yip[j]==xip[i] ) {
			 x2yIdx[i]=-(j+1);    x2yIdx[xnidx+j]=-(i+1);    maccnd++;
			 break;
		  }
		}
		if ( x2yIdx[i]==0 )
		  ERROR("tprod: Couldn't find a matching y-idx for the x");
		if( sz(xinfo,i) != sz(yinfo,j)) /* check sizes match too */
		  ERROR("tprod: Matched dims must have the same size!");
	 } else { /* just copy it through */
		x2yIdx[i]=(int)xip[i];
		/* search for the matching y, & check sizes match */
		for( j=0; j<ynidx && yip[j]!=xip[i]; j++);
		if ( j<ynidx ){ /* sequential dimension */
		  if ( sz(xinfo,i) != sz(yinfo,j) )
			 ERROR("tprod: Matched dims must have the same size!");
		  if ( sz(xinfo,i)!=1 ) { /* only *really* sequ if >1 size strides */
			 seqnd++; 
		  } 
		}
	 }
  }
  /* now set the y parts -- for the non-set non-accumulated dimensions */ 
  for( i=0; i<ynidx; i++){ 
	 if( yip[i] > .0 ) { x2yIdx[i+xnidx]=(int)yip[i]; }
  }
  /*   } */
  znd=MAX(znd,1); /* ensure at least 1 output dim */
  maccnd=MAX(maccnd,1); /* ensure at least 1 macc dim */
  
  /* compute the mxInfo for the accumulated and rest sub-matrices */  
  xmacc = mkemptymxInfo(maccnd);
  ymacc = mkemptymxInfo(maccnd);
  /* N.B. xrest.sz holds the	size of the combined x and y rest matrix */
  xrest = mkemptymxInfo(znd); 
  yrest = mkemptymxInfo(znd);

  initrestmaccmxInfo(znd, xinfo, yinfo, x2yIdx, xnidx, ynidx,
							&xrest, &yrest, &xmacc, &ymacc);

  /* compute the size of the output matrix */
  zinfo=initzmxInfo(znd, xinfo, yinfo, x2yIdx, xnidx, ynidx); 

  /* optimise/standardize the query so its the way tprod wants it */
  zrest = copymxInfo(zinfo);
  optimisetprodQuery(&zrest, &xrest, &yrest, &xmacc, &ymacc);  
  if ( xrest.rp != xinfo.rp ) { /* swap xinfo/yinfo if needed */
	 MxInfo tmp = xinfo; xinfo=yinfo; yinfo=tmp;
  }

  /* Now do the actuall work to compute the result */  
  if ( yinfo.numel==0 || xinfo.numel== 0 ) { /* deal with null inputs */
	 WARNING("tprod: Empty matrix input!");
	 /* return an empty matrix */
	 plhs[0]=mxCreateNumericArray(zinfo.nd,zinfo.sz,mxDOUBLE_CLASS,
											(xinfo.ip==0&&yinfo.ip==0)?mxREAL:mxCOMPLEX);
	 	 
  } else if ( useMATLAB && /* allowed */
		 seqnd==0 &&                     /* no sequential dims */
		 xmacc.nd <= 1 &&            /* at most 1 macc dim */
		 xrest.nd <= 2 &&            /* at most 2 output dims */
		 (xrest.nd<= 1 ||            /* 1 from X */
		  ((xrest.stride[0]==0) || (stride(xrest,1)==0))) && 
 		 (yrest.nd<= 1 ||            /* 1 from Y */
		  ((yrest.stride[0]==0) || (stride(yrest,1)==0))) &&
				  (xmacc.numel*(2+(xinfo.ip==0)+(yinfo.ip==0)) < MATLABMACCTHRESHOLDSIZE ) /* not tooo big! */
				  ){ 
	 /* Phew! we can use matlab! */
	 if ( xrest.stride[0]>0 ) { /* x comes before y in output */
		plhs[0]=MATLAB_mm(zinfo,xinfo,yinfo,xrest,yrest,
								xmacc,ymacc);
	 } else { /* y comes before x in output, reverse order of inputs */
		plhs[0]=MATLAB_mm(zinfo,yinfo,xinfo,yrest,xrest,
								ymacc,xmacc);
	 }
  } else {

	 /* otherwise do it ourselves */
	 /* create the data for the z matrix and set its pointer */
	 plhs[0]=mxCreateNumericArray(zinfo.nd,zinfo.sz,zinfo.dtype,
											(xinfo.ip==0&&yinfo.ip==0)?mxREAL:mxCOMPLEX);
	 zinfo.rp = mxGetPr(plhs[0]); zrest.rp=zinfo.rp;
	 zinfo.ip = mxGetPi(plhs[0]); zrest.ip=zinfo.ip;

	 /* call tprod to do the real work */
	 /* do the (appropriately typed) operation */
	 if(        xrest.dtype==DOUBLE_DTYPE && yrest.dtype==DOUBLE_DTYPE ) {/*dd*/
		retVal= ddtprod(zrest,xrest,yrest,xmacc,ymacc,BLKSZ);

	 } else if( xrest.dtype==DOUBLE_DTYPE && yrest.dtype==SINGLE_DTYPE ) {/*ds*/
		retVal= dstprod(zrest,xrest,yrest,xmacc,ymacc,BLKSZ);

	 } else if( xrest.dtype==SINGLE_DTYPE && yrest.dtype==DOUBLE_DTYPE ) {/*sd*/
		retVal= sdtprod(zrest,xrest,yrest,xmacc,ymacc,BLKSZ);
 
	 } else if( xrest.dtype==SINGLE_DTYPE && yrest.dtype==SINGLE_DTYPE ){/*ss*/
		retVal= sstprod(zrest,xrest,yrest,xmacc,ymacc,BLKSZ);

	 } else {
 		ERROR("tprod: Inputs of unsupported type: only double/single");
		
	 }
	 /* check for errors */
	 switch ( retVal ) {
	 case ZTYPEMISMATCH : 
		ERROR("tprod: Z is of unsupported type"); break;
	 case XTYPEMISMATCH :
		ERROR("tprod: X is of unsupported type"); break;
	 case YTYPEMISMATCH :
		ERROR("tprod: Y is of unsupported type"); break;
	 case INTYPEMISMATCH :
		ERROR("tprod: input real/complex mix unsupported"); break;
	 case OTHERERROR :
		ERROR("tprod: Something else went wrong, sorry!"); break;
	 default: ;
	 }
  }
  
  /* ensure the output has the size we want */
  if ( plhs[0] ) mxSetDimensions(plhs[0],zinfo.sz,zinfo.nd);
  
  /* free up all the memory we've allocated */
  /* N.B. not clear we need to do this from the matlab web-site should happen
	  automatically */
  delmxInfo(&xinfo);delmxInfo(&yinfo);delmxInfo(&zinfo);
  delmxInfo(&xmacc);  delmxInfo(&ymacc);
  delmxInfo(&xrest);  delmxInfo(&yrest);
  FREE(x2yIdx);
}
Esempio n. 24
0
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
{
	struct mxArray_Tag *mx;
    mwSize inbytes, outbytes, i, k, idim, ndim;
	mwSize *dims_old, *dims_new;
    char *outstring;
    mxClassID outclass;
	int out_numeric;

/* Check input arguments */

	if( nrhs > 2 ) {
        mexErrMsgTxt("Too many input arguments.");
	}
	if( nrhs < 2 ) {
        mexErrMsgTxt("Not enough input arguments.");
	}
	if( nlhs > 1 ) {
        mexErrMsgTxt("Too many output arguments.");
	}
	if( mxIsSparse(prhs[0]) || (!mxIsNumeric(prhs[0]) && !mxIsChar(prhs[0]) && !mxIsLogical(prhs[0])) ) {
        mexErrMsgTxt("The first input argument must be a full numeric value, or char, or logical.");
	}
	if( !mxIsChar(prhs[1]) ) {
        mexErrMsgTxt("The second input argument must be a character array.");
	}

/* Get input argument byte length */

   inbytes = mxGetElementSize(prhs[0]);

/* Check second input argument for desired output type */

   outstring = mxArrayToString(prhs[1]);

   out_numeric = 1;
   if(        strcmp(outstring,"int8") == 0 ) {
       outclass = mxINT8_CLASS;
       outbytes = 1;
   } else if( strcmp(outstring,"uint8") == 0 ) {
       outclass = mxUINT8_CLASS;
       outbytes = 1;
   } else if( strcmp(outstring,"int16") == 0 ) {
       outclass = mxINT16_CLASS;
       outbytes = 2;
   } else if( strcmp(outstring,"uint16") == 0 ) {
       outclass = mxUINT16_CLASS;
       outbytes = 2;
   } else if( strcmp(outstring,"int32") == 0 ) {
       outclass = mxINT32_CLASS;
       outbytes = 4;
   } else if( strcmp(outstring,"uint32") == 0 ) {
       outclass = mxUINT32_CLASS;
       outbytes = 4;
   } else if( strcmp(outstring,"int64") == 0 ) {
       outclass = mxINT64_CLASS;
       outbytes = 8;
   } else if( strcmp(outstring,"uint64") == 0 ) {
       outclass = mxUINT64_CLASS;
       outbytes = 8;
   } else if( strcmp(outstring,"double") == 0 ) {
       outclass = mxDOUBLE_CLASS;
       outbytes = 8;
   } else if( strcmp(outstring,"single") == 0 ) {
       outclass = mxSINGLE_CLASS;
       outbytes = 4;
   } else if( strcmp(outstring,"char") == 0 ) {
       outclass = mxCHAR_CLASS;
       outbytes = 2;
	   out_numeric = 0;
   } else if( strcmp(outstring,"logical") == 0 ) {
       outclass = mxLOGICAL_CLASS;
       outbytes = 1;
	   out_numeric = 0;
   } else {
       mxFree(outstring);
       mexErrMsgTxt("Unsupported class.\n");
   }
   mxFree(outstring);

/* Check for complex coversion to non-numeric */

   if( mxIsComplex(prhs[0]) && !out_numeric ) {
       mexErrMsgTxt("Cannot typecast a complex input to a non-numeric class.\n");
   }

/* Check for empty input. No data to share, so simply create a new empty variable */

    if( mxIsEmpty(prhs[0]) ) {
	    if( out_numeric ) {
		    plhs[0] = mxCreateNumericArray(mxGetNumberOfDimensions(prhs[0]),
			                               mxGetDimensions(prhs[0]),
							               outclass, mxREAL);
	    } else if( outclass == mxCHAR_CLASS ) {
		    plhs[0] = mxCreateCharArray(mxGetNumberOfDimensions(prhs[0]),
		 	                            mxGetDimensions(prhs[0]));
	    } else {
		    plhs[0] = mxCreateLogicalArray(mxGetNumberOfDimensions(prhs[0]),
			                              mxGetDimensions(prhs[0]));
	    }
	    return;
    }

/* Check the old & new sizes for compatibility */

    ndim = mxGetNumberOfDimensions(prhs[0]);
    dims_old = mxGetDimensions(prhs[0]);
    for( i=0; i<ndim; i++ ) {
	    if( dims_old[i] != 1 || i == ndim-1 ) {
		    k = (dims_old[i] * inbytes) / outbytes;
			if( k * outbytes != dims_old[i] * inbytes ) {
                mexErrMsgTxt("Too few input values to make output type.\n");
			}
			idim = i;
		    break;
	    }
    }
	dims_new = mxMalloc(ndim * sizeof(*dims_new));
    for( i=0; i<ndim; i++ ) {
		dims_new[i] = dims_old[i];
    }
	dims_new[idim] = k;

/* Create the output array as a shared data copy, then manually set the class
 * and size parameters by accessing the structure fields directly. Note that
 * this is using undocumented MATLAB API functions and hacking of the
 * mxArray_tag structure, so this may not work in future versions of MATLAB.
 */
   // mx = (struct mxArray_Tag *) prhs[0];
   // printf("old flags: %#6x\n", mx->flags);

   plhs[0] = mxCreateSharedDataCopy(prhs[0]);
   mx = (struct mxArray_Tag *) plhs[0];
   mx->ClassID = outclass;
   mx->VariableType = VariableType_Temporary;
   mxSetDimensions(plhs[0],dims_new,ndim);
   mxFree(dims_new);

	//mexPrintf("post shared data copy\n");

   // printf("new flags: %#6x\n", mx->flags);
   return;

   // this breaks in R2018a, @djoshea removing
/* Also need to fix up the flags */

   if( outclass == mxDOUBLE_CLASS ) {
	   if( mxGetNumberOfElements(plhs[0]) == 1 ) {
		   mx->flags = 0x0211;  /* Set numeric, temporary, and full double scalar bits */
	   } else {
		   mx->flags = 0x0210;  /* Set numeric and temporary bits */
	   }
   } else if( out_numeric ) {
	   mx->flags = 0x0210;  /* Set numeric and temporary bits */
   } else {
	   mx->flags = 0x0010;  /* Set the temporary bit */
   }
}
Esempio n. 25
0
void
mexFunction(int nlhs,mxArray *plhs[],int nrhs,const mxArray *prhs[])
{
    
    int number_new_dims, number_input_elements, number_new_elements, i;
    int *new_dims;  
    
    /* Check for proper number of input and output arguments */    
    if (nrhs < 3) {
        mexErrMsgTxt("At least 3 input arguments required.");
    } 
    if(nlhs > 1){
        mexErrMsgTxt("Too many output arguments.");
    }
    number_new_dims = nrhs-1;
    if (mxIsSparse(prhs[0]) && number_new_dims != 2){
	mexErrMsgTxt("Multidimensional sparse arrays are not supported.\n");
    }

    number_input_elements = mxGetNumberOfElements(prhs[0]); 
    
    /* Allocate memory for the new_dims array on the fly */
    new_dims = mxMalloc(number_new_dims * sizeof(*new_dims)); 

    /* Create the dimensions array and check to make sure total number of
       elements for the input array is the same for the reshaped array. */
    number_new_elements=1;
    for (i=0; i< number_new_dims;i++){
	const mxArray *pa;
	pa = prhs[i+1];
	if(mxGetNumberOfElements(pa) != 1) {
	    /* Free allocated memory */
	    mxFree(new_dims);
	    mexErrMsgTxt("Size arguments must be integer scalars.");
	}
	new_dims[i] = (int)mxGetScalar(pa);
	number_new_elements = new_dims[i]*number_new_elements; 
    }
    if (number_new_elements != number_input_elements){
	/* Free allocated memory */
	mxFree(new_dims);
	mexErrMsgTxt("Total number of elements in the new array, must equal number of elements in input array.\n");
    } 
    /* Duplicate the array */
    plhs[0] = mxDuplicateArray(prhs[0]); 
    
    /* If array is sparse, use the sparse routine to reshape,
       otherwise, use mxSetDimensions. */
    if (mxIsSparse(plhs[0])){ 
	int mold; /* old number of rows */ 
	int nold; /* old number of columns */ 
	int *jcold; /*old jc array */ 
	int *ir; /* ir array that is modified in place */ 
	int mnew; /* new number of rows */ 
	int nnew; /* new number of columns */
	int *jcnew; /* new jc array */  
	int j, offset, offset1;
		
	/* Allocate space for new jc. */	
	jcnew = ((int*)mxCalloc(new_dims[1]+1, sizeof(int)));

	mnew = new_dims[0];
	nnew = new_dims[1];
		
	/* Get M, N, Ir and Jc of input array. */
	mold = mxGetM(plhs[0]);
	nold = mxGetN(plhs[0]);
	jcold = mxGetJc(plhs[0]);
	ir = mxGetIr(plhs[0]);
	
	/* First change ir so it acts like one long column vector */
	for (i=1, offset=mold; i < nold; i++, offset+=mold){
	    for (j=jcold[i]; j < jcold[i+1]; j++){
		ir[j] += offset;
	    }
	}
	/* Then fix ir and jcnew for new m and n */
	for (i=0, j=0, offset=mnew-1, offset1=0; i < jcold[nold]; ) {
	    if (ir[i] > offset) {
		jcnew[++j] = i;
		offset  += mnew;
		offset1 += mnew;
	    } else {
		ir[i++] -= offset1;
	    }
	}
	for (j++; j <= nnew; j++){
	    jcnew[j]=jcold[nold];
	}

	/* Free the old Jc, set the new Jc, M, and N. */
	mxFree(mxGetJc(plhs[0]));
	mxSetJc(plhs[0],jcnew);
	mxSetM(plhs[0],mnew);
	mxSetN(plhs[0],nnew);
    }
    else{
	/* Set the new dimensions. */
	mxSetDimensions(plhs[0],new_dims, number_new_dims);
    }

/* Free allocated memory*/
    mxFree(new_dims);
}
Esempio n. 26
0
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
{
    /************************************************************************************************************************\
     MATLAB
     [H Q ytilde alpha converged numiter]
        = gauss_int(y, Hng, H, Hd, Z, Zd, T, Td, R, Rd, Qng, Q, Qd, c, cd, a1, P1, alpha0, maxiter, tol0, tolP, inv_method)
    \************************************************************************************************************************/

    /*** Input variables ***/
    int p, m, r, n;
    double *y;
    int *miss, *pmiss, *imiss;
    int Hd, Zd, Td, Rd, Qd, cd, sta;
    double *H, *Z, *T, *R, *Q, *c, *a1, *P1, *P1_inf;
    double tol0, tolP;
    int maxiter, inv_method;
    
    /*** Output variables ***/
    int dims[3];
    mxArray *H, *Q;
    double *ytilde, *alpha;
    int converged, numiter;
    
    /*** Buffer variables ***/
    double *a, *P, *P_inf, *v, *invF, *F2, *L, *L1;
    int d, *Fns;
    
    /*** Retrieve data ***/
    get_data(prhs[0], &p, &n, (int *)0, &y, &ymiss);
    
    /*** Retrieve model ***/
    get_nong_model(prhs + 1, &p, &m, &rr, &Hd, &Zd, &Td, &Rd, &Qd, &cd, &H, &Z, &T, &R, &Q, &c, &a1, &P1, &P1_inf);
    sta         = !Hd && !Zd && !Td && !Rd && !Qd;
    
    /*** Retrieve analysis settings ***/
    maxiter     = (int)mxGetScalar(prhs[18]);
    tol0        = mxGetScalar(prhs[19]);
    tolP        = mxGetScalar(prhs[20]);
    inv_method  = (nrhs >= 22) ? (int)mxGetScalar(prhs[21]) : 0;
    
    /*** Truncate Z and H w.r.t. missing data ***/
    if(miss) truncate_yHZ(p, m, n, N, &y, miss, &pmiss, &imiss, &H, &Hd, &Z, &Zd);
    else { pmiss = (int *)0; imiss = (int *)0; }
    
    /*** Allocate output variables ***/
    dims[0]     = m; dims[1] = NN; dims[2] = n;
    alphahat    = mxGetPr(plhs[0] = mxCreateNumericArray(3, dims, mxDOUBLE_CLASS, mxREAL));
    dims[0]     = m; dims[1] = m; dims[2] = n;
    V           = mxGetPr(plhs[1] = mxCreateNumericArray(3, dims, mxDOUBLE_CLASS, mxREAL));
    dims[0]     = m; dims[1] = NN; dims[2] = n+1;
    r           = mxGetPr(plhs[2] = mxCreateNumericArray(3, dims, mxDOUBLE_CLASS, mxREAL));
    dims[0]     = m; dims[1] = m; dims[2] = n+1;
    N           = mxGetPr(plhs[3] = mxCreateNumericArray(3, dims, mxDOUBLE_CLASS, mxREAL));
    
    /*** Allocate workspace ***/
    a       = (double *)mxCalloc(m*NN*(n+1), sizeof(double));
    P       = (double *)mxCalloc(m*m*(n+1), sizeof(double));
    P_inf   = (double *)mxCalloc(m*m*(n+1), sizeof(double));
    Fns     = (int *)mxCalloc(n, sizeof(int));
    v       = (double *)mxCalloc(p*NN*n, sizeof(double));
    invF    = (double *)mxCalloc(p*p*n, sizeof(double));
    F2      = (double *)mxCalloc(p*p*n, sizeof(double));
    L       = (double *)mxCalloc(m*m*n, sizeof(double));
    L1      = (double *)mxCalloc(m*m*n, sizeof(double));

    /*** Kalman filter ***/
    kalman(p, m, rr, n, NN, y, (int *)0, false, pmiss, sta, H, Hd, Z, Zd, T, Td, R, Rd, Q, Qd, c, cd, a1, P1, P1_inf,
        a, P, P_inf, &d, Fns, v, (double *)0, invF, F2, (double *)0, (double *)0,
        L, L1, (double *)0, (double *)0, (double *)0, (double *)0, (double *)0, tol0, tolP, inv_method);
    
    /*** Fast smoother ***/
    statesmo(p, m, n, NN, (int *)0, false, pmiss, Z, Zd, T, Td, a, P, P_inf, d, Fns, v, invF, F2, L, L1,
        r, (double *)0, N, (double *)0, (double *)0, alphahat, V);
    
    /*** Cleanup ***/
    cleanup();
    mxFree(a);
    mxFree(P);
    mxFree(P_inf);
    mxFree(Fns);
    mxFree(v);
    mxFree(invF);
    mxFree(F2);
    mxFree(L);
    mxFree(L1);
    
    /*** Postprocessing ***/
    if(NN == 1) {
        dims[0] = m; dims[1] = n;
        mxSetDimensions(plhs[0], dims, 2);
        dims[0] = m; dims[1] = n+1;
        mxSetDimensions(plhs[2], dims, 2);
    }
    if(m == 1) {
        dims[0] = 1; dims[1] = n;
        mxSetDimensions(plhs[1], dims, 2);
        dims[0] = 1; dims[1] = n+1;
        mxSetDimensions(plhs[3], dims, 2);
    }
}
Esempio n. 27
0
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])

	/* bloch(b1,gradxyz,dt,t1,t2,df,dx,dy,dz,mode,mx,my,mz) */
{
double *b1r;	/* Real-part of B1 field.	*/
double *b1i;	/* Imag-part of B1 field.	*/
double *gx;	/* X-axis gradient. 		*/
double *gy;	/* Y-axis gradient. 		*/
double *gz;	/* Z-axis gradient. 		*/
double *tp;	/* Time steps (s)		*/
double *ti;	/* Time intervals (s) 		*/
double t1;	/* T1 time constant (s)	 	*/
double t2;	/* T2 time constant (s)		*/
double *df;	/* Off-resonance Frequencies (Hz)	*/
double *dx;	/* X Positions (cm)			*/
double *dy;	/* Y Positions (cm)			*/
double *dz;	/* Z Positions (cm)			*/
int md;		/* Mode - 0=from M0, 1=steady-state	*/
double tstep;	/* Time step, if single parameter */
double *mxin;	/* Input points */
double *myin;
double *mzin;

double *mxout;	/* Input points */
double *myout;
double *mzout;

double *mx;	/* Output Arrays */
double *my;
double *mz;

int gyaflag=0;	/* 1 if gy was allocated. */ 
int gzaflag=0;	/* 1 if gy was allocated. */ 
int dyaflag=0;	/* 1 if dy was allocated. */ 
int dzaflag=0;	/* 1 if dy was allocated. */ 

int ntime;	/* Number of time points. 	 */
int ntout;	/* Number of time poitns at output. */
int outsize[3];	/* Output matrix sizes		*/

int ngrad;	/* Number of gradient dimensions */
int nf;
int npos;	/* Number of positions.  Calculated from nposN and nposM, depends on them. */
int nposM;	/* Height of passed position matrix. */
int nposN;	/* Width of passed position matrix. */
int nfnpos;	/* Number of frequencies * number of positions. */
int ntnfnpos;	/* Number of output times *frequencies*number of positions. */
int count;



#ifdef DEBUG
  printf("---------------------------------------\n");
  printf("3D-position + frequency Bloch Simulator\n");
  printf("---------------------------------------\n\n");
#endif

ntime = mxGetM(prhs[0]) * mxGetN(prhs[0]);	/* Number of Time, RF, and Grad points */


/* ====================== RF (B1) =========================
 * :  If complex, split up.  If real, allocate an imaginary part. ==== */
if (mxIsComplex(prhs[0]))
	{
	b1r = mxGetPr(prhs[0]);
	b1i = mxGetPi(prhs[0]);
	}
else
	{
	b1r = mxGetPr(prhs[0]);
	b1i = (double *)malloc(ntime * sizeof(double));
	for (count=0; count < ntime; count++)
		b1i[count]=0.0;
	}
#ifdef DEBUG
  printf("%d B1 points.\n",ntime);
#endif


/* ======================= Gradients ========================= */

ngrad = mxGetM(prhs[1]) * mxGetN(prhs[1]);	/* Number of Time, RF, and Grad points */
gx = mxGetPr(prhs[1]);				/* X-gradient is first N points. */

if (ngrad < 2*ntime)		/* Need to allocate Y-gradient. */
	{
	#ifdef DEBUG
	  printf("Assuming 1-Dimensional Gradient\n");
	#endif
	gy = (double *)malloc(ntime * sizeof(double));
	gyaflag=1;
	for (count=0; count < ntime; count++)
		gy[count]=0.0;
	}
else
	{
	#ifdef DEBUG
	  printf("Assuming (at least) 2-Dimensional Gradient\n");
	#endif
	gy = gx + ntime;	/* Assign from Nx3 input array. */
	}

if (ngrad < 3*ntime)		/* Need to allocate Z-gradient. */
	{
	gz = (double *)malloc(ntime * sizeof(double));
	gzaflag=1;
	for (count=0; count < ntime; count++)
		gz[count]=0.0;
	}
else
	{
	#ifdef DEBUG
	  printf("Assuming 3-Dimensional Gradient\n");
	#endif
	gz = gx + 2*ntime; 	/* Assign from Nx3 input array. */
	}

	/* Warning if Gradient length is not 1x, 2x, or 3x RF length. */

	
#ifdef DEBUG
  printf("%d Gradient Points (total) \n",ngrad);
#endif
if ( (ngrad != ntime) && (ngrad != 2*ntime) && (ngrad != 3*ntime) )
		printf("Gradient length differs from B1 length\n");


if (gx == NULL) 
	printf("ERROR:  gx is not allocated. \n");
if (gy == NULL) 
	printf("ERROR:  gy is not allocated. \n");
if (gz == NULL) 
	printf("ERROR:  gz is not allocated. \n");



/* === Time points ===== */

/*	THREE Cases:
		1) Single value given -> this is the interval length for all.
		2) List of intervals given.
		3) Monotonically INCREASING list of end times given.

	For all cases, the goal is for tp to have the intervals.
*/

ti = NULL;
tp = mxGetPr(prhs[2]);
if (mxGetM(prhs[2]) * mxGetN(prhs[2]) == 1)	/* === Case 1 === */
	{
	tp = (double *)malloc(ntime * sizeof(double));
	tstep = *(mxGetPr(prhs[2]));
	for (count =0; count < ntime; count++)
		tp[count]=tstep;
	}
else if (mxGetM(prhs[2]) * mxGetN(prhs[2]) != ntime)
	printf("Time-point length differs from B1 length\n");

else	
	{
	tp = mxGetPr(prhs[2]);
	ti = (double *)malloc(ntime * sizeof(double));
	if (( times2intervals( tp, ti, ntime )))
		{
		printf("Times are monotonically increasing. \n");
		tp = ti;
		}
	}


/* === Relaxation Times ===== */

t1 = *mxGetPr(prhs[3]);
t2 = *mxGetPr(prhs[4]);

/* === Frequency Points ===== */

df = mxGetPr(prhs[5]);
nf = mxGetM(prhs[5]) * mxGetN(prhs[5]);
	
#ifdef DEBUG
  printf("%d Frequency points.\n",nf);
#endif


/* === Position Points ===== */

nposM = mxGetM(prhs[6]);
nposN = mxGetN(prhs[6]);

#ifdef DEBUG
  printf("Position vector is %d x %d. \n",nposM,nposN);
#endif

if (nposN==3)			/* Assume 3 position dimensions given */
	{
	npos = nposM;
	#ifdef DEBUG
	  printf("Assuming %d 3-Dimensional Positions\n",npos);
	#endif
	dx = mxGetPr(prhs[6]);
	dy = dx + npos;
	dz = dy + npos;
	}

else if (nposN==2)		/* Assume only 2 position dimensions given */
	{
	npos = nposM;
	#ifdef DEBUG
	  printf("Assuming %d 2-Dimensional Positions\n",npos);
	#endif
	dx = mxGetPr(prhs[6]);
	dy = dx + npos;
	dz = (double *)malloc(npos * sizeof(double));
	dzaflag=1;
	for (count=0; count < npos; count++)
		dz[count]=0.0;
	}

else				/* Either 1xN, Nx1 or something random.  In all these
				   cases we assume that 1 position is given, because it
				   is too much work to try to figure out anything else! */
	{
	npos = nposM * nposN;
	#ifdef DEBUG
	  printf("Assuming %d 1-Dimensional Positions\n",npos);
	#endif
	dx = mxGetPr(prhs[6]);
	dy = (double *)malloc(npos * sizeof(double));
	dz = (double *)malloc(npos * sizeof(double));
	dyaflag=1;
	dzaflag=1;
	for (count=0; count < npos; count++)
		{
		dy[count]=0.0;
		dz[count]=0.0;
		}
	#ifdef DEBUG
	  if ((nposM !=1) && (nposN!=1))		
		{
		printf("Position vector should be 1xN, Nx1, Nx2 or Nx3. \n");
		printf(" -> Assuming 1 position dimension is given. \n");
		}	
	#endif
	}

if (dx == NULL) 
	printf("ERROR:  dx is not allocated. \n");
if (dy == NULL) 
	printf("ERROR:  dy is not allocated. \n");
if (dz == NULL) 
	printf("ERROR:  dz is not allocated. \n");

nfnpos = nf*npos;	/* Just used to speed things up below. 	*/ 


/* ===== Mode, defaults to 0 (simulate single endpoint, transient). ==== */

if (nrhs > 7)
	md = (int)(*mxGetPr(prhs[7]));		
else
	md = 0;


if (md & 2)
	ntout = ntime;		/* Include time points.	*/
else
	ntout = 1;

#ifdef DEBUG
  printf("Mode = %d, %d Output Time Points \n",md,ntout);
#endif

ntnfnpos = ntout*nfnpos;


#ifdef DEBUG
if ((md & 1)==0)
	printf("Simulation from Initial Condition.\n");
else
	printf("Simulation of Steady-State.\n");


if ((md & 2)==0)
	printf("Simulation to Endpoint. \n");
else
	printf("Simulation over Time.\n");
#endif


/* ===== Allocate Output Magnetization vectors arrays.	*/

plhs[0] = mxCreateDoubleMatrix(ntnfnpos,1,mxREAL);	/* Mx, output. */
plhs[1] = mxCreateDoubleMatrix(ntnfnpos,1,mxREAL);	/* My, output. */
plhs[2] = mxCreateDoubleMatrix(ntnfnpos,1,mxREAL);	/* Mz, output. */

mx = mxGetPr(plhs[0]);
my = mxGetPr(plhs[1]);
mz = mxGetPr(plhs[2]);

mxout = mx;
myout = my;
mzout = mz;

/* ===== If Initial Magnetization is given... */

if ( (nrhs > 10) &&	 
	(mxGetM(prhs[8]) * mxGetN(prhs[8]) == nfnpos) &&
        (mxGetM(prhs[9]) * mxGetN(prhs[9]) == nfnpos) &&
        (mxGetM(prhs[10]) * mxGetN(prhs[10]) == nfnpos)  )

		/* Set output magnetization to that passed. 
			If multiple time points, then just the 
			first is set.				*/

		
	{
	#ifdef DEBUG
  	  printf("Using Specified Initial Magnetization.\n");
	#endif

	mxin = mxGetPr(prhs[8]);
	myin = mxGetPr(prhs[9]);
	mzin = mxGetPr(prhs[10]);
	for (count =0; count < nfnpos; count++)
		{
		*mxout = *mxin++;
		*myout = *myin++;
		*mzout = *mzin++;
		mxout += ntout;
		myout += ntout;
		mzout += ntout;
		}
	}
else 
	{
	#ifdef DEBUG
	if (nrhs > 10) 	 /* Magnetization given, but wrong size! */
		{
		printf("Initial magnetization passed, but not Npositions x Nfreq. \n");
		}
	  printf(" --> Using [0; 0; 1] for initial magnetization. \n");
	#endif
	for (count =0; count < nfnpos; count++)
		{
		*mxout = 0;	/* Set magnetization to Equilibrium */
		*myout = 0;
		*mzout = 1;
		mxout += ntout;
		myout += ntout;
		mzout += ntout;
		}
	}	


/* ======= Do The Simulation! ====== */

#ifdef DEBUG
  printf("Calling blochsimfz() function in Mex file.\n");
#endif

blochsimfz(b1r,b1i,gx,gy,gz,tp,ntime,t1,t2,df,nf,dx,dy,dz,npos,mx,my,mz,md);


/* ======= Reshape Output Matrices ====== */

if ((ntout > 1) && (nf > 1) && (npos > 1))
	{
	outsize[0]=ntout;
	outsize[1]=npos;
	outsize[2]=nf;
	mxSetDimensions(plhs[0],outsize,3);  /* Set to 3D array. */
	mxSetDimensions(plhs[1],outsize,3);  /* Set to 3D array. */
	mxSetDimensions(plhs[2],outsize,3);  /* Set to 3D array. */
	}
else			/* Basically "squeeze" the matrix. */
	{
	if (ntout > 1)	
		{
		outsize[0]=ntout;
		outsize[1]=npos*nf;
		}
	else
		{
		outsize[0]=npos;
		outsize[1]=nf;
		}
	mxSetDimensions(plhs[0],outsize,2);  /* Set to 2D array. */
	mxSetDimensions(plhs[1],outsize,2);  /* Set to 2D array. */
	mxSetDimensions(plhs[2],outsize,2);  /* Set to 2D array. */
	}


/* ====== Free up allocated memory, if necessary. ===== */

if (!mxIsComplex(prhs[0]))
	free(b1i);	/* We had to allocate this before. */

if (mxGetM(prhs[2]) * mxGetN(prhs[2]) == 1)
	free(tp);	/* We had to allocate this. */

if (ti != NULL)
	free(ti);

if (dyaflag==1)
	free(dy);
if (dzaflag==1)
	free(dz);
if (gyaflag==1)
	free(gy);
if (gzaflag==1)
	free(gz);

}
void mexFunction( int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]){ ALLOCATES();

  CreateTicTacToc( CallMatlab );
  CreateTicTacToc( callSort   );
  int               I, J, K, ii, jj, kk;
  int               IJ, IJK, IJK_1;
  int               DI, DJ, DK, DIJK, DIJK_1;
  int               CDI, CDJ, CDK;
  int               result, fevals = 0;
  int               NVOLS, NVOLS_1, n, s, s_start, s_end, v_init;
  real              *volumes, *V, x, y, *DIST, *order, last_distance;
  int               *VV=NULL, nV, v, vv;
  char              skip;
  triplet           *TS=NULL, *DTS=NULL, T;
  mxArray           *INPUT[2]={NULL,NULL}, *OUTPUT[3]={NULL,NULL,NULL};
  double            *MAXs, LAST_MAX;
  double            thisMINx, thisMINy;
  double            *idxs;
  double            *vols;
  double            *ijk;
  char              callSort;
  mwSize            toVec[2]={1,1};
  char              VERBOSE = 0;
  char              STR[1024];
  
  
  if( nlhs > 1 ){
    mxErrMsgTxt("too much outputs");
  }


  if( mxIsChar( prhs[nrhs-1] ) ){
    mxGetString( prhs[nrhs-1], STR, 100 );
    if( ! myStrcmpi(STR,"verbose") ){ 
      VERBOSE = 1;
    } else {
      mxErrMsgTxt("only 'verbose' option allowed.");
    }
    nrhs = nrhs-1;
  }
  
  
  if( nrhs != 3 ){
    mxErrMsgTxt("sintax error. max_min_multiples_erodes( V , F , volumes )");
  }

  if( mxGetClassID( prhs[1] ) != mxFUNCTION_CLASS ){
    mxErrMsgTxt("F have to be a function_handle.");
  }

  if( myNDims( prhs[0] ) > 3  ){
    mxErrMsgTxt("bigger than 3d arrays is not allowed.");
  }
  
  NVOLS   = myNumel( prhs[2] );
  NVOLS_1 = NVOLS - 1;
  volumes = myGetPr( prhs[2] );
  
  
  I     = mySize( prhs[0] , 0 );
  J     = mySize( prhs[0] , 1 );
  K     = mySize( prhs[0] , 2 );
  IJ    = I*J;
  IJK   = IJ*K;
  

  VV = (int     *) mxMalloc( IJK*sizeof( int     ) );
  TS     = (triplet *) mxMalloc( IJK*sizeof( triplet ) );

  V = myGetPr( prhs[0] );

  v  = 0; 
  nV = 0;
  for( kk = 0 ; kk < K ; kk++ ){ for( jj = 0 ; jj < J ; jj++ ){ for( ii = 0 ; ii < I ; ii++ ){
    x = V[ v ];
    if( x == x ){
      VV[ nV ] = v;
      TS[ v ].isnan = 0;
      TS[ v ].i     = ii;
      TS[ v ].j     = jj;
      TS[ v ].k     = kk;
      nV++;
    } else {
      TS[ v ].isnan = 1;
    }
    v++;
  }}}


  INPUT[0] = prhs[1];
  INPUT[1] = mxCreateNumericMatrix( 1 , 3 , mxDOUBLE_CLASS , mxREAL );
  ijk = (double *) mxGetData( INPUT[1] );
  
  
  ijk[0] = TS[ VV[ nV/2] ].i + 1;
  ijk[1] = TS[ VV[ nV/2] ].j + 1;
  ijk[2] = TS[ VV[ nV/2] ].k + 1;
  


  OUTPUT[2] = mexCallMATLABWithTrap( 2 , OUTPUT , 2 , INPUT , "feval" );
  
  if( OUTPUT[2] == NULL ){
    
    callSort = 0;
    if( mxGetClassID( OUTPUT[0] ) != mxDOUBLE_CLASS ){
      if( INPUT[1]  != NULL ){ mxDestroyArray( INPUT[1] );  INPUT[1]=NULL;  }
      if( OUTPUT[0] != NULL ){ mxDestroyArray( OUTPUT[0] ); OUTPUT[0]=NULL; }
      if( OUTPUT[1] != NULL ){ mxDestroyArray( OUTPUT[1] ); OUTPUT[1]=NULL; }
      if( OUTPUT[2] != NULL ){ mxDestroyArray( OUTPUT[2] ); OUTPUT[2]=NULL; }
      mxErrMsgTxt("F debe retornar un double en el primer output.");
    }
    if( mxGetClassID( OUTPUT[1] ) != mxDOUBLE_CLASS ){
      if( INPUT[1]  != NULL ){ mxDestroyArray( INPUT[1] );  INPUT[1]=NULL;  }
      if( OUTPUT[0] != NULL ){ mxDestroyArray( OUTPUT[0] ); OUTPUT[0]=NULL; }
      if( OUTPUT[1] != NULL ){ mxDestroyArray( OUTPUT[1] ); OUTPUT[1]=NULL; }
      if( OUTPUT[2] != NULL ){ mxDestroyArray( OUTPUT[2] ); OUTPUT[2]=NULL; }
      mxErrMsgTxt("F debe retornar un double en el segundo output.");
    }
    
  } else {

    callSort = 1;
    if( VERBOSE ){
      mexPrintf("sort has to be called\n");
    }
    
    mxDestroyArray( OUTPUT[2] ); OUTPUT[2] = NULL;

    result = mexCallMATLAB( 1 , OUTPUT , 2 , INPUT , "feval" );
    if( result ){ mxErrMsgTxt("error computing la funcion."); }

    if( mxGetClassID( OUTPUT[0] ) != mxDOUBLE_CLASS ){
      if( INPUT[1]  != NULL ){ mxDestroyArray( INPUT[1] );  INPUT[1]=NULL;  }
      if( OUTPUT[0] != NULL ){ mxDestroyArray( OUTPUT[0] ); OUTPUT[0]=NULL; }
      if( OUTPUT[1] != NULL ){ mxDestroyArray( OUTPUT[1] ); OUTPUT[1]=NULL; }
      if( OUTPUT[2] != NULL ){ mxDestroyArray( OUTPUT[2] ); OUTPUT[2]=NULL; }
      mxErrMsgTxt("F debe retornar un double en el primer output.");
    }

  }

  DI   = mySize( OUTPUT[0] , 0 );
  DJ   = mySize( OUTPUT[0] , 1 );
  DK   = mySize( OUTPUT[0] , 2 );
  
  DTS  = (triplet *) mxMalloc( 2*DI*DJ*DK*sizeof( triplet ) );
  

  plhs[0] = mxCreateNumericMatrix( NVOLS , 1 , mxREAL_CLASS , mxREAL );
  MAXs    = (real *) mxGetData( plhs[0] );
  for( n = 0 ; n < NVOLS ; n++ ){
    MAXs[n] = -10000;
  }

  
  LAST_MAX = MAXs[ NVOLS_1 ];
  for( v_init = 0 ; v_init < EVERY ; v_init++ ){
    if( utIsInterruptPending() ){
      if( INPUT[1]  != NULL ){ mxDestroyArray( INPUT[1] );  INPUT[1]=NULL;  }
      if( OUTPUT[0] != NULL ){ mxDestroyArray( OUTPUT[0] ); OUTPUT[0]=NULL; }
      if( OUTPUT[1] != NULL ){ mxDestroyArray( OUTPUT[1] ); OUTPUT[1]=NULL; }
      if( OUTPUT[2] != NULL ){ mxDestroyArray( OUTPUT[2] ); OUTPUT[2]=NULL; }
      mexPrintf("USER INTERRUP!!!\n");
      mxErrMsgTxt("USER INTERRUP!!!");
    }
    if( VERBOSE ){
      mexPrintf("v_init:  %d  (%g)  of  %d\n", v_init , LAST_MAX , EVERY );
    }

    for( v = v_init ; v < nV ; v += EVERY ){
      vv = VV[ v ];
      
      thisMINx =   V[ vv ];
      thisMINy =  -thisMINx;
      if( ( thisMINx < LAST_MAX )  && ( thisMINy < LAST_MAX ) ){
        continue;
      }

      T = TS[ vv ];
      
      ijk[0] = T.i + 1;
      ijk[1] = T.j + 1;
      ijk[2] = T.k + 1;
      

      if( OUTPUT[0] != NULL ){ mxDestroyArray( OUTPUT[0] ); OUTPUT[0]=NULL; }
      if( OUTPUT[1] != NULL ){ mxDestroyArray( OUTPUT[1] ); OUTPUT[1]=NULL; }
      if( OUTPUT[2] != NULL ){ mxDestroyArray( OUTPUT[2] ); OUTPUT[2]=NULL; }

      if( !callSort ){
        tic( CallMatlab );
        result = mexCallMATLAB( 2 , OUTPUT , 2 , INPUT , "feval" ); fevals++;
        tac( CallMatlab );
      } else {
        tic( CallMatlab );
        result = mexCallMATLAB( 1 , OUTPUT , 2 , INPUT , "feval" ); fevals++;
        tac( CallMatlab );
      }
      
      DI   = mySize( OUTPUT[0] , 0 );
      DJ   = mySize( OUTPUT[0] , 1 );
      DK   = mySize( OUTPUT[0] , 2 );

      DIJK    = DI*DJ*DK;

      if( volumes[ NVOLS_1 ] > DIJK ){
      if( INPUT[1]  != NULL ){ mxDestroyArray( INPUT[1] );  INPUT[1]=NULL;  }
      if( OUTPUT[0] != NULL ){ mxDestroyArray( OUTPUT[0] ); OUTPUT[0]=NULL; }
      if( OUTPUT[1] != NULL ){ mxDestroyArray( OUTPUT[1] ); OUTPUT[1]=NULL; }
      if( OUTPUT[2] != NULL ){ mxDestroyArray( OUTPUT[2] ); OUTPUT[2]=NULL; }
        mxErrMsgTxt("el maximo volumen debe ser menor que numel(DIST)");
      }

      DIJK_1  = DIJK - 1;

      DIST  = (double  *) mxGetData( OUTPUT[0] );
      
      DTS  = (triplet *) mxRealloc( DTS , DIJK*sizeof( triplet ) );
      s = 0;
      for( kk = 0 ; kk < DK ; kk++ ){ for( jj = 0 ; jj < DJ ; jj++ ){ for( ii = 0 ; ii < DI ; ii++ ){
        DTS[ s ].i = ii;
        DTS[ s ].j = jj;
        DTS[ s ].k = kk;
        s++;
      }}}


      if( !callSort ){
        order = (double  *) mxGetData( OUTPUT[1] );
      } else {
        toVec[0] = mxGetNumberOfElements( OUTPUT[0] );
        mxSetDimensions( OUTPUT[0] ,  toVec  , 2 );
        
        tic( callSort );
        result = mexCallMATLAB( 2 , OUTPUT+1 , 1 , OUTPUT , "sort" );
        tac( callSort );
      
        order = (double  *) mxGetData( OUTPUT[2] );
      }
      
      CDI = DTS[ (int) ( order[0] - 1 ) ].i;
      CDJ = DTS[ (int) ( order[0] - 1 ) ].j;
      CDK = DTS[ (int) ( order[0] - 1 ) ].k;
      
      
      skip   = 0;

      s = 0;
      for( n = 0 ; n < NVOLS ; n++ ){
        s_end = (int) ( volumes[n] - 1 );
        last_distance = DIST[ (int) order[ s_end ] - 1 ];
        
        while( s_end < DIJK_1 && DIST[ (int) ( order[ s_end + 1 ] - 1 ) ] == last_distance ){
          s_end++;
        }
        s_end++;
        
        for( ; s < s_end ; s++ ){
          vv = (int) ( order[ s ] - 1 );
          
          ii = T.i + DTS[ vv ].i - CDI;  if( ii < 0 || ii > I ){ skip = 1; break; }
          jj = T.j + DTS[ vv ].j - CDJ;  if( jj < 0 || jj > J ){ skip = 1; break; }
          kk = T.k + DTS[ vv ].k - CDK;  if( kk < 0 || kk > K ){ skip = 1; break; }
            
          vv = ii + jj*I + kk*IJ;
          if( TS[ vv ].isnan ){  skip = 1; break; }
          x =  V[ vv ];  if( x < thisMINx ){ thisMINx = x; }
          y = -x;        if( y < thisMINy ){ thisMINy = y; }
          if( ( thisMINx < LAST_MAX )  && ( thisMINy < LAST_MAX ) ){
            skip = 1; break; 
          }
        }
        if( skip ){  break; }
        if( thisMINx > MAXs[n] ){ MAXs[n] = thisMINx; }
        if( thisMINy > MAXs[n] ){ MAXs[n] = thisMINy; }
      }
      LAST_MAX = MAXs[ NVOLS_1 ];

    }
    
  }
  if( INPUT[1]  != NULL ){ mxDestroyArray( INPUT[1]  ); INPUT[1] =NULL; }
  if( OUTPUT[0] != NULL ){ mxDestroyArray( OUTPUT[0] ); OUTPUT[0]=NULL; }
  if( OUTPUT[1] != NULL ){ mxDestroyArray( OUTPUT[1] ); OUTPUT[1]=NULL; }
  if( OUTPUT[2] != NULL ){ mxDestroyArray( OUTPUT[2] ); OUTPUT[2]=NULL; }
  
  if( VERBOSE ){
    mexPrintf( "\nfevals: %d  en  tiempo:   CallMatlab: %20.30g    sorting: %20.30g\n" , fevals , toc( CallMatlab ) , toc( callSort ) );
  }
  
  
  if(  VV != NULL ){  mxFree(  VV ); }
  if(  TS != NULL ){  mxFree(  TS ); }
  if( DTS != NULL ){  mxFree( DTS ); }

  myFreeALLOCATES();

}
Esempio n. 29
0
/*
  This function computes the generalised matrix products.  Basicially it
  works by spliting the input X and Y matrices into 2 *virtual* sub-matrices,
  one for the "outer" product dimensions (x/y rest) (over which the cartesian
  product is computed) and one for the "inner" product matrices (over which
  the inner product - or multiply accumulate - is computed).  Once these 2
  matrices have been computed the result is simply an outer product in
  tprod and inner product in macc */
void mexFunction(const int nlhs, mxArray *plhs[], 
                 const int nrhs, const mxArray *prhs[]) {
  int i, maccnd=0, seqnd=0, BLKSZ=DEFAULTBLKSZ, err=OK; 
  const int xargi=0, ydimspecarg=3;
  int xdimspecarg=0, yargi=0; /* possibly other way round? */
  bool useMATLAB=true;
  int callType=0;
  MxInfo xinfo, yinfo, zinfo;
  MxInfo xmacc, ymacc, zrest, xrest, yrest;
  int znd, xnidx=0, ynidx=0;
  int *x2yIdx=0;
  if (nrhs < 4 || nrhs >6)	 { ERROR("tprod: Incorrect number of inputs."); err=OTHERERROR; }
  if (nlhs > 1) { ERROR("tprod: Too many output arguments."); err=OTHERERROR; }
  if ( mxGetNumberOfDimensions(prhs[ydimspecarg]) > 2 ){
	 ERROR("tprod: ydimspec must be a vector"); err=OTHERERROR; }
  /* parse the tprod options list */
  if( nrhs >= 5 && mxIsChar(prhs[4]) ) {
	 char *opnmStr=mxArrayToString(prhs[4]);
	 for (i=0 ; opnmStr[i] != 0; i++ ) {
		switch ( opnmStr[i] ) {
		case 'm': case 'M':   useMATLAB=false;  break;
		case 'n': case 'N':   callType=1;    break; /* new call type */
		case 'o': case 'O':   callType=-1;   break; /* old call type */
		default: 
		  WARNING("tprod: Unrecognised tprod option");
		}
	 }
	 mxFree(opnmStr); opnmStr=0;
  }

  if ( nrhs==6 && mxGetNumberOfElements(prhs[5])==1 ){
	 BLKSZ=(int)mxGetScalar(prhs[5]);
  }

  /* Get X */
  xinfo = mkmxInfoMxArray(prhs[xargi],0);
  /* remove trailing singlenton dimensions from x and y */
  for( i=xinfo.nd; i>1; i-- ) if ( xinfo.sz[i-1]!=1 ) break;  xinfo.nd=i;

  /*----------------------------------------------------------------------*/
  /* Identify the calling convention used */
  if ( callType == 0 ) {

	 /* Try and identify the calling convention used, i.e. 
		 X,Y,xdimspec,ydimspec, or X,xdimspec,Y,ydimspec (deprecated) */
	 if ( mxGetNumberOfDimensions(prhs[1])==2 &&		
			( (mxGetN(prhs[1])==1 && mxGetM(prhs[1])>=xinfo.nd) /* Xdimspec OK */
			  || (mxGetN(prhs[1])>=xinfo.nd && mxGetM(prhs[1])==1) ) ) {
		int ynd = 0; 
		const int *ysz = 0;
		yargi = 2; /* start by trying new call type */
		ynd=mxGetNumberOfDimensions(prhs[yargi]);
		ysz = mxGetDimensions(prhs[yargi]); /* size of poss Y*/
		for( i=ynd; i>1; i-- ) if ( ysz[i-1]!=1 ) break; ynd=i; 
		if( mxGetNumberOfElements(prhs[ydimspecarg]) >= ynd ){/*Ydimspec OK*/
		  callType = 1 ;  /* new call type */
		}
	 }
	 if( mxGetNumberOfDimensions(prhs[2])==2 &&
		  ((mxGetN(prhs[2])==1 && mxGetM(prhs[2])>=xinfo.nd)/* xdimspec OK */
			|| (mxGetN(prhs[2])>=xinfo.nd && mxGetM(prhs[2])==1) ) ) {
		/* Consitent so far, check the ydimspec is OK */
		int ynd = 0; 
		const int *ysz = 0;
		yargi  = 1; /* start by trying new call type */
		ynd=mxGetNumberOfDimensions(prhs[yargi]);
		ysz = mxGetDimensions(prhs[yargi]); /* size of poss Y*/
		for( i=ynd; i>1; i-- ) if ( ysz[i-1]!=1 ) break; ynd=i; 
		if ( mxGetNumberOfElements(prhs[ydimspecarg]) >= ynd ) {
		  
		  if ( callType == 0 ) { /* argument 3 is CONSISTENT, and 2 *WASN'T* */
			 callType = -1; 
			 
		  } else { /* argument 2 consistent ALSO */
			 /* of one of them matches exactly and the other doesn't */
			 int xnd = mxGetNumberOfDimensions(prhs[xargi]); /* num input X dims */
			 if ( xnd==2 && xinfo.nd == 1 ) xnd=1; /* col vec is special case*/
			 if ( xnd == mxGetNumberOfElements(prhs[1]) /* 1 matches *exactly* */
					&& xnd != mxGetNumberOfElements(prhs[2]) ) { /* 2 doesn't */
				callType = 1;
			 } else if( xnd == mxGetNumberOfElements(prhs[2])/* 2 *exact* match */
							&& xnd != mxGetNumberOfElements(prhs[1]) ){/* 1 doesn't */
				callType = -1;
			 } else { /* neither or both match exactly */
				callType = 1;
				WARNING("tprod: Could not unambigiously determine calling convention, tprod(X,xdimspec,Y,ydimspec) assumed. Use 'n' or 'o' to force new/old convention.");
			 }
		  }
		}
	 } 
  }
  switch ( callType ) {
  case 1:  xdimspecarg=1; yargi=2; break;/* new type: X,xdimspec,Y,xdimspec */
  case -1: xdimspecarg=2; yargi=1; break;/* old type: X,Y,xdimspec,xdimspec */
  default: ERROR("tprod: Couldnt identify calling convention."); err=OTHERERROR;
  }

  /* Now we know where the Y is we can get it too! */
  yinfo = mkmxInfoMxArray(prhs[yargi],0); 
  /* empty set as input for y means make it copy of x */
  if ( yinfo.numel==0 && yinfo.nd==2 && yinfo.sz[0]==0 && yinfo.sz[1]==0 ) { 
	 yinfo=copymxInfo(xinfo); 
  }
  /* remove trailing singlenton dimensions from x and y */
  for( i=yinfo.nd; i>1; i-- ) if ( yinfo.sz[i-1]!=1 ) break;  yinfo.nd=i;

  /* check the types are what we can use */
  if ( !(xinfo.dtype == DOUBLE_DTYPE || xinfo.dtype == SINGLE_DTYPE ) ){
	 ERROR("tprod: X type unsuppored: only full double/single"); err=UNSUPPORTEDINPUTS;
  }
  if ( mxIsSparse(prhs[xargi]) ){
	 ERROR("tprod: X is sparse, only full double/single supported"); err=UNSUPPORTEDINPUTS;
  }
  if ( !(yinfo.dtype == DOUBLE_DTYPE || yinfo.dtype == SINGLE_DTYPE ) ){
	 ERROR("tprod: Y type unsuppored: only double, single"); err=UNSUPPORTEDINPUTS;
  }
  if ( mxIsSparse(prhs[yargi]) ){
	 ERROR("tprod: X is sparse, only full double/single supported"); err=UNSUPPORTEDINPUTS;
  }
       
  /* fill in the x2yIdx for the new type of indicies */
  maccnd=0;
  xnidx=mxGetNumberOfElements(prhs[xdimspecarg]);
  ynidx=mxGetNumberOfElements(prhs[ydimspecarg]);
  err = compx2yIdx_dd(xinfo,xnidx,mxGetPr(prhs[xdimspecarg]), 
								 yinfo,ynidx,mxGetPr(prhs[ydimspecarg]),
								 &x2yIdx,&znd,&maccnd,&seqnd);
  if ( err != 0 ) { /* FREE and return */
	 delmxInfo(&xinfo);  delmxInfo(&yinfo);
	 if ( x2yIdx != 0 ) FREE(x2yIdx); 
	 return ; 
  }

  #ifdef LOGGING  
  FILE *fd = fopen("/tmp/tprod.log","a");
  if( fd==0 ){WARNING("Couldn't open log file /tmp/tprod.log\n"); fd=stderr;}
  fprintf(fd,"tprod( ");
  printMxInfoSummary(fd,xinfo);fprintf(fd," ,[");
  for(i=0; i<xnidx; i++) fprintf(fd,"%d ", (int)mxGetPr(prhs[xdimspecarg])[i]);
  fprintf(fd,"] , ");
  printMxInfoSummary(fd,yinfo);fprintf(fd," ,[");  
  for(i=0; i<ynidx; i++) fprintf(fd,"%d ", (int)mxGetPr(prhs[ydimspecarg])[i]);
  fprintf(fd,"] )\n"); 
  if ( fd!=stderr ) fclose(fd);
  #endif

  /* compute the mxInfo for the accumulated and rest sub-matrices */  
  xmacc = mkemptymxInfo(maccnd);
  ymacc = mkemptymxInfo(maccnd);
  /* N.B. xrest.sz holds the	size of the combined x and y rest matrix */
  xrest = mkemptymxInfo(znd); 
  yrest = mkemptymxInfo(znd);

  err = initrestmaccmxInfo(znd, xinfo, yinfo, 
										x2yIdx, xnidx, ynidx,
										&xrest, &yrest, &xmacc, &ymacc);
  if ( err != 0 ) { /* FREE and return */
	 delmxInfo(&xinfo);  delmxInfo(&yinfo);
	 delmxInfo(&xmacc);  delmxInfo(&ymacc);
	 delmxInfo(&xrest);  delmxInfo(&yrest);
	 FREE(x2yIdx);
	 return; 
  }

  /* compute the size of the output matrix */
  zinfo=initzmxInfo(znd, xinfo, yinfo, x2yIdx, xnidx, ynidx); 

  /* optimise/standardize the query so its the way tprod wants it */
  zrest = copymxInfo(zinfo);
  err =  optimisetprodQuery(&zrest, &xrest, &yrest, 
										 &xmacc, &ymacc);  
  if ( err != OK ) { /* free everything and return */
	 delmxInfo(&xinfo);  delmxInfo(&yinfo); delmxInfo(&zinfo);
	 delmxInfo(&xmacc);  delmxInfo(&ymacc);
	 delmxInfo(&xrest);  delmxInfo(&yrest); delmxInfo(&zrest);
	 FREE(x2yIdx);
	 return; 
  }
  
  if ( xrest.rp != xinfo.rp ) { /* swap xinfo/yinfo if needed */
	 MxInfo tmp = xinfo; xinfo=yinfo; yinfo=tmp;
  }

  /* Now do the actuall work to compute the result */  
  if ( yinfo.numel==0 || xinfo.numel== 0 ) { /* deal with null inputs */
	 WARNING("tprod: Empty matrix input!");
	 /* return an empty matrix */
	 plhs[0]=mxCreateNumericArray(zinfo.nd,zinfo.sz,mxDOUBLE_CLASS,
											(xinfo.ip==0&&yinfo.ip==0)?mxREAL:mxCOMPLEX);
	 	 
  } else if ( useMATLAB && /* allowed */
		 seqnd==0 &&                     /* no sequential dims */
		 xmacc.nd <= 1 &&            /* at most 1 macc dim */
		 xrest.nd <= 2 &&            /* at most 2 output dims */
		 (xrest.nd<= 1 ||            /* 1 from X */
		  ((xrest.stride[0]==0) || (stride(xrest,1)==0))) && 
 		 (yrest.nd<= 1 ||            /* 1 from Y */
		  ((yrest.stride[0]==0) || (stride(yrest,1)==0))) &&
				  (xmacc.numel*(2+(xinfo.ip==0)+(yinfo.ip==0)) < MATLABMACCTHRESHOLDSIZE ) /* not tooo big! */
				  ){ 
	 /* Phew! we can use matlab! */
	 if ( xrest.stride[0]>0 ) { /* x comes before y in output */
		plhs[0]=MATLAB_mm(zinfo,xinfo,yinfo,xrest,yrest,
								xmacc,ymacc);
	 } else { /* y comes before x in output, reverse order of inputs */
		plhs[0]=MATLAB_mm(zinfo,yinfo,xinfo,yrest,xrest,
								ymacc,xmacc);
	 }
  } else {

	 /* otherwise do it ourselves */
	 /* create the data for the z matrix and set its pointer */
	 plhs[0]=mxCreateNumericArray(zinfo.nd,zinfo.sz,zinfo.dtype,
											(xinfo.ip==0&&yinfo.ip==0)?mxREAL:mxCOMPLEX);
	 zinfo.rp = mxGetPr(plhs[0]); zrest.rp=zinfo.rp;
	 zinfo.ip = mxGetPi(plhs[0]); zrest.ip=zinfo.ip;

	 /* call tprod to do the real work */
	 /* do the (appropriately typed) operation */
	 if(        xrest.dtype==DOUBLE_DTYPE && yrest.dtype==DOUBLE_DTYPE ) {/*dd*/
		err= ddtprod(zrest,xrest,yrest,xmacc,ymacc,BLKSZ);

	 } else if( xrest.dtype==DOUBLE_DTYPE && yrest.dtype==SINGLE_DTYPE ) {/*ds*/
		err= dstprod(zrest,xrest,yrest,xmacc,ymacc,BLKSZ);

	 } else if( xrest.dtype==SINGLE_DTYPE && yrest.dtype==DOUBLE_DTYPE ) {/*sd*/
		err= sdtprod(zrest,xrest,yrest,xmacc,ymacc,BLKSZ);
 
	 } else if( xrest.dtype==SINGLE_DTYPE && yrest.dtype==SINGLE_DTYPE ){/*ss*/
		err= sstprod(zrest,xrest,yrest,xmacc,ymacc,BLKSZ);

	 } else {
		err= UNSUPPORTEDINPUTS;
		
	 }
	 /* check for errors */
	 switch ( err ) {
	 case ZTYPEMISMATCH : 
		ERROR("tprod: Z is of unsupported type"); break;
	 case XTYPEMISMATCH :
		ERROR("tprod: X is of unsupported type"); break;
	 case YTYPEMISMATCH :
		ERROR("tprod: Y is of unsupported type"); break;
	 case INTYPEMISMATCH :
		ERROR("tprod: input real/complex mix unsupported"); break;
	 case OTHERERROR :
		ERROR("tprod: Something else went wrong, sorry!"); break;
	 case UNSUPPORTEDINPUTS :
 		ERROR("tprod: Inputs of unsupported type: only double/single"); break;
	 default: ;
	 }
  }
  
  /* ensure the output has the size we want */
  if ( err==OK && plhs[0] ) mxSetDimensions(plhs[0],zinfo.sz,zinfo.nd);
  
  /* free up all the memory we've allocated */
  /* N.B. not clear we need to do this from the matlab web-site should happen
	  automatically */
  delmxInfo(&xinfo);delmxInfo(&yinfo);delmxInfo(&zinfo);
  delmxInfo(&xmacc);  delmxInfo(&ymacc);
  delmxInfo(&xrest);  delmxInfo(&yrest);
  FREE(x2yIdx);
}