Пример #1
0
static mxArray *makeMxFromNumeric(const PyArrayObject *pSrc, bool &is_reference)
{
  npy_intp lRows=0, lCols=0;
  bool lIsComplex;
  bool lIsNotAMatrix = false;
  double *lR = NULL;
  double *lI = NULL;
  mxArray *lRetval = NULL;
  mwSize dims[NPY_MAXDIMS];
  mwSize dimsEmpty [2];
  memset(&dimsEmpty, 0, 2 * sizeof(mwSize));
  mwSize nDims = pSrc->nd;
  const PyArrayObject *ap=NULL;
  mxClassID classID = mxUNKNOWN_CLASS;

  switch (pSrc->nd) {
  case 0:                       // XXX the evil 0D
    lRows = 1;
    lCols = 1;
    lIsNotAMatrix = true;
    break;
  case 1:
    lRows = pSrc->dimensions[0];
    lCols = min(1, lRows); // for array([]): to avoid zeros((0,1)) !
    lIsNotAMatrix = true;
    break;
  default:
      for (mwSize i = 0;i != nDims; i++) {
        dims[i]=(mwSize)pSrc->dimensions[i];
      }
    break;
  }
  switch (pSrc->descr->type_num) {
  case PyArray_OBJECT:
    PyErr_SetString(PyExc_TypeError, "Non-numeric array types not supported");
    return NULL;
  case PyArray_CFLOAT:
  case PyArray_CDOUBLE:
    lIsComplex = true;
    break;
  default:
    lIsComplex = false;
  }

  // converts to fortran order if not already
  if(!PyArray_ISFORTRAN(pSrc)){ 
    ap = (PyArrayObject * const)PyArray_FromArray((PyArrayObject*)pSrc,NULL,NPY_ALIGNED|NPY_F_CONTIGUOUS);
  }
  else{
    ap = pSrc;
  }

  if(lIsNotAMatrix)
    lRetval = mxCreateDoubleMatrix(lRows, lCols, lIsComplex ? mxCOMPLEX : mxREAL);
  else {
    switch (ap->descr->type_num) {
      case PyArray_CFLOAT:
      case PyArray_CDOUBLE:
        classID = mxDOUBLE_CLASS;
        is_reference = false;
        break;
      case PyArray_BOOL:
        classID = mxLOGICAL_CLASS;
        is_reference = true;
        break;
      case PyArray_CHAR:
        classID = mxCHAR_CLASS;
        is_reference = true;
        break;
      case PyArray_DOUBLE:
        classID = mxDOUBLE_CLASS;
        is_reference = true;
        break;
      case PyArray_FLOAT:
        classID = mxSINGLE_CLASS;
        is_reference = true;
        break;
      case PyArray_INT8:
        classID = mxINT8_CLASS;
        is_reference = true;
        break;
      case PyArray_UINT8:
        classID = mxUINT8_CLASS;
        is_reference = true;
        break;
      case PyArray_INT16:
        classID = mxINT16_CLASS;
        is_reference = true;
        break;
      case PyArray_UINT16:
        classID = mxUINT16_CLASS;
        is_reference = true;
        break;
      case PyArray_INT32:
        classID = mxINT32_CLASS;
        is_reference = true;
        break;
      case PyArray_UINT32:
        classID = mxUINT32_CLASS;
        is_reference = true;
        break;
#ifdef NPY_INT64
      case PyArray_INT64:
        classID = mxINT64_CLASS;
        is_reference = true;
        break;
      case PyArray_UINT64:
        classID = mxUINT64_CLASS;
        is_reference = true;
        break;
#endif
    }
    if (!is_reference) {
      lRetval = mxCreateNumericArray(nDims,dims,classID,lIsComplex ? mxCOMPLEX : mxREAL);
    } else {
/*
      // code for create and mxArray ref on the numpy object
      lRetval = mxCreateNumericArray(2, dimsEmpty, classID, lIsComplex ? mxCOMPLEX : mxREAL);
      if (mxSetDimensions(lRetval, dims, nDims) == 1) {
        // failed to reset the dimensions
        mxDestroyArray(lRetval);
        lRetval = NULL;
      } else {
        mxSetData(lRetval, PyArray_DATA(ap));
      }
*/
      // uses memcopy for faster copying
      is_reference = false;
      lRetval = mxCreateNumericArray(nDims, dims, classID, lIsComplex ? mxCOMPLEX : mxREAL);
      // this is a sanity check, it should not fail
      int matlab_nbytes = mxGetNumberOfElements(lRetval) * mxGetElementSize(lRetval);
      if (matlab_nbytes == PyArray_NBYTES(pSrc)) {
        memcpy(mxGetData(lRetval), PyArray_DATA(ap), PyArray_NBYTES(pSrc));
      } else {
        PyErr_SetString(PyExc_TypeError, "Number of bytes do not match");
      }
    }
  }

  if (lRetval == NULL) return NULL;
  lR = mxGetPr(lRetval);
  lI = mxGetPi(lRetval);
  if (lIsNotAMatrix) {
    void *p = PyArray_DATA(ap);
    switch (ap->descr->type_num) {
    case PyArray_CHAR:
      copyNumericVector2Mx((char *)(p), lRows, lR, pSrc->strides);
      break;

    case PyArray_UBYTE:
      copyNumericVector2Mx((unsigned char *)(p), lRows, lR, pSrc->strides);
      break;

    case PyArray_SBYTE:
      copyNumericVector2Mx((signed char *)(p), lRows, lR, pSrc->strides);
      break;

    case PyArray_SHORT:
      copyNumericVector2Mx((short *)(p), lRows, lR, pSrc->strides);
      break;

    case PyArray_INT:
      copyNumericVector2Mx((int *)(p), lRows, lR, pSrc->strides);
      break;

    case PyArray_LONG:
      copyNumericVector2Mx((long *)(p), lRows, lR, pSrc->strides);
      break;

    case PyArray_FLOAT:
      copyNumericVector2Mx((float *)(p), lRows, lR, pSrc->strides);
      break;

    case PyArray_DOUBLE:
      copyNumericVector2Mx((double *)(p), lRows, lR, pSrc->strides);
      break;

    case PyArray_CFLOAT:
      copyCplxNumericVector2Mx((float *)(p), lRows, lR, lI, pSrc->strides);
      break;

    case PyArray_CDOUBLE:
      copyCplxNumericVector2Mx((double *)(p), lRows, lR, lI, pSrc->strides);
      break;
    }
  } else {
    void *p = PyArray_DATA(ap);
    npy_intp size = PyArray_SIZE(pSrc);

    switch (pSrc->descr->type_num) {
    case PyArray_CFLOAT:
      copyCplxNumeric2Mx((float *)p,size,lR,lI);
      break;

    case PyArray_CDOUBLE:
      copyCplxNumeric2Mx((double *)p,size,lR,lI);
      break;
    }
  }
  
  if(ap != pSrc){
    Py_DECREF(const_cast<PyArrayObject *>(ap));
  }
  return lRetval;
}
Пример #2
0
static mxArray *makeMxFromNumeric(const PyArrayObject *pSrc)
{
  npy_intp lRows=0, lCols=0;
  bool lIsComplex;
  bool lIsNotAMatrix = false;
  double *lR = NULL;
  double *lI = NULL;
  mxArray *lRetval = NULL;
  mwSize dims[NPY_MAXDIMS];
  mwSize nDims = pSrc->nd;
  const PyArrayObject *ap=NULL;

  switch (pSrc->nd) {
  case 0:                       // XXX the evil 0D
    lRows = 1;
    lCols = 1;
    lIsNotAMatrix = true;
    break;
  case 1:
    lRows = pSrc->dimensions[0];
    lCols = min(1, lRows); // for array([]): to avoid zeros((0,1)) !
    lIsNotAMatrix = true;
    break;
  default:
      for (mwSize i = 0;i != nDims; i++) {
        dims[i]=(mwSize)pSrc->dimensions[i];
      }
    break;
  }
  switch (pSrc->descr->type_num) {
  case PyArray_OBJECT:
    PyErr_SetString(PyExc_TypeError, "Non-numeric array types not supported");
    return NULL;
  case PyArray_CFLOAT:
  case PyArray_CDOUBLE:
    lIsComplex = true;
    break;
  default:
    lIsComplex = false;
  }

  // converts to fortran order if not already
  if(!PyArray_ISFORTRAN(pSrc)){ 
    ap = (PyArrayObject * const)PyArray_FromArray((PyArrayObject*)pSrc,NULL,NPY_ALIGNED|NPY_F_CONTIGUOUS);
  }
  else{
    ap = pSrc;
  }

  if(lIsNotAMatrix)
    lRetval = mxCreateDoubleMatrix(lRows, lCols, lIsComplex ? mxCOMPLEX : mxREAL);
  else
    lRetval = mxCreateNumericArray(nDims,dims,mxDOUBLE_CLASS,lIsComplex ? mxCOMPLEX : mxREAL);

  if (lRetval == NULL) return NULL;
  lR = mxGetPr(lRetval);
  lI = mxGetPi(lRetval);
  if (lIsNotAMatrix) {
    void *p = PyArray_DATA(ap);
    switch (ap->descr->type_num) {
    case PyArray_CHAR:
      copyNumericVector2Mx((char *)(p), lRows, lR, pSrc->strides);
      break;

    case PyArray_UBYTE:
      copyNumericVector2Mx((unsigned char *)(p), lRows, lR, pSrc->strides);
      break;

    case PyArray_SBYTE:
      copyNumericVector2Mx((signed char *)(p), lRows, lR, pSrc->strides);
      break;

    case PyArray_SHORT:
      copyNumericVector2Mx((short *)(p), lRows, lR, pSrc->strides);
      break;

    case PyArray_INT:
      copyNumericVector2Mx((int *)(p), lRows, lR, pSrc->strides);
      break;

    case PyArray_LONG:
      copyNumericVector2Mx((long *)(p), lRows, lR, pSrc->strides);
      break;

    case PyArray_FLOAT:
      copyNumericVector2Mx((float *)(p), lRows, lR, pSrc->strides);
      break;

    case PyArray_DOUBLE:
      copyNumericVector2Mx((double *)(p), lRows, lR, pSrc->strides);
      break;

    case PyArray_CFLOAT:
      copyCplxNumericVector2Mx((float *)(p), lRows, lR, lI, pSrc->strides);
      break;

    case PyArray_CDOUBLE:
      copyCplxNumericVector2Mx((double *)(p), lRows, lR, lI, pSrc->strides);
      break;
    }
  } else {
    void *p = PyArray_DATA(ap);
    npy_intp size = PyArray_SIZE(pSrc);

    switch (pSrc->descr->type_num) {
    case PyArray_CHAR:
      copyNumeric2Mx((char *)p,size,lR);
      break;

    case PyArray_UBYTE:
      copyNumeric2Mx((unsigned char *)p,size,lR);
      break;

    case PyArray_SBYTE:
      copyNumeric2Mx((signed char *)p,size,lR);
      break;

    case PyArray_SHORT:
      copyNumeric2Mx((short *)p,size,lR);
      break;

    case PyArray_INT:
      copyNumeric2Mx((int *)p,size,lR);
      break;

    case PyArray_LONG:
      copyNumeric2Mx((long *)p,size,lR);
      break;

    case PyArray_FLOAT:
      copyNumeric2Mx((float *)p,size,lR);
      break;

    case PyArray_DOUBLE:
      copyNumeric2Mx((double *)p,size,lR);
      break;

    case PyArray_CFLOAT:
      copyCplxNumeric2Mx((float *)p,size,lR,lI);
      break;

    case PyArray_CDOUBLE:
      copyCplxNumeric2Mx((double *)p,size,lR,lI);
      break;
    }
  }
  
  if(ap != pSrc){
    Py_DECREF(const_cast<PyArrayObject *>(ap));
  }
  return lRetval;
}
Пример #3
0
static mxArray *makeMxFromNumeric(const PyArrayObject *pSrc)
{
  npy_intp lRows, lCols;
  bool lIsComplex;
  bool lIsNotAMatrix = false;
  double *lR = NULL;
  double *lI = NULL;
  mxArray *lRetval = NULL;
    
  switch (pSrc->nd) {
  case 0:                       // XXX the evil 0D
    lRows = 1;
    lCols = 1;
    lIsNotAMatrix = true;
    break;
  case 1:
    lRows = pSrc->dimensions[0];
    lCols = min(1, lRows); // for array([]): to avoid zeros((0,1)) !
    lIsNotAMatrix = true;       
    break;
  case 2:
    lCols = pSrc->dimensions[1];
    lRows = pSrc->dimensions[0];
    break;
  default:
    char strbuff[1024];
    sprintf(strbuff, 
            "Only arrays with up to 2D are currently supported (not %dD)",
            pSrc->nd);
    PyErr_SetString(PyExc_TypeError, strbuff);
    goto error_return;
  }

  switch (pSrc->descr->type_num) {
  case PyArray_OBJECT:
    PyErr_SetString(PyExc_TypeError, "Non-numeric array types not supported");
    return NULL;
        
  case PyArray_CFLOAT:
  case PyArray_CDOUBLE:
    lIsComplex = true;
    break;
        
  default:
    lIsComplex = false;
  }
    
  lRetval = mxCreateDoubleMatrix(lRows, lCols, lIsComplex ? mxCOMPLEX : mxREAL);

  if (lRetval == NULL) return NULL;

  lR = mxGetPr(lRetval);
  lI = mxGetPi(lRetval);
  if (lIsNotAMatrix) {
    switch (pSrc->descr->type_num) {
    case PyArray_CHAR:
      copyNumericVector2Mx((char *)(pSrc->data), lRows, lR, pSrc->strides);
      break;

    case PyArray_UBYTE:
      copyNumericVector2Mx((unsigned char *)(pSrc->data), lRows, lR, pSrc->strides);
      break;

    case PyArray_SBYTE:
      copyNumericVector2Mx((signed char *)(pSrc->data), lRows, lR, pSrc->strides);
      break;

    case PyArray_SHORT: 
      copyNumericVector2Mx((short *)(pSrc->data), lRows, lR, pSrc->strides);
      break;

    case PyArray_INT:
      copyNumericVector2Mx((int *)(pSrc->data), lRows, lR, pSrc->strides);
      break;

    case PyArray_LONG:
      copyNumericVector2Mx((long *)(pSrc->data), lRows, lR, pSrc->strides);
      break;

    case PyArray_FLOAT:
      copyNumericVector2Mx((float *)(pSrc->data), lRows, lR, pSrc->strides);
      break;

    case PyArray_DOUBLE:
      copyNumericVector2Mx((double *)(pSrc->data), lRows, lR, pSrc->strides);
      break;

    case PyArray_CFLOAT:
      copyCplxNumericVector2Mx((float *)(pSrc->data), lRows, lR, lI, pSrc->strides);
      break;

    case PyArray_CDOUBLE:
      copyCplxNumericVector2Mx((double *)(pSrc->data), lRows, lR, lI, pSrc->strides);
      break;
    }
  } else {
    switch (pSrc->descr->type_num) {
    case PyArray_CHAR:
      copyNumeric2Mx((char *)(pSrc->data), lRows, lCols, lR, pSrc->strides);
      break;

    case PyArray_UBYTE:
      copyNumeric2Mx((unsigned char *)(pSrc->data), lRows, lCols, lR, pSrc->strides);
      break;

    case PyArray_SBYTE:
      copyNumeric2Mx((signed char *)(pSrc->data), lRows, lCols, lR, pSrc->strides);
      break;

    case PyArray_SHORT: 
      copyNumeric2Mx((short *)(pSrc->data), lRows, lCols, lR, pSrc->strides);
      break;

    case PyArray_INT:
      copyNumeric2Mx((int *)(pSrc->data), lRows, lCols, lR, pSrc->strides);
      break;

    case PyArray_LONG:
      copyNumeric2Mx((long *)(pSrc->data), lRows, lCols, lR, pSrc->strides);
      break;

    case PyArray_FLOAT:
      copyNumeric2Mx((float *)(pSrc->data), lRows, lCols, lR, pSrc->strides);
      break;

    case PyArray_DOUBLE:
      copyNumeric2Mx((double *)(pSrc->data), lRows, lCols, lR, pSrc->strides);
      break;

    case PyArray_CFLOAT:
      copyCplxNumeric2Mx((float *)(pSrc->data), lRows, lCols, lR, lI, pSrc->strides);
      break;

    case PyArray_CDOUBLE:
      copyCplxNumeric2Mx((double *)(pSrc->data), lRows, lCols, lR, lI, pSrc->strides);
      break;
    }
  }
  return lRetval;

 error_return:
  return NULL;
}