result_type operator()(A0& yi, A1& inputs) const { yi.resize(inputs.extent()); const child0 & x = boost::proto::child_c<0>(inputs); if (numel(x) <= 1) BOOST_ASSERT_MSG(numel(x) > 1, "Interpolation requires at least two sample points in each dimension."); else { BOOST_ASSERT_MSG(issorted(x, 'a'), "for 'linear' interpolation x values must be sorted in ascending order"); const child1 & y = boost::proto::child_c<1>(inputs); BOOST_ASSERT_MSG(numel(x) == numel(y), "The grid vectors do not define a grid of points that match the given values."); const child2 & xi = boost::proto::child_c<2>(inputs); bool extrap = false; value_type extrapval = Nan<value_type>(); choices(inputs, extrap, extrapval, N1()); table<index_type> index = bsearch (x, xi); table<value_type> dx = xi-x(index); yi = fma(oneminus(dx), y(index), dx*y(oneplus(index))); value_type b = value_type(x(begin_)); value_type e = value_type(x(end_)); if (!extrap) yi = nt2::if_else(nt2::logical_or(boost::simd::is_nge(xi, b), boost::simd::is_nle(xi, e)), extrapval, yi); } return yi; }
lie_Index searchterm(poly* p, entry* t) { lie_Index l=0, u, len=p->ncols; entry** expon; cmpfn_tp cmp=set_ordering(cmpfn,len,defaultgrp); if (!issorted(p)) { p=Reduce_pol(p); } u=p->nrows; expon=p->elm; while (u-l>1) { lie_Index m=(u+l)/2; cmp_tp c=(*cmp)(expon[m],t,len); if (c<0) u=m; else if (c>0) l=m+1; else return m; } return l<u && eqrow(expon[l],t,len) ? l : -1; }
BOOST_FORCEINLINE result_type operator()(const A0& a0, const A1& up) const { size_t dim = nt2::firstnonsingleton(a0); return issorted(a0, dim, up); }
void mexFunction( int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[] ) { // INPUT: double *pdData, *pdItems; double dirIfFound = DIR_IF_FOUND_DEFAULT; // default value double dirIfNotFound = DIR_IF_NOT_FOUND_DEFAULT; // default value // OUTPUT: double *pdPos; // Local: long i, N, nItems; int checkIfSorted; mwSize nrows,ncols; const mxArray * pArg; char *pArgStr; const mwSize *dims; mwSize numDims; /* --------------- Check inputs ---------------------*/ if (nrhs < 2) mexErrMsgTxt("at least 2 inputs required"); if (nrhs > 5) mexErrMsgTxt("maximum of 5 inputs"); /// ------------------- data ---------- pArg = prhs[0]; nrows = mxGetM(pArg); ncols = mxGetN(pArg); if(!mxIsNumeric(pArg) || !mxIsDouble(pArg) || mxIsEmpty(pArg) || mxIsComplex(pArg) || ((nrows > 1) && (ncols >1)) ) { mexErrMsgTxt("Input 1 (data) must be a noncomplex vector of doubles."); } pdData = mxGetPr(prhs[0])-1; // subtract 1 for 1..N indexing N = nrows * ncols; /// ------------------- items ---------- pArg = prhs[1]; nrows = mxGetM(pArg); ncols = mxGetN(pArg); if(!mxIsNumeric(pArg) || !mxIsDouble(pArg) || mxIsEmpty(pArg) || mxIsComplex(pArg) ) { mexErrMsgTxt("Input 2 (items) must be a noncomplex double matrix."); } pdItems = mxGetPr(prhs[1])-1; nItems = nrows * ncols; /// ------------------- dirIfFound ---------- if (nrhs >= 3) { pArg = prhs[2]; if (mxIsEmpty(pArg)) { dirIfFound = DIR_IF_FOUND_DEFAULT; } else if (mxIsChar(pArg)) { pArgStr = mxArrayToString(pArg); if (strcmp(pArgStr, "first")==0) { dirIfFound = -1.0; } else if (strcmp(pArgStr, "last")==0) { dirIfFound = 1.0; } else if (strcmp(pArgStr, "any")==0) dirIfFound = 0.0; else mexErrMsgTxt("Input 3 (dirIfFound), if input as a string, must be either 'first', 'last', or 'any'"); } else { if(!mxIsNumeric(pArg) || mxIsComplex(pArg) || mxGetN(pArg)*mxGetM(pArg) != 1) mexErrMsgTxt("Input 3 (dirIfFound) must be a real scalar or a string"); dirIfFound = mxGetScalar(prhs[2]); if (!( (dirIfFound == -1) || (dirIfFound == 0) || (dirIfFound == 1) ) ) mexErrMsgTxt("Input 3 (dirIfFound) must be either -1, 0, or 1"); } } /// ------------------- dirIfNotFound ---------- if (nrhs >= 4) { pArg = prhs[3]; if (mxIsEmpty(pArg)) { dirIfNotFound == DIR_IF_NOT_FOUND_DEFAULT; // default value } else if (mxIsChar(pArg)) { pArgStr = mxArrayToString(pArg); if (strcmp(pArgStr, "exact")==0) dirIfNotFound = 0.0; else if (strcmp(pArgStr, "down")==0) dirIfNotFound = -1.0; else if (strcmp(pArgStr, "up")==0) dirIfNotFound = 1.0; else if (strcmp(pArgStr, "closest")==0) dirIfNotFound = 2.0; else if (strcmp(pArgStr, "frac")==0) dirIfNotFound = 0.5; else mexErrMsgTxt("Input 4 (dirIfNotFound), if input as a string, must be either 'exact', 'down', 'up', 'closest', or 'frac'"); } else { if (!mxIsNumeric(pArg) || mxIsComplex(pArg) || mxGetN(pArg)*mxGetM(pArg) != 1) { mexErrMsgTxt("Input 4 (dirIfNotFound) must be a real scalar"); } dirIfNotFound = mxGetScalar(prhs[3]); if (! ((dirIfNotFound == -1) || (dirIfNotFound == 0) || (dirIfNotFound == 0.5) || (dirIfNotFound == 1) || (dirIfNotFound == 2)) ) mexErrMsgTxt("Input 4 (dirIfNotFound) must be either -1, 0, 1, 2, or 0.5"); } } checkIfSorted = CHECK_IF_INPUT_SORTED_DEFAULT; if (nrhs == 5) { if (!mxIsEmpty(prhs[4])) checkIfSorted = 1; } if (checkIfSorted) { if (!issorted(pdData, N)) mexErrMsgTxt("Input 1 (data) must be sorted."); } /// ------------------- pos (OUTPUT)---------- numDims = mxGetNumberOfDimensions(prhs[1]); // this outputs with the same dimensions as the input dims = mxGetDimensions(prhs[1]); plhs[0] = mxCreateNumericArray(numDims, dims, mxDOUBLE_CLASS, mxREAL); pdPos = mxGetPr(plhs[0])-1; // CALL BINARY SEARCH FUNCTION; for (i=1; i<=nItems; i++) { pdPos[i] = binarySearch(pdData, N, pdItems[i], dirIfFound, dirIfNotFound); } }