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; }
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; }
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; }