3-5 ���������������������MEX ������������

¥»¸`±N¤¶²Ð¨â­Ó½d¨Ò¡A¥H«K¹ï¤Gºû¯x°}¶i¦æ³B²z¡A

²Ä¤@­Ó½d¨Ò¬O arrayx2.c¡A¥i±N¿é¤J¤Gºû¯x°}¡]¥i¯à¥]§t¹ê³¡©Mµê³¡¡^­¼¥H 2¡A¨ä¤º®e¦p¤U¡G

­ì©lÀÉ¡]03-À³¥Îµ{¦¡¤¶­±/arrayx2.c¡^¡G¡]¦Ç¦â°Ï°ì«ö¨â¤U§Y¥i«þ¨©¡^
/* ¦¹¨ç¦¡¬° MATLAB ªº MEX ÀɮסA¨ä¿é¤J¬°¤@­Ó¦V¶q¡A¿é¥X«h¬°2­¼¥H¦¹¦V¶q¡C */

#include "mex.h"	/* mex.h ¥]§t mxArray µ²ºcªº©w¸q¡A¥H¤Î¨ä¥L¬ÛÃö¸ê°T */

/* prhs = pointer to the right-hand-side arguments¡A§Y«ü¦V¿é¤JÅܼƦCªº«ü¼Ð */
/* prls = pointer to the  left-hand-side arguments¡A§Y«ü¦V¿é¥XÅܼƦCªº«ü¼Ð */
#define IN  prhs[0]	/* ©w¸q IN  ¬°¦¹¨ç¦¡ªº²Ä¤@­Ó¿é¤JÅܼơA¥H«K«áÄò¨ú¥Î */
#define OUT plhs[0]	/* ©w¸q OUT ¬°¦¹¨ç¦¡ªº²Ä¤@­Ó¿é¥XÅܼơA¥H«K«áÄò¨ú¥Î */

/* ¦¹¨ç¦¡ªº¥\¯à¬°±N¦V¶q x ªº¨C¤@­Ó¤¸¯À­¼¥H2¡A¦A±Nµ²ªG°e¨ì y ¦V¶q¡C */
/* ¦¹¨ç¦¡±N·|³Q mexFunction ©Ò©I¥s¡C */
void timestwo(double y[], double x[], int length) {
	int i;
	for (i=0; i<length; i++)
		y[i] = 2.0*x[i];
}

/* ¦¹¨ç¦¡¬°©M MATLAB ·¾³qªº¥D­n¨ç¦¡ */
void mexFunction( int nlhs, mxArray *plhs[],
                  int nrhs, const mxArray *prhs[] ) {
	double *xr, *xi, *yr, *yi;
	int length = mxGetM(IN)*mxGetN(IN);
  
	/* Àˬd¿é¥X©M¿é¤JÅܼƭӼƬO§_³£¬O1¡A¨ä¤¤		  */
	/* nrhs = no. of right-hand-side arguments¡]¿é¤JÅܼƭӼơ^*/
	/* nlhs = no. of  left-hand-side arguments¡]¿é¥XÅܼƭӼơ^*/
	if(nrhs!=1)	/* Àˬd¿é¤JÅܼƭӼƬO§_¬O1 */
		mexErrMsgTxt("One input required.");
	if(nlhs>1)	/* Àˬd¿é¥XÅܼƭӼƬO§_¬O1 */
		mexErrMsgTxt("Too many output arguments");
  
	/* Àˬd¿é¤JÅܼƬO§_¦X®æ */
	if(!mxIsDouble(IN))		/* Àˬd¿é¤JÅܼƬO§_¬° double */
		mexErrMsgTxt("Input must be a double.");
  
	/* °t¸m°O¾ÐÅéµ¹¿é¥XÅÜ¼Æ */
	OUT = mxCreateDoubleMatrix(mxGetM(IN), mxGetN(IN), mxCOMPLEX);
  
	/* ¨ú±o¿é¤J©M¿é¥XÅܼƪº¹ê³¡«ü¼Ð */
	xr = mxGetPr(IN);
	yr = mxGetPr(OUT);
	/* ¨ú±o¿é¤J©M¿é¥XÅܼƪºµê³¡«ü¼Ð */
	if (mxIsComplex(IN)) {
		xi = mxGetPi(IN);
		yi = mxGetPi(OUT);
	}
  
	/* °õ¦æ¹ê»Úªº¹Bºâ¡G±N¿é¤J¦V¶qªº¹ê³¡­¼¥H2 */
	timestwo(yr, xr, length);
	/* °õ¦æ¹ê»Úªº¹Bºâ¡G±N¿é¤J¦V¶qªºµê³¡­¼¥H2 */
	if (mxIsComplex(IN))
		timestwo(yi, xi, length);
}

Hint
¥Ñ©ó©Ò¦³ªº°}¦C¦b MATLAB ¤º³¡³£ªí¥Ü¦¨¤@­Óªø¦V¶q¡]¨Ò¦p¡A¹ï¤G¬°¯x°}¨Ó»¡¡A´N¬O¤@­Ó¥Ñ¦U­Ó¦æ¦V¶q©Ò¦ê±µ¦Ó¦¨ªºªø¦V¶q¡^¡A¦]¦¹¦b¤W­z½d¨Ò¤¤¡A§Ú­Ì¥i¥Ñ length = mxGetM(IN)*mxGetN(IN) ¨Ó¨ú±o¦¹ªø¦V¶qªºªø«×¡C

±µµÛ¡A§Ú­Ì¥i¥H½sĶ¥H¤Wµ{¦¡¡G

>> mex arrayx2.c

±ý½T»{¥i°õ¦æÀɪº¦s¦b¡A¥i¿é¤J¦p¤U¡G

>> which arrayx2 D:\matlabBook\MATLABµ{¦¡³]­p¡G¶i¶¥½g\03-À³¥Îµ{¦¡¤¶­±\arrayx2.mexw64

±ý¶i¦æ´ú¸Õ¡A¥i¿é¤J¦p¤U¡G

>> arrayx2([1 2 3]) ans = 2 4 6 >> arrayx2([1+i 2+2i 3+3i; 4 5 6]) ans = 2.0000 + 2.0000i 4.0000 + 4.0000i 6.0000 + 6.0000i 8.0000 10.0000 12.0000 >> arrayx2('Test string') ??? Input must be a double. ¥»¸`ªº²Ä¤G­Ó MEX ½d¨Ò¬O pairdist.c¡]ÀɦW¬°¡upairwise distance¡vªºÂ²ºÙ¡^¡A¥i±µ¨ü¨â­Ó¿é¤J¯x°} A ©M B¡A¯x°}ªº¤j¤p¤À§O¬O p¡Ñm ¤Î p¡Ñn¡A¦¹¨â­Ó¯x°}¤À§O¥Nªí¥Ñ m ­Óª½¦æ¦V¶q¤Î n ­Óª½¦æ¦V¶q©Ò§Î¦¨ªº¶°¦X¡A¦Ó¨C¤@­Ó¦V¶qªºªø«×³£¬O p¡C¦¹ MEX Àɮ׶Ǧ^¤@­Ó¶ZÂ÷¯x°} C¡A¨ä¤¤ C(i, j)¬°¦V¶q A(:, i) ©M¦V¶q B(:, j) ªº¯xÂ÷¡C

