调用matlab算法,在外部调用Matlab引擎实现数学计算

1. 调用MATLAB的方法

Matlab是强大的数学工具,有些时候我们需要自己解一些题,但又不想自己写算法的时候,就可以使用Matlab提供的外部调用功能,也就是说你的程序只需要编写其他部分,而计算交给Matlab实现。

实现外部调用有三种方法:

1.

在C或者Fortran语言中调用(本文介绍)

2.

与Matlab通讯

在UNIX下使用管道(pipe),在Windows下使用COM和DDE方式

3.

使用WebService接口

如果希望在更大的范围内进行数据交换和计算,比如Internet,可以使用这个接口

本文只介绍第一种方法,如果有人对后两者感兴趣,或者哪天我有空再对后面的两种做介绍。“C或者Fortran语言中调用MATLAB”又称为使用MATLAB引擎,在Matlab的使用手册中,详细的解释了如何使用这个功能。

2. 工作原理

工作流程如下图所示:

a4c26d1e5885305701be709a3d33442f.png

Matlab提供了一组C和Fortran的接口函数,我们简单看一下C的接口函数:

C Engine Routines

Function

Purpose

Start up

MATLAB engine

Shut

down MATLAB engine

Get a

MATLAB array from the MATLAB engine

Send a

MATLAB array to the MATLAB engine

Execute

a MATLAB command

Create a

buffer to store MATLAB text output

Start a

MATLAB engine session for single, nonshared use

Determine visibility of

MATLAB engine session

Show or

hide MATLAB engine session

很简单明确的接口吧,一看名字就基本上猜出来用法了。详细使用请看MATLAB的参考手册,如果有需要帮助的可以告诉我。

3. 简单的例子

我们假设需要做如下的运算:

A =

pascal(3);

B = magic(3);

X = A + B

pascal(n)是产生n大小的pascal方阵,在我国一般称为杨辉三角形。

magic(n)产生n大小的幻方,也就是横竖对角线相加的数是相等的。

最后一句话是两个Matrix相加。

在MATLAB中的结果如下:

>> A = pascal(3)

A =

1 1 1

1 2 3

1 3 6

>> B = magic(3)

B =

8 1 6

3 5 7

4 9 2

>> X = A + B

X =

9 2 7

4 7 10

5 12 8

假设我们要自己写代码实现上面的运算。我在WindowsXP(SP2), MATLAB6.5,

VC7.0下实现。具体的步骤是:

1). 设置环境变量PATH

PATH里面要包括MATLAB的exe, dll那个路径 %MATLAB_PATH%\bin\win32

2). 设置VC的路径

运行VC

include增加MATLAB的include路径 %MATLAB_PATH%\extern\include

lib增加%MATLAB_PATH%\extern\lib\win32\microsoft\msvc70

3).

在VC中新建一个console项目(也可以是win32,mfc等其他项目),项目的link输入增加libeng.lib和libmx.lib

4). main函数的代码:

#include

#include

#include

void

print_matrix_2d(mxArray * matrix, const char * matrix_name)

{

//Get the

datatype name of the matrix

const char *

name = mxGetClassName(matrix);

//Get the

data, that is double in this example

double* k =

(double*)mxGetPr(matrix);

//get row and column dimention

int row =

mxGetM(matrix);

int col =

mxGetN(matrix);

//print the matrix

printf("%s =

\n", matrix_name);

for(int i =

0; i < row; i++) {

printf(" ");

for(int j = 0; j < col; j++)

printf("%d ", (int)(*(k + i * col +

j)));

printf("\n");

}

}

int

main(int argc, char * argv[])

{

Engine

*ep;

mxArray *A =

NULL, *B = NULL, *X = NULL;

//Open the MATLAB Engine

if (!(ep =

engOpen("\0"))) {

fprintf(stderr, "\nCan't start MATLAB engine\n");

return EXIT_FAILURE;

}

//Run command in matlab

//A =

pascal(3); B = magic(3); X = A + B;

engEvalString(ep, "A = pascal(3)");

engEvalString(ep, "B = magic(3)");

engEvalString(ep, "X = A + B");

//Get results

A =

engGetVariable(ep, "A");

B =

engGetVariable(ep, "B");

X =

engGetVariable(ep, "X");

//print matrix

print_matrix_2d(A, "A");

print_matrix_2d(B, "B");

print_matrix_2d(X, "X");

printf("Done!\n");

//release results

mxDestroyArray(X);

mxDestroyArray(B);

mxDestroyArray(A);

//close MATLAB Engine

engClose(ep);

return

EXIT_SUCCESS;

}

上面的代码很简单,看一下其中的注释参考一下MATLAB的文档就可以理解了。至于为什么要把哪个指针写成(int)(*(k

+ i * col +

j)),是因为在C++里做的,C++对指针类型检查比较严格,而且虽然返回的是double,但实际上我们知道,这个例子中是integer的数据类型。这个还有其他写法,不过这不是我们现在的讨论重点。

5). 运行结果:

A

=

1 1 1

1 2 3

1 3 6

B =

8 3 4

1 5 9

6 7 2

X =

9 4 5

2 7 12

7 10 8

Done!

运行的时候开始会比较慢,这是因为在打开MATLAB引擎,这将会造成一些系统的开销,但是计算的时候会很快。

MATLAB支持窗体式的调用,这意味着你甚至可以重新写一个跟MATLAB界面完全不同的界面。另外,在UNIX系统下,MATLAB可以不在同一台机器上,他有一种方法可以允许调用在不同主机上的MATLAB,这暗示着你可以搭建一个MATLAB服务器。

详细情况请参考MATLAB的文档。

(这个例子比较简单,如果有任何错误或者问题,请给我留言......不知道有没有人看呢还,哈哈)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值