void LTFAT_NAME(ltfatMexFnc)( int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[] ) { // Register exit function only once static int atExitFncRegistered = 0; if(!atExitFncRegistered) { LTFAT_NAME(ltfatMexAtExit)(LTFAT_NAME(dctMexAtExitFnc)); atExitFncRegistered = 1; } LTFAT_REAL *c_r, *c_i; const LTFAT_REAL *f_r, *f_i; dct_kind kind; mwIndex L = mxGetM(prhs[0]); mwIndex W = mxGetN(prhs[0]); mwIndex type = (mwIndex) mxGetScalar(prhs[1]); // Copy inputs and get pointers if( mxIsComplex(prhs[0])) { f_i = mxGetImagData(prhs[0]); plhs[0] = ltfatCreateMatrix(L, W, LTFAT_MX_CLASSID, mxCOMPLEX); c_i = mxGetImagData(plhs[0]); } else { plhs[0] = ltfatCreateMatrix(L, W, LTFAT_MX_CLASSID, mxREAL); } f_r = mxGetData(prhs[0]); c_r = mxGetData(plhs[0]); switch(type) { case 1: kind = DSTI; break; case 2: kind = DSTII; break; case 3: kind = DSTIII; break; case 4: kind = DSTIV; break; default: mexErrMsgTxt("Unknown type."); } LTFAT_FFTW(plan) p = LTFAT_NAME(dst_init)( L, W, c_r, kind); LTFAT_NAME(dctMexAtExitFnc)(); LTFAT_NAME(p_old) = p; LTFAT_NAME(dst_execute)(p,f_r,L,W,c_r,kind); if( mxIsComplex(prhs[0])) { LTFAT_NAME(dst_execute)(p,f_i,L,W,c_i,kind); } return; }
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) { mxArray *data; /* element data in a structure */ FILE *fob; double *pd; double dbu_to_uu; int etype; /* check argument number */ if (nrhs != 3) { mexErrMsgTxt("3 input arguments expected."); } if (nlhs != 1) { mexErrMsgTxt("one output argument expected."); } /* get file handle argument */ fob = get_file_ptr((mxArray *)prhs[0]); /* get type argument */ pd = mxGetData(prhs[1]); etype = pd[0]; /* get unit conversion factor: database units --> user units */ pd = mxGetData(prhs[2]); dbu_to_uu = pd[0]; /* decide what to do */ switch (etype) { case BOUNDARY: read_boundary(fob, &data, dbu_to_uu); break; case PATH: read_path(fob, &data, dbu_to_uu); break; case SREF: read_sref(fob, &data, dbu_to_uu); break; case AREF: read_aref(fob, &data, dbu_to_uu); break; case TEXT: read_text(fob, &data, dbu_to_uu); break; case NODE: read_node(fob, &data, dbu_to_uu); break; case BOX: read_box(fob, &data, dbu_to_uu); break; default: mexErrMsgTxt("gds_read_element : unknown element type."); } plhs[0] = data; }
void mexFunction( int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[] ) /* left hand side right hand side /* function [z,kz] = mandelbrot_step(z,kz,z0,d); * Take one step of the Mandelbrot iteration. * Complex arithmetic: * z = z.^2 + z0 * kz(abs(z) < 2) == d * Real arithmetic: * x <-> real(z); * y <-> imag(z); * u <-> real(z0); * v <-> imag(z0); * [x,y] = [x.^2-y.^2+u, 2*x.*y+v]; * kz(x.^2+y.^2 < 4) = d; */ { double *x,*y,*u,*v,t; unsigned short *kz, *num, d; int j ,n, m; int dim[] = {1, 1}; x = mxGetPr(prhs[0]); y = mxGetPi(prhs[0]); kz = (unsigned short *) mxGetData(prhs[1]); u = mxGetPr(prhs[2]); v = mxGetPi(prhs[2]); d = (unsigned short) mxGetScalar(prhs[3]); plhs[0] = prhs[0]; plhs[1] = prhs[1]; plhs[2] = mxCreateNumericArray(2,dim,mxUINT32_CLASS,mxREAL); num = mxGetData(plhs[2]); *num = 0; n = mxGetN(prhs[0]); m = mxGetM(prhs[0]); if(1){ for (j=n*m; j--; ) { if (kz[j] == d-1) { t = x[j]; x[j] = x[j]*x[j] - y[j]*y[j] + u[j]; y[j] = (t+t)*y[j] + v[j]; if (x[j]*x[j] + y[j]*y[j] < 4) { kz[j] = d; } else { *num = *num+1; } } } } else { for (j=0; j<n*m; j++) { if (kz[j] == d-1) { t = x[j]; x[j] = x[j]*x[j] - y[j]*y[j] + u[j]; y[j] = 2*t*y[j] + v[j]; if (x[j]*x[j] + y[j]*y[j] < 4) { kz[j] = d; } } } } return; }
/** * parse search option */ inline ESearchScheme getopt_search_scheme(const mxArray* mxSearchWay) { return (ESearchScheme)(*((const int*)mxGetData(mxSearchWay))); }
/* The matlab mex function */ void mexFunction( int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[] ) { /* Ox and Oy are the grid points */ /* Zo is the input image */ /* Zi is the transformed image */ /* nx and ny are the number of grid points (inside the image) */ double *Ox,*Oy,*Oz,*I1,*I2,*dxa, *dya,*dza, *E, *Egradient, *ThreadOut; mxArray *matlabCallOut[1]={0}; mxArray *matlabCallIn[1]={0}; double *Nthreadsd; int Nthreads; /* Finite difference step size */ double step=0.01; /* index offsets */ int offset1, offset2, offset3; /* Dims outputs */ const int dims_error[2]={1,1}; int dims_error_gradient[4]={1,1,1,3}; /* double pointer array to store all needed function variables) */ double ***ThreadArgs; double **ThreadArgs1; /* Handles to the worker threads */ ThreadHANDLE *ThreadList; /* ID of Threads */ double **ThreadID; double *ThreadID1; /* Size of input image */ mwSize Isizex, Isizey, Isizez; double Isize_d[3]={0,0,0}; const mwSize *dims; /* Size of grid */ mwSize Osizex, Osizey, Osizez; int Onumel; double Osize_d[3]={0,0,0}; /* B-spline variablesl */ double u,v,w; int u_index=0; int v_index=0; int w_index=0; double *Bu, *Bv, *Bw; /* Loop variables */ int i,j; /* Grid distance */ int dx,dy,dz; /* X,Y,Z coordinates of current pixel */ int x,y,z; /* Check for proper number of arguments. */ if(nrhs!=8) { mexErrMsgTxt("Eight inputs are required."); } /* Get the sizes of the grid */ dims = mxGetDimensions(prhs[0]); Osizex = dims[0]; Osizey = dims[1]; Osizez = dims[2]; Onumel = Osizex*Osizey*Osizez; /* Create image matrix for the return arguments with the size of input image */ dims = mxGetDimensions(prhs[3]); Isizex = dims[0]; Isizey = dims[1]; Isizez = dims[2]; /* Create image matrix for the Error return argument */ plhs[0] = mxCreateNumericArray(2, dims_error, mxDOUBLE_CLASS, mxREAL); if(nlhs>1) { dims_error_gradient[0]=Osizex; dims_error_gradient[1]=Osizey; dims_error_gradient[2]=Osizez; /* Error Gradient needed */ plhs[1] = mxCreateNumericArray(4, dims_error_gradient, mxDOUBLE_CLASS, mxREAL); } /* Assign pointers to each input. */ Ox=(double *)mxGetData(prhs[0]); Oy=(double *)mxGetData(prhs[1]); Oz=(double *)mxGetData(prhs[2]); I1=(double *)mxGetData(prhs[3]); I2=(double *)mxGetData(prhs[4]); dxa=(double *)mxGetData(prhs[5]); dya=(double *)mxGetData(prhs[6]); dza=(double *)mxGetData(prhs[7]); /* Get the spacing of the uniform b-spline grid */ dx=(int)dxa[0]; dy=(int)dya[0]; dz=(int)dza[0]; /* Get number of allowed threads */ mexCallMATLAB(1, matlabCallOut, 0, matlabCallIn, "maxNumCompThreads"); Nthreadsd=mxGetPr(matlabCallOut[0]); Nthreads=(int)Nthreadsd[0]; /* Reserve room for handles of threads in ThreadList */ ThreadList = (ThreadHANDLE*)malloc(Nthreads* sizeof( ThreadHANDLE )); ThreadID = (double **)malloc( Nthreads* sizeof(double *) ); ThreadArgs = (double ***)malloc( Nthreads* sizeof(double **) ); if(nlhs==1){ ThreadOut = (double *)malloc(Nthreads* sizeof(double) ); } else { ThreadOut = (double *)malloc(Nthreads*(1+Onumel*3)*sizeof(double) ); } /* Assign pointer to output. */ E = mxGetPr(plhs[0]); if(nlhs>1) { Egradient = mxGetPr(plhs[1]); } /* Make polynomial look up tables */ Bu=malloc(dx*4*sizeof(double)); Bv=malloc(dy*4*sizeof(double)); Bw=malloc(dz*4*sizeof(double)); for (x=0; x<dx; x++) { u=((double)x/(double)dx)-floor((double)x/(double)dx); Bu[mindex2(0,x,4)] = (double)pow((1-u),3)/6; Bu[mindex2(1,x,4)] = (double)( 3*pow(u,3) - 6*pow(u,2) + 4)/6; Bu[mindex2(2,x,4)] = (double)(-3*pow(u,3) + 3*pow(u,2) + 3*u + 1)/6; Bu[mindex2(3,x,4)] = (double)pow(u,3)/6; } for (y=0; y<dy; y++) { v=((double)y/(double)dy)-floor((double)y/(double)dy); Bv[mindex2(0,y,4)] = (double)pow((1-v),3)/6; Bv[mindex2(1,y,4)] = (double)( 3*pow(v,3) - 6*pow(v,2) + 4)/6; Bv[mindex2(2,y,4)] = (double)(-3*pow(v,3) + 3*pow(v,2) + 3*v + 1)/6; Bv[mindex2(3,y,4)] = (double)pow(v,3)/6; } for (z=0; z<dz; z++) { w=((double)z/(double)dz)-floor((double)z/(double)dz); Bw[mindex2(0,z,4)] = (double)pow((1-w),3)/6; Bw[mindex2(1,z,4)] = (double)( 3*pow(w,3) - 6*pow(w,2) + 4)/6; Bw[mindex2(2,z,4)] = (double)(-3*pow(w,3) + 3*pow(w,2) + 3*w + 1)/6; Bw[mindex2(3,z,4)] = (double)pow(w,3)/6; } Isize_d[0]=(double)Isizex; Isize_d[1]=(double)Isizey; Isize_d[2]=(double)Isizez; Osize_d[0]=(double)Osizex; Osize_d[1]=(double)Osizey; Osize_d[2]=(double)Osizez; /* Reserve room for 16 function variables(arrays) */ for (i=0; i<Nthreads; i++) { /* Make Thread ID */ ThreadID1= (double *)malloc( 1* sizeof(double) ); ThreadID1[0]=(double)i; ThreadID[i]=ThreadID1; /* Make Thread Structure */ ThreadArgs1 = (double **)malloc( 16 * sizeof( double * ) ); ThreadArgs1[0]=Bu; ThreadArgs1[1]=Bv; ThreadArgs1[2]=Bw; ThreadArgs1[3]=Isize_d; ThreadArgs1[4]=Osize_d; ThreadArgs1[5]=ThreadOut; ThreadArgs1[6]=dxa; ThreadArgs1[7]=dya; ThreadArgs1[8]=dza; ThreadArgs1[9]=ThreadID[i]; ThreadArgs1[10]=Ox; ThreadArgs1[11]=Oy; ThreadArgs1[12]=Oz; ThreadArgs1[13]=I1; ThreadArgs1[14]=I2; ThreadArgs1[15]=Nthreadsd; ThreadArgs[i]=ThreadArgs1; if(nlhs==1){ StartThread(ThreadList[i], &transformvolume_error, ThreadArgs[i]) } else{ StartThread(ThreadList[i], &transformvolume_gradient, ThreadArgs[i]) } } for (i=0; i<Nthreads; i++) { WaitForThreadFinish(ThreadList[i]); } /* Add accumlated error of all threads */ E[0]=0; for (i=0; i<Nthreads; i++) { E[0]+=ThreadOut[i]; } E[0]/=Nthreads; if(nlhs>1) { for (i=0; i<Nthreads; i++) { offset1=i*(3*Onumel); offset2=offset1+Onumel; offset3=offset2+Onumel; for(j=0; j<Onumel; j++) { Egradient[j]+=ThreadOut[Nthreads+j+offset1]/step; Egradient[j+Onumel]+=ThreadOut[Nthreads+j+offset2]/step; Egradient[j+2*Onumel]+=ThreadOut[Nthreads+j+offset3]/step; } } for(j=0; j<3*Onumel; j++) { Egradient[j]/=Nthreads; } } for (i=0; i<Nthreads; i++) { free(ThreadArgs[i]); free(ThreadID[i]); } free(ThreadArgs); free(ThreadID ); free(ThreadList); free(Bu); free(Bv); free(Bw); }
/* The matlab mex function */ void mexFunction( int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[] ) { double *Iout; XnUInt64 *MXadress; if(nrhs==0) { printf("Open failed: Give Pointer to Kinect as input\n"); mexErrMsgTxt("Kinect Error"); } MXadress = (XnUInt64*)mxGetData(prhs[0]); if(MXadress[0]>0){ g_Context = ((xn::Context*) MXadress[0])[0]; } if(MXadress[2]>0) { g_DepthGenerator = ((xn::DepthGenerator*) MXadress[2])[0]; } else { mexErrMsgTxt("No Depth Node in Kinect Context"); } XnStatus nRetVal = XN_STATUS_OK; xn::DepthMetaData depthMD; // Process the data g_DepthGenerator.GetMetaData(depthMD); XnUInt16 g_nXRes = depthMD.FullXRes(); XnUInt16 g_nYRes = depthMD.FullYRes(); const XnDepthPixel* pDepth = depthMD.Data(); int Jdimsc[3]; Jdimsc[0]=g_nXRes; Jdimsc[1]=g_nYRes; Jdimsc[2]=3; int npixels=Jdimsc[0]*Jdimsc[1]; int index; XnPoint3D *pt_proj =new XnPoint3D[npixels]; XnPoint3D *pt_world=new XnPoint3D[npixels]; for(int y=0; y<Jdimsc[1]; y++) { for(int x=0; x<Jdimsc[0]; x++) { index=x+y*Jdimsc[0]; pt_proj[index].X=(XnFloat)x; pt_proj[index].Y=(XnFloat)y; pt_proj[index].Z=pDepth[x+y*Jdimsc[0]]; } } g_DepthGenerator.ConvertProjectiveToRealWorld ( (XnUInt32)npixels, pt_proj, pt_world); plhs[0] = mxCreateNumericArray(3, Jdimsc, mxDOUBLE_CLASS, mxREAL); Iout = mxGetPr(plhs[0]); for(int y=0; y<Jdimsc[1]; y++) { for(int x=0; x<Jdimsc[0]; x++) { index=x+y*Jdimsc[0]; Iout[index]=pt_world[index].X; Iout[index+npixels]=pt_world[index].Y; Iout[index+npixels*2]=pt_world[index].Z; } } delete[] pt_proj; delete[] pt_world; }
/** * parse split rule */ inline ANNsplitRule getopt_split_rule(const mxArray* mxSplitRule) { return (ANNsplitRule)(*((const int*)mxGetData(mxSplitRule))); }
void mexFunction(int nlhs, mxArray* plhs[], int nrhs, const mxArray* prhs[]) { mxArray* img; u_int8_t* p_img; /*The image from Matlab*/ u_int8_t** p_gray; /*Image converted for texture calcs*/ int mrows; /*Image height*/ int ncols; /*Image width*/ TEXTURE* features ; /*Returned struct of features*/ int i ; int imgsize[2] ; int imgindex[2] ; long offset ; int outputsize[2] ; /*Dimensions of TEXTURE struct*/ int outputindex[2] ; float* output ; /*Features to return*/ int distance, angle; /*Parameters for texture calculations*/ if (nrhs != 3) mexErrMsgTxt("\n mb_texture (im, distance, angle),\n\n" "This function returns the 14 image texture statistics described by R. Haralick.\n" "The statistics are calculated from the image's co-occurence matrix specified\n" "for a particular distance and angle. Distance is measured in pixels and\n" "the angle is measured in degrees.\n"); else if (nlhs != 1) mexErrMsgTxt("mb_texture returns a single output.\n") ; if (!mxIsNumeric(prhs[0])) mexErrMsgTxt("mb_texture requires the first input to be numeric\n") ; if (!mxIsUint8(prhs[0])) mexCallMATLAB(1, &img, 1, prhs, "im2uint8_dynamic_range"); else img = prhs[0]; mrows = mxGetM(img) ; ncols = mxGetN(img) ; if (!(mrows > 1) || !(ncols > 1)) mexErrMsgTxt("mb_texture requires an input image, not a scalar.\n") ; if ( !mxIsNumeric(prhs[1]) || (mxIsComplex(prhs[1])) ) mexErrMsgTxt("The second argument (distance) should be numeric and not complex."); if ( !mxIsNumeric(prhs[2]) || (mxIsComplex(prhs[2])) ) mexErrMsgTxt("The third argument (angle) should be numeric and not complex."); p_img = (u_int8_t*) mxGetData(img) ; distance = (double) mxGetScalar(prhs[1]) ; angle = (double) mxGetScalar(prhs[2]) ; imgsize[col] = ncols ; imgsize[row] = mrows ; p_gray = mxCalloc(mrows, sizeof(u_int8_t*)) ; if(p_gray) { for(i=0; i<mrows ; i++) { p_gray[i] = mxCalloc(ncols, sizeof(u_int8_t)) ; if(!p_gray[i]) mexErrMsgTxt("mb_texture : error allocating p_gray[i]") ; } } else mexErrMsgTxt("mb_texture : error allocating p_gray") ; for(imgindex[row] = 0 ; imgindex[row] < imgsize[row] ; imgindex[row]++) for(imgindex[col]=0; imgindex[col] < imgsize[col]; imgindex[col]++) { offset = mxCalcSingleSubscript(prhs[0], 2, imgindex) ; p_gray[imgindex[row]][imgindex[col]] = p_img[offset] ; } if (! (features=Extract_Texture_Features(distance, angle, p_gray,mrows, ncols, 255))) mexErrMsgTxt("ERROR: Could not compute Haralick Features."); outputsize[row] = 14; outputsize[col] = 1; plhs[0] = mxCreateNumericArray(2, outputsize, mxSINGLE_CLASS, mxREAL) ; if (!plhs[0]) mexErrMsgTxt("mb_texture: error allocating return variable.") ; output = (float*)mxGetData(plhs[0]) ; /* Copy the features into the return variable */ outputindex[row]=0 ; outputindex[col]=0 ; offset = mxCalcSingleSubscript(plhs[0], 2, outputindex) ; output[offset] = features->ASM; outputindex[row]++ ; offset = mxCalcSingleSubscript(plhs[0], 2, outputindex) ; output[offset] = features->contrast; outputindex[row]++ ; offset = mxCalcSingleSubscript(plhs[0], 2, outputindex) ; output[offset] = features->correlation; outputindex[row]++ ; offset = mxCalcSingleSubscript(plhs[0], 2, outputindex) ; output[offset] = features->variance; outputindex[row]++ ; offset = mxCalcSingleSubscript(plhs[0], 2, outputindex) ; output[offset] = features->IDM; outputindex[row]++ ; offset = mxCalcSingleSubscript(plhs[0], 2, outputindex) ; output[offset] = features->sum_avg; outputindex[row]++ ; offset = mxCalcSingleSubscript(plhs[0], 2, outputindex) ; output[offset] = features->sum_var; outputindex[row]++ ; offset = mxCalcSingleSubscript(plhs[0], 2, outputindex) ; output[offset] = features->sum_entropy; outputindex[row]++ ; offset = mxCalcSingleSubscript(plhs[0], 2, outputindex) ; output[offset] = features->entropy; outputindex[row]++ ; offset = mxCalcSingleSubscript(plhs[0], 2, outputindex) ; output[offset] = features->diff_var; outputindex[row]++ ; offset = mxCalcSingleSubscript(plhs[0], 2, outputindex) ; output[offset] = features->diff_entropy; outputindex[row]++ ; offset = mxCalcSingleSubscript(plhs[0], 2, outputindex) ; output[offset] = features->meas_corr1; outputindex[row]++ ; offset = mxCalcSingleSubscript(plhs[0], 2, outputindex) ; output[offset] = features->meas_corr2; outputindex[row]++ ; offset = mxCalcSingleSubscript(plhs[0], 2, outputindex) ; output[offset] = features->max_corr_coef; /* Memory clean-up. */ for (i=0; i<mrows ; i++) mxFree(p_gray[i]) ; mxFree(p_gray) ; /* features is calloc'd inside of Extract_Texture_Features */ free(features) ; }
void mcx_set_field(const mxArray *root,const mxArray *item,int idx, Config *cfg){ const char *name=mxGetFieldNameByNumber(root,idx); const int *arraydim; char *jsonshapes=NULL; int i,j; if(strcmp(name,"nphoton")==0 && cfg->replay.seed!=NULL) return; cfg->flog=stderr; GET_1ST_FIELD(cfg,nphoton) GET_ONE_FIELD(cfg,nblocksize) GET_ONE_FIELD(cfg,nthread) GET_ONE_FIELD(cfg,tstart) GET_ONE_FIELD(cfg,tstep) GET_ONE_FIELD(cfg,tend) GET_ONE_FIELD(cfg,maxdetphoton) GET_ONE_FIELD(cfg,sradius) GET_ONE_FIELD(cfg,maxgate) GET_ONE_FIELD(cfg,respin) GET_ONE_FIELD(cfg,isreflect) GET_ONE_FIELD(cfg,isref3) GET_ONE_FIELD(cfg,isrefint) GET_ONE_FIELD(cfg,isnormalized) GET_ONE_FIELD(cfg,isgpuinfo) GET_ONE_FIELD(cfg,issrcfrom0) GET_ONE_FIELD(cfg,autopilot) GET_ONE_FIELD(cfg,minenergy) GET_ONE_FIELD(cfg,unitinmm) GET_ONE_FIELD(cfg,reseedlimit) GET_ONE_FIELD(cfg,printnum) GET_ONE_FIELD(cfg,voidtime) GET_ONE_FIELD(cfg,issaveseed) GET_ONE_FIELD(cfg,replaydet) GET_ONE_FIELD(cfg,faststep) GET_ONE_FIELD(cfg,maxvoidstep) GET_ONE_FIELD(cfg,maxjumpdebug) GET_VEC3_FIELD(cfg,srcpos) GET_VEC3_FIELD(cfg,srcdir) GET_VEC3_FIELD(cfg,steps) GET_VEC3_FIELD(cfg,crop0) GET_VEC3_FIELD(cfg,crop1) GET_VEC4_FIELD(cfg,srcparam1) GET_VEC4_FIELD(cfg,srcparam2) else if(strcmp(name,"vol")==0){ if(!mxIsUint8(item) || mxGetNumberOfDimensions(item)!=3 ) mexErrMsgTxt("the 'vol' field must be a 3D uint8 array"); arraydim=mxGetDimensions(item); for(i=0;i<3;i++) ((unsigned int *)(&cfg->dim))[i]=arraydim[i]; if(cfg->vol) free(cfg->vol); cfg->vol=(unsigned char *)malloc(cfg->dim.x*cfg->dim.y*cfg->dim.z); memcpy(cfg->vol,mxGetData(item),cfg->dim.x*cfg->dim.y*cfg->dim.z); printf("mcx.dim=[%d %d %d];\n",cfg->dim.x,cfg->dim.y,cfg->dim.z); }else if(strcmp(name,"detpos")==0){ arraydim=mxGetDimensions(item); if(arraydim[0]>0 && arraydim[1]!=4) mexErrMsgTxt("the 'detpos' field must have 4 columns (x,y,z,radius)"); double *val=mxGetPr(item); cfg->detnum=arraydim[0]; if(cfg->detpos) free(cfg->detpos); cfg->detpos=(float4 *)malloc(cfg->detnum*sizeof(float4)); for(j=0;j<4;j++) for(i=0;i<cfg->detnum;i++) ((float *)(&cfg->detpos[i]))[j]=val[j*cfg->detnum+i]; printf("mcx.detnum=%d;\n",cfg->detnum); }else if(strcmp(name,"prop")==0){ arraydim=mxGetDimensions(item); if(arraydim[0]>0 && arraydim[1]!=4) mexErrMsgTxt("the 'prop' field must have 4 columns (mua,mus,g,n)"); double *val=mxGetPr(item); cfg->medianum=arraydim[0]; if(cfg->prop) free(cfg->prop); cfg->prop=(Medium *)malloc(cfg->medianum*sizeof(Medium)); for(j=0;j<4;j++) for(i=0;i<cfg->medianum;i++) ((float *)(&cfg->prop[i]))[j]=val[j*cfg->medianum+i]; printf("mcx.medianum=%d;\n",cfg->medianum); }else if(strcmp(name,"session")==0){ int len=mxGetNumberOfElements(item); if(!mxIsChar(item) || len==0) mexErrMsgTxt("the 'session' field must be a non-empty string"); if(len>MAX_SESSION_LENGTH) mexErrMsgTxt("the 'session' field is too long"); int status = mxGetString(item, cfg->session, MAX_SESSION_LENGTH); if (status != 0) mexWarnMsgTxt("not enough space. string is truncated."); printf("mcx.session='%s';\n",cfg->session); }else if(strcmp(name,"srctype")==0){ int len=mxGetNumberOfElements(item); const char *srctypeid[]={"pencil","isotropic","cone","gaussian","planar","pattern","fourier","arcsine","disk","fourierx","fourierx2d","zgaussian","line","slit", "rectangular",""}; char strtypestr[MAX_SESSION_LENGTH]={'\0'}; if(!mxIsChar(item) || len==0) mexErrMsgTxt("the 'srctype' field must be a non-empty string"); if(len>MAX_SESSION_LENGTH) mexErrMsgTxt("the 'srctype' field is too long"); int status = mxGetString(item, strtypestr, MAX_SESSION_LENGTH); if (status != 0) mexWarnMsgTxt("not enough space. string is truncated."); cfg->srctype=mcx_keylookup(strtypestr,srctypeid); if(cfg->srctype==-1) mexErrMsgTxt("the specified source type is not supported"); printf("mcx.srctype='%s';\n",strtypestr); }else if(strcmp(name,"outputtype")==0){ int len=mxGetNumberOfElements(item); const char *outputtype[]={"flux","fluence","energy","jacobian",""}; char outputstr[MAX_SESSION_LENGTH]={'\0'}; if(!mxIsChar(item) || len==0) mexErrMsgTxt("the 'outputtype' field must be a non-empty string"); if(len>MAX_SESSION_LENGTH) mexErrMsgTxt("the 'outputtype' field is too long"); int status = mxGetString(item, outputstr, MAX_SESSION_LENGTH); if (status != 0) mexWarnMsgTxt("not enough space. string is truncated."); cfg->outputtype=mcx_keylookup(outputstr,outputtype); if(cfg->outputtype==-1) mexErrMsgTxt("the specified output type is not supported"); printf("mcx.outputtype='%s';\n",outputstr); }else if(strcmp(name,"debuglevel")==0){ int len=mxGetNumberOfElements(item); const char debugflag[]={'R','M','P','\0'}; char debuglevel[MAX_SESSION_LENGTH]={'\0'}; if(!mxIsChar(item) || len==0) mexErrMsgTxt("the 'debuglevel' field must be a non-empty string"); if(len>MAX_SESSION_LENGTH) mexErrMsgTxt("the 'debuglevel' field is too long"); int status = mxGetString(item, debuglevel, MAX_SESSION_LENGTH); if (status != 0) mexWarnMsgTxt("not enough space. string is truncated."); cfg->debuglevel=mcx_parsedebugopt(debuglevel,debugflag); if(cfg->debuglevel==0) mexWarnMsgTxt("the specified debuglevel is not supported"); printf("mcx.debuglevel='%d';\n",cfg->debuglevel); }else if(strcmp(name,"srcpattern")==0){ arraydim=mxGetDimensions(item); double *val=mxGetPr(item); if(cfg->srcpattern) free(cfg->srcpattern); cfg->srcpattern=(float*)malloc(arraydim[0]*arraydim[1]*sizeof(float)); for(i=0;i<arraydim[0]*arraydim[1];i++) cfg->srcpattern[i]=val[i]; printf("mcx.srcpattern=[%d %d];\n",arraydim[0],arraydim[1]); }else if(strcmp(name,"shapes")==0){ int len=mxGetNumberOfElements(item); if(!mxIsChar(item) || len==0) mexErrMsgTxt("the 'shapes' field must be a non-empty string"); jsonshapes=new char[len+1]; mxGetString(item, jsonshapes, len+1); jsonshapes[len]='\0'; }else if(strcmp(name,"detphotons")==0){ arraydim=mxGetDimensions(item); dimdetps[0]=arraydim[0]; dimdetps[1]=arraydim[1]; detps=(float *)malloc(arraydim[0]*arraydim[1]*sizeof(float)); memcpy(detps,mxGetData(item),arraydim[0]*arraydim[1]*sizeof(float)); printf("mcx.detphotons=[%d %d];\n",arraydim[0],arraydim[1]); }else if(strcmp(name,"seed")==0){ arraydim=mxGetDimensions(item); if(MAX(arraydim[0],arraydim[1])==0) mexErrMsgTxt("the 'seed' field can not be empty"); if(!mxIsUint8(item)){ double *val=mxGetPr(item); cfg->seed=val[0]; printf("mcx.seed=%d;\n",cfg->seed); }else{ seedbyte=arraydim[0]; cfg->replay.seed=malloc(arraydim[0]*arraydim[1]); if(arraydim[0]!=sizeof(float)*RAND_BUF_LEN) mexErrMsgTxt("the row number of cfg.seed does not match RNG seed byte-length"); memcpy(cfg->replay.seed,mxGetData(item),arraydim[0]*arraydim[1]); cfg->seed=SEED_FROM_FILE; cfg->nphoton=arraydim[1]; printf("mcx.nphoton=%d;\n",cfg->nphoton); } }else if(strcmp(name,"gpuid")==0){ int len=mxGetNumberOfElements(item); if(mxIsChar(item)){ if(len==0) mexErrMsgTxt("the 'gpuid' field must be an integer or non-empty string"); if(len>MAX_DEVICE) mexErrMsgTxt("the 'gpuid' field is too long"); int status = mxGetString(item, cfg->deviceid, MAX_DEVICE); if (status != 0) mexWarnMsgTxt("not enough space. string is truncated."); printf("mcx.gpuid='%s';\n",cfg->deviceid); }else{ double *val=mxGetPr(item); cfg->gpuid=val[0]; memset(cfg->deviceid,0,MAX_DEVICE); if(cfg->gpuid<MAX_DEVICE){ memset(cfg->deviceid,'0',cfg->gpuid-1); cfg->deviceid[cfg->gpuid-1]='1'; }else mexErrMsgTxt("GPU id can not be more than 256"); printf("mcx.gpuid=%d;\n",cfg->gpuid); } for(int i=0;i<MAX_DEVICE;i++) if(cfg->deviceid[i]=='0') cfg->deviceid[i]='\0'; }else if(strcmp(name,"workload")==0){ double *val=mxGetPr(item); arraydim=mxGetDimensions(item); if(arraydim[0]*arraydim[1]>MAX_DEVICE) mexErrMsgTxt("the workload list can not be longer than 256"); for(i=0;i<arraydim[0]*arraydim[1];i++) cfg->workload[i]=val[i]; printf("mcx.workload=<<%d>>;\n",arraydim[0]*arraydim[1]); }else{ printf("WARNING: redundant field '%s'\n",name); } if(jsonshapes){ Grid3D grid={&(cfg->vol),&(cfg->dim),{1.f,1.f,1.f},0}; if(cfg->issrcfrom0) memset(&(grid.orig.x),0,sizeof(float3)); int status=mcx_parse_shapestring(&grid,jsonshapes); delete [] jsonshapes; if(status){ mexErrMsgTxt(mcx_last_shapeerror()); } } }
void mexFunction( int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) { if (nrhs!=5) mexErrMsgTxt("Five inputs required"); //get the lsh objcect Lsh* lsh = *(Lsh**)mxGetData(lshIn); //get the class of points mxClassID classID = getClassID(lshPointsIn); //get number of points in search data mwSize npoints = getNpoints(pointsIn); //number of nearest neighbors to return uint k = (uint) *mxGetPr(kIn); //empty distance, then use the one inside the lsh DistanceType dist; if (mxIsEmpty(distIn)) dist = lsh->opt.dist; else dist = getDistanceType(distIn); // mexPrintf("sizes are: %dx%d %dx%d\n", rows1, cols1, rows2, cols2); mxArray *dists, *ids; uint n1; #define __CASE(CLASS) \ { \ /*datas*/ \ Data<TYPEOF_##CLASS> lshPoints, points; \ fillData(lshPoints, lshPointsIn); \ fillData(points, pointsIn); \ /*allocate output*/ \ n1 = points.size(); \ dists = mxCreateNumericMatrix(k, n1, mxSINGLE_CLASS, mxREAL); \ ids = mxCreateNumericMatrix(k, n1, mxUINT32_CLASS, mxREAL); \ /*compute*/ \ getKnn(*lsh, lshPoints, points, k, dist, (uint*) mxGetData(ids), \ (float*) mxGetData(dists)); \ /*clear memory*/ \ lshPoints.clear(); \ points.clear(); \ } __SWITCH(classID, __CASE) //add one to the ids to make it Matlab compatible uint* idp = (uint*) mxGetData(ids); float* distp = (float*) mxGetData(dists); for (mwSize i=0; i<k*n1; ++i) { if (distp[i] < numeric_limits<float>::infinity()) idp[i] += 1; } idsOut = ids; if (nlhs>1) distsOut = dists; }
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) { if(!(nlhs==1 || nlhs==2) || nrhs!=2){ mexErrMsgTxt("Usage: output = forest_eval(input, model)\n"); } const mxArray* inputArr = prhs[0]; const mxArray* modelArr = prhs[1]; #ifdef USE_DOUBLE if(mxGetClassID(inputArr)!=mxDOUBLE_CLASS){ mexErrMsgTxt("Invalid input type, expecting double array.\n"); } double* input = (double*)mxGetData(inputArr); #else if(mxGetClassID(inputArr)!=mxINT8_CLASS){ mexErrMsgTxt("Invalid input type, expecting int8 array.\n"); } char* input = (char*)mxGetData(inputArr); #endif const mwSize* inputDims = mxGetDimensions(inputArr); int height = inputDims[0]; int width = mxGetNumberOfDimensions(inputArr) > 1 ? inputDims[1] : 1; int nTypes = mxGetNumberOfDimensions(inputArr) > 2 ? inputDims[2] : 1; const mxArray* treesArr = safeGetField(modelArr, 0, "trees"); int nTrees = (int)mxGetNumberOfElements(treesArr); if(nTrees <= 0){ mexErrMsgTxt("No trees to traverse!\n"); } //printf("Number of trees: %d\n", nTrees); std::vector<Tree> trees; for(int t=0; t<nTrees; ++t) { const mxArray* nodesArr = safeGetField(treesArr, t, "nodes"); double* nodes = mxGetPr(nodesArr); const mwSize* nodesDims = mxGetDimensions(nodesArr); const mxArray* leavesArr = safeGetField(treesArr, t, "leaves"); const mwSize* leavesDims = mxGetDimensions(leavesArr); double* leaves = mxGetPr(leavesArr); //printf("Tree[%d] has %d non-terminal nodes, and %d leaves\n", // t, nodesDims[0], leavesDims[0]); int depth = log2(nodesDims[0]+leavesDims[0]+1); int nNodes = (1 << (depth-1)) - 1; int nLeaves = (1 << (depth-1)); if(nodesDims[0]!=nNodes || leavesDims[0]!=nLeaves){ char errorMsg[256]; sprintf(errorMsg, "Invalid number of nodes. " "The tree should have %d non-terminals, and %d leaves.\n", nNodes, nLeaves); mexErrMsgTxt(errorMsg); } if(nodesDims[1]!=4){ mexErrMsgTxt("Wrong tree format!"); } Tree tree = {nodes, leaves, nodesDims, leavesDims}; trees.push_back(tree); } // normalizatin factor for each tree double invNTree = 1/(double)nTrees; // length of target variables int nClasses = trees[0].leavesDims[1]; mwSize outputDims[] = {height, width, nClasses}; mxArray* outputArr = mxCreateNumericArray(3, outputDims, mxDOUBLE_CLASS, mxREAL); double* output = mxGetPr(outputArr); mwSize indexDims[] = {height, width, nTrees}; mxArray* indexArr = nullptr; double* index = nullptr; if(nlhs>1){ indexArr = mxCreateNumericArray(3, indexDims, mxDOUBLE_CLASS, mxREAL); index = mxGetPr(indexArr); } // search over all the trees for(int t=0; t<nTrees; ++t) { // searh over all the pixels for(int x=0; x<width; ++x){ for(int y=0; y<height; ++y){ // traverse the binary tree int nodeIndex = 0; while(nodeIndex<trees[t].nodesDims[0]) { int offX = (int)valueAt(trees[t].nodes, trees[t].nodesDims, nodeIndex, 0); int offY = (int)valueAt(trees[t].nodes, trees[t].nodesDims, nodeIndex, 1); int type = (int)valueAt(trees[t].nodes, trees[t].nodesDims, nodeIndex, 2); #ifdef USE_DOUBLE double threshold = valueAt(trees[t].nodes, trees[t].nodesDims, nodeIndex, 3); #else char threshold = (char)valueAt(trees[t].nodes, trees[t].nodesDims, nodeIndex, 3); #endif int absY = clamp(y + offY, 0, height-1); int absX = clamp(x + offX, 0, width-1); type = clamp(type, -1, nTypes-1); if( type >= 0 ) { if(valueAt(input, inputDims, absY, absX, type) > threshold) nodeIndex = (nodeIndex<<1) + 2; else nodeIndex = (nodeIndex<<1) + 1; } else { while(nodeIndex<trees[t].nodesDims[0]){ nodeIndex = (nodeIndex<<1) + 1; } } } // find the terminal node int leafIndex = nodeIndex - trees[t].nodesDims[0]; //printf("%d => %d\n", nodeIndex, leafIndex); for(int c=0; c<nClasses; ++c){ valueAt(output, outputDims, y, x, c) += invNTree * valueAt(trees[t].leaves, trees[t].leavesDims, leafIndex, c); } if(nlhs>1){ valueAt(index, indexDims, y, x, t) = leafIndex; } } } } plhs[0] = outputArr; if(nlhs>1){ plhs[1] = indexArr; } }
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) { /* Variables */ int n, s,s1,s2,n1,n2,e, yInd, nNodes, nEdges, maxState, sizeYmap[3], *y, *edgeEnds, *nStates,*yMAP; double pot,maxPot, *nodePot, *edgePot; /* Input */ nodePot = mxGetPr(prhs[0]); edgePot = mxGetPr(prhs[1]); edgeEnds = (int*)mxGetPr(prhs[2]); nStates = (int*)mxGetPr(prhs[3]); if (!mxIsClass(prhs[2],"int32")||!mxIsClass(prhs[3],"int32")) mexErrMsgTxt("edgeEnds and nStates must be int32"); /* Compute Sizes */ nNodes = mxGetDimensions(prhs[0])[0]; maxState = mxGetDimensions(prhs[0])[1]; nEdges = mxGetDimensions(prhs[2])[0]; /* Output */ sizeYmap[0] = nNodes; sizeYmap[1] = 1; plhs[0] = mxCreateNumericArray(2,sizeYmap,mxINT32_CLASS,mxREAL); yMAP = mxGetData(plhs[0]); /* Initialize */ y = mxCalloc(nNodes,sizeof(int)); maxPot = -1; while(1) { pot = 1; /* Node Potentials */ for(n = 0; n < nNodes; n++) { pot *= nodePot[n + nNodes*y[n]]; } /* Edge Potentials */ for(e = 0; e < nEdges; e++) { n1 = edgeEnds[e]-1; n2 = edgeEnds[e+nEdges]-1; pot *= edgePot[y[n1] + maxState*(y[n2] + maxState*e)]; } /* Compare potential of current configuration against best */ if (pot > maxPot) { maxPot = pot; for(n = 0; n < nNodes;n++) { yMAP[n] = y[n]+1; } } /* Go to next y */ for(yInd = 0; yInd < nNodes; yInd++) { y[yInd] += 1; if(y[yInd] < nStates[yInd]) { break; } else { y[yInd] = 0; } } /* Stop when we are done all y combinations */ if(yInd == nNodes) { break; } } /* Free memory */ mxFree(y); }
//========================================================================= void populate_object_flags(unsigned char *js,mxArray *plhs[], struct sdata *slog){ // // For each object, identify which "unique" object it belongs to and // which index it has in that object. // // Populates (into object_info structure) // --------------------------------------- // max_keys_in_object // n_uniqe_objects: scalar // object_ids: array // unique_object_first_md_indices: array // mxArray *object_info = plhs[0]; //mxGetField(plhs[0],0,"object_info"); //TODO: Change this to numeric ... int n_objects = get_field_length2(object_info,"obj__next_sibling_index_object"); if (n_objects == 0){ slog->obj__n_unique_objects = 0; setStructField2(object_info,0,mxINT32_CLASS,0,E_obj__object_ids); return; } //Main data info //------------------------------------- uint8_t *types = get_u8_field_by_number(plhs[0],E_types); int *d1 = get_int_field_by_number(plhs[0],E_d1); //TODO: Change this to numeric ... mwSize n_entries = get_field_length(plhs,"d1"); //Information needed for this processing //--------------------------------------------------------------------- //Object related uint8_t *object_depths = get_u8_field_by_number(object_info,E_obj__object_depths); int *child_count_object = get_int_field_by_number(object_info,E_obj__child_count_object); int *next_sibling_index_object = get_int_field_by_number(object_info,E_obj__next_sibling_index_object); int *n_objects_at_depth = slog->obj__n_objects_at_depth; mwSize n_depths = MAX_DEPTH_ARRAY_LENGTH; //get_field_length2(object_info,"n_objects_at_depth"); //Some initial - meta setup //--------------------------------------------------------------------- int *process_order = mxMalloc(n_objects*sizeof(int)); populateProcessingOrder(process_order, types, n_entries, TYPE_OBJECT, n_objects_at_depth, n_depths, object_depths); //What is the max # of keys per object? int max_children = 0; for (int iObject = 0; iObject < n_objects; iObject++){ if (child_count_object[iObject] > max_children){ max_children = child_count_object[iObject]; } } slog->obj__max_keys_in_object = max_children; if (max_children == 0){ //So we only have an empty object int *unique_object_first_md_indices = mxMalloc(1*sizeof(int)); unique_object_first_md_indices[0] = process_order[0]; int *object_ids = mxCalloc(n_objects,sizeof(int)); setStructField2(object_info,unique_object_first_md_indices, mxINT32_CLASS,1,E_obj__unique_object_first_md_indices); setStructField2(object_info,object_ids,mxINT32_CLASS,n_objects,E_obj__object_ids); slog->obj__n_unique_objects = 1; return; } //Key related //--------------------------------- mxArray *key_info = plhs[0]; mxArray *temp_key_p = mxGetFieldByNumber(key_info,0,E_key__key_p); unsigned char **key_p = (unsigned char **)mxGetData(temp_key_p); int *key_sizes = get_int_field_by_number(key_info,E_key__key_sizes); int *next_sibling_index_key = get_int_field_by_number(key_info,E_key__next_sibling_index_key); //These are our outputs //--------------------------------------------------------------------- //Which unique object, each object entry belongs to int *object_ids = mxMalloc(n_objects*sizeof(int)); int n_unique_allocated; if (n_objects > N_INITIAL_UNIQUE_OBJECTS){ n_unique_allocated = N_INITIAL_UNIQUE_OBJECTS; }else{ n_unique_allocated = n_objects; } //We need this so that later we can go back and parse the keys //TODO: We could technically parse the keys right away ... int *unique_object_first_md_indices = mxMalloc(n_unique_allocated*sizeof(int)); //--------------------------------------------------------------------- //Variables for the loop int cur_object_id = -1; //-1, allows incrementing into current value //po - process order int cur_po_index = 0; int cur_object_md_index; int cur_object_data_index; int cur_key_data_index; int temp_key_md_index; int n_keys_current_object; int *object_key_sizes = mxMalloc(max_children*sizeof(int)); unsigned char **object_key_pointers = mxMalloc(max_children*sizeof(unsigned char *)); int last_obj_iter = -1; bool done = false; bool diff_object; // Main Loop //--------------------------------------------------------------------- while (!done){ //Creation of a Reference Object //----------------------------------------------------------------- // - other objects will be compared to this object cur_object_md_index = process_order[cur_po_index]; cur_object_data_index = RETRIEVE_DATA_INDEX(cur_object_md_index); n_keys_current_object = child_count_object[cur_object_data_index]; object_ids[cur_object_data_index] = ++cur_object_id; //Logging of unique_object_first_data_indices //Technically we could post-process this bit ... //i.e. after assigning all objects unique ids, run through //and populate unique_object_first_data_indices if (cur_object_id >= n_unique_allocated){ n_unique_allocated = 2*n_unique_allocated; if (n_unique_allocated > n_objects){ n_unique_allocated = n_objects; } unique_object_first_md_indices = mxRealloc(unique_object_first_md_indices, n_unique_allocated*sizeof(int)); } unique_object_first_md_indices[cur_object_id] = cur_object_md_index; //----------------------------------------------------------------- //Store key information for comparison to other objects ... //----------------------------------------------------------------- cur_key_data_index = RETRIEVE_DATA_INDEX((cur_object_md_index + 1)); for (int iKey = 0; iKey < n_keys_current_object; iKey ++){ object_key_sizes[iKey] = key_sizes[cur_key_data_index]; object_key_pointers[iKey] = key_p[cur_key_data_index]; temp_key_md_index = next_sibling_index_key[cur_key_data_index]; cur_key_data_index = RETRIEVE_DATA_INDEX(temp_key_md_index); } //----------------------------------------------------------------- // Loop through the other objects and compare //----------------------------------------------------------------- diff_object = false; while (!diff_object){ ++cur_po_index; if (cur_po_index == n_objects){ done = true; break; } cur_object_md_index = process_order[cur_po_index]; cur_object_data_index = RETRIEVE_DATA_INDEX(cur_object_md_index); if (n_keys_current_object == child_count_object[cur_object_data_index]){ //TODO //It might be better to combine these two loops //Here we check if the keys are the same length //--------------------------------------------------------- cur_key_data_index = RETRIEVE_DATA_INDEX((cur_object_md_index + 1)); for (int iKey = 0; iKey < n_keys_current_object; iKey ++){ if (object_key_sizes[iKey] != key_sizes[cur_key_data_index]){ diff_object = true; break; } temp_key_md_index = next_sibling_index_key[cur_key_data_index]; cur_key_data_index = RETRIEVE_DATA_INDEX(temp_key_md_index); } //Here we check if the key values are the same //--------------------------------------------------------- if (!diff_object){ cur_key_data_index = RETRIEVE_DATA_INDEX((cur_object_md_index + 1)); for (int iKey = 0; iKey < n_keys_current_object; iKey ++){ if (memcmp(object_key_pointers[iKey], key_p[cur_key_data_index],object_key_sizes[iKey])){ diff_object = true; break; }; temp_key_md_index = next_sibling_index_key[cur_key_data_index]; cur_key_data_index = RETRIEVE_DATA_INDEX(temp_key_md_index); } } if (!diff_object){ object_ids[cur_object_data_index] = cur_object_id; } }else{ diff_object = true; } } } mxFree(object_key_pointers); mxFree(object_key_sizes); mxFree(process_order); //TODO: We could truncate these ... //TODO: Change to #2 method with enumeration ... setStructField2(object_info,unique_object_first_md_indices, mxINT32_CLASS,cur_object_id+1,E_obj__unique_object_first_md_indices); setStructField2(object_info,object_ids, mxINT32_CLASS,n_objects,E_obj__object_ids); slog->obj__n_unique_objects = cur_object_id+1; }
//========================================================================= //========================================================================= void initialize_unique_objects(unsigned char *js,mxArray *plhs[], struct sdata *slog){ // // This code will initialize unique objects (structures) with keys, // based on already having identified unique objects earlier. // // This function populates // ----------------------- // objects : cell array of empty structs with fields int n_unique_objects = slog->obj__n_unique_objects; if (n_unique_objects == 0){ return; } int *d1 = get_int_field_by_number(plhs[0],E_d1); mxArray *object_info = plhs[0]; int *child_count_object = get_int_field_by_number(object_info,E_obj__child_count_object); int *unique_object_first_md_indices = get_int_field_by_number(object_info,E_obj__unique_object_first_md_indices); int max_keys_in_object = slog->obj__max_keys_in_object; if (max_keys_in_object == 0){ //We have at least one objects, but none of the objects have keys //Create a single unique object with no fields ... mxArray *all_objects = mxCreateCellMatrix(1,1); mxArray *s = mxCreateStructMatrix(1,0,0,0); mxSetCell(all_objects, 0, s); mxSetFieldByNumber(object_info,0,E_obj__objects,all_objects); return; } //TODO: Define this here ... int *object_ids = get_int_field_by_number(object_info,E_obj__object_ids); mxArray *key_info = plhs[0]; mxArray *temp_key_p = mxGetFieldByNumber(key_info,0,E_key__key_p); unsigned char **key_p = (unsigned char **)mxGetData(temp_key_p); int *key_sizes = get_int_field_by_number(key_info,E_key__key_sizes); int *next_sibling_index_key = get_int_field_by_number(key_info,E_key__next_sibling_index_key); //Note, Matlab does a deep copy of this field, so we are only //allocating a temporary array, note the final values. const char **fieldnames = mxMalloc(max_keys_in_object*sizeof(char *)); //This is the output, stored in our output structure as "objects" mxArray *all_objects = mxCreateCellMatrix(1, n_unique_objects); mxArray *s; unsigned char *cur_key_p; int cur_key_md_index; int cur_key_data_index; int cur_key_size; int temp_key_index; int cur_object_md_index; int cur_object_data_index; int n_keys_in_object; // For each unique object, get an example object and grab the fields // of that object. for (int iObj = 0; iObj < n_unique_objects; iObj++){ cur_object_md_index = unique_object_first_md_indices[iObj]; cur_object_data_index = d1[cur_object_md_index]; n_keys_in_object = child_count_object[cur_object_data_index]; cur_key_md_index = cur_object_md_index + 1; cur_key_data_index = d1[cur_key_md_index]; for (int iKey = 0; iKey < n_keys_in_object; iKey++){ cur_key_p = key_p[cur_key_data_index]; cur_key_size = key_sizes[cur_key_data_index]; //JAH Notes 2018-09 //1) This is modifying the original the JSON string // which should be documented ... // - we could fix this by writing the " back in // - "my_string" => "my_string\0 => "my_string" // - Matlab is deep copying the strings in // mxCreateStructMatrix //2) We are not parsing for UTF-8, Matlab only supports // ASCII for fields, this should be documented //At a minimum, we'll zero out the key to specify length //for Matlab. Matlab takes in an array of pointers to //null-terminated strings rather than allowing us to specify //the size. So here we add null termination into the string. //Note that we are always zeroing a terminating quote symbol. *(cur_key_p + cur_key_size) = 0; fieldnames[iKey] = cur_key_p; //TODO: It is not obvious how the next sibling behaves at the //end - comment on this here ... cur_key_md_index = next_sibling_index_key[cur_key_data_index]; cur_key_data_index = d1[cur_key_md_index]; } //We'll initialize as empty here, because we don't get much of //an advantage of preinitializing if we are going to chop this up later //Initialing to zero still logs the field names //Any advantage of 1,0 vs 0,0?, vs even 1,1? //1,1 might be good if we only have 1 example, then we could //just use it later ... - this would require counting how many //objects take on this value ... s = mxCreateStructMatrix(1,0,n_keys_in_object,fieldnames); mxSetCell(all_objects, iObj, s); } mxFree(fieldnames); mxSetFieldByNumber(object_info,0,E_obj__objects,all_objects); }
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) { ALLOCATES(); real *G, *X, *out, x, distance; int i,I,n,N,closest; int issorted = 0, InfOutside = 0; char STR[100]; G = myGetPr( prhs[0] ); I = myNumel( prhs[0] ); if( I == 0 ){ plhs[0] = mxCreateDoubleMatrix( 0, 0, mxREAL ); goto EXIT; } X = myGetPr( prhs[1] ); N = myNumel( prhs[1] ); if( nrhs > 2 ){ if( !mxIsChar(prhs[2]) ){ myErrMsgTxt("String expected\n"); } mxGetString( prhs[2], STR, 100 ); if( ! myStrcmpi( STR , "sorted" ) ){ issorted = 1; } if( ! myStrcmpi( STR , "inside" ) ){ InfOutside = 1; } } if( nrhs > 3 ){ if( !mxIsChar(prhs[3]) ){ myErrMsgTxt("String expected\n"); } mxGetString( prhs[3], STR, 100 ); if( ! myStrcmpi( STR , "sorted" ) ){ issorted = 1; } if( ! myStrcmpi( STR , "inside" ) ){ InfOutside = 1; } } plhs[0] = mxCreateNumericArray( mxGetNumberOfDimensions(prhs[1]) , mxGetDimensions(prhs[1]) , mxREAL_CLASS , mxREAL ); out = (real *) mxGetData( plhs[0] ); if( !issorted ){ issorted = checkIsSorted(G,I); } if( issorted ) { i = -1; for( n = 0 ; n<N ; n++ ){ x = X[n]; if( InfOutside ){ if( x < G[ 0 ] ){ out[n] = INFn; continue; } if( x > G[I-1] ){ out[n] = INFp; continue; } } /***************************************************************************** I = numel(G) ... -2 ) [. 0 ) [. 1 ) [. 2 ) ... [. I-3 ) [. I-2 ] ( -101 ... * * * * * * G0 G1 G2 GI-3 GI-2 GI-1 *****************************************************************************/ i = GetInterval( x , G , I , i ); if( i == -2 ){ i = 0; } else if( i == -101 ){ i = I-1; } else if( fabs( x - G[ i ] ) > fabs( x - G[i+1] ) ){ i++; } out[n] = i+1; } } else { if( InfOutside ){ myErrMsgTxt("No se puede usar la opcion 'inside' si la grilla no esta sorted\n"); } for( n = 0 ; n<N ; n++ ){ x = X[n]; closest = 0; distance = fabs( x - G[0] ); for( i = I-1 ; i ; i-- ){ // for( i = 0 ; i < I ; i++ ){ if( fabs( x - G[i] ) < distance ){ closest = i; distance = fabs( x - G[i] ); } if( distance == 0 ){ break; } } out[n] = closest+1; } } EXIT: myFreeALLOCATES(); }
/*********************************************************************** * * HANDLE_NC_INQ_VAR_CHUNKING: * * code for handling the nc_inq_var_chunking routine. * * [storage,chunksize,status] = mexnc('inq_var_chunking',ncid,varid); * **********************************************************************/ void handle_nc_inq_var_chunking ( int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[], op *nc_op ) { int ncid; int varid; int storage; size_t chunksize[NC_MAX_DIMS]; /* * Pointer shortcut to matrix data. * */ double *pr; /* * Size of chunking matrix. * */ mwSize mxsize[2]; /* * Return status from netcdf operation. * */ int status; /* * Loop index * */ int j; /* * Number of dimensions (inferred from length of chunk argument) * */ int ndims; /* * Make sure that the inputs are the right type. * */ check_numeric_argument_type ( prhs, nc_op->opname, 1 ); check_numeric_argument_type ( prhs, nc_op->opname, 2 ); pr = mxGetData ( prhs[1] ); ncid = (int)(pr[0]); pr = mxGetData ( prhs[2] ); varid = (int)(pr[0]); status = nc_inq_varndims(ncid,varid,&ndims); if ( status != NC_NOERR ) { sprintf ( error_message, "Internal call to nc_inq_varndims failed, operation \"%s\", line %d file \"%s\"\n", nc_op->opname, __LINE__, __FILE__ ); mexErrMsgTxt ( error_message ); return; } status = nc_inq_var_chunking ( ncid, varid, &storage, chunksize ); plhs[2] = mexncCreateDoubleScalar ( status ); if ( storage == NC_CONTIGUOUS ) { plhs[0] = mxCreateString ( "contiguous" ); /* * Return [] for the chunksize * */ mxsize[0] = 0; mxsize[1] = 0; plhs[1] = mxCreateNumericArray ( 2, mxsize, mxDOUBLE_CLASS, mxREAL ); return; } plhs[0] = mxCreateString ( "chunked" ); mxsize[0] = 1; mxsize[1] = ndims; plhs[1] = mxCreateNumericArray ( 2, mxsize, mxDOUBLE_CLASS, mxREAL ); pr = mxGetData ( plhs[1] ); for ( j = 0; j < ndims; ++j ) { pr[j] = chunksize[j]; } return; }
/* The gateway routine */ void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) { /* ----------------- Variables ----------------- */ /* input variables */ /* mandatory input */ int startIdx; int endIdx; double * inReal; /* optional input */ int optInTimePeriod; int optInFastKPeriod; int optInFastDPeriod; double optInFastDMA; /* output variables */ int outBegIdx; int outNbElement; double* outFastK; double* outFastD; /* input dimentions */ int inSeriesRows; int inSeriesCols; /* error handling */ TA_RetCode retCode; /* ----------------- input/output count ----------------- */ /* Check for proper number of arguments. */ if (nrhs < 1 || nrhs > 5) mexErrMsgTxt("#5 inputs possible #4 optional."); if (nlhs != 2) mexErrMsgTxt("#2 output required."); /* ----------------- INPUT ----------------- */ /* Create a pointer to the input matrix inReal. */ inReal = mxGetPr(prhs[0]); /* Get the dimensions of the matrix input inReal. */ inSeriesCols = mxGetN(prhs[0]); if (inSeriesCols != 1) mexErrMsgTxt("inReal only vector alowed."); inSeriesRows = mxGetM(prhs[0]); endIdx = inSeriesRows - 1; startIdx = 0; /* Process optional arguments */ if (nrhs >= 1+1) { if (!mxIsDouble(prhs[1]) || mxIsComplex(prhs[1]) || mxGetN(prhs[1])*mxGetM(prhs[1]) != 1) mexErrMsgTxt("Input optInTimePeriod must be a scalar."); /* Get the scalar input optInTimePeriod. */ optInTimePeriod = (int) mxGetScalar(prhs[1]); } else { optInTimePeriod = 14; } if (nrhs >= 2+1) { if (!mxIsDouble(prhs[2]) || mxIsComplex(prhs[2]) || mxGetN(prhs[2])*mxGetM(prhs[2]) != 1) mexErrMsgTxt("Input optInFastKPeriod must be a scalar."); /* Get the scalar input optInTimePeriod. */ optInFastKPeriod = (int) mxGetScalar(prhs[2]); } else { optInFastKPeriod = 5; } if (nrhs >= 3+1) { if (!mxIsDouble(prhs[3]) || mxIsComplex(prhs[3]) || mxGetN(prhs[3])*mxGetM(prhs[3]) != 1) mexErrMsgTxt("Input optInFastDPeriod must be a scalar."); /* Get the scalar input optInTimePeriod. */ optInFastDPeriod = (int) mxGetScalar(prhs[3]); } else { optInFastDPeriod = 3; } if (nrhs >= 4+1) { if (!mxIsDouble(prhs[4]) || mxIsComplex(prhs[4]) || mxGetN(prhs[4])*mxGetM(prhs[4]) != 1) mexErrMsgTxt("Input optInFastDMA must be a scalar."); /* Get the scalar input optInTimePeriod. */ optInFastDMA = mxGetScalar(prhs[4]); } else { optInFastDMA = 0; } /* ----------------- OUTPUT ----------------- */ outFastK = mxCalloc(inSeriesRows, sizeof(double)); outFastD = mxCalloc(inSeriesRows, sizeof(double)); /* -------------- Invocation ---------------- */ retCode = TA_STOCHRSI( startIdx, endIdx, inReal, optInTimePeriod, optInFastKPeriod, optInFastDPeriod, optInFastDMA, &outBegIdx, &outNbElement, outFastK, outFastD); /* -------------- Errors ---------------- */ if (retCode) { mxFree(outFastK); mxFree(outFastD); mexPrintf("%s%i","Return code=",retCode); mexErrMsgTxt(" Error!"); } // Populate Output plhs[0] = mxCreateDoubleMatrix(outBegIdx+outNbElement,1, mxREAL); memcpy(((double *) mxGetData(plhs[0]))+outBegIdx, outFastK, outNbElement*mxGetElementSize(plhs[0])); mxFree(outFastK); plhs[1] = mxCreateDoubleMatrix(outBegIdx+outNbElement,1, mxREAL); memcpy(((double *) mxGetData(plhs[1]))+outBegIdx, outFastD, outNbElement*mxGetElementSize(plhs[1])); mxFree(outFastD); } /* END mexFunction */
/*********************************************************************** * * HANDLE_NC_DEF_VAR_CHUNKING: * * code for handling the nc_def_var_chunking routine. * * status = mexnc('def_var_chunking',ncid,varid,storage,chunksize); * **********************************************************************/ void handle_nc_def_var_chunking ( int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[], op *nc_op ) { int ncid; int varid; int storage; size_t chunksize[NC_MAX_DIMS]; /* * Pointer shortcut to matrix data. * */ double *pr; /* * Return status from netcdf operation. * */ int status; /* * Loop index * */ int j; /* * Number of dimensions (inferred from length of chunk argument) * */ int ndims; /* * number of elements in chunking parameter. * */ mwSize nelts; /* * Make sure that the inputs are the right type. * */ check_numeric_argument_type ( prhs, nc_op->opname, 1 ); check_numeric_argument_type ( prhs, nc_op->opname, 2 ); if ( !((mxIsChar(prhs[3]) == false) || (mxIsDouble(prhs[3]) == false )) ) { sprintf ( error_message, "datatype argument must be matlab native double precision (<== that one, please) or character, operation \"%s\", line %d file \"%s\"\n", nc_op->opname, __LINE__, __FILE__ ); mexErrMsgTxt ( error_message ); return; } check_numeric_argument_type ( prhs, nc_op->opname, 4 ); pr = mxGetData ( prhs[1] ); ncid = (int)(pr[0]); pr = mxGetData ( prhs[2] ); varid = (int)(pr[0]); if ( mxIsChar ( prhs[3] ) ) { /* * This one is for backwards compatibility. I really * wish people would not do this... * */ storage = interpret_char_parameter ( prhs[3] ); } else { pr = mxGetData ( prhs[3] ); storage = (int) (pr[0]); } status = nc_inq_varndims(ncid,varid,&ndims); if ( status != NC_NOERR ) { sprintf ( error_message, "Internal call to nc_inq_varndims failed, operation \"%s\", line %d file \"%s\"\n", nc_op->opname, __LINE__, __FILE__ ); mexErrMsgTxt ( error_message ); return; } nelts = mxGetNumberOfElements(prhs[4]); /* * Make sure the user didn't do something really stupid like give too many dimensions. * */ if ( nelts > NC_MAX_VAR_DIMS ) { sprintf ( error_message, "given number of chunk elements (%d) exceeds preset maximum of %d, operation \"%s\", line %d file \"%s\"\n", nelts, NC_MAX_VAR_DIMS, nc_op->opname, __LINE__, __FILE__ ); mexErrMsgTxt ( error_message ); return; } /* * Tell the user not to provide a chunksize argument for contiguous storage. * */ if ( ( storage == NC_CONTIGUOUS ) && (nelts > 0) ) { sprintf ( error_message, "If the storage type is NC_CONTIGUOUS, then the chunksize parameter must be [], line %d file \"%s\"", __LINE__, __FILE__ ); mexErrMsgTxt ( error_message ); return; } pr = mxGetData ( prhs[4] ); for ( j = 0; j < nelts; ++j ) { chunksize[j] = pr[j]; } status = nc_def_var_chunking ( ncid, varid, storage, chunksize ); plhs[0] = mexncCreateDoubleScalar ( status ); return; }
/** * parse bucket_size */ inline int getopt_bucket_size(const mxArray* mxBucketSize) { return *((const int*)mxGetData(mxBucketSize)); }
/* Matlab Gateway routine */ void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) { char *pszSRS_WKT = NULL; GDALDatasetH hSrcDS, hDstDS; GDALDriverH hDriver; GDALRasterBandH hBand; OGRSpatialReference oSrcSRS, oDstSRS; GDALResampleAlg interpMethod = GRA_NearestNeighbour; GDALTransformerFunc pfnTransformer = NULL; CPLErr eErr; GDAL_GCP *pasGCPs = NULL; void *hTransformArg; static int runed_once = FALSE; /* It will be set to true if reaches end of main */ int nx, ny, i, j, m, n, c = 0, n_pts, n_fields; char *pszSrcSRS = NULL, *pszSrcWKT = NULL; char *pszDstSRS = NULL, *pszDstWKT = NULL; double *in_data, *ptr_d, *x, *y, *z; mxArray *mx_ptr; int nGCPCount = 0, nOrder = 0; char **papszMetadataOptions = NULL; char *tmp, *txt; int bInverse = FALSE; int *bSuccess; char **papszTO = NULL; if (nrhs == 2 && mxIsStruct(prhs[1])) { /* -------------------------------------------------- */ /* -------- See for projection stuff ---------------- */ mx_ptr = mxGetField(prhs[1], 0, "SrcProjSRS"); if (mx_ptr != NULL) pszSrcSRS = (char *)mxArrayToString(mx_ptr); mx_ptr = mxGetField(prhs[1], 0, "SrcProjWKT"); if (mx_ptr != NULL) pszSrcWKT = (char *)mxArrayToString(mx_ptr); mx_ptr = mxGetField(prhs[1], 0, "DstProjSRS"); if (mx_ptr != NULL) pszDstSRS = (char *)mxArrayToString(mx_ptr); mx_ptr = mxGetField(prhs[1], 0, "DstProjWKT"); if (mx_ptr != NULL) pszDstWKT = (char *)mxArrayToString(mx_ptr); /* -------------------------------------------------- */ /* -------- Do we have GCPs? ----------------------- */ mx_ptr = mxGetField(prhs[1], 0, "gcp"); if (mx_ptr != NULL) { nGCPCount = mxGetM(mx_ptr); if (mxGetN(mx_ptr) != 4) mexErrMsgTxt("GDALWARP: GCPs must be a Mx4 array"); ptr_d = mxGetPr(mx_ptr); pasGCPs = (GDAL_GCP *) mxCalloc( nGCPCount, sizeof(GDAL_GCP) ); GDALInitGCPs( 1, pasGCPs + nGCPCount - 1 ); for (i = 0; i < nGCPCount; i++) { pasGCPs[i].dfGCPPixel = ptr_d[i]; pasGCPs[i].dfGCPLine = ptr_d[i+nGCPCount]; pasGCPs[i].dfGCPX = ptr_d[i+2*nGCPCount]; pasGCPs[i].dfGCPY = ptr_d[i+3*nGCPCount]; pasGCPs[i].dfGCPZ = 0; } } /* ---- Have we an order request? --- */ mx_ptr = mxGetField(prhs[1], 0, "order"); if (mx_ptr != NULL) { ptr_d = mxGetPr(mx_ptr); nOrder = (int)*ptr_d; if (nOrder != -1 || nOrder != 0 || nOrder != 1 || nOrder != 2 || nOrder != 3) nOrder = 0; } /* -------------------------------------------------- */ mx_ptr = mxGetField(prhs[1], 0, "inverse"); if (mx_ptr != NULL) bInverse = TRUE; mx_ptr = mxGetField(prhs[1], 0, "ResampleAlg"); if (mx_ptr != NULL) { txt = (char *)mxArrayToString(mx_ptr); if (!strcmp(txt,"nearest")) interpMethod = GRA_NearestNeighbour; else if (!strcmp(txt,"bilinear")) interpMethod = GRA_Bilinear; else if (!strcmp(txt,"cubic") || !strcmp(txt,"bicubic")) interpMethod = GRA_Cubic; else if (!strcmp(txt,"spline")) interpMethod = GRA_CubicSpline; } } else { mexPrintf("Usage: out = gdaltransform_mex(IN,PAR_STRUCT)\n\n"); mexPrintf(" IN is a Mx2 or Mx3 array of doubles with X, Y (,Z)\n"); mexPrintf(" PAR_STRUCT is a structure with at most two of the next fields:\n"); mexPrintf("\t\t'SrcProjSRS', 'SrcProjWKT' -> Source projection string\n"); mexPrintf("\t\t'DstProjSRS', 'DstProjWKT' -> Target projection string\n"); mexPrintf("\t\t\tSRS stands for a string of the type used by proj4\n"); mexPrintf("\t\t\tWKT stands for a string on the 'Well Known Text' format\n\n"); mexPrintf("\t\t\tIf one of the Src or Dst fields is absent a GEOGRAPHIC WGS84 is assumed\n"); mexPrintf("\nOPTIONS\n"); mexPrintf("\t\t'gcp' a [Mx4] array with Ground Control Points\n"); mexPrintf("\t\t'inverse' reverse transformation. e.g from georef to rows-columns\n"); if (!runed_once) /* Do next call only at first time this MEX is loaded */ GDALAllRegister(); mexPrintf( "The following format drivers are configured and support Create() method:\n" ); for( i = 0; i < GDALGetDriverCount(); i++ ) { hDriver = GDALGetDriver(i); if( GDALGetMetadataItem( hDriver, GDAL_DCAP_CREATE, NULL ) != NULL) mexPrintf("%s: %s\n", GDALGetDriverShortName(hDriver), GDALGetDriverLongName(hDriver)); } return; } if (!runed_once) /* Do next call only at first time this MEX is loaded */ GDALAllRegister(); /* ----- Check that first argument contains at least a mx2 table */ n_pts = mxGetM (prhs[0]); n_fields = mxGetN(prhs[0]); if (!mxIsNumeric(prhs[0]) || (n_fields < 2)) { mexPrintf("GDALTRANSFORM ERROR: first argument must contain a mx2 (or mx3) table\n"); mexErrMsgTxt(" with the x,y (,z) positions to convert.\n"); } DEBUGA(1); /* ---------- Set the Source projection ---------------------------- */ /* If it was not provided assume it is Geog WGS84 */ if (pszSrcSRS == NULL && pszSrcWKT == NULL) oSrcSRS.SetWellKnownGeogCS( "WGS84" ); else if (pszSrcWKT != NULL) oSrcSRS.importFromWkt( &pszSrcWKT ); else { if( oSrcSRS.SetFromUserInput( pszSrcSRS ) != OGRERR_NONE ) mexErrMsgTxt("GDALTRANSFORM: Translating source SRS failed."); } if (pszSrcWKT == NULL) oSrcSRS.exportToWkt( &pszSrcWKT ); /* ------------------------------------------------------------------ */ DEBUGA(2); /* ---------- Set up the Target coordinate system ------------------- */ /* If it was not provided assume it is Geog WGS84 */ CPLErrorReset(); if (pszDstSRS == NULL && pszDstWKT == NULL) oDstSRS.SetWellKnownGeogCS( "WGS84" ); else if (pszDstWKT != NULL) oDstSRS.importFromWkt( &pszDstWKT ); else { if( oDstSRS.SetFromUserInput( pszDstSRS ) != OGRERR_NONE ) mexErrMsgTxt("GDALTRANSFORM: Translating target SRS failed."); } if (pszDstWKT == NULL) oDstSRS.exportToWkt( &pszDstWKT ); /* ------------------------------------------------------------------ */ /* -------------------------------------------------------------------- */ /* Create a transformation object from the source to */ /* destination coordinate system. */ /* -------------------------------------------------------------------- */ if( nGCPCount != 0 && nOrder == -1 ) { pfnTransformer = GDALTPSTransform; hTransformArg = GDALCreateTPSTransformer( nGCPCount, pasGCPs, FALSE ); } else if( nGCPCount != 0 ) { DEBUGA(3); pfnTransformer = GDALGCPTransform; hTransformArg = GDALCreateGCPTransformer( nGCPCount, pasGCPs, nOrder, FALSE ); } else { pfnTransformer = GDALGenImgProjTransform; //hTransformArg = GDALCreateGenImgProjTransformer2( hSrcDS, hDstDS, papszTO ); hTransformArg = GDALCreateGenImgProjTransformer( NULL, pszSrcWKT, NULL, pszDstWKT, nGCPCount == 0 ? FALSE : TRUE, 0, nOrder ); } //CSLDestroy( papszTO ); DEBUGA(4); if( hTransformArg == NULL ) mexErrMsgTxt("GDALTRANSFORM: Generating transformer failed."); in_data = (double *)mxGetData(prhs[0]); if (n_pts == 1) { x = &in_data[0]; y = &in_data[1]; bSuccess = &c; } else { x = (double *)mxCalloc(n_pts, sizeof(double)); y = (double *)mxCalloc(n_pts, sizeof(double)); bSuccess = (int *)mxCalloc(n_pts, sizeof(int)); for (j = 0; j < n_pts; j++) { x[j] = in_data[j]; y[j] = in_data[j+n_pts]; } } DEBUGA(5); z = (double *)mxCalloc(n_pts, sizeof(double)); if (n_fields == 3) for (j = 0; j < n_pts; j++) z[j] = in_data[j+2*n_pts]; if ( !pfnTransformer( hTransformArg, bInverse, n_pts, x, y, z, bSuccess ) ) mexPrintf( "Transformation failed.\n" ); DEBUGA(6); if( nGCPCount != 0 && nOrder == -1 ) GDALDestroyTPSTransformer(hTransformArg); else if( nGCPCount != 0 ) GDALDestroyGCPTransformer(hTransformArg); else GDALDestroyGenImgProjTransformer(hTransformArg); /* -------------- Copy the result into plhs --------------------------------- */ plhs[0] = mxCreateDoubleMatrix (n_pts,n_fields, mxREAL); ptr_d = mxGetPr(plhs[0]); for (j = 0; j < n_pts; j++) { ptr_d[j] = x[j]; ptr_d[j+n_pts] = y[j]; } if (n_pts > 1) { mxFree((void *)x); mxFree((void *)y); mxFree((void *)bSuccess); } if (n_fields == 3) { for (j = 0; j < n_pts; j++) ptr_d[j+2*n_pts] = z[j]; } mxFree((void *)z); if (pszDstWKT && strlen(pszDstWKT) > 1 ) OGRFree(pszDstWKT); if (pszSrcWKT && strlen(pszSrcWKT) > 1 ) OGRFree(pszSrcWKT); //OGRFree(pszSrcWKT); //OGRFree(pszDstWKT); if (nGCPCount > 0) { GDALDeinitGCPs( nGCPCount, pasGCPs ); // makes this mex crash in the next call mxFree((void *) pasGCPs ); } runed_once = TRUE; /* Signals that next call won't need to call GDALAllRegister() again */ }
/** * parse shrink rule */ inline ANNshrinkRule getopt_shrink_rule(const mxArray* mxShrinkRule) { return (ANNshrinkRule)(*((const int*)mxGetData(mxShrinkRule))); }
maxpool3d* factory_mp3d_homebrew::parse_and_create(int no, mxArray *vo[], int ni, mxArray const *vi[]) { if (ni < 1) throw mp3d_ex("Too few input arguments."); // fprop or bprop? maxpool3d holder; int opt_beg = -1; xpuMxArrayTW::DEV_TYPE dt; if (no == 2) { // fprop holder.X.setMxArray( (mxArray*) vi[0] ); // we won't change it dt = holder.X.getDevice(); if ( ni < 1 || (holder.X.getElemType() != mxSINGLE_CLASS) ) throw mp3d_ex("For fprop(), there should be at least one input, X, of SINGLE type," "be all gpuArray or be all mxArray.\n"); holder.ct = maxpool3d::FPROP; opt_beg = 1; } else if (no == 1) { // bprop holder.dY.setMxArray( (mxArray*) vi[0]); holder.ind.setMxArray( (mxArray*) vi[1]); dt = holder.dY.getDevice(); if ( ni < 2 || holder.dY.getElemType() != mxSINGLE_CLASS || holder.ind.getElemType() != mxINT32_CLASS) throw mp3d_ex("For bprop(): there should be at least 3 arguments, dzdY, ind.\n" "The dzdY must be SINGLE, the max index ind must be int32," "they should be both gpuArray or be both mxArray.\n"); holder.ct = maxpool3d::BPROP; opt_beg = 2; } else { throw mp3d_ex("Unrecognized arguments/way of calling. " "The output should be either [Y, ind] (fprop) or ind (bprop). "); } // if bprop: create dX if szX is provided args:(dzdY, ind, szX) if (holder.ct == maxpool3d::BPROP) { if (ni >= 3 && !mxIsChar(vi[2]) ) { // szX provided, check it if (!mxIsDouble(vi[2])) mexErrMsgTxt("setCArray: pa must be double matrix\n"); double *ptr = (double*)mxGetData(vi[2]); mwSize nelem = mxGetNumberOfElements(vi[2]); if (nelem > 5 || nelem < 3) throw mp3d_ex("The third argument must be: 3 <= numel(szX) <= 5.\n"); // get szX mwSize szX[5]; szX[3] = szX[4] = 1; for (int i = 0; i < nelem; ++i) szX[i] = (mwSize) ptr[i]; // create the dX holder.dX.setMxArray( createVol5dZeros(szX, holder.dY.dt) ); // reset the option beginning opt_beg = 3; } else // issue the warning mexWarnMsgTxt("For bprop(), the calling method with 2 args:\n" "[...] = mex_maxpool3d(dzdY, ind, ...)\n" "is deprecated, because this could cause ambiguity when inferring input X size.\n" "Use the new one to specify the size for input X (or dzdX) explicitly:\n" "[...] = mex_maxpool3d(dzdY, ind, szX,...)\n"); } // set options set_options(holder, opt_beg, ni, vi); // check validity check_padpool(holder); // create the desired worker and set the parameters #ifdef WITH_GPUARRAY if (dt == xpuMxArrayTW::GPU) return new maxpool3d_gpu(holder); else return new maxpool3d_cpu(holder); #else return new maxpool3d_cpu(holder); #endif // WITH_GPUARRAY }
/** * parse k (the number of neighbors) */ inline int getopt_k(const mxArray* mxK) { return *((const int*)mxGetData(mxK)); }
void mcx_set_field(const mxArray *root,const mxArray *item,int idx, Config *cfg){ const char *name=mxGetFieldNameByNumber(root,idx); const int *arraydim; int i,j; cfg->flog=stderr; GET_1ST_FIELD(cfg,nphoton) GET_ONE_FIELD(cfg,nblocksize) GET_ONE_FIELD(cfg,nthread) GET_ONE_FIELD(cfg,seed) GET_ONE_FIELD(cfg,tstart) GET_ONE_FIELD(cfg,tstep) GET_ONE_FIELD(cfg,tend) GET_ONE_FIELD(cfg,maxdetphoton) GET_ONE_FIELD(cfg,detradius) GET_ONE_FIELD(cfg,sradius) GET_ONE_FIELD(cfg,maxgate) GET_ONE_FIELD(cfg,respin) GET_ONE_FIELD(cfg,gpuid) GET_ONE_FIELD(cfg,isreflect) GET_ONE_FIELD(cfg,isref3) GET_ONE_FIELD(cfg,isrefint) GET_ONE_FIELD(cfg,isnormalized) GET_ONE_FIELD(cfg,issavedet) GET_ONE_FIELD(cfg,issave2pt) GET_ONE_FIELD(cfg,isgpuinfo) GET_ONE_FIELD(cfg,autopilot) GET_ONE_FIELD(cfg,minenergy) GET_ONE_FIELD(cfg,unitinmm) GET_VEC3_FIELD(cfg,srcpos) GET_VEC3_FIELD(cfg,srcdir) GET_VEC3_FIELD(cfg,steps) GET_VEC3_FIELD(cfg,crop0) GET_VEC3_FIELD(cfg,crop1) else if(strcmp(name,"vol")==0){ if(!mxIsUint8(item) || mxGetNumberOfDimensions(item)!=3 ) mexErrMsgTxt("the 'vol' field must be a 3D uint8 array"); arraydim=mxGetDimensions(item); for(i=0;i<3;i++) ((unsigned int *)(&cfg->dim))[i]=arraydim[i]; if(cfg->vol) free(cfg->vol); cfg->vol=(unsigned char *)malloc(cfg->dim.x*cfg->dim.y*cfg->dim.z); memcpy(cfg->vol,mxGetData(item),cfg->dim.x*cfg->dim.y*cfg->dim.z); printf("mcx.dim=[%d %d %d];\n",cfg->dim.x,cfg->dim.y,cfg->dim.z); }else if(strcmp(name,"detpos")==0){ arraydim=mxGetDimensions(item); if(arraydim[0]>0 && arraydim[1]!=4) mexErrMsgTxt("the 'detpos' field must have 4 columns (x,y,z,radius)"); double *val=mxGetPr(item); cfg->detnum=arraydim[0]; if(cfg->detpos) free(cfg->detpos); cfg->detpos=(float4 *)malloc(cfg->detnum*sizeof(float4)); for(j=0;j<4;j++) for(i=0;i<cfg->detnum;i++) ((float *)(&cfg->detpos[i]))[j]=val[j*cfg->detnum+i]; printf("mcx.detnum=%d;\n",cfg->detnum); }else if(strcmp(name,"prop")==0){ arraydim=mxGetDimensions(item); if(arraydim[0]>0 && arraydim[1]!=4) mexErrMsgTxt("the 'prop' field must have 4 columns (mua,mus,g,n)"); double *val=mxGetPr(item); cfg->medianum=arraydim[0]; if(cfg->prop) free(cfg->prop); cfg->prop=(Medium *)malloc(cfg->medianum*sizeof(Medium)); for(j=0;j<4;j++) for(i=0;i<cfg->medianum;i++) ((float *)(&cfg->prop[i]))[j]=val[j*cfg->medianum+i]; printf("mcx.medianum=%d;\n",cfg->medianum); }else if(strcmp(name,"session")==0){ int len=mxGetNumberOfElements(item); if(!mxIsChar(item) || len==0) mexErrMsgTxt("the 'session' field must be a non-empty string"); if(len>MAX_SESSION_LENGTH) mexErrMsgTxt("the 'session' field is too long"); int status = mxGetString(item, cfg->session, MAX_SESSION_LENGTH); if (status != 0) mexWarnMsgTxt("not enough space. string is truncated."); printf("mcx.session='%s';\n",cfg->session); }else{ printf("WARNING: redundant field '%s'\n",name); } }
static void read_sref(FILE *fob, mxArray **data, double dbu_to_uu) { mxArray *pstruct; mxArray *pprop = NULL; mxArray *pa; double *pd; tList xylist; uint16_t rtype, rlen; int nprop = 0; int mtotal = 0; int k, m, nle; element_t sref; const char *fields[] = {"internal", "xy", "prop"}; xy_block vertex; /* initialize element */ init_element(&sref, GDS_SREF); /* output data structure */ pstruct = mxCreateStructMatrix(1,1, 3, fields); /* create a list for the XY data record(s) */ if ( create_list(&xylist) == -1 ) mexErrMsgTxt("gds_read_element (sref) : could not create list for XY records."); /* read element properties */ while (1) { if ( read_record_hdr(fob, &rtype, &rlen) ) mexErrMsgTxt("gds_read_element (sref) : could not read record header."); if (rtype == ENDEL) break; switch (rtype) { case XY: m = rlen / (2*sizeof(int32_t)); vertex.mxy = m; vertex.xy = read_xy2(fob, m, dbu_to_uu); list_insert_object(xylist, &vertex, sizeof(xy_block), AFTER); mtotal += m; break; case SNAME: if ( read_string(fob, sref.sname, rlen) ) mexErrMsgTxt("gds_read_element (sref) : could not read structure name."); break; case STRANS: if ( read_word(fob, &sref.strans.flags) ) mexErrMsgTxt("gds_read_element (sref) : could not read strans data."); sref.has |= HAS_STRANS; break; case MAG: if ( read_real8(fob, &sref.strans.mag) ) mexErrMsgTxt("gds_read_element (sref) : could not read magnification."); sref.has |= HAS_MAG; break; case ANGLE: if ( read_real8(fob, &sref.strans.angle) ) mexErrMsgTxt("gds_read_element (sref) : could not read angle."); sref.has |= HAS_ANGLE; break; case ELFLAGS: sref.elflags = read_elflags(fob); sref.has |= HAS_ELFLAGS; break; case PLEX: sref.plex = read_plex(fob); sref.has |= HAS_PLEX; break; case PROPATTR: pprop = resize_property_structure(pprop, nprop+1); mxSetFieldByNumber(pprop, nprop, 0, read_propattr(fob)); break; case PROPVALUE: mxSetFieldByNumber(pprop, nprop, 1, read_propvalue(fob,rlen)); nprop += 1; break; default: mexPrintf("Unknown record id: 0x%x\n", rtype); mexErrMsgTxt("SREF : found unknown element property."); } } /* catenate XY records */ nle = list_entries(xylist); if ( !nle ) mexErrMsgTxt("gds_read_element (sref) : element has no XY record."); pa = mxCreateDoubleMatrix(mtotal,2, mxREAL); pd = mxGetData(pa); list_head(xylist); for (k=0; k<nle; k++) { get_current_object(xylist, &vertex, sizeof(xy_block)); memcpy(pd, vertex.xy, 2*vertex.mxy*sizeof(double)); pd += 2*vertex.mxy; mxFree(vertex.xy); } mxSetFieldByNumber(pstruct, 0, 1, pa); erase_list_entries(xylist); delete_list(&xylist); /* set prop field */ if ( nprop ) { mxSetFieldByNumber(pstruct, 0, 2, pprop); } else { mxSetFieldByNumber(pstruct, 0, 2, empty_matrix()); } /* store structure with element data */ mxSetFieldByNumber(pstruct, 0, 0, copy_element_to_array(&sref)); /* return data */ *data = pstruct; }
/***********************************************************************//** * \brief mexFunction to append a stack to an existing em-file. **************************************************************************/ void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray*prhs[]) { size_t filename_length = 0; #define __MAX_FILENAME_LENGTH__ ((int)2048) char filename[__MAX_FILENAME_LENGTH__+1]; #define __MAX_S__LENGTH__ (__MAX_FILENAME_LENGTH__+1024) char s[__MAX_S__LENGTH__+1]; tom_io_em_header header; #define __BUFFERLENGTH_SYNOPSIS__ 1024 char synopsis[__BUFFERLENGTH_SYNOPSIS__]; void *data; mxArray *mxData; size_t sizex, sizey, sizez; mxClassID mxType; mxComplexity mxIsComplexVolume; size_t i; int res; int header_read; int allow_conversion = 1; mxArray *plhs_tmp[5] = { NULL, NULL, NULL, NULL, NULL }; snprintf(synopsis, __BUFFERLENGTH_SYNOPSIS__, "[size, magic, comment, emdata, userdata] = %s(filename, volume, [allow_conversion])", mexFunctionName()); if (nrhs==0 && nlhs==0) { /* Print help */ mexPrintf("SYNOPSIS: %s\n", synopsis); mexPrintf("mex-file compiled from file \"" __FILE__ "\" at " __DATE__ ", " __TIME__ ".\n"); return; } if (nrhs < 2 || nrhs > 3) { snprintf(s, __MAX_S__LENGTH__, "%s: call function with up to 3 parameters: %s.", mexFunctionName(), synopsis); mexErrMsgTxt(s); } if (nlhs>5) { snprintf(s, __MAX_S__LENGTH__, "%s: Too many output parameters: %s.", mexFunctionName(), synopsis); mexErrMsgTxt(s); } { const mxArray *PRHS_FILENAME = prhs[0]; const mxArray *PRHS_VOLUME = prhs[1]; const mwSize *size; /* Check input parameters! */ if (!mxIsChar(PRHS_FILENAME) || mxGetNumberOfDimensions(PRHS_FILENAME)!=2 || mxGetM(PRHS_FILENAME)!=1 || (filename_length=mxGetN(PRHS_FILENAME))<1) { snprintf(s, __MAX_S__LENGTH__, "%s: needs the file name as first parameter: %s.", mexFunctionName(), synopsis); mexErrMsgTxt(s); } if (filename_length >= __MAX_FILENAME_LENGTH__) { snprintf(s, __MAX_S__LENGTH__, "%s: Maximal length of file name exceeded. (Recompile with larger buffer :)", mexFunctionName()); mexErrMsgTxt(s); } mxGetString(PRHS_FILENAME, filename, __MAX_FILENAME_LENGTH__); if (!mxIsNumeric(PRHS_VOLUME) || mxGetNumberOfDimensions(PRHS_VOLUME)>3) { snprintf(s, __MAX_S__LENGTH__, "%s: needs a numerical volume as second parameter: %s", mexFunctionName(), synopsis); mexErrMsgTxt(s); } data = mxGetData(PRHS_VOLUME); size = mxGetDimensions(PRHS_VOLUME); mxType = mxGetClassID(PRHS_VOLUME); mxIsComplexVolume = mxIsComplex(PRHS_VOLUME); sizex = size[0]; sizey = size[1]; sizez = mxGetNumberOfDimensions(PRHS_VOLUME)==3 ? size[2] : 1; if (mxIsComplexVolume) { if (mxType==mxSINGLE_CLASS || mxType==mxDOUBLE_CLASS) { mwSize size[3]; size_t x, y, z; size[0] = sizex*2; size[1] = sizey; size[2] = sizez; if (!(mxData = mxCreateNumericArray(sizez==1 ? 2 : 3, size, mxType, mxREAL))) { mexErrMsgTxt("%s: Error allocating temporary buffer for complex data."); } data = mxGetData(mxData); if (mxType == mxSINGLE_CLASS) { float *data_as_real = (float *)data; const float *data_real = (const float *)mxGetData(PRHS_VOLUME); const float *data_complex = (const float *)mxGetImagData(PRHS_VOLUME); for (z=0; z<sizez; z++) { for (y=0; y<sizey; y++) { for (x=0; x<sizex; x++) { *data_as_real++ = *data_real++; *data_as_real++ = *data_complex++; } } } } else { double *data_as_real = (double *)data; const double *data_real = (const double *)mxGetData(PRHS_VOLUME); const double *data_complex = (const double *)mxGetImagData(PRHS_VOLUME); for (z=0; z<sizez; z++) { for (y=0; y<sizey; y++) { for (x=0; x<sizex; x++) { *data_as_real++ = *data_real++; *data_as_real++ = *data_complex++; } } } } } else { snprintf(s, __MAX_S__LENGTH__, "%s: Complex data for this type not supported (currently only for single and double).", mexFunctionName()); mexErrMsgTxt(s); } } if (nrhs >= 3) { mwSize numel; numel = mxGetM(prhs[2]) * mxGetN(prhs[2]); if (!(mxIsNumeric(prhs[2]) || mxIsLogical(prhs[2])) || numel>1) { snprintf(s, __MAX_S__LENGTH__, "%s: allow_conversion must be one of true, false or [].", mexFunctionName(), synopsis); mexErrMsgTxt(s); } if (numel == 1) { allow_conversion = mxGetScalar(prhs[2]) != 0.; } } } { /* Allocate the memory for the ouput, so that in case of successfully writing, no error can happen afterwards in the mexfunction. */ switch (nlhs) { case 5: if (!(plhs_tmp[4] = mxCreateNumericMatrix(1, 256, mxINT8_CLASS, mxREAL))) { mexErrMsgTxt("Error allocating memory"); } case 4: if (!(plhs_tmp[3] = mxCreateNumericMatrix(1, 40, mxINT32_CLASS, mxREAL))) { mexErrMsgTxt("Error allocating memory"); } case 3: if (!(plhs_tmp[2] = mxCreateNumericMatrix(1, 80, mxINT8_CLASS, mxREAL))) { mexErrMsgTxt("Error allocating memory"); } case 2: if (!(plhs_tmp[1] = mxCreateNumericMatrix(1, 4, mxINT8_CLASS, mxREAL))) { mexErrMsgTxt("Error allocating memory"); } case 1: if (!(plhs_tmp[0] = mxCreateNumericMatrix(3, 1, mxUINT32_CLASS, mxREAL))) { mexErrMsgTxt("Error allocating memory"); } } } res = tom_io_em_write_append_stack(filename, data, getIOTypeFromMxClassID(mxType, mxIsComplexVolume), sizex, sizey, sizez, 0, 0, 0, &header, &header_read, allow_conversion); if (res != TOM_ERR_OK) { if (res ==TOM_ERR_WRITE_FILE) { snprintf(s, __MAX_S__LENGTH__, "%s: IO-error occured. The em-file may now be damaged :(", mexFunctionName()); mexErrMsgTxt(s); } else if (res==TOM_ERR_OPEN_FILE) { snprintf(s, __MAX_S__LENGTH__, "%s: Error opening the file \"%s\" for writing.", mexFunctionName(), filename); mexErrMsgTxt(s); } else if (header_read && res==TOM_ERR_WRONG_IOTYPE_CONVERSION) { snprintf(s, __MAX_S__LENGTH__, "%s: Wrong typeconversion: can not convert volume of type %d to type %d as in the em-file.", mexFunctionName(), getIOTypeFromMxClassID(mxType, mxIsComplexVolume), tom_io_em_get_iotype_header(&header)); mexErrMsgTxt(s); } else if (res == TOM_ERR_IOTYPE_NOT_SUPPORTED) { snprintf(s, __MAX_S__LENGTH__, "%s: Saving data of type %d to em-file is (currently) not supported.", mexFunctionName(), getIOTypeFromMxClassID(mxType, mxIsComplexVolume)); mexErrMsgTxt(s); } else if (header_read && TOM_ERR_WRONG_DATA_SIZE && (sizex!=header.dims[0] || sizey!=header.dims[1])) { snprintf(s, __MAX_S__LENGTH__, "%s: Size mismatch: The volume has dimension %dx%dx%d, but the em-file has size %dx%dx%d.", mexFunctionName(), sizex, sizey, sizez, header.dims[0], header.dims[1], header.dims[2]); mexErrMsgTxt(s); } else { snprintf(s, __MAX_S__LENGTH__, "%s: Unexpected error. Is the \"%s\" a valid em-file? (%d)", mexFunctionName(), filename, res); mexErrMsgTxt(s); } } { /* Construct the output. */ void *pdata; switch (nlhs) { case 5: pdata = mxGetData(plhs[4] = plhs_tmp[4]); for (i=0; i<256; i++) { ((int8_t *)pdata)[i] = header.userdata[i]; } case 4: pdata = mxGetData(plhs[3] = plhs_tmp[3]); for (i=0; i<40; i++) { ((int32_t *)pdata)[i] = header.emdata[i]; } case 3: pdata = mxGetData(plhs[2] = plhs_tmp[2]); for (i=0; i<80; i++) { ((int8_t *)pdata)[i] = header.comment[i]; } case 2: pdata = mxGetData(plhs[1] = plhs_tmp[1]); ((int8_t *)pdata)[0] = header.machine; ((int8_t *)pdata)[1] = header.byte2; ((int8_t *)pdata)[2] = header.byte3; ((int8_t *)pdata)[3] = header.type; case 1: pdata = mxGetData(plhs[0] = plhs_tmp[0]); ((uint32_t *)pdata)[0] = header.dims[0]; ((uint32_t *)pdata)[1] = header.dims[1]; ((uint32_t *)pdata)[2] = header.dims[2]; break; case 0: default: break; } } }
void LTFAT_NAME(ltfatMexFnc)( int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[] ) { static int atExitRegistered = 0; if(!atExitRegistered) { LTFAT_NAME(ltfatMexAtExit)(LTFAT_NAME(fftrealAtExit)); atExitRegistered = 1; } mwSignedIndex L, W, L2; LTFAT_REAL *f, *cout_r, *cout_i; LTFAT_FFTW(iodim) dims[1], howmanydims[1]; LTFAT_FFTW(plan) p; L = mxGetM(prhs[0]); W = mxGetN(prhs[0]); L2 = (L/2)+1; // Get pointer to input. f= mxGetData(prhs[0]); plhs[0] = ltfatCreateMatrix(L2, W, LTFAT_MX_CLASSID, mxCOMPLEX); // Get pointer to output. cout_r = mxGetData(plhs[0]); cout_i = mxGetImagData(plhs[0]); // Create plan. Copy data from f to cout. dims[0].n = L; dims[0].is = 1; dims[0].os = 1; howmanydims[0].n = W; howmanydims[0].is = L; howmanydims[0].os = L2; // The calling prototype //fftw_plan fftw_plan_guru_split_dft_r2c( // int rank, const fftw_iodim *dims, // int howmany_rank, const fftw_iodim *howmany_dims, // double *in, double *ro, double *io, // unsigned flags); /* We are violating this here: You must create the plan before initializing the input, because FFTW_MEASURE overwrites the in/out arrays. (Technically, FFTW_ESTIMATE does not touch your arrays, but you should always create plans first just to be sure.) */ p = LTFAT_FFTW(plan_guru_split_dft_r2c)(1, dims, 1, howmanydims, f, cout_r, cout_i, FFTW_ESTIMATE); /* ... creating a new plan is quick once one exists for a given size ... so why not to store the old plan.. */ LTFAT_NAME(fftrealAtExit)(); LTFAT_NAME(p_old) = p; // Real FFT. LTFAT_FFTW(execute)(p); // LTFAT_FFTW(destroy_plan)(p); return; }
void homogToInds(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) { /* [rs,cs,is]=homogToInds(H,m,n,r0,r1,c0,c1,flag); */ int m, n, flag; double *H, r0, r1, c0, c1; int *is, m1, n1, ind=0, i, j, fr, fc; double *rs, *cs, r, c, m2, n2, z; /* extract inputs */ H = (double*) mxGetData(prhs[0]); m = (int) mxGetScalar(prhs[1]); n = (int) mxGetScalar(prhs[2]); r0 = mxGetScalar(prhs[3]); r1 = mxGetScalar(prhs[4]); c0 = mxGetScalar(prhs[5]); c1 = mxGetScalar(prhs[6]); flag = (int) mxGetScalar(prhs[7]); /* initialize memory */ m1 = (int) (r1-r0+1); m2 = (m+1.0)/2.0; n1 = (int) (c1-c0+1); n2 = (n+1.0)/2.0; rs = mxMalloc(sizeof(double)*m1*n1); cs = mxMalloc(sizeof(double)*m1*n1); is = mxMalloc(sizeof(int)*m1*n1); /* Compute rs an cs */ if( H[2]==0 && H[5]==0 ) { for( i=0; i<n1; i++ ) { r = H[0]*r0 + H[3]*(c0+i) + H[6] + m2; c = H[1]*r0 + H[4]*(c0+i) + H[7] + n2; for(j=0; j<m1; j++) { rs[ind]=r; cs[ind]=c; r+=H[0]; c+=H[1]; ind++; } } } else { for( i=0; i<n1; i++ ) { r = H[0]*r0 + H[3]*(c0+i) + H[6]; c = H[1]*r0 + H[4]*(c0+i) + H[7]; z = H[2]*r0 + H[5]*(c0+i) + 1; for(j=0; j<m1; j++) { rs[ind]=r/z+m2; cs[ind]=c/z+n2; r+=H[0]; c+=H[1]; z+=H[2]; ind++; } } } /* clamp and compute ids according to flag */ if( flag==1 ) { /* nearest neighbor */ for(i=0; i<n1*m1; i++) { r = rs[i]<1 ? 1 : (rs[i]>m ? m : rs[i]); c = cs[i]<1 ? 1 : (cs[i]>n ? n : cs[i]); is[i] = ((int) (r-.5)) + ((int) (c-.5)) * m; } } else if(flag==2) { /* bilinear */ for(i=0; i<n1*m1; i++) { r = rs[i]<2 ? 2 : (rs[i]>m-1 ? m-1 : rs[i]); c = cs[i]<2 ? 2 : (cs[i]>n-1 ? n-1 : cs[i]); fr = (int) r; fc = (int) c; rs[i]=r-fr; cs[i]=c-fc; is[i]=(fr-1)+(fc-1)*m; } } else { /* other cases - clamp only */ for(i=0; i<n1*m1; i++) { rs[i] = rs[i]<2 ? 2 : (rs[i]>m-1 ? m-1 : rs[i]); cs[i] = cs[i]<2 ? 2 : (cs[i]>n-1 ? n-1 : cs[i]); } } /* create output array */ plhs[0] = mxCreateNumericMatrix(0,0,mxDOUBLE_CLASS,mxREAL); plhs[1] = mxCreateNumericMatrix(0,0,mxDOUBLE_CLASS,mxREAL); plhs[2] = mxCreateNumericMatrix(0,0,mxINT32_CLASS,mxREAL); mxSetData(plhs[0],rs); mxSetM(plhs[0],m1); mxSetN(plhs[0],n1); mxSetData(plhs[1],cs); mxSetM(plhs[1],m1); mxSetN(plhs[1],n1); mxSetData(plhs[2],is); mxSetM(plhs[2],m1); mxSetN(plhs[2],n1); }
// [E,ind,segs] = mexFunction(model,I,chns,chnsSs) - helper for edgesDetect.m void mexFunction( int nl, mxArray *pl[], int nr, const mxArray *pr[] ) { // get inputs mxArray *model = (mxArray*) pr[0]; float *I = (float*) mxGetData(pr[1]); float *chns = (float*) mxGetData(pr[2]); float *chnsSs = (float*) mxGetData(pr[3]); // extract relevant fields from model and options float *thrs = (float*) mxGetData(mxGetField(model,0,"thrs")); uint32 *fids = (uint32*) mxGetData(mxGetField(model,0,"fids")); uint32 *child = (uint32*) mxGetData(mxGetField(model,0,"child")); uint8 *segs = (uint8*) mxGetData(mxGetField(pr[0],0,"segs")); uint8 *nSegs = (uint8*) mxGetData(mxGetField(pr[0],0,"nSegs")); uint16 *eBins = (uint16*) mxGetData(mxGetField(model,0,"eBins")); uint32 *eBnds = (uint32*) mxGetData(mxGetField(model,0,"eBnds")); mxArray *opts = mxGetField(model,0,"opts"); const int shrink = (int) mxGetScalar(mxGetField(opts,0,"shrink")); const int imWidth = (int) mxGetScalar(mxGetField(opts,0,"imWidth")); const int gtWidth = (int) mxGetScalar(mxGetField(opts,0,"gtWidth")); const int nChns = (int) mxGetScalar(mxGetField(opts,0,"nChns")); const int nCells = (int) mxGetScalar(mxGetField(opts,0,"nCells")); const uint32 nChnFtrs = (uint32) mxGetScalar(mxGetField(opts,0,"nChnFtrs")); const int stride = (int) mxGetScalar(mxGetField(opts,0,"stride")); const int nTreesEval = (int) mxGetScalar(mxGetField(opts,0,"nTreesEval")); int sharpen = (int) mxGetScalar(mxGetField(opts,0,"sharpen")); int nThreads = (int) mxGetScalar(mxGetField(opts,0,"nThreads")); const int nBnds = int(mxGetNumberOfElements(mxGetField(model,0,"eBnds"))-1)/ int(mxGetNumberOfElements(mxGetField(model,0,"thrs"))); const char *msgSharpen="Model supports sharpening of at most %i pixels!\n"; if( sharpen>nBnds-1 ) { sharpen=nBnds-1; mexPrintf(msgSharpen,sharpen); } // get dimensions and constants const mwSize *imgSize = mxGetDimensions(pr[1]); const int h = (int) imgSize[0]; const int w = (int) imgSize[1]; const int Z = mxGetNumberOfDimensions(pr[1])<=2 ? 1 : imgSize[2]; const mwSize *fidsSize = mxGetDimensions(mxGetField(model,0,"fids")); const int nTreeNodes = (int) fidsSize[0]; const int nTrees = (int) fidsSize[1]; const int h1 = (int) ceil(double(h-imWidth)/stride); const int w1 = (int) ceil(double(w-imWidth)/stride); const int h2 = h1*stride+gtWidth; const int w2 = w1*stride+gtWidth; const int imgDims[3] = {h,w,Z}; const int chnDims[3] = {h/shrink,w/shrink,nChns}; const int indDims[3] = {h1,w1,nTreesEval}; const int outDims[3] = {h2,w2,1}; const int segDims[5] = {gtWidth,gtWidth,h1,w1,nTreesEval}; // construct lookup tables uint32 *iids, *eids, *cids, *cids1, *cids2; iids = buildLookup( (int*)imgDims, gtWidth ); eids = buildLookup( (int*)outDims, gtWidth ); cids = buildLookup( (int*)chnDims, imWidth/shrink ); buildLookupSs( cids1, cids2, (int*)chnDims, imWidth/shrink, nCells ); // create outputs pl[0] = mxCreateNumericArray(3,outDims,mxSINGLE_CLASS,mxREAL); float *E = (float*) mxGetData(pl[0]); pl[1] = mxCreateNumericArray(3,indDims,mxUINT32_CLASS,mxREAL); uint32 *ind = (uint32*) mxGetData(pl[1]); if(nl>2) pl[2] = mxCreateNumericArray(5,segDims,mxUINT8_CLASS,mxREAL); uint8 *segsOut; if(nl>2) segsOut = (uint8*) mxGetData(pl[2]); // apply forest to all patches and store leaf inds #ifdef USEOMP nThreads = min(nThreads,omp_get_max_threads()); #pragma omp parallel for num_threads(nThreads) #endif for( int c=0; c<w1; c++ ) for( int t=0; t<nTreesEval; t++ ) { for( int r0=0; r0<2; r0++ ) for( int r=r0; r<h1; r+=2 ) { int o = (r*stride/shrink) + (c*stride/shrink)*h/shrink; // select tree to evaluate int t1 = ((r+c)%2*nTreesEval+t)%nTrees; uint32 k = t1*nTreeNodes; while( child[k] ) { // compute feature (either channel or self-similarity feature) uint32 f = fids[k]; float ftr; if( f<nChnFtrs ) ftr = chns[cids[f]+o]; else ftr = chnsSs[cids1[f-nChnFtrs]+o]-chnsSs[cids2[f-nChnFtrs]+o]; // compare ftr to threshold and move left or right accordingly if( ftr < thrs[k] ) k = child[k]-1; else k = child[k]; k += t1*nTreeNodes; } // store leaf index and update edge maps ind[ r + c*h1 + t*h1*w1 ] = k; } } // compute edge maps (avoiding collisions from parallel executions) if( !sharpen ) for( int c0=0; c0<gtWidth/stride; c0++ ) { #ifdef USEOMP #pragma omp parallel for num_threads(nThreads) #endif for( int c=c0; c<w1; c+=gtWidth/stride ) { for( int r=0; r<h1; r++ ) for( int t=0; t<nTreesEval; t++ ) { uint32 k = ind[ r + c*h1 + t*h1*w1 ]; float *E1 = E + (r*stride) + (c*stride)*h2; int b0=eBnds[k*nBnds], b1=eBnds[k*nBnds+1]; if(b0==b1) continue; for( int b=b0; b<b1; b++ ) E1[eids[eBins[b]]]++; if(nl>2) memcpy(segsOut+(r+c*h1+t*h1*w1)*gtWidth*gtWidth, segs+k*gtWidth*gtWidth,gtWidth*gtWidth*sizeof(uint8)); } } } // computed sharpened edge maps, snapping to local color values if( sharpen ) { // compute neighbors array const int g=gtWidth; uint16 N[4096*4]; for( int c=0; c<g; c++ ) for( int r=0; r<g; r++ ) { int i=c*g+r; uint16 *N1=N+i*4; N1[0] = c>0 ? i-g : i; N1[1] = c<g-1 ? i+g : i; N1[2] = r>0 ? i-1 : i; N1[3] = r<g-1 ? i+1 : i; } #ifdef USEOMP #pragma omp parallel for num_threads(nThreads) #endif for( int c=0; c<w1; c++ ) for( int r=0; r<h1; r++ ) { for( int t=0; t<nTreesEval; t++ ) { // get current segment and copy into S uint32 k = ind[ r + c*h1 + t*h1*w1 ]; int m = nSegs[k]; if( m==1 ) continue; uint8 S0[4096], *S=(nl<=2) ? S0 : segsOut+(r+c*h1+t*h1*w1)*g*g; memcpy(S,segs+k*g*g, g*g*sizeof(uint8)); // compute color model for each segment using every other pixel int ci, ri, s, z; float ns[100], mus[1000]; const float *I1 = I+(c*stride+(imWidth-g)/2)*h+r*stride+(imWidth-g)/2; for( s=0; s<m; s++ ) { ns[s]=0; for( z=0; z<Z; z++ ) mus[s*Z+z]=0; } for( ci=0; ci<g; ci+=2 ) for( ri=0; ri<g; ri+=2 ) { s = S[ci*g+ri]; ns[s]++; for( z=0; z<Z; z++ ) mus[s*Z+z]+=I1[z*h*w+ci*h+ri]; } for(s=0; s<m; s++) for( z=0; z<Z; z++ ) mus[s*Z+z]/=ns[s]; // update segment S according to local color values int b0=eBnds[k*nBnds], b1=eBnds[k*nBnds+sharpen]; for( int b=b0; b<b1; b++ ) { float vs[10], d, e, eBest=1e10f; int i, sBest=-1, ss[4]; for( i=0; i<4; i++ ) ss[i]=S[N[eBins[b]*4+i]]; for( z=0; z<Z; z++ ) vs[z]=I1[iids[eBins[b]]+z*h*w]; for( i=0; i<4; i++ ) { s=ss[i]; if(s==sBest) continue; e=0; for( z=0; z<Z; z++ ) { d=mus[s*Z+z]-vs[z]; e+=d*d; } if( e<eBest ) { eBest=e; sBest=s; } } S[eBins[b]]=sBest; } // convert mask to edge maps (examining expanded set of pixels) float *E1 = E + c*stride*h2 + r*stride; b1=eBnds[k*nBnds+sharpen+1]; for( int b=b0; b<b1; b++ ) { int i=eBins[b]; uint8 s=S[i]; uint16 *N1=N+i*4; if( s!=S[N1[0]] || s!=S[N1[1]] || s!=S[N1[2]] || s!=S[N1[3]] ) E1[eids[i]]++; } } } } // free memory delete [] iids; delete [] eids; delete [] cids; delete [] cids1; delete [] cids2; }
void mexFunction( int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[] ) { /*Input output boilerplate*/ if(nlhs != 1 || nrhs != 6) mexErrMsgTxt("Function must be called with 6 arguments and has 1 return values"); const mxArray *x_ptr = prhs[0]; mexmetypecheck(x_ptr,mxDOUBLE_CLASS,"Argument x (#1) is expected to be of type double"); const mwSize x_m = mxGetM(x_ptr); const mwSize x_n = mxGetN(x_ptr); const mwSize x_length = x_m == 1 ? x_n : x_m; const mwSize x_numel = mxGetNumberOfElements(x_ptr); const int x_ndims = mxGetNumberOfDimensions(x_ptr); const mwSize *x_size = mxGetDimensions(x_ptr); const double *x = (double *) mxGetData(x_ptr); const mxArray *firstknot_ptr = prhs[1]; mexmetypecheck(firstknot_ptr,mxDOUBLE_CLASS,"Argument firstknot (#2) is expected to be of type double"); const mwSize firstknot_m = mxGetM(firstknot_ptr); const mwSize firstknot_n = mxGetN(firstknot_ptr); const mwSize firstknot_length = firstknot_m == 1 ? firstknot_n : firstknot_m; const mwSize firstknot_numel = mxGetNumberOfElements(firstknot_ptr); const int firstknot_ndims = mxGetNumberOfDimensions(firstknot_ptr); const mwSize *firstknot_size = mxGetDimensions(firstknot_ptr); const double *firstknot = (double *) mxGetData(firstknot_ptr); const mxArray *lastknot_ptr = prhs[2]; mexmetypecheck(lastknot_ptr,mxDOUBLE_CLASS,"Argument lastknot (#3) is expected to be of type double"); const mwSize lastknot_m = mxGetM(lastknot_ptr); const mwSize lastknot_n = mxGetN(lastknot_ptr); const mwSize lastknot_length = lastknot_m == 1 ? lastknot_n : lastknot_m; const mwSize lastknot_numel = mxGetNumberOfElements(lastknot_ptr); const int lastknot_ndims = mxGetNumberOfDimensions(lastknot_ptr); const mwSize *lastknot_size = mxGetDimensions(lastknot_ptr); const double *lastknot = (double *) mxGetData(lastknot_ptr); const mxArray *knots_ptr = prhs[3]; mexmetypecheck(knots_ptr,mxDOUBLE_CLASS,"Argument knots (#4) is expected to be of type double"); const mwSize knots_m = mxGetM(knots_ptr); const mwSize knots_n = mxGetN(knots_ptr); const mwSize knots_length = knots_m == 1 ? knots_n : knots_m; const mwSize knots_numel = mxGetNumberOfElements(knots_ptr); const int knots_ndims = mxGetNumberOfDimensions(knots_ptr); const mwSize *knots_size = mxGetDimensions(knots_ptr); const double *knots = (double *) mxGetData(knots_ptr); const mxArray *weights_ptr = prhs[4]; mexmetypecheck(weights_ptr,mxDOUBLE_CLASS,"Argument weights (#5) is expected to be of type double"); const mwSize weights_m = mxGetM(weights_ptr); const mwSize weights_n = mxGetN(weights_ptr); const mwSize weights_length = weights_m == 1 ? weights_n : weights_m; const mwSize weights_numel = mxGetNumberOfElements(weights_ptr); const int weights_ndims = mxGetNumberOfDimensions(weights_ptr); const mwSize *weights_size = mxGetDimensions(weights_ptr); const double *weights = (double *) mxGetData(weights_ptr); const mxArray *order_ptr = prhs[5]; mexmetypecheck(order_ptr,mxDOUBLE_CLASS,"Argument order (#6) is expected to be of type double"); if(mxGetNumberOfElements(order_ptr) != 1) mexErrMsgTxt("Argument order (#6) must be scalar"); const double order = (double) mxGetScalar(order_ptr); mwSize Sx_dims[] = {x_length,1}; plhs[0] = mxCreateNumericArray(2,Sx_dims,mxDOUBLE_CLASS,mxREAL); mxArray **Sx_ptr = &plhs[0]; double *Sx = (double *) mxGetData(*Sx_ptr); /* * Actual function */ int orderint = (int) order; int jj,ii; for(jj = 0; jj < x_length; jj++) { double s = 0; for(ii = firstknot[jj]; ii < lastknot[jj]; ii++) { s += weights[ii-1]*bin(&(knots[-1]),ii,orderint,x[jj]); } Sx[jj] = s; } }