Hint
¹ï©ó¤j¶q¸ê®Æªº³B²z¡A¤@¯ëªººD¨Ò³£¬O±N¦U­Ó¦V¶q¥Hª½¦æ¦V¶qªº¤è¦¡°ï¦¨¤@­Ó¯x°}¡A¦A¶i¦æ¦UºØ³B²z¡C

pairdist.c ªºµ{¦¡½X¦p¤U¡G

­ì©lÀÉ¡]03-À³¥Îµ{¦¡¤¶­±/pairdist.c¡^¡G¡]¦Ç¦â°Ï°ì«ö¨â¤U§Y¥i«þ¨©¡^
#include <math.h>
#include "mex.h"	/* mex.h ¥]§t mxArray µ²ºcªº©w¸q¡A¥H¤Î¨ä¥L¬ÛÃö¸ê°T */

/* prhs = pointer to the right-hand-side arguments¡A§Y«ü¦V¿é¤JÅܼƦCªº«ü¼Ð */
/* prls = pointer to the  left-hand-side arguments¡A§Y«ü¦V¿é¥XÅܼƦCªº«ü¼Ð */
#define	MAT1 prhs[0]	/* ©w¸q MAT1 ¬°¦¹¨ç¼Æªº²Ä¤@­Ó¿é¤JÅܼơA¥H«K«áÄò¨ú¥Î */
#define	MAT2 prhs[1]	/* ©w¸q MAT1 ¬°¦¹¨ç¼Æªº²Ä¤G­Ó¿é¤JÅܼơA¥H«K«áÄò¨ú¥Î */
#define	OUT  plhs[0]	/* ©w¸q OUT  ¬°¦¹¨ç¼Æªº²Ä¤@­Ó¿é¥XÅܼơA¥H«K«áÄò¨ú¥Î */

