Matlab混合编程
Matlab混合编程
混合编程目的
在Matlab中采用混合编程目的主要包括
- 利用已有的函数库,避免重复工作
- 加速计算,特别是减少循环所用时间
- 利用GPU等进行异构编程
混合编程方法—mex函数
目前已有的方法包括两种:(1)将c/Fortran源程序改写为mex函数,然后编译为二进制文件进行调用;(2)将c/Fortran源程序编译为动态链接库然后进行调用。在这两种方法中,前者计算速度更快,更适合混合编程方法。
mex函数是一类特殊的c/Fortran函数接口,编译后的二进制文件可以被matlab直接调用。
1.1.mex函数声明
首先看下mex函数声明格式
void mexFunction (int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
其中包含四个参数,其中nlhs与nrhs分别是输出参数与输入参数个数(Num of arguments on Left/Right Hand Side),plhs与prhs则是输入参数指针数组,mxArray为 Matlab 中数据结构体,其声明包含在头文件mex.h内。
1.2.mex函数参数调用
传入mex函数的参数都保存在mxArray结构体数组内,在使用参数进行计算时,需首先将其转换为C语言对应类型。
常用几个获得参数函数包括:
double mxGetScalar(const mxArray *pm);
double *mxGetPr(const mxArray *pm);
其中pm为对应mxArray类型的输入参数指针,如prhs[0]等。
- mxGetScalar
获取标量参数; - mxGetPr
获取向量/矩阵参数;
在使用mxGetPr或mxGetScalar函数获得输入参数对应的double类型指针之后,我们便可以直接对参数的值进行相应操作。需要注意的是,在Matlab中数组是按照列优先进行排列的,即是说当我们采用double类型指针*p指向一个[m x n]大小的矩阵时,p(i,j)对应的元素应为
p[(i-1)+(j-1)*m]
另外,在C函数中一般需要将矩阵维度也作为参数传入,但是在mex函数中,结构体mxArray则包含了相应的矩阵维度信息,采用函数
size_t mxGetM(const mxArray *pm);
size_t mxGetN(const mxArray *pm);
可以分别获得矩阵行数与列数,减少参数个数。
Matlab中自定义类型mxArray实际是一个包含多个矩阵信息的结构体,函数mxGetM,mxGetN和mxGetPr等分别返回结构体包含的对应元素。
1.3.mex函数返回参数
mex返回参数个数一般是确定的,可以用如下语句进行判断
if (nlhs != 2)
mexErrMsgTxt("Wrong number of output arguments");
在对输出变量元素进行操作之前,需要首先为其申请内存
mxArray *mxCreateDoubleMatrix(mwSize m, mwSize n, mxComplexity ComplexFlag);
其中m和n为矩阵大小,ComplexFlag为元素类型,包括mxREAL与mxCOMPLEX,前者代表申请大小为[m x n]的实数矩阵,后者申请相同大小的复数矩阵。
在为输出参数申请内存完毕后,即可用mxGetPr函数来获取输出参数对应double类型指针,然后进行赋值操作。
示例
目标:使用混合编译的方法,在Matlab中调用 Polylib 函数库
1.采用mex函数
使用c添加mex接口函数
#include "mex.h"
void mexFunction (int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
{
double *p_c, *p_d;
double *p_a, *p_b;
int c_rows, c_cols;
int d_rows, d_cols;
int numEl;
int n;
mxAssert(nlhs==2 && nrhs==2, "Error: number of variables");
c_rows = mxGetM(prhs[0]);// get rows of c
c_cols = mxGetN(prhs[0]);// get cols of c
d_rows = mxGetM(prhs[1]);// get rows of d
d_cols = mxGetN(prhs[1]);// get cols of d
mxAssert(c_rows==d_rows && c_cols==d_cols, "Error: cols and rows");
// create output buffer
plhs[0] = mxCreateDoubleMatrix(c_rows, c_cols, mxREAL);
plhs[1] = mxCreateDoubleMatrix(c_rows, c_cols, mxREAL);
// get buffer pointers
p_a = (double*)mxGetData(plhs[0]);
p_b = (double*)mxGetData(plhs[1]);
p_c = (double*)mxGetData(prhs[0]);
p_d = (double*)mxGetData(prhs[1]);
// compute a = c + d; b = c - d;
numEl = c_rows*c_cols;
for (n = 0; n < numEl; n++)
{
p_a[n] = p_c[n] + p_d[n];
p_b[n] = p_c[n] - p_d[n];
}
}
2.采用动态链接库
使用gcc编译为动态链接库,使用Matlab写接口对应的函数
CC=gcc-4.6
target:
${CC} -c polylib.c
${CC} -shared -fPIC -o libpolylib.dyld polylib.o
在Matlab中查看动态库包含指令
>> loadlibrary('libpolylib.dyld');
>> list = libfunctions('libpolylib','-full')
list =
'[doublePtr, doublePtr, doublePtr] Dgj(doublePtr, doublePtr, doublePtr, int32, double, double)'
'[doublePtr, doublePtr, doublePtr] Dglj(doublePtr, doublePtr, doublePtr, int32, double, double)'
'[doublePtr, doublePtr, doublePtr] Dgrjm(doublePtr, doublePtr, doublePtr, int32, double, double)'
'[doublePtr, doublePtr, doublePtr] Dgrjp(doublePtr, doublePtr, doublePtr, int32, double, double)'
'[doublePtr, doublePtr, doublePtr] Imgj(doublePtr, doublePtr, doublePtr, int32, int32, double, double)'
'[doublePtr, doublePtr, doublePtr] Imglj(doublePtr, doublePtr, doublePtr, int32, int32, double, double)'
'[doublePtr, doublePtr, doublePtr] Imgrjm(doublePtr, doublePtr, doublePtr, int32, int32, double, double)'
'[doublePtr, doublePtr, doublePtr] Imgrjp(doublePtr, doublePtr, doublePtr, int32, int32, double, double)'
'[double, doublePtr] hgj(int32, double, doublePtr, int32, double, double)'
'[double, doublePtr] hglj(int32, double, doublePtr, int32, double, double)'
'[double, doublePtr] hgrjm(int32, double, doublePtr, int32, double, double)'
'[double, doublePtr] hgrjp(int32, double, doublePtr, int32, double, double)'
'[doublePtr, doublePtr] jacobd(int32, doublePtr, doublePtr, int32, double, double)'
'[doublePtr, doublePtr, doublePtr] jacobfd(int32, doublePtr, doublePtr, doublePtr, int32, double, double)'
'[doublePtr, doublePtr] zwgj(doublePtr, doublePtr, int32, double, double)'
'[doublePtr, doublePtr] zwglj(doublePtr, doublePtr, int32, double, double)'
'[doublePtr, doublePtr] zwgrjm(doublePtr, doublePtr, int32, double, double)'
'[doublePtr, doublePtr] zwgrjp(doublePtr, doublePtr, int32, double, double)'
想要调用的是zwgj函数,输入参数类型为(doublePtr, doublePtr, int32, double, double),注意Matlab中对应变量类型
| C Type | Equivalent Matlab Type |
|---|---|
| char,byte | int8 |
| unsigned char,byte | uint8 |
| short | int16 |
| unsigned short | uint16 |
| int | int32 |
| long(Windows) | int32,long |
| long(Linux) | int64,long |
| unsigned int | unit32 |
| unsigned long(Windows) | uint32,long |
| unsigned long (Linux) | uint64,long |
| float | single |
| double | double |
| char * | 1xn char array |
| *char[] | cell array of strings |
其中libfunctions函数显示的变量类型对应为
| C Pointer Type | Argument Data Type | Equivalent Matlab Type |
|---|---|---|
| double * | doublePtr | double |
| float * | singlePtr | single |
| integer pointer types (int *) | (u)int(size)Ptr | (u)int(size) |
| Matrix of signed bytes | int8Ptr | int8 |
| Null-terminated string passed by value | cstring | 1xn char array |
| Array of pointers to strings (or one **char) | stringPtrPtr | cell array of strings |
| enum | enumPtr | |
| type ** | Same as typePtr with an added Ptr (for example, double ** is doublePtrPtr) | lib.pointer object |
| void * | voidPtr | |
| void ** | voidPtrPtr | lib.pointer object |
| C-style structure | structure | MATLAB struct |
| mxArray * | MATLAB array | MATLAB array |
| mxArray ** | MATLAB arrayPtr | lib.pointer object |
对应的Matlab接口函数为
loadlibrary('libpolylib.dyld');
np = int32(5);
z = zeros(1,np); w = zeros(1,np);
[z, w] = calllib('libpolylib', 'zwgj', z, w,np,alpha,beta);
其中np转换为对应的int32类型变量
Matlab混合编程的更多相关文章
- C++和MATLAB混合编程-DLL
先小话一下DLL,DLL是动态链接库,是源代码编译后的二进制库文件和程序接口,和静态链接库不同的是,程序在编译时并不链接动态链接库的执行体,而是在文件中保留一个调用标记,在程序运行时才将动态链接库文件 ...
- java matlab混合编程之返回值Struct类型
java matlab混合编程的时候当返回值是Struct类型(matlab中的返回类型)如何来取得(java中)其值? 上网找,看到这个网页:http://www.mathworks.cn/cn/h ...
- WPF(C#)与MATLAB混合编程
WPF(C#)与MATLAB混合编程 WPF可以为开发者提供便捷地构建用户交互界面的解决方法,而matlab则在科学计算方面有着无与伦比的优势,因此在一些需要将科学算法转换为应用软件的项目中,需要应用 ...
- VC 与Matlab混合编程之引擎操作详解
Visual C++ 是当前主流的应用程序开发环境之一,开发环境强大,开发的程序执行速度快.但在科学计算方面函数库显得不够丰富.读取.显示数据图形不方便. Matlab 是一款将数值分析.矩阵计算.信 ...
- VS/Qt C++和Matlab混合编程
最近两天在搞C++和Matlab混合编程,这个中间过程真是让人心酸啊,最后还是搞定成功!现在把这个过程记录一下. 首先自己的电脑本来就安装着matlab2013b,按着网上的说法首先需要输入!mcc, ...
- C++和MATLAB混合编程求解多项式系数(矩阵相除)
摘要:MATLAB对于矩阵处理是非常高效的,而C++对于矩阵操作是非常麻烦的,因而可以采用C++与MATLAB混合编程求解矩阵问题. 主要思路就是,在MATLAB中编写函数脚本并使用C++编译为dll ...
- matlab混合编程向导(vc,vb,.net...)
一.matlab与vc混编 1.通过mcc将matlab的m文件转化为cpp,c文件或dll供vc调用: 这方面的实现推荐精华区Zosco和ljw总结的方法(x-6-1-4-3-1和2) ...
- C#Matlab混合编程类 初始化问题解决方法
************** 异常文本 ************** System.TypeInitializationException: “myPlus.matClass”的类型初始值设定项引发异 ...
- 国内第一部C#.Net调用Matlab混合编程视频教程
本博客所有文章分类的总目录:[总目录]本博客博文总目录-实时更新 Matlab和C#混合编程文章目录:[目录]Matlab和C#混合编程文章目录 一.视频说明 2014年的5.1,我将这套视频教 ...
随机推荐
- JVM:类加载与字节码技术-1
JVM:类加载与字节码技术-1 说明:这是看了 bilibili 上 黑马程序员 的课程 JVM完整教程 后做的笔记 内容 类文件结构 字节码指令 下面的内容在后续笔记中: 编译期处理 类加载阶段 类 ...
- OO前三次作业思考(第一次OO——Blog)
OO前三次作业总结 基于度量分析程序结构 由于三次作业较多,决定分析内容.功能最为复杂的第三次作业. 上图为第三次作业的类图.我使用了一个抽象类Factor,写了五个因子继承Factor,然后又单独开 ...
- spring cloud ribbon的使用
上节我们学会了如何搭建一个eureka server服务,本节我们使用ribbon来实现服务间的调用. 前置条件: 1.创建几个工程 eureka-server |- 服务注册 ...
- 主集天线和分集天线——4G天线技术
主集天线和分集天线 分集接收技术是一项主要的抗衰落技术,可以大大提高多径衰落信道传输下的可靠性,在实际的移动通信系统中,移动台常常工作在城市建筑群或其他复杂的地理环境中,而且移动的速度和方向是任意的. ...
- (转载)linux chmod命令用法
chmod----改变一个或多个文件的存取模式(mode) chmod [options] mode files 只能文件属主或特权用户才能使用该功能来改变文件存取模式.mode可以是数字形式(八 ...
- 第K个数 牛客网 程序员面试金典 C++ Python
第K个数 牛客网 程序员面试金典 C++ Python 题目描述 有一些数的素因子只有3.5.7,请设计一个算法,找出其中的第k个数. 给定一个数int k,请返回第k个数.保证k小于等于100. 测 ...
- Codeforces Global Round 16题解
E. Buds Re-hanging 对于这个题该开始还是没想法的,但这显然是个思维题,还是要多多动手推样例,实践一下. 简化题意:给定一个有根树,规定某个点为树干,当且仅当这个点不是根,且这个点至少 ...
- JAVA笔记15__TCP服务端、客户端程序 / ECHO程序 /
/** * TCP:传输控制协议,采用三方握手的方式,保证准确的连接操作. * UDP:数据报协议,发送数据报,例如:手机短信或者是QQ消息. */ /** * TCP服务器端程序 */ public ...
- HCNP Routing&Switching之BGP路由控制
前文我们了解了BGP的路由属性和优选规则相关话题,回顾请参考https://www.cnblogs.com/qiuhom-1874/p/15489497.html:今天我们来聊一聊BGP路由控制相关话 ...
- v-bind使用
v-bind基本使用 动态地绑定一个或多个属性,或者绑定一个组件 prop 到表达式. 语法:v-bind:属性名 = 属性值 <!-- 绑定一个 attribute --> <im ...