Ejecutar código C en Matlab: parte 2

written by uve 13 October 2010

Ahora que ya hemos visto cómo hacer un Hola Mundo! vamos a ver como podemos controlar los parámetros de entrada y salida. De esta forma podremos interactuar con los tipos de datos propios de Matlab.

Para controlar los parámetros de entrada y los valores de retorno, podemos ver los parámetros que recibe la función mexFunction:

void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]);
  • nlhs: Número de mxArray esperados en la parte izquierda (Left Hand Side)
  • plhs: Array de punteros de salida esperados
  • nrhs: Número de mxArray esperados en la parte derecha (Right Hand Side)
  • prhs: Array de punteros de datos de entrada. Los datos de entrada son de sólo lectura y no deberían ser alterados.

Al principio puede resultar muy confuso, lo reconozco. Así que voy a tratar de aclararlo un poco más. Supongamos que ejecutamos la función foo desde Matlab:

>> [a, b] = foo( [0 1 0; 1 1 1], 'parametro2', 3.5 )

¿Cómo se traduce esto?

  • nlhs = 2 (Referentes a las variables a y b)
  • En plhs se espera que creen los valores para a y b
  • nrhs = 3 (Referentes al array, al string y al flotante)
  • En prhs podemos acceder a cada uno de los parámetos de entrada. Brutamente podemos decir que prhs[0] = [0 1 0; 1 1 1], prhs[1] = 'parametro2' y prhs[2] = 3.5 (en realidad son punteros a mxArray, pero así que más claro)

Por ejemplo, podemos forzar a que se reciban solamente dos parámetros:

void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
{
    if(nrhs != 2)
        ...
}

¿Qué hacer en estas circunstancias? Pues simple, mostrar un error y abortar la función. Para ello, Matlab nos ofrece una función que se encarga de ello: mexErrMsgTxt.

void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
{
    if(nrhs != 2)
        mexErrMsgTxt("Dos parámetros requeridos.");
    ...
}

mxArray es una estructura especial que representa un tipo de dato Matlab. Todos los tipos de arrays de Matlab (scalars, vectors, matrices, strings, cell arrays, etc.) son mxArray. Todas las variables de Matlab son almacenadas como un mxArray. La estructura mxArray contiene los siguientes datos:

  • El nombre de la variable
  • Sus dimensiones
  • Su tipo de dato
  • Cuando la variable es real o es compleja

Matlab provee una serie de funciones para poder trabajar con estas estructuras. Podemos consultar las funciones disponibles en el API oficial.

Aquí podemos ver un ejemplo completo. Se reciben dos enteros que representan el alto y el ancho de una matriz; la función crea una matriz de doubles de las dimensiones indicadas y la devuelve:

#include "mex.h"

/* mexFunction es la rutina de enlace con el código C. */
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
{
    int rows, columns;
    if(nrhs != 2)
        mexErrMsgTxt("Dos parámetros requeridos.");
    else if(!mxIsNumeric(prhs[0]) || !mxIsNumeric(prhs[1]))
        mexErrMsgTxt("Los parámetros deben ser numéricos.");
    if (nlhs != 1)
        mexErrMsgTxt("Hay un valor de retorno.");
    rows = (int)mxGetScalar(prhs[0]);
    columns = (int)mxGetScalar(prhs[1]);
    mexPrintf("Filas:%d, Columnas:%d\n", rows, columns);
    plhs[0] = mxCreateDoubleMatrix(rows, columns, mxREAL);
}

Tags

La teoría es cuando crees saber algo, pero no funciona.
La práctica es cuando algo funciona, pero no sabes por qué.
Los programadores combinan la teoría y la práctica:
Nada funciona y no saben por qué.