Matlab混合编程

混合编程目的

在Matlab中采用混合编程目的主要包括

  1. 利用已有的函数库,避免重复工作
  2. 加速计算,特别是减少循环所用时间
  3. 利用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[])

其中包含四个参数,其中nlhsnrhs分别是输出参数与输入参数个数(Num of arguments on Left/Right Hand Side),plhsprhs则是输入参数指针数组,mxArray为 Matlab 中数据结构体,其声明包含在头文件mex.h内。

1.2.mex函数参数调用

传入mex函数的参数都保存在mxArray结构体数组内,在使用参数进行计算时,需首先将其转换为C语言对应类型。

常用几个获得参数函数包括:

double mxGetScalar(const mxArray *pm);
double *mxGetPr(const mxArray *pm);

其中pm为对应mxArray类型的输入参数指针,如prhs[0]等。

  1. mxGetScalar

    获取标量参数;
  2. mxGetPr

    获取向量/矩阵参数;

在使用mxGetPrmxGetScalar函数获得输入参数对应的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实际是一个包含多个矩阵信息的结构体,函数mxGetMmxGetNmxGetPr等分别返回结构体包含的对应元素。


1.3.mex函数返回参数

mex返回参数个数一般是确定的,可以用如下语句进行判断

if (nlhs != 2)
mexErrMsgTxt("Wrong number of output arguments");

在对输出变量元素进行操作之前,需要首先为其申请内存

mxArray *mxCreateDoubleMatrix(mwSize m, mwSize n, mxComplexity ComplexFlag);

其中m和n为矩阵大小,ComplexFlag为元素类型,包括mxREALmxCOMPLEX,前者代表申请大小为[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混合编程的更多相关文章

  1. C++和MATLAB混合编程-DLL

    先小话一下DLL,DLL是动态链接库,是源代码编译后的二进制库文件和程序接口,和静态链接库不同的是,程序在编译时并不链接动态链接库的执行体,而是在文件中保留一个调用标记,在程序运行时才将动态链接库文件 ...

  2. java matlab混合编程之返回值Struct类型

    java matlab混合编程的时候当返回值是Struct类型(matlab中的返回类型)如何来取得(java中)其值? 上网找,看到这个网页:http://www.mathworks.cn/cn/h ...

  3. WPF(C#)与MATLAB混合编程

    WPF(C#)与MATLAB混合编程 WPF可以为开发者提供便捷地构建用户交互界面的解决方法,而matlab则在科学计算方面有着无与伦比的优势,因此在一些需要将科学算法转换为应用软件的项目中,需要应用 ...

  4. VC 与Matlab混合编程之引擎操作详解

    Visual C++ 是当前主流的应用程序开发环境之一,开发环境强大,开发的程序执行速度快.但在科学计算方面函数库显得不够丰富.读取.显示数据图形不方便. Matlab 是一款将数值分析.矩阵计算.信 ...

  5. VS/Qt C++和Matlab混合编程

    最近两天在搞C++和Matlab混合编程,这个中间过程真是让人心酸啊,最后还是搞定成功!现在把这个过程记录一下. 首先自己的电脑本来就安装着matlab2013b,按着网上的说法首先需要输入!mcc, ...

  6. C++和MATLAB混合编程求解多项式系数(矩阵相除)

    摘要:MATLAB对于矩阵处理是非常高效的,而C++对于矩阵操作是非常麻烦的,因而可以采用C++与MATLAB混合编程求解矩阵问题. 主要思路就是,在MATLAB中编写函数脚本并使用C++编译为dll ...

  7. matlab混合编程向导(vc,vb,.net...)

    一.matlab与vc混编  1.通过mcc将matlab的m文件转化为cpp,c文件或dll供vc调用:     这方面的实现推荐精华区Zosco和ljw总结的方法(x-6-1-4-3-1和2)  ...

  8. C#Matlab混合编程类 初始化问题解决方法

    ************** 异常文本 ************** System.TypeInitializationException: “myPlus.matClass”的类型初始值设定项引发异 ...

  9. 国内第一部C#.Net调用Matlab混合编程视频教程

       本博客所有文章分类的总目录:[总目录]本博客博文总目录-实时更新 Matlab和C#混合编程文章目录:[目录]Matlab和C#混合编程文章目录 一.视频说明 2014年的5.1,我将这套视频教 ...

随机推荐

  1. JVM:类加载与字节码技术-1

    JVM:类加载与字节码技术-1 说明:这是看了 bilibili 上 黑马程序员 的课程 JVM完整教程 后做的笔记 内容 类文件结构 字节码指令 下面的内容在后续笔记中: 编译期处理 类加载阶段 类 ...

  2. OO前三次作业思考(第一次OO——Blog)

    OO前三次作业总结 基于度量分析程序结构 由于三次作业较多,决定分析内容.功能最为复杂的第三次作业. 上图为第三次作业的类图.我使用了一个抽象类Factor,写了五个因子继承Factor,然后又单独开 ...

  3. spring cloud ribbon的使用

    上节我们学会了如何搭建一个eureka server服务,本节我们使用ribbon来实现服务间的调用. 前置条件: 1.创建几个工程 eureka-server             |- 服务注册 ...

  4. 主集天线和分集天线——4G天线技术

    主集天线和分集天线 分集接收技术是一项主要的抗衰落技术,可以大大提高多径衰落信道传输下的可靠性,在实际的移动通信系统中,移动台常常工作在城市建筑群或其他复杂的地理环境中,而且移动的速度和方向是任意的. ...

  5. (转载)linux chmod命令用法

    chmod----改变一个或多个文件的存取模式(mode) chmod [options] mode files   只能文件属主或特权用户才能使用该功能来改变文件存取模式.mode可以是数字形式(八 ...

  6. 第K个数 牛客网 程序员面试金典 C++ Python

    第K个数 牛客网 程序员面试金典 C++ Python 题目描述 有一些数的素因子只有3.5.7,请设计一个算法,找出其中的第k个数. 给定一个数int k,请返回第k个数.保证k小于等于100. 测 ...

  7. Codeforces Global Round 16题解

    E. Buds Re-hanging 对于这个题该开始还是没想法的,但这显然是个思维题,还是要多多动手推样例,实践一下. 简化题意:给定一个有根树,规定某个点为树干,当且仅当这个点不是根,且这个点至少 ...

  8. JAVA笔记15__TCP服务端、客户端程序 / ECHO程序 /

    /** * TCP:传输控制协议,采用三方握手的方式,保证准确的连接操作. * UDP:数据报协议,发送数据报,例如:手机短信或者是QQ消息. */ /** * TCP服务器端程序 */ public ...

  9. HCNP Routing&Switching之BGP路由控制

    前文我们了解了BGP的路由属性和优选规则相关话题,回顾请参考https://www.cnblogs.com/qiuhom-1874/p/15489497.html:今天我们来聊一聊BGP路由控制相关话 ...

  10. v-bind使用

    v-bind基本使用 动态地绑定一个或多个属性,或者绑定一个组件 prop 到表达式. 语法:v-bind:属性名 = 属性值 <!-- 绑定一个 attribute --> <im ...