Esta página aún no se ha traducido para esta versión. Puede ver la versión más reciente de esta página en inglés.

Actualice los archivos MEX para usar la API de Interleaved Complex

En este tema se describe cómo actualizar los archivos Mex para usar la API de intercalada complejo. Puede seguir utilizando la API compleja independiente llamando al comando con la opción.mex-R2017b Sin embargo, para obtener más información sobre el uso de esta opción, consulte¿Necesito actualizar mis archivos MEX para usar la API de Interleaved Complex?

Nota

Si compila los archivos MEX mediante el comando con la opción, primero debe actualizar el código fuente para usar la API de 64 bits.mex-compatibleArrayDims Para obtener información, consulte.Actualice los archivos MEX para usar la API de 64 bits

Para actualizar su código fuente MEX, utilice la siguiente lista de comprobación.

  1. Revise el código para el uso y los punteros, los punteros devueltos por las funciones/y/.prpimxGetPrmxGetPimxGetDatamxGetImagData En la API intercalada complejo, hay un puntero,, el valor devuelto por y las otras funciones de datos con tipo.pamxGetDoubles Es importante comprobar la complejidad de una matriz de entrada antes de intentar leer los datos. Las llamadas a y en matrices complejas devuelven resultados diferentes en la API compleja intercalada que en la API compleja independiente.mxGetPrmxGetData

  2. Prepare el código antes de editarlo.

    Antes de modificar el código, compruebe que la función MEX funciona con la API.-R2017b Como mínimo, compile una lista de entradas y salidas esperadas, o cree un conjunto de pruebas completo. Utilice estas pruebas para comparar los resultados con el código fuente actualizado. Los resultados deben ser idénticos.

    Copia de respaldo de todos los archivos de origen, binarios y de prueba.

  3. Refactorizar de forma iterativa el código existente comprobando las siguientes condiciones.

  4. Después de cada cambio, compile con la API de intercalada Complex. Para compilar, escriba: para compilar, escriba:myMexFile.c

    mex -R2018a myMexFile.c
    myMexFile.F

    mex -R2018a myMexFile.F
  5. Resuelva errores y advertencias.

  6. Prueba después de cada refactorización.

    Compare los resultados de la ejecución de la función MEX compilada con la API intercalada compleja con los resultados de su binario original. Si hay diferencias o errores, utilice un depurador para investigar la causa. Para obtener información sobre las capacidades del depurador, consulte la documentación del compilador.

  7. Agregar información de compilación a MEX archivo de ayuda

Compruebe la complejidad de la matriz mediantemxIsComplex

Si el código llama a la función para determinar si una matriz tiene elementos complejos, utilice la función en su lugar.mxGetPimxIsComplex Esta función se compila con las API y.-R2017b-R2018a Busque en el código los siguientes patrones.

Reemplazar código fuente C:Con:
mxArray *pa; ... if (mxGetPi(pa)) {      /* process complex array */ } 
mxArray *pa; ... if (mxIsComplex(pa)) {      /* process complex array */ }
double *ptr; ptr = mxGetPi(pa); if (ptr != NULL) {      /* process complex array */ } 

Agregar para admitir representaciones de números complejosMX_HAS_INTERLEAVED_COMPLEX

Para escribir código que se compila con las API y, agregue la macro.-R2017b-R2018aMX_HAS_INTERLEAVED_COMPLEX Esta macro devuelve si se compila el archivo MEX con la opción.true-R2018a

Encapsular el código siguiente en una instrucción garantiza que este código se compile con la u opción.#if MX_HAS_INTERLEAVED_COMPLEX-R2017b-R2018amex Sin embargo, en este ejemplo, no hay ningún código para ejecutar cuando se compila con.-R2018a