/* ¦¹¨ç¼Æ¬°©M MATLAB ·¾³qªº¥D­n¨ç¼Æ */
void mexFunction(
	int nlhs,	mxArray *plhs[],
	int nrhs, const mxArray *prhs[]) {
	double	*out, *mat1, *mat2, squareSum;
	int m, p, n, p2, i, j, k;

	/* Àˬd¿é¥XÅܼƭӼƬO§_¬°2¡B¿é¤JÅܼƭӼƬO§_¬°1¡A¨ä¤¤	  */
	/* nrhs = no. of right-hand-side arguments¡]¿é¤JÅܼƭӼơ^*/
	/* nlhs = no. of  left-hand-side arguments¡]¿é¥XÅܼƭӼơ^*/
	if (nrhs!=2)
		mexErrMsgTxt("PAIRDIST requires two input arguments.");

	/* Àˬdºû«×¬O§_²Å¦X­n¨D */
	p  = mxGetM(MAT1);
	m  = mxGetN(MAT1);
	p2  = mxGetM(MAT2);
	n = mxGetN(MAT2);
	if (p != p2)
		mexErrMsgTxt("Matrix sizes mismatch!");

	/* Àˬd¿é¤JÅÜ¼Æ¸ê®Æ«¬ºA¬O§_²Å¦X­n¨D */
	if (!mxIsNumeric(MAT1) || mxIsSparse(MAT1)  || !mxIsDouble(MAT1))
		mexErrMsgTxt("Input 1 is not a full numerical array!");
	if (!mxIsNumeric(MAT2) || mxIsSparse(MAT2)  || !mxIsDouble(MAT2))
		mexErrMsgTxt("Input 2 is not a full numerical array!");

	/* °t¸m°O¾ÐÅéµ¹¿é¥XÅÜ¼Æ */
	OUT = mxCreateDoubleMatrix(m, n, mxREAL);

	/* ¨ú±o¿é¤J©M¿é¥XÅܼƪº¹ê³¡«ü¼Ð */
	out = mxGetPr(OUT);
	mat1 = mxGetPr(MAT1);
	mat2 = mxGetPr(MAT2);

	/* ¹ê»Ú­pºâ³¡¥÷ */
	/* MAT1(i+1, j+1) ªº­È¬O mat1[j*m+i] */
	/* MAT2(i+1, j+1) ªº­È¬O mat2[j*n+i] */
	/*  OUT(i+1, j+1) ªº­È¬O  out[j*m+i] */

	for (i=0; i<m; i++)
		for (j=0; j<n; j++) {
			squareSum = 0;
			for (k=0; k<p; k++)
				squareSum += pow(mat1[i*p+k]-mat2[j*p+k], 2.0);
			out[j*m+i] = sqrt(squareSum);
		}
}

Hint
  • ¦b¤W­z½d¨Ò¤¤¡A½Ð¯S§Oª`·N¯x°}ªº¯Á¤Þ¡A­Y¨Ï¥Î 0-based indexing¡A«h MATLAB ¯x°} OUT(i+1, j+1) ©Ò¹ïÀ³ªº¤¸¯À­È¬O out[j*m+i]¡C
  • ¦]¬°¶ZÂ÷¯x°}¬O¹ïºÙªº¡A¦]¦¹­Y¦Ò¼{­pºâ®Ä¯à¡A¹ï¨¤½u¥H¤Uªº¤¸¯À¥i¥Hª½±µ«þ¨©¹ï¨¤½u¥H¤Wªº¤¸¯À¡A¦Ó¤£¥²­«ºâ¤@¹M¡C

±µµÛ¡A§Ú­Ì¥i¥H¹ï¥H¤Wµ{¦¡¶i¦æ½sĶ¡G

>> mex pairdist.c ½sͧ¹¦¹µ{¦¡«á¡A¥i´ú¸Õ¦p¤U¡G >> which pairdist D:\matlabBook\MATLABµ{¦¡³]­p¡G¶i¶¥½g\03-À³¥Îµ{¦¡¤¶­±\pairdist.mexw64 >> pairdist([2 3], [2 3 4]) ans = 0 1 2 1 0 1 >> A = rand(2, 3); >> B = rand(2, 4); >> C = pairdist(A, B) C = 0.5104 0.9806 0.4544 0.5649 0.3562 0.2347 0.5911 0.2628 0.2101 0.5891 0.2675 0.1639 >> pairdist('string1', 'string2') ??? Input 1 is not a full numerical array! ¥»¸`©Ò¤¶²Ðªº½d¨Ò¡A§¡¬O¹ï¤Gºû¯x°}¶i¦æ³B²z¡A¨ä¥¦§ó½ÆÂøªº½d¨Ò¡A¥i¨£ MATLAB API ªº¬ÛÃö¤â¥U¡C
MATLABµ{¦¡³]­p¡G¶i¶¥½g