/* $Id: spm_diffeo.c 6137 2014-08-19 12:43:11Z john $ */ /* (c) John Ashburner (2011) */ #include "mex.h" #include #include "shoot_optim3d.h" #include "shoot_diffeo3d.h" #include "shoot_multiscale.h" #include "shoot_regularisers.h" #include "shoot_dartel.h" #include "shoot_bsplines.h" #include "shoot_boundary.h" static void boundary_mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) { if ((nlhs<=1) && (nrhs==0)) { mwSize nout[] = {1,1,1}; plhs[0] = mxCreateNumericArray(2,nout, mxDOUBLE_CLASS, mxREAL); mxGetPr(plhs[0])[0] = get_bound(); } else if ((nrhs==1) && (nlhs==0)) { if (!mxIsNumeric(prhs[0]) || mxIsComplex(prhs[0]) || mxIsSparse(prhs[0]) || !mxIsDouble(prhs[0])) mexErrMsgTxt("Data must be numeric, real, full and double"); set_bound(mxGetPr(prhs[0])[0]); } } static void cgs3_mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) { const mwSize *dm; int nit=1; double tol=1e-10; float *A, *b, *x, *scratch1, *scratch2, *scratch3; static double param[] = {1.0, 1.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}; if (nrhs!=3 || nlhs>1) mexErrMsgTxt("Incorrect usage"); if (!mxIsNumeric(prhs[0]) || mxIsComplex(prhs[0]) || mxIsSparse(prhs[0]) || !mxIsSingle(prhs[0])) mexErrMsgTxt("Data must be numeric, real, full and single"); if (mxGetNumberOfDimensions(prhs[0])!=4) mexErrMsgTxt("Wrong number of dimensions."); if (mxGetDimensions(prhs[0])[3]!=6) mexErrMsgTxt("4th dimension of 1st arg must be 6."); if (!mxIsNumeric(prhs[1]) || mxIsComplex(prhs[1]) || mxIsSparse(prhs[1]) || !mxIsSingle(prhs[1])) mexErrMsgTxt("Data must be numeric, real, full and single"); if (mxGetNumberOfDimensions(prhs[1])!=4) mexErrMsgTxt("Wrong number of dimensions."); dm = mxGetDimensions(prhs[1]); if (dm[3]!=3) mexErrMsgTxt("4th dimension of second arg must be 3."); if (mxGetDimensions(prhs[0])[0] != dm[0]) mexErrMsgTxt("Incompatible 1st dimension."); if (mxGetDimensions(prhs[0])[1] != dm[1]) mexErrMsgTxt("Incompatible 2nd dimension."); if (mxGetDimensions(prhs[0])[2] != dm[1]) mexErrMsgTxt("Incompatible 3rd dimension."); if (!mxIsNumeric(prhs[2]) || mxIsComplex(prhs[2]) || mxIsSparse(prhs[2]) || !mxIsDouble(prhs[2])) mexErrMsgTxt("Data must be numeric, real, full and double"); if (mxGetNumberOfElements(prhs[2]) != 10) mexErrMsgTxt("Third argument should contain vox1, vox2, vox3, param1, param2, param3, param4, param5, tol and nit."); param[0] = 1/mxGetPr(prhs[2])[0]; param[1] = 1/mxGetPr(prhs[2])[1]; param[2] = 1/mxGetPr(prhs[2])[2]; param[3] = mxGetPr(prhs[2])[3]; param[4] = mxGetPr(prhs[2])[4]; param[5] = mxGetPr(prhs[2])[5]; param[6] = mxGetPr(prhs[2])[6]; param[7] = mxGetPr(prhs[2])[7]; tol = mxGetPr(prhs[2])[8]; nit = (int)(mxGetPr(prhs[2])[9]); plhs[0] = mxCreateNumericArray(4,dm, mxSINGLE_CLASS, mxREAL); A = (float *)mxGetPr(prhs[0]); b = (float *)mxGetPr(prhs[1]); x = (float *)mxGetPr(plhs[0]); scratch1 = (float *)mxCalloc(dm[0]*dm[1]*dm[2]*3,sizeof(float)); scratch2 = (float *)mxCalloc(dm[0]*dm[1]*dm[2]*3,sizeof(float)); scratch3 = (float *)mxCalloc(dm[0]*dm[1]*dm[2]*3,sizeof(float)); cgs3((mwSize *)dm, A, b, param, tol, nit, x,scratch1,scratch2,scratch3); mxFree((void *)scratch3); mxFree((void *)scratch2); mxFree((void *)scratch1); } static void fmg3_mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) { const mwSize *dm; int cyc=1, nit=1; float *A, *b, *x, *scratch; static double param[] = {1.0, 1.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}; if ((nrhs!=3 && nrhs!=4) || nlhs>1) mexErrMsgTxt("Incorrect usage"); if (!mxIsNumeric(prhs[0]) || mxIsComplex(prhs[0]) || mxIsSparse(prhs[0]) || !mxIsSingle(prhs[0])) mexErrMsgTxt("Data must be numeric, real, full and single"); if (mxGetNumberOfDimensions(prhs[0])!=4) mexErrMsgTxt("Wrong number of dimensions."); if (mxGetDimensions(prhs[0])[3]!=6) mexErrMsgTxt("4th dimension of 1st arg must be 6."); if (!mxIsNumeric(prhs[1]) || mxIsComplex(prhs[1]) || mxIsSparse(prhs[1]) || !mxIsSingle(prhs[1])) mexErrMsgTxt("Data must be numeric, real, full and single"); if (mxGetNumberOfDimensions(prhs[1])!=4) mexErrMsgTxt("Wrong number of dimensions."); dm = mxGetDimensions(prhs[1]); if (dm[3]!=3) mexErrMsgTxt("4th dimension of second arg must be 3."); if (mxGetDimensions(prhs[0])[0] != dm[0]) mexErrMsgTxt("Incompatible 1st dimension."); if (mxGetDimensions(prhs[0])[1] != dm[1]) mexErrMsgTxt("Incompatible 2nd dimension."); if (mxGetDimensions(prhs[0])[2] != dm[2]) mexErrMsgTxt("Incompatible 3rd dimension."); if (!mxIsNumeric(prhs[2]) || mxIsComplex(prhs[2]) || mxIsSparse(prhs[2]) || !mxIsDouble(prhs[2])) mexErrMsgTxt("Data must be numeric, real, full and double"); if (mxGetNumberOfElements(prhs[2]) != 10) mexErrMsgTxt("Third argument should contain vox1, vox2, vox3, param1, param2, param3, param4, param5, ncycles and relax-its."); param[0] = 1/mxGetPr(prhs[2])[0]; param[1] = 1/mxGetPr(prhs[2])[1]; param[2] = 1/mxGetPr(prhs[2])[2]; param[3] = mxGetPr(prhs[2])[3]; param[4] = mxGetPr(prhs[2])[4]; param[5] = mxGetPr(prhs[2])[5]; param[6] = mxGetPr(prhs[2])[6]; param[7] = mxGetPr(prhs[2])[7]; cyc = mxGetPr(prhs[2])[8]; nit = (int)(mxGetPr(prhs[2])[9]); { /* Penalise absolute displacements slightly in case supplied Hessian is too small. Extra penalty based on value in centre of difference operator, scaled by some slightly arbitrary amount. */ double v0 = param[0]*param[0], v1 = param[1]*param[1], v2 = param[2]*param[2], lam1 = param[4], lam2 = param[5], mu = param[6], lam = param[7], w000, wx000, wy000, wz000; w000 = lam2*(6*(v0*v0+v1*v1+v2*v2) +8*(v0*v1+v0*v2+v1*v2)) +lam1*2*(v0+v1+v2); wx000 = 2*mu*(2*v0+v1+v2)/v0+2*lam + w000/v0; wy000 = 2*mu*(v0+2*v1+v2)/v1+2*lam + w000/v1; wz000 = 2*mu*(v0+v1+2*v2)/v2+2*lam + w000/v2; param[3] += (wx000 + wy000 + wz000)*1.2e-7/3.0; } if (nrhs>=4) { int i; float *x_orig; if (!mxIsNumeric(prhs[3]) || mxIsComplex(prhs[3]) || mxIsSparse(prhs[3]) || !mxIsSingle(prhs[3])) mexErrMsgTxt("Data must be numeric, real, full and single"); if (mxGetNumberOfDimensions(prhs[3])!=4) mexErrMsgTxt("Wrong number of dimensions."); if (mxGetDimensions(prhs[3])[3]!=3) mexErrMsgTxt("4th dimension of fourth arg must be 3."); if (mxGetDimensions(prhs[3])[0] != dm[0]) mexErrMsgTxt("Incompatible 1st dimension."); if (mxGetDimensions(prhs[3])[1] != dm[1]) mexErrMsgTxt("Incompatible 2nd dimension."); if (mxGetDimensions(prhs[3])[2] != dm[2]) mexErrMsgTxt("Incompatible 3rd dimension."); plhs[0] = mxCreateNumericArray(4,dm, mxSINGLE_CLASS, mxREAL); x_orig = (float *)mxGetPr(prhs[3]); x = (float *)mxGetPr(plhs[0]); for(i=0; i1) mexErrMsgTxt("Incorrect usage"); if (!mxIsNumeric(prhs[0]) || mxIsComplex(prhs[0]) || mxIsSparse(prhs[0]) || !mxIsSingle(prhs[0])) mexErrMsgTxt("Data must be numeric, real, full and single"); if (mxGetNumberOfDimensions(prhs[0])!=4) mexErrMsgTxt("Wrong number of dimensions."); dm = mxGetDimensions(prhs[0]); if (dm[3]!=3) mexErrMsgTxt("4th dimension of 1st arg must be 3."); if (!mxIsNumeric(prhs[1]) || mxIsComplex(prhs[1]) || mxIsSparse(prhs[1]) || !mxIsDouble(prhs[1])) mexErrMsgTxt("Data must be numeric, real, full and double"); if (mxGetNumberOfElements(prhs[1]) != 10) mexErrMsgTxt("Second argument should contain vox1, vox2, vox3, param1, param2, param3, param4, param5, ncycles and relax-its."); param[0] = 1/mxGetPr(prhs[1])[0]; param[1] = 1/mxGetPr(prhs[1])[1]; param[2] = 1/mxGetPr(prhs[1])[2]; param[3] = mxGetPr(prhs[1])[3]; param[4] = mxGetPr(prhs[1])[4]; param[5] = mxGetPr(prhs[1])[5]; param[6] = mxGetPr(prhs[1])[6]; param[7] = mxGetPr(prhs[1])[7]; cyc = (int)(mxGetPr(prhs[1])[8]); nit = (int)(mxGetPr(prhs[1])[9]); if (nrhs>=3) { int i; float *x_orig; if (!mxIsNumeric(prhs[2]) || mxIsComplex(prhs[2]) || mxIsSparse(prhs[2]) || !mxIsSingle(prhs[2])) mexErrMsgTxt("Data must be numeric, real, full and single"); if (mxGetNumberOfDimensions(prhs[2])!=4) mexErrMsgTxt("Wrong number of dimensions."); if (mxGetDimensions(prhs[2])[3]!=3) mexErrMsgTxt("4th dimension of third arg must be 3."); if (mxGetDimensions(prhs[2])[0] != dm[0]) mexErrMsgTxt("Incompatible 1st dimension."); if (mxGetDimensions(prhs[2])[1] != dm[1]) mexErrMsgTxt("Incompatible 2nd dimension."); if (mxGetDimensions(prhs[2])[2] != dm[2]) mexErrMsgTxt("Incompatible 3rd dimension."); plhs[0] = mxCreateNumericArray(4,dm, mxSINGLE_CLASS, mxREAL); x_orig = (float *)mxGetPr(prhs[2]); x = (float *)mxGetPr(plhs[0]); for(i=0; i1) mexErrMsgTxt("Incorrect usage"); if (!mxIsNumeric(prhs[0]) || mxIsComplex(prhs[0]) || mxIsSparse(prhs[0]) || !mxIsDouble(prhs[0])) mexErrMsgTxt("Data must be numeric, real, full and double"); if (!mxIsNumeric(prhs[1]) || mxIsComplex(prhs[1]) || mxIsSparse(prhs[1]) || !mxIsDouble(prhs[1])) mexErrMsgTxt("Data must be numeric, real, full and double"); if (mxGetNumberOfElements(prhs[0]) != 3) mexErrMsgTxt("Wrong number of dimensions."); dm[0] = (mwSize)(mxGetPr(prhs[0])[0]); dm[1] = (mwSize)(mxGetPr(prhs[0])[1]); dm[2] = (mwSize)(mxGetPr(prhs[0])[2]); if (mxGetNumberOfElements(prhs[1]) != 8) mexErrMsgTxt("Second argument should contain vox1, vox2, vox3, param1, param2, param3, param4, param5."); param[0] = 1/mxGetPr(prhs[1])[0]; param[1] = 1/mxGetPr(prhs[1])[1]; param[2] = 1/mxGetPr(prhs[1])[2]; param[3] = mxGetPr(prhs[1])[3]; param[4] = mxGetPr(prhs[1])[4]; param[5] = mxGetPr(prhs[1])[5]; param[6] = mxGetPr(prhs[1])[6]; param[7] = mxGetPr(prhs[1])[7]; if (param[6]==0 && param[7]==0) { plhs[0] = mxCreateNumericArray(3,dm, mxSINGLE_CLASS, mxREAL); } else { dm[3] = 3; dm[4] = 3; plhs[0] = mxCreateNumericArray(5,dm, mxSINGLE_CLASS, mxREAL); } kernel(dm, param, (float *)mxGetPr(plhs[0])); } static void rsz_mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) { mwSize na[32], nc[32]; int i, nd; float *a, *b, *c; if ((nrhs!=2) || (nlhs>1)) mexErrMsgTxt("Incorrect usage."); if (!mxIsNumeric(prhs[0]) || mxIsComplex(prhs[0]) || mxIsSparse(prhs[0]) || !mxIsSingle(prhs[0])) mexErrMsgTxt("Data must be numeric, real, full and single"); if (!mxIsNumeric(prhs[1]) || mxIsComplex(prhs[1]) || mxIsSparse(prhs[1]) || !mxIsDouble(prhs[1])) mexErrMsgTxt("Data must be numeric, real, full and double"); if (mxGetNumberOfDimensions(prhs[0])>32) mexErrMsgTxt("Too many dimensions."); na[0] = na[1] = na[2] = 1; for(i=0; i1)) mexErrMsgTxt("Incorrect usage."); if (!mxIsNumeric(prhs[0]) || mxIsComplex(prhs[0]) || mxIsSparse(prhs[0]) || !mxIsSingle(prhs[0])) mexErrMsgTxt("Data must be numeric, real, full and single"); if (mxGetNumberOfDimensions(prhs[0])>3) mexErrMsgTxt("Wrong number of dimensions."); na[0] = na[1] = na[2] = 1; for(i=0; i1) mexErrMsgTxt("Incorrect usage"); if (!mxIsNumeric(prhs[0]) || mxIsComplex(prhs[0]) || mxIsSparse(prhs[0]) || !mxIsSingle(prhs[0])) mexErrMsgTxt("Data must be numeric, real, full and single"); nd = mxGetNumberOfDimensions(prhs[0]); if (nd!=4) mexErrMsgTxt("Wrong number of dimensions."); dm = mxGetDimensions(prhs[0]); if (dm[3]!=3) mexErrMsgTxt("4th dimension must be 3."); if (mxGetNumberOfElements(prhs[1]) != 8) mexErrMsgTxt("Parameters should contain vox1, vox2, vox3, param1, param2, param3, param4 and param5."); param[0] = 1/mxGetPr(prhs[1])[0]; param[1] = 1/mxGetPr(prhs[1])[1]; param[2] = 1/mxGetPr(prhs[1])[2]; param[3] = mxGetPr(prhs[1])[3]; param[4] = mxGetPr(prhs[1])[4]; param[5] = mxGetPr(prhs[1])[5]; param[6] = mxGetPr(prhs[1])[6]; param[7] = mxGetPr(prhs[1])[7]; plhs[0] = mxCreateNumericArray(nd,dm, mxSINGLE_CLASS, mxREAL); vel2mom((mwSize *)dm, (float *)mxGetPr(prhs[0]), param, (float *)mxGetPr(plhs[0])); } static void comp_mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) { float *A, *B, *C; mwSize nd, i; const mwSize *dmp; mwSize dm[3], mm; if (nrhs == 0) mexErrMsgTxt("Incorrect usage"); if (nrhs == 2) { if (nlhs > 1) mexErrMsgTxt("Only 1 output argument required"); } else if (nrhs == 4) { if (nlhs > 2) mexErrMsgTxt("Only 2 output argument required"); } else mexErrMsgTxt("Either 2 or 4 input arguments required"); for(i=0; i 1) mexErrMsgTxt("Only 1 output argument required"); } else mexErrMsgTxt("Two input arguments required"); for(i=0; i4) mexErrMsgTxt("Wrong number of dimensions."); dmf[0] = dmf[1] = dmf[2] = dmf[3] = 1; for(i=0; i 2) mexErrMsgTxt("Up to two output arguments required"); for(i=0; i<2; i++) if (!mxIsNumeric(prhs[i]) || mxIsComplex(prhs[i]) || mxIsSparse( prhs[i]) || !mxIsSingle(prhs[i])) mexErrMsgTxt("Data must be numeric, real, full and single"); nd = mxGetNumberOfDimensions(prhs[0]); if (nd>4) mexErrMsgTxt("Wrong number of dimensions."); dmf[0] = dmf[1] = dmf[2] = dmf[3] = 1; for(i=0; i=3) { if (!mxIsNumeric(prhs[2]) || mxIsComplex(prhs[2]) || mxIsSparse( prhs[2]) || !mxIsDouble(prhs[2])) mexErrMsgTxt("Data must be numeric, real, full and double"); if (mxGetNumberOfElements(prhs[2])!= 3) mexErrMsgTxt("Output dimensions must have three elements"); dmo[0] = (int)floor(mxGetPr(prhs[2])[0]); dmo[1] = (int)floor(mxGetPr(prhs[2])[1]); dmo[2] = (int)floor(mxGetPr(prhs[2])[2]); } else { dmo[0] = dmf[0]; dmo[1] = dmf[1]; dmo[2] = dmf[2]; } dmo[3] = dmf[3]; plhs[0] = mxCreateNumericArray(4,dmo, mxSINGLE_CLASS, mxREAL); f = (float *)mxGetPr(prhs[0]); Y = (float *)mxGetPr(prhs[1]); po = (float *)mxGetPr(plhs[0]); if (nlhs>=2) { plhs[1] = mxCreateNumericArray(3,dmo, mxSINGLE_CLASS, mxREAL); so = (float *)mxGetPr(plhs[1]); } else so = (float *)0; m = dmf[0]*dmf[1]*dmf[2]; n = dmf[3]; push(dmo, m, n, Y, f, po, so); } static void pushc_mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) { float *f, *Y, *so, *po; int nd, i, m, n; mwSize dmf[4]; mwSize dmo[4]; const mwSize *dmy; if ((nrhs != 2) && (nrhs != 3)) mexErrMsgTxt("Two or three input arguments required"); if (nlhs > 2) mexErrMsgTxt("Up to two output arguments required"); for(i=0; i<2; i++) if (!mxIsNumeric(prhs[i]) || mxIsComplex(prhs[i]) || mxIsSparse( prhs[i]) || !mxIsSingle(prhs[i])) mexErrMsgTxt("Data must be numeric, real, full and single"); nd = mxGetNumberOfDimensions(prhs[0]); if (nd>4) mexErrMsgTxt("Wrong number of dimensions."); dmf[0] = dmf[1] = dmf[2] = dmf[3] = 1; for(i=0; i=3) { if (!mxIsNumeric(prhs[2]) || mxIsComplex(prhs[2]) || mxIsSparse( prhs[2]) || !mxIsDouble(prhs[2])) mexErrMsgTxt("Data must be numeric, real, full and double"); if (mxGetNumberOfElements(prhs[2])!= 3) mexErrMsgTxt("Output dimensions must have three elements"); dmo[0] = (int)floor(mxGetPr(prhs[2])[0]); dmo[1] = (int)floor(mxGetPr(prhs[2])[1]); dmo[2] = (int)floor(mxGetPr(prhs[2])[2]); } else { dmo[0] = dmf[0]; dmo[1] = dmf[1]; dmo[2] = dmf[2]; } dmo[3] = dmf[3]; plhs[0] = mxCreateNumericArray(4,dmo, mxSINGLE_CLASS, mxREAL); f = (float *)mxGetPr(prhs[0]); Y = (float *)mxGetPr(prhs[1]); po = (float *)mxGetPr(plhs[0]); if (nlhs>=2) { plhs[1] = mxCreateNumericArray(3,dmo, mxSINGLE_CLASS, mxREAL); so = (float *)mxGetPr(plhs[1]); } else so = (float *)0; m = dmf[0]*dmf[1]*dmf[2]; n = dmf[3]; pushc(dmo, m, n, Y, f, po, so); } static void pushc_grads_mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) { float *f, *Y, *J, *po; int nd, i; mwSize dmf[4]; mwSize dmo[4]; const mwSize *dmy; const mxArray *jacp = 0, *dimp = 0; if ((nrhs<2) || (nrhs>4)) mexErrMsgTxt("Two, three or four input arguments required"); if (nlhs > 1) mexErrMsgTxt("Up to one output argument required"); for(i=0; i<2; i++) if (!mxIsNumeric(prhs[i]) || mxIsComplex(prhs[i]) || mxIsSparse( prhs[i]) || !mxIsSingle(prhs[i])) mexErrMsgTxt("Data must be numeric, real, full and single"); nd = mxGetNumberOfDimensions(prhs[0]); if (nd>4) mexErrMsgTxt("Wrong number of dimensions."); dmf[0] = dmf[1] = dmf[2] = dmf[3] = 1; for(i=0; i=3) { if (nrhs>=4) { jacp = prhs[2]; dimp = prhs[3]; } else { if (mxIsDouble(prhs[2])) dimp = prhs[2]; else jacp = prhs[2]; } } if (jacp) { nd = mxGetNumberOfDimensions(jacp); if (nd!=5) mexErrMsgTxt("Wrong number of dimensions."); dmy = mxGetDimensions(jacp); if (dmy[0]!=dmf[0] || dmy[1]!=dmf[1] || dmy[2]!=dmf[2] || dmy[3]!=3 || dmy[4]!=3) mexErrMsgTxt("Incompatible dimensions."); J = (float *)mxGetPr(jacp); } else J = (float *)0; if (dimp) { if (!mxIsNumeric(dimp) || mxIsComplex(dimp) || mxIsSparse(dimp) || !mxIsDouble(dimp)) mexErrMsgTxt("Data must be numeric, real, full and double"); if (mxGetNumberOfElements(prhs[3])!= 3) mexErrMsgTxt("Output dimensions must have three elements"); dmo[0] = (int)floor(mxGetPr(dimp)[0]); dmo[1] = (int)floor(mxGetPr(dimp)[1]); dmo[2] = (int)floor(mxGetPr(dimp)[2]); } else { dmo[0] = dmf[0]; dmo[1] = dmf[1]; dmo[2] = dmf[2]; } dmo[3] = dmf[3]; plhs[0] = mxCreateNumericArray(4,dmo, mxSINGLE_CLASS, mxREAL); po = (float *)mxGetPr(plhs[0]); pushc_grads(dmo, dmf, Y, J, f, po); } static void smalldef_mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) { int nd; const mwSize *dm; float *v, *t; double sc = 1.0; if (((nrhs != 1) && (nrhs != 2)) || (nlhs>2)) mexErrMsgTxt("Incorrect usage."); if (!mxIsNumeric(prhs[0]) || mxIsComplex(prhs[0]) || mxIsSparse(prhs[0]) || !mxIsSingle(prhs[0])) mexErrMsgTxt("Data must be numeric, real, full and single"); nd = mxGetNumberOfDimensions(prhs[0]); if (nd!=4) mexErrMsgTxt("Wrong number of dimensions."); dm = mxGetDimensions(prhs[0]); if (dm[3]!=3) mexErrMsgTxt("4th dimension must be 3."); if (nrhs>1) { if (!mxIsNumeric(prhs[1]) || mxIsComplex(prhs[1]) || mxIsSparse(prhs[1]) || !mxIsDouble(prhs[1])) mexErrMsgTxt("Data must be numeric, real, full and double"); if (mxGetNumberOfElements(prhs[1]) > 1) mexErrMsgTxt("Params must contain one element"); if (mxGetNumberOfElements(prhs[1]) >= 1) sc = (float)(mxGetPr(prhs[1])[0]); } v = (float *)mxGetPr(prhs[0]); plhs[0] = mxCreateNumericArray(nd,dm, mxSINGLE_CLASS, mxREAL); t = (float *)mxGetPr(plhs[0]); if (nlhs < 2) { smalldef((mwSize *)dm, sc, v, t); } else { float *J; mwSize dmj[5]; dmj[0] = dm[0]; dmj[1] = dm[1]; dmj[2] = dm[2]; dmj[3] = 3; dmj[4] = 3; plhs[1] = mxCreateNumericArray(5,dmj, mxSINGLE_CLASS, mxREAL); J = (float *)mxGetPr(plhs[1]); smalldef_jac1((mwSize *)dm, sc, v, t, J); } } static void det_mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) { int nd; const mwSize *dm; if (((nrhs != 1)) || (nlhs>1)) mexErrMsgTxt("Incorrect usage."); if (!mxIsNumeric(prhs[0]) || mxIsComplex(prhs[0]) || mxIsSparse(prhs[0]) || !mxIsSingle(prhs[0])) mexErrMsgTxt("Data must be numeric, real, full and single"); nd = mxGetNumberOfDimensions(prhs[0]); if (nd!=5) mexErrMsgTxt("Wrong number of dimensions."); dm = mxGetDimensions(prhs[0]); if (dm[3]!=3) mexErrMsgTxt("4th dimension must be 3."); if (dm[4]!=3) mexErrMsgTxt("5th dimension must be 3."); plhs[0] = mxCreateNumericArray(3,dm, mxSINGLE_CLASS, mxREAL); determinant((mwSize *)dm,(float *)mxGetPr(prhs[0]),(float *)mxGetPr(plhs[0])); } static void minmax_div_mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) { mwSize nd; const mwSize *dm; static mwSize nout[] = {1, 2, 1}; if ((nrhs != 1) || (nlhs>1)) mexErrMsgTxt("Incorrect usage."); if (!mxIsNumeric(prhs[0]) || mxIsComplex(prhs[0]) || mxIsSparse(prhs[0]) || !mxIsSingle(prhs[0])) mexErrMsgTxt("Data must be numeric, real, full and single"); nd = mxGetNumberOfDimensions(prhs[0]); if (nd!=4) mexErrMsgTxt("Wrong number of dimensions."); dm = mxGetDimensions(prhs[0]); if (dm[3]!=3) mexErrMsgTxt("4th dimension must be 3."); plhs[0] = mxCreateNumericArray(2,nout, mxDOUBLE_CLASS, mxREAL); minmax_div((mwSize *)dm,(float *)mxGetPr(prhs[0]),(double *)mxGetPr(plhs[0])); } static void divergence_mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) { mwSize nd; const mwSize *dm; if ((nrhs != 1) || (nlhs>1)) mexErrMsgTxt("Incorrect usage."); if (!mxIsNumeric(prhs[0]) || mxIsComplex(prhs[0]) || mxIsSparse(prhs[0]) || !mxIsSingle(prhs[0])) mexErrMsgTxt("Data must be numeric, real, full and single"); nd = mxGetNumberOfDimensions(prhs[0]); if (nd!=4) mexErrMsgTxt("Wrong number of dimensions."); dm = mxGetDimensions(prhs[0]); if (dm[3]!=3) mexErrMsgTxt("4th dimension must be 3."); plhs[0] = mxCreateNumericArray(3,dm, mxSINGLE_CLASS, mxREAL); divergence((mwSize *)dm,(float *)mxGetPr(prhs[0]),(float *)mxGetPr(plhs[0])); } static void def2det_mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) { mwSize nd; const mwSize *dm; mwSize dm1[3]; int pl = -1; if ((nrhs < 1) || (nrhs>2) || (nlhs>1)) mexErrMsgTxt("Incorrect usage."); if (!mxIsNumeric(prhs[0]) || mxIsComplex(prhs[0]) || mxIsSparse(prhs[0]) || !mxIsSingle(prhs[0])) mexErrMsgTxt("Data must be numeric, real, full and single"); nd = mxGetNumberOfDimensions(prhs[0]); if (nd!=4) mexErrMsgTxt("Wrong number of dimensions."); dm = mxGetDimensions(prhs[0]); if (dm[3]!=3) mexErrMsgTxt("4th dimension must be 3."); dm1[0] = dm[0]; dm1[1] = dm[1]; dm1[2] = dm[2]; if (nrhs==2) { if (!mxIsNumeric(prhs[1]) || mxIsComplex(prhs[1]) || mxIsSparse(prhs[1]) || !mxIsDouble(prhs[1]) || (mxGetNumberOfElements(prhs[1])!=1)) mexErrMsgTxt("Slice number must be a numeric, real, full and double scalar"); pl = (int)mxGetPr(prhs[1])[0]; if (pl<1 || pl>=dm[2]) mexErrMsgTxt("Slice number is out of range"); dm1[2] = 1; } plhs[0] = mxCreateNumericArray(3,dm1, mxSINGLE_CLASS, mxREAL); def2det((mwSize *)dm,(float *)mxGetPr(prhs[0]),(float *)mxGetPr(plhs[0]), pl); } static void def2jac_mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) { mwSize nd; const mwSize *dm; mwSize dm1[5]; int pl = -1; if ((nrhs < 1) || (nrhs>2) || (nlhs>1)) mexErrMsgTxt("Incorrect usage."); if (!mxIsNumeric(prhs[0]) || mxIsComplex(prhs[0]) || mxIsSparse(prhs[0]) || !mxIsSingle(prhs[0])) mexErrMsgTxt("Data must be numeric, real, full and single"); nd = mxGetNumberOfDimensions(prhs[0]); if (nd!=4) mexErrMsgTxt("Wrong number of dimensions."); dm = mxGetDimensions(prhs[0]); if (dm[3]!=3) mexErrMsgTxt("4th dimension must be 3."); dm1[0] = dm[0]; dm1[1] = dm[1]; dm1[2] = dm[2]; dm1[3] = 3; dm1[4] = 3; if (nrhs==2) { if (!mxIsNumeric(prhs[1]) || mxIsComplex(prhs[1]) || mxIsSparse(prhs[1]) || !mxIsDouble(prhs[1]) || (mxGetNumberOfElements(prhs[1])!=1)) mexErrMsgTxt("Slice number must be a numeric, real, full and double scalar"); pl = (int)mxGetPr(prhs[1])[0]; if (pl<1 || pl>=dm[2]) mexErrMsgTxt("Slice number is out of range"); dm1[2] = 1; } plhs[0] = mxCreateNumericArray(5,dm1, mxSINGLE_CLASS, mxREAL); def2jac((mwSize *)dm,(float *)mxGetPr(prhs[0]),(float *)mxGetPr(plhs[0]), pl); } static void brc_mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) { float *A, *B, *C; int nd, i; const mwSize *dm, *dm1; if (nrhs == 0) mexErrMsgTxt("Incorrect usage"); if (nrhs != 2) mexErrMsgTxt("Incorrect number of input arguments"); if (nlhs > 1) mexErrMsgTxt("Only 1 output argument required"); for(i=0; i4 || nlhs > 1) mexErrMsgTxt("Incorrect usage."); if (!mxIsNumeric(prhs[0]) || mxIsComplex(prhs[0]) || mxIsSparse(prhs[0]) || !mxIsSingle(prhs[0])) mexErrMsgTxt("Data must be numeric, real, full and single"); if (mxGetNumberOfDimensions(prhs[0])!=4) mexErrMsgTxt("Wrong number of dimensions."); for(i=0; i<4; i++) { dim_y[i] = dim_iy[i] = mxGetDimensions(prhs[0])[i]; } if (dim_y[3]!=3) mexErrMsgTxt("4th dimension of 1st arg must be 3."); Y = (float *)mxGetData(prhs[0]); if (nrhs>1) { if (!mxIsNumeric(prhs[1]) || mxIsComplex(prhs[1]) || mxIsComplex(prhs[1]) || !mxIsDouble(prhs[1]) || mxGetM(prhs[1]) * mxGetN(prhs[1]) != 3) mexErrMsgTxt("Output dimensions must be numeric, real, full, double and contain three elements."); dim_iy[0] = (mwSize)mxGetPr(prhs[1])[0]; dim_iy[1] = (mwSize)mxGetPr(prhs[1])[1]; dim_iy[2] = (mwSize)mxGetPr(prhs[1])[2]; if (nrhs>2) get_mat(prhs[2],M1); else id_mat(M1); if (nrhs>3) get_mat(prhs[3],M2); else id_mat(M2); } plhs[0] = mxCreateNumericArray(4, dim_iy,mxSINGLE_CLASS,mxREAL); iY = (float *)mxGetData(plhs[0]); invdef(dim_y, Y, dim_iy, iY, M1, M2); } #include void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) { set_bound(get_bound()); if ((nrhs>=1) && mxIsChar(prhs[0])) { int buflen; char *fnc_str; buflen = mxGetNumberOfElements(prhs[0]); fnc_str = (char *)mxCalloc(buflen+1,sizeof(mxChar)); mxGetString(prhs[0],fnc_str,buflen+1); if (!strcmp(fnc_str,"comp")) { mxFree(fnc_str); comp_mexFunction(nlhs, plhs, nrhs-1, &prhs[1]); } else if (!strcmp(fnc_str,"vel2mom")) { mxFree(fnc_str); vel2mom_mexFunction(nlhs, plhs, nrhs-1, &prhs[1]); } else if (!strcmp(fnc_str,"smalldef")) { mxFree(fnc_str); smalldef_mexFunction(nlhs, plhs, nrhs-1, &prhs[1]); } else if (!strcmp(fnc_str,"samp")) { mxFree(fnc_str); samp_mexFunction(nlhs, plhs, nrhs-1, &prhs[1]); } else if (!strcmp(fnc_str,"push")) { mxFree(fnc_str); push_mexFunction(nlhs, plhs, nrhs-1, &prhs[1]); } else if (!strcmp(fnc_str,"pushc")) { mxFree(fnc_str); pushc_mexFunction(nlhs, plhs, nrhs-1, &prhs[1]); } else if (!strcmp(fnc_str,"pushg") || !strcmp(fnc_str,"Ad*")) { mxFree(fnc_str); pushc_grads_mexFunction(nlhs, plhs, nrhs-1, &prhs[1]); } else if (!strcmp(fnc_str,"det")) { mxFree(fnc_str); det_mexFunction(nlhs, plhs, nrhs-1, &prhs[1]); } else if (!strcmp(fnc_str,"divrange")) { mxFree(fnc_str); minmax_div_mexFunction(nlhs, plhs, nrhs-1, &prhs[1]); } else if (!strcmp(fnc_str,"fmg") || !strcmp(fnc_str,"FMG")) { mxFree(fnc_str); fmg3_mexFunction(nlhs, plhs, nrhs-1, &prhs[1]); } else if (!strcmp(fnc_str,"mom2vel")) { mxFree(fnc_str); fmg3_noa_mexFunction(nlhs, plhs, nrhs-1, &prhs[1]); } else if (!strcmp(fnc_str,"cgs") || !strcmp(fnc_str,"CGS")) { mxFree(fnc_str); cgs3_mexFunction(nlhs, plhs, nrhs-1, &prhs[1]); } else if (!strcmp(fnc_str,"kernel") || !strcmp(fnc_str,"kern")) { mxFree(fnc_str); kernel_mexFunction(nlhs, plhs, nrhs-1, &prhs[1]); } else if (!strcmp(fnc_str,"restrict")) { mxFree(fnc_str); restrict_mexFunction(nlhs, plhs, nrhs-1, &prhs[1]); } else if (!strcmp(fnc_str,"rsz") || !strcmp(fnc_str,"resize")) { mxFree(fnc_str); rsz_mexFunction(nlhs, plhs, nrhs-1, &prhs[1]); } else if (!strcmp(fnc_str,"brc") || !strcmp(fnc_str,"bracket")) { mxFree(fnc_str); brc_mexFunction(nlhs, plhs, nrhs-1, &prhs[1]); } else if (!strcmp(fnc_str,"dartel") || !strcmp(fnc_str,"DARTEL") || !strcmp(fnc_str,"Dartel")) { mxFree(fnc_str); dartel_mexFunction(nlhs, plhs, nrhs-1, &prhs[1]); } else if (!strcmp(fnc_str,"Exp") || !strcmp(fnc_str,"exp")) { mxFree(fnc_str); exp_mexFunction(nlhs, plhs, nrhs-1, &prhs[1]); } else if (!strcmp(fnc_str,"boundary") || !strcmp(fnc_str,"bound")) { mxFree(fnc_str); boundary_mexFunction(nlhs, plhs, nrhs-1, &prhs[1]); } else if (!strcmp(fnc_str,"bsplinc")) { mxFree(fnc_str); bsplinc_mexFunction(nlhs, plhs, nrhs-1, &prhs[1]); } else if (!strcmp(fnc_str,"bsplins")) { mxFree(fnc_str); bsplins_mexFunction(nlhs, plhs, nrhs-1, &prhs[1]); } else if (!strcmp(fnc_str,"div") || !strcmp(fnc_str,"divergence")) { mxFree(fnc_str); divergence_mexFunction(nlhs, plhs, nrhs-1, &prhs[1]); } else if (!strcmp(fnc_str,"def2det") || !strcmp(fnc_str,"jacdet")) { mxFree(fnc_str); def2det_mexFunction(nlhs, plhs, nrhs-1, &prhs[1]); } else if (!strcmp(fnc_str,"def2jac") || !strcmp(fnc_str,"jacobian")) { mxFree(fnc_str); def2jac_mexFunction(nlhs, plhs, nrhs-1, &prhs[1]); } else if (!strcmp(fnc_str,"invdef") || !strcmp(fnc_str,"inv")) { mxFree(fnc_str); invdef_mexFunction(nlhs, plhs, nrhs-1, &prhs[1]); } else { mxFree(fnc_str); mexErrMsgTxt("Option not recognised."); } } else { fmg3_mexFunction(nlhs, plhs, nrhs, prhs); } }