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,我将这套视频教 ...
随机推荐
- C# 如何使用代码添加控件及控件事件
1.首先简单设计一下界面: 添加了Click事件 <Window x:Class="WpfApp.MainWindow" xmlns="http://schemas ...
- [no_code][Beta]项目展示博客
$( "#cnblogs_post_body" ).catalog() 团队项目链接 Beta阶段核心开发点: github 前端 github 后端 github OCR文档-含 ...
- [no_code][Alpha]测试报告
项目 内容 2020春季计算机学院软件工程(罗杰 任健) 2020春季计算机学院软件工程(罗杰 任健) 作业要求 测试报告 我们在这个课程的目标是 设计出一个OCR表单处理软件 这个作业在哪个具体方面 ...
- 使用nexus搭建一个docker私服
使用nexus搭建docker私服 一.需求: 二.实现步骤 1.编写`docker-compose`文件,实现`nexus`的部署 2.修改/usr/lib/systemd/system/docke ...
- 热身训练1 Calculator
题目出处:Calculator 简要题意: 你有一个确定的函数,f(x)=+...*...^...,其中共有n个操作,从左到右依次计算. 共有m次询问,我们每次询问,1.会修改f(x)中的操作:2.输 ...
- 疯狂Java基础Day2
巩固Java流程控制的学习... 一.用户交互Scanner 通过Scanner类获取用户的输入 import java.util.Scanner; public class Demo1 { publ ...
- 转:(WIN)S04-CH01 PCIE XDMA开发环境搭建以及环路测试
摘要: 这一章开始主要介绍 XILINX FPGA PICE IP XDMA IP的使用.XDMA IP使用部分教程分LINUX 篇和WINDOWS篇两个部分.通过实战,面向应用,提供给大家 XILI ...
- AtCoder Beginner Contest 213 F题 题解
F - Common Prefixes 该题也是囤了好久的题目了,看题目公共前缀,再扫一眼题目,嗯求每个后缀与其他后缀的公共前缀的和,那不就是后缀数组吗?对于这类问题后缀数组可是相当在行的. 我们用后 ...
- 就因为把int改成Integer,第2天被辞了
本文节选自<设计模式就该这样学>之享元模式(Flyweight Pattern) 1 故事背景 一个程序员就因为改了生产环境上的一个方法参数,把int型改成了Integer类型,因为涉及到 ...
- 第35篇-方法调用指令之invokespecial与invokestatic
这一篇将详细介绍invokespecial和invokestatic字节码指令的汇编实现逻辑 1.invokespecial指令 invokespecial指令的模板定义如下: def(Bytecod ...