没有合适的资源?快使用搜索试试~ 我知道了~
资源推荐
资源详情
资源评论
Writing MATLAB C/MEX Code
®
Pascal Getreuer, April 2010
Contents
Page
1 Introduction 1
2 Getting Started 2
3 Inputs and Outputs 3
4 Numeric Arrays 5
5 Creating an Uninitialized Numeric Array 8
6 Calling a MATLAB function from MEX 9
7 Calling a MATLAB function handle from MEX 11
8 Calling MATLAB from a non-MEX Program 14
9 Memory 15
10 Non-Numeric Variables 19
11 FFTs with FFTW 23
12 Miscellaneous 27
13 Further Reading 28
1
Introduction
It is possible to compile C, C++, or Fortran code so that it is callable from Matlab. This kind of
program is called a Matlab Executable (MEX) external interface function, or more briefly a “MEX-
function.” MEX enables the high performance of C, C++, and Fortran while working within the
Matlab environment. We will discuss C/MEX functions, which also applies directly to C++/MEX.
Fortran/MEX is quite different and we do not discuss it here.
Warning This is not a beginner’s tutorial to Matlab. Familiarity with C
and Matlab is assumed. Use at your own risk.
MEX
the spooky beast
Matlab
C
C
++
Fortran
MEX is often more trouble than it is worth. Matlab’s JIT interpreter in recent versions runs M-
code so efficiently that it is often times difficult to do much better with C. Before turning to MEX
in an application, optimize your M-code (see my other article, “Writing Fast Matlab Code”). MEX-
functions are best suited to substitute one or two bottleneck M-functions in an application. If you
replace all functions in an application with MEX, you might as well port the application entirely to C.
1
2
Getting Started
The following program demonstrates the basic structure of a MEX-function.
hello.c
#include "mex.h" /
*
Always include this
*
/
void mexFunction(int nlhs, mxArray
*
plhs[], /
*
Output variables
*
/
int nrhs, const mxArray
*
prhs[]) /
*
Input variables
*
/
{
mexPrintf("Hello, world!\n"); /
*
Do something interesting
*
/
return;
}
Copy the code into Matlab’s editor (it has a C mode) or into the C editor of your choice, and save it
as hello.c.
The next step is to compile. On the Matlab console, compile hello.c by entering the command
>> mex hello.c
If successful, this command produces a compiled file called hello.mexa64 (or similar, depending on
platform). Compiling requires that you have a C compiler and that Matlab is configured to use it.
Matlab will autodetect most popular compilers, including Microsoft Visual C/C++ and GCC. As a
fallback, some distributions of Matlab come with the Lcc C compiler. Run mex -setup to change the
selected compiler and build settings.
Once the MEX-function is compiled, we can call it from Matlab just like any M-file function:
>> hello
Hello, world!
Note that compiled MEX files might not be compatible between different platforms or different versions
of Matlab. They should be compiled for each platform/version combination that you need. It is
possible to compile a MEX file for a target platform other than the host’s using the -<arch> option,
for example, mex -win32 hello.c.
Matlab comes with examples of MEX in matlab/extern/examples. For detailed reference, also see
matrix.h and the other files in matlab/extern/include.
2
3
Inputs and Outputs
Of course, a function like hello.c with no inputs or outputs is not very useful. To understand inputs
and outputs, let’s take a closer look at the line
void mexFunction(int nlhs, mxArray
*
plhs[], int nrhs, const mxArray
*
prhs[])
Here “mxArray” is a type for representing a Matlab variable, and the arguments are:
C/MEX Meaning M-code equivalent
nlhs Number of output variables nargout
plhs Array of mxArray pointers to the output variables varargout
nrhs Number of input variables nargin
prhs Array of mxArray pointers to the input variables varargin
These MEX variables are analogous to the M-code variables nargout, varargout, nargin, and varargin.
The naming “lhs” is an abbreviation for left-hand side (output variables) and “rhs” is an abbreviation
for right-hand side (input variables).
For example, suppose the MEX-function is called as
[X,Y] = mymexfun(A,B,C)
Then nlhs = 2 and plhs[0] and plhs[1] are pointers (type mxArray*) pointing respectively to X and Y.
Similarly, the inputs are given by rlhs = 3 with prhs[0], prhs[1], and prhs[2] pointing respectively
to A, B, and C.
The output variables are initially unassigned; it is the responsibility of the MEX-function to create
them. If nlhs = 0, the MEX-function is still allowed return one output variable, in which case plhs[0]
represents the ans variable.
The following code demonstrates a MEX-function with inputs and outputs.
normalizecols.c
/
*
NORMALIZECOLS.C Normalize the columns of a matrix
Syntax: B = normalizecols(A)
or B = normalizecols(A,p)
The columns of matrix A are normalized so that norm(B(:,n),p) = 1.
*
/
#include <math.h>
#include "mex.h"
#define IS REAL 2D FULL DOUBLE(P) (!mxIsComplex(P) && \
mxGetNumberOfDimensions(P) == 2 && !mxIsSparse(P) && mxIsDouble(P))
#define IS REAL SCALAR(P) (IS REAL 2D FULL DOUBLE(P) && mxGetNumberOfElements(P) == 1)
void mexFunction(int nlhs, mxArray
*
plhs[], int nrhs, const mxArray
*
prhs[])
{
/
*
Macros for the ouput and input arguments
*
/
#define B OUT plhs[0]
3
array的维度是大于等于2的,标量的维度也是2
#define A IN prhs[0]
#define P IN prhs[1]
double
*
B,
*
A, p, colnorm;
int M, N, m, n;
if(nrhs < 1 | | nrhs > 2) /
*
Check the number of arguments
*
/
mexErrMsgTxt("Wrong number of input arguments.");
else if(nlhs > 1)
mexErrMsgTxt("Too many output arguments.");
if(!IS REAL 2D FULL DOUBLE(A IN)) /
*
Check A
*
/
mexErrMsgTxt("A must be a real 2D full double array.");
if(nrhs == 1) /
*
If p is unspecified, set it to a default value
*
/
p = 2.0;
else /
*
If P was specified, check that it is a real double scalar
*
/
if(!IS REAL SCALAR(P IN))
mexErrMsgTxt("P must be a real double scalar.");
else
p = mxGetScalar(P
IN); /
*
Get p
*
/
M = mxGetM(A IN); /
*
Get the dimensions of A
*
/
N = mxGetN(A IN);
A = mxGetPr(A IN); /
*
Get the pointer to the data of A
*
/
B OUT = mxCreateDoubleMatrix(M, N, mxREAL); /
*
Create the output matrix
*
/
B = mxGetPr(B OUT); /
*
Get the pointer to the data of B
*
/
for(n = 0; n < N; n++) /
*
Compute a matrix with normalized columns
*
/
{
for(m = 0, colnorm = 0.0; m < M; m++) colnorm += pow(A[m + M
*
n], p);
colnorm = pow(fabs(colnorm),1.0/p); /
*
Compute the norm of the nth column
*
/
for(m = 0; m < M; m++) B[m + M
*
n] = A[m + M
*
n]/colnorm;
}
return;
}
Much of the code is spent verifying the inputs. MEX provides the following functions to check datatype,
dimensions, and so on:
C/MEX Meaning M-code equivalent
mxIsDouble(A IN) True for a double array isa(A,'double')
mxIsComplex(A IN) True if array is complex ∼isreal(A)
mxIsSparse(A IN) True if array is sparse issparse(A)
mxGetNumberOfDimensions(A IN) Number of array dimensions ndims(A)
mxGetNumberOfElements(A IN) Number of array elements numel(A)
The normalizecols.c example simplifies input parsing by combining some of these checks into a
macro IS REAL 2D FULL DOUBLE. Notice how we check nrhs==1 to see if the function was called as
normalizedcols(A) or normalizedcols(A,p).
Another approach to input parsing is to rename this MEX-function as “normalizecolsmx.c” and create
an M-function wrapper:
4
剩余28页未读,继续阅读
资源评论
u010873869
- 粉丝: 5
- 资源: 13
上传资源 快速赚钱
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
最新资源
- (源码)基于Spring Boot和Vue的高性能售票系统.zip
- (源码)基于Windows API的USB设备通信系统.zip
- (源码)基于Spring Boot框架的进销存管理系统.zip
- (源码)基于Java和JavaFX的学生管理系统.zip
- (源码)基于C语言和Easyx库的内存分配模拟系统.zip
- (源码)基于WPF和EdgeTTS的桌宠插件系统.zip
- (源码)基于PonyText的文本排版与预处理系统.zip
- joi_240913_8.8.0_73327_share-2EM46K.apk
- Library-rl78g15-fpb-1.2.1.zip
- llvm-17.0.1.202406-rl78-elf.zip
资源上传下载、课程学习等过程中有任何疑问或建议,欢迎提出宝贵意见哦~我们会及时处理!
点击此处反馈
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功