Reemplazar código fuente C:Con:
static void analyze_double(const mxArray *array_ptr) {     mwSize total_num_of_elements, index;     double *pr, *pi;     total_num_of_elements = mxGetNumberOfElements(array_ptr);     pr = mxGetPr(array_ptr);     pi = mxGetPi(array_ptr);     for (index=0; index<total_num_of_elements; index++)  {         if (mxIsComplex(array_ptr)) {             mexPrintf("%g + %gi\n", *pr++, *pi++);         }         else {             mexPrintf("%g\n", *pr++);         }     } } 
static void analyze_double(const mxArray *array_ptr) {     mwSize total_num_of_elements, index;     total_num_of_elements = mxGetNumberOfElements(array_ptr);      #if MX_HAS_INTERLEAVED_COMPLEX         /* add interleaved complex API code here */     #ELSE         /* separate complex API processing */         double *pr, *pi;         pr = mxGetPr(array_ptr);         pi = mxGetPi(array_ptr);         for (index=0; index<total_num_of_elements; index++)  {             if (mxIsComplex(array_ptr)) {                 mexPrintf("%g + %gi\n", *pr++, *pi++);             }             else {                 mexPrintf("%g\n", *pr++);             }         }     #endif }
Reemplace el código fuente de Fortran:Con:
mwPointer prhs(*), pr pr = mxGetPr(prhs(1))
mwPointer prhs(*), pr #if MX_HAS_INTERLEAVED_COMPLEX       pr = mxGetDoubles(prhs(1)) #else       pr = mxGetPr(prhs(1)) #endif 

Usar funciones de acceso a datos con tipo

Para utilizar las funciones y, debe comprobar el tipo de la entrada y convertir manualmente la salida del puntero al tipo correcto.mxGetDatamxGetImagDatamxArray Las funciones de acceso a datos con tipo comprueban el tipo de la matriz y devuelven el tipo de puntero correcto. Cuando se utiliza el y funciones en el código siguiente para procesar una matriz, no es necesario recordar el correspondiente tipo de C,.mxGetInt16smxGetComplexInt16sint16short int

Reemplazar código fuente C:Con:
static void analyze_int16(const mxArray *array_ptr) {     short int  *pr, *pi;     pr = (short int *)mxGetData(array_ptr);     pi = (short int *)mxGetImagData(array_ptr);          if (mxIsComplex(array_ptr)) {          /* process complex data *pr,*pi */     }     else {         /* process real data *pr */     } }
static void analyze_int16(const mxArray *array_ptr) {     mxComplexInt16 *pc;     mxInt16 *p;     if(mxIsComplex(array_ptr)) {         pc = mxGetComplexInt16s(array_ptr);         /* process complex data (*pc).real,(*pc).imag */         }     }     else {         p = mxGetInt16s(array_ptr);         /* process real data *p */         }     } }

Mango ComplexmxArrays

Los siguientes ejemplos muestran cómo utiliza una variable de matriz para representar una matriz compleja.MATLAB®

Complex CmxArrays

Supongamos que tiene las siguientes variables complejas y desea agregar los números reales y los números imaginarios de y para crear la matriz.mxArrayxyz Matrices y son del mismo tamaño.xy

mxArray * x, y, z;

En lugar de crear dos punteros y para array, cree un puntero de tipo.xrxixxcmxComplexDouble Para acceder a las partes reales e imaginarias del elemento, utilice y.xc[i]xc[i].realxc[i].imag

Reemplazar código fuente C:Con:
double  *xr, *xi, *yr, *yi, *zr, *zi; /* get pointers to the real and imaginary parts of the arrays */ xr = mxGetPr(x); xi = mxGetPi(x); yr = mxGetPr(y); yi = mxGetPi(y); zr = mxGetPr(z); zi = mxGetPi(z);  ... /* perform addition on element i */ zr[i] = xr[i] + yr[i]; zi[i] = xi[i] + yi[i]; 
/* get pointers to the complex arrays */ mxComplexDouble * xc = mxGetComplexDoubles(x); mxComplexDouble * yc = mxGetComplexDoubles(y); mxComplexDouble * zc = mxGetComplexDoubles(z);  ... /* perform addition on element i */ zc[i].real = xc[i].real + yc[i].real; zc[i].imag = xc[i].imag + yc[i].imag; 

El código siguiente copia una en un argumento de salida.mxArray El código muestra cómo probar y copiar matrices complejas.

Reemplazar código fuente C:Con:
mxGetPr(plhs[0])[0] = mxGetPr(prhs[0])[index]; if (mxIsComplex(prhs[0])) {     mxGetPi(plhs[0])[0] = mxGetPi(prhs[0])[index]; } 
if (mxIsComplex(prhs[0])) {    mxGetComplexDoubles(plhs[0])[0] = mxGetComplexDoubles(prhs[0])[index]; } else {    mxGetDoubles(plhs[0])[0] = mxGetDoubles(prhs[0])[index]; } 

Complex FortranmxArrays

Supongamos que tiene dos Double complejos y desea pasarlos a una función Fortran con argumentos de entrada y definidos de la siguiente manera.mxArraysxy

complex*16 x(*), y(*)

En lugar de convertir por separado las partes reales e imaginarias de cada una, utilice la función.mxArraymxGetComplexDoubles

Reemplace el código fuente de Fortran:Con:
      mwPointer mxGetPr, mxGetPi  C     Copy the data into native COMPLEX Fortran arrays.       call mxCopyPtrToComplex16(      +    mxGetPr(prhs(1)),      +    mxGetPi(prhs(1)),x,nx)       call mxCopyPtrToComplex16(      +    mxGetPr(prhs(2)),      +    mxGetPi(prhs(2)),y,ny) 
      mwPointer mxGetComplexDoubles       integer*4 status       integer*4 mxCopyPtrToComplex16, mxCopyComplex16ToPtr  C     Copy the data into native COMPLEX Fortran arrays.       status =       +   mxCopyPtrToComplex16(mxGetComplexDoubles(prhs(1)),x,nx) C     Test status for error conditions        status =       +   mxCopyPtrToComplex16(mxGetComplexDoubles(prhs(2)),y,ny) C     Test status for error conditions 

Mantener la complejidad demxArray

Este fragmento de código de C muestra cómo convertir una matriz de entrada real, doble, en una matriz compleja.prhs[0] El código siguiente configura las variables utilizadas para rellenar la parte compleja de la matriz con números consecutivos.

// code to check number of arguments and expected types mwSize rows = mxGetM(prhs[0]); mwSize cols = mxGetN(prhs[0]); mwSize sz = mxGetElementSize(prhs[0]);

El código siguiente muestra cómo se utiliza para convertir una matriz de entrada real, doble, a un complejo intercalado.mxMakeArrayComplexmxArray Para obtener más ejemplos, consulte.mxMakeArrayComplex (C)

Reemplazar código fuente C:Con:
plhs[0] = mxDuplicateArray(prhs[0]);  mxDouble *dc = (mxDouble*)mxMalloc(rows*cols*sz); mxSetImagData(plhs[0], dc); for (int i = 0 ; i < rows*cols ; i++) {     dc[i] = i+1; } 
plhs[0] = mxDuplicateArray(prhs[0]);  if (mxMakeArrayComplex(plhs[0])) {     mxComplexDouble *dt = mxGetComplexDoubles(plhs[0]);     for (int i = 0 ; i < rows*cols ; i++)     {         dt[i].imag = i+1;     } } 

Reemplazar funciones complejas separadas

Las siguientes funciones no están en la API compleja intercalada. Debe reemplazarlos con funciones complejas intercaladas al manipular datos complejos.

  • mxGetPi

  • mxSetPi

  • mxGetImagData

  • mxSetImagData

Puede reemplazar las llamadas a y con una llamada a.mxGetPrmxGetPimxGetComplexDoubles Esta función verifica que la matriz contiene elementos de tipo.mxComplexDouble Del mismo modo, reemplaza y.mxSetComplexDoublesmxSetPrmxSetPi

Las funciones y no comprobar el tipo de la matriz.mxGetDatamxGetImagData En su lugar, debe convertir el valor devuelto al tipo de puntero que coincida con el tipo especificado por la entrada. Reemplace las llamadas a y con la función de acceso a datos única, adecuada y con tipo, por ejemplo,.mxGetDatamxGetImagDatamxGetComplexInt64s

Reemplazar código fuente C:Con:
mxArray *pa; mwSize numElements;   int64_T  *pr, *pi; pr = (int64_T *)mxGetData(pa); pi = (int64_T *)mxGetImagData(pa); numElements = mxGetNumberOfElements(pa); 
mxArray *pa; mwSize numElements;   mxComplexInt64 *pc; pc = mxGetComplexInt64s(pa); numElements = mxGetNumberOfElements(pa); 

Calcular tamaño de datos de matriz conmxGetElementSize

En la API, la función devuelve un tipo de datos complejo.-R2018amxGetElementSize (C)sizeof(std::complex<T>)mxArrayT Este valor es el doble del valor devuelto por la función en la API.-R2017b De forma similar, en la API devuelve el doble del valor que la función en la API.mxGetElementSize (Fortran)-R2018a-R2017b

Considere la posibilidad de reemplazar las funciones a-ser-eliminadas

Las siguientes funciones se encuentran tanto en el API como en el.-R2017b-R2018a Aunque no es necesario reemplazarlos con funciones de acceso a datos con tipo, las funciones de datos con tipo proporcionan comprobación de tipos. Además, si lo usa, puede elegir cualquier procesamiento de matriz complejo.mxGetPrmxGetPi Este patrón de código provoca errores al escribir funciones MEX.-R2018a

Puede reemplazar las llamadas a con una llamada a.mxGetPrmxGetDoubles Esta función verifica que la matriz contiene elementos de tipo.mxDouble Del mismo modo, reemplaza.mxSetDoublesmxSetPr Para reemplazar las llamadas a y las funciones, elija la función de acceso a datos con tipo adecuada, por ejemplo, y.mxGetDatamxSetDatamxGetInt64smxSetInt64s

Reemplazar código fuente C:Con:
double *y; /*  create a pointer y to input matrix */ y = mxGetPr(prhs[1]); 
mxDouble *p; p = mxGetDoubles(prhs[1]); 
Reemplace el código fuente de Fortran:Con:
      mwPointer pr       mwPointer mxGetPr C     Create a pointer to input matrix       pr = mxGetPr(prhs(1)) 
      mwPointer pr       mwPointer mxGetDoubles        pr = mxGetDoubles(prhs(1)) 

Agregar información de compilación a MEX archivo de ayuda

Considere la posibilidad de crear un archivo de ayuda, descrito en, que contiene información de compilación.Utilice archivos de ayuda con funciones MEX Por ejemplo, cree un archivo que contenga el texto siguiente.displayTypesafeNumeric.m

% displayTypesafeNumeric.m Help file for displayTypesafeNumeric C MEX function %  % Use the following command to build this MEX file: % mex -R2018a displayTypesafeNumeric.c

En la solicitud de comando, escriba:MATLAB

help displayTypesafeNumeric
displayTypesafeNumeric.m Help file for displayTypesafeNumeric C MEX function      Use the following command to build this MEX file:   mex -R2018a displayTypesafeNumeric.c

Consulte también

Temas relacionados