// offset allows linking the data object to a sub-volume (in the z direction)
	// offset is measured in floats.
	CFloat32CustomMemoryMatlab3D(const mxArray* _pArray, bool bUnshare, size_t iOffset)
	{
		// Convert from slice to offset
		mwSize dims[3];
		get3DMatrixDims(_pArray, dims);
		iOffset *= dims[0];
		iOffset *= dims[1];

		//fprintf(stderr, "Passed:\narray: %p\tdata: %p\n", (void*)_pArray, (void*)mxGetData(_pArray));
		// First unshare the input array, so that we may modify it.
		if (bUnshare) {
#if 0
			// Unsupported in Matlab R2014b
			if (mxIsSharedArray(_pArray)) {
				fprintf(stderr, "Performance note: unsharing shared array in link\n");
			}
#endif
			mxUnshareArray(_pArray, false);
			//fprintf(stderr, "Unshared:\narray: %p\tdata: %p\n", (void*)_pArray, (void*)mxGetData(_pArray));
		}
		// Then create a (persistent) copy so the data won't be deleted
		// or changed.
		m_pLink = mxCreateSharedDataCopy(_pArray);
		//fprintf(stderr, "SharedDataCopy:\narray: %p\tdata: %p\n", (void*)m_pLink, (void*)mxGetData(m_pLink));
		mexMakeArrayPersistent(m_pLink);
		m_fPtr = (float *)mxGetData(m_pLink);
		m_fPtr += iOffset;
	}
Beispiel #2
0
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) {

  // Check inputs
  if (nrhs != 2) {
    mexErrMsgIdAndTxt("Numerical:nth_element:nrhs", "Arguments should be the matrix of columns and the rank of the desired element");
  }
  if (!mxIsNumeric(prhs[0])) {
    mexErrMsgIdAndTxt("nth_element:prhs", "First argument must be a numeric matrix.");
  }
  if (!mxIsNumeric(prhs[1]) || mxGetNumberOfDimensions(prhs[1]) != 2 || mxGetM(prhs[1]) != 1 || mxGetN(prhs[1]) != 1) {
    mexErrMsgIdAndTxt("nth_element:prhs", "Second argument must be a scalar.");
  }
  const mwSize nrows = mxGetM(prhs[0]);
  const mwSize ncols = mxGetN(prhs[0]);


  // Validate rank argument
  mwIndex rank = (mwIndex) mxGetScalar(prhs[1]);
  if (rank < 1) {
    mexErrMsgIdAndTxt("nth_element:prhs", "Rank cannot be less than 1.");
  }
  if (rank > nrows) {
    mexErrMsgIdAndTxt("nth_element:prhs", "Rank cannot be greater than the number of rows.");
  }

  // Convert matlab-style index (starts at 1) to C++ (starts at 0).
  rank--;
  
  
  // If user wants to also get the rearranged indices, have to do extra work
  unsigned int *indices;
  if (nlhs > 1) {
      plhs[1] = mxCreateNumericMatrix(nrows, ncols, mxUINT32_CLASS, mxREAL);
      indices = (unsigned int *) mxGetData(plhs[1]);
      for (mwIndex i = 0; i < ncols; ++i) {
          for (mwIndex j = 0; j < nrows; ++j) indices[i*nrows + j] = j;
      }
  }
  
  
  // Unshare input array if necessary, then modify inplace.  UNDOCUMENTED CALLS!!
  plhs[0] = (mxArray*) prhs[0];
  mxUnshareArray(plhs[0], true);
  if (nlhs > 1) {
      run_nth_element(plhs[0], indices, rank, ncols, nrows);
      for (mwIndex i = 0; i < ncols*nrows; ++i) ++indices[i]; // Fix for janky Matlab 1-indexing
  } else {
    run_nth_element(plhs[0], rank, ncols, nrows);
  }
}
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) {

  // Check inputs
  if (nrhs != 1) {
    mexErrMsgIdAndTxt("Numerical:fast_median:nrhs", "Arguments should be the matrix of columns and the rank of the desired element");
  }
  if (!mxIsNumeric(prhs[0])) {
    mexErrMsgIdAndTxt("Numerical:fast_median:prhs", "Input argument must be a numeric matrix.");
  }

  // Unshare input array if necessary, then modify inplace.  UNDOCUMENTED MEX CALLS!!
  plhs[0] = (mxArray*) prhs[0];
  mxUnshareArray(plhs[0], true);
  plhs[0] = run_fast_median(plhs[0]);
}