目录
10.1在Excel中使用MATLAB
Spreadsheet Link程序
- 通过这一程序,可以在Excel工作区和MATLAB工作区之间进行数据交换,也可以在Excel中调用MATLAB的算法
- 安装与启动
- 打开Excel2016
- 文件-选项-加载项-转到-浏览
- 进入目录E:\MATLAB\R2018A\toolbox\exlink,选择excllink.xlam
- 打勾确定返回,就可以在Excel中看到MATLAB的标志了
将Excel表格中的数据导出到MATLAB工作空间中
- 在Excel中选择要导出的变量,选择导出到MATLAB即可
从MATLAB工作空间导入数据到Excel表格中
- 单击要导入的起始单元格,选择导入到Excel,输入变量名即可
在Excel中调用MATLAB函数进行运算
- 在Excel中选要放数据的表单,单击“MATLAB Function Wizard”,选择对应函数即可
10.2MATLAB文件操作
文件打开与关闭
- 文件的打开
fid = fopen(fiename, permission)
其中fid为文件识别号,filename为待操作的文件名,permission是对文件的允许使用方式.
r 以只读方式打开一个文件
w 以写方式打开一个文件
a 在文件末尾添加数据
r+ 以读和写方式打开一个文件
- 文件的关闭
status = fclose(fid)
文本文件的读写
fscanf 用于读取文本文件内容
fprintf 用于将数据写入文本文件中
[A, count] = fscanf(fid, fmt, size)
count = fprint(fid, fmt, A)
其中A用于存放读写的数据,count返回成功读写的数据元素个数;参数fid为文件标识号,fmt用以控制读取的数据格式,size用于指定A的大小.fmt的格式如下表格所示:(%之后还可以加上数据宽度,例如%3d)
%d |
整数 |
%f | 小数形式的实数 |
%e |
科学计数法形式的实数 |
%c | 字符 |
%s | 字符串 |
size的取值为:n, inf, [m,n]
二进制文件的读写
fread用于读取二进制文件
fwrite用于将数据写入文件
[A, count] = fread(fid, szie, precision, skip)
count=fwrite(fid, A, precision)
其中,A用于存放读写的数据,count返回读写成功的数据个数.fid为文件识别号,size用于指定A的大小,precision指定读写数据的类型,skip指定按比例周期性的跳过一些数据(默认为0).
fid=fopen('模拟数据.dat','w');
x=linspace(0,2*pi,100);
y=exp(x).*sin(x);
count=fwrite(fid, [x; y], 'double');
fclose(fid);
数据文件定位
fseek函数,用于改变文件位置指针的位置
fseek(fid, offset, origin)
- 其中参数fid为文件标识号,offset表示位置指针相对移动的字节数;origin表示位置指针移动的参照位置.
- origin的取值如下:
'cof' 或 0 | 文件指针当前位置 |
'bof' 或 -1 | 文件的开始位置 |
'eof' 或 1 | 文件的结束位置 |
- ftell用于查询文件指针的当前位置
psition=ftell(fid)
返回值为从文件头到指针当前位置的字节数.若返回值为-1,表示获取文件当前位置失败.
- feof用于判断当前文件位置指针是否到达文件尾部
status=feof(fid)
到达文件结束位置时,返回值为1,否则为0
fid=fopen('模拟数据.dat','r');
status=fseek(fid, -40*2*8, 'eof');
x=[]; y=[];
while ~feof(fid)
x=[x; fread(fid,1,'double')];
y=[y; fread(fid,1,'double')];
end
plot(x,y);
fclose(fid);
10.3在其他语言中读写MATLAB数据文件
MAT文件的概念
- matlab存储数据的标准格式,在MATLAB中用load和save命令
- 操作MAT文件的API函数封装于两个标准库文件中
libmat.lib 包含对MAT文件的操作函数
libmx.lib 包含对MAT文件中矩阵的操作函数
C++程序中MAT文件的基本操作
- 定义指向MAT文件的指针
MATFile *mfp; 其中,MATFile指定指针类型,mfp为指针变量
- 打开与关闭MAT文件
mfp=matOpen(filename, mode)
matClose(mfp)
filename为文件名,mode为对文件的使用方式,如果文件打开成功,返回句柄,否则返回NULL.访问方式分为:r(只读模式),w(只写模式),u(更新模式)
- 读写MAT文件
matPutVariable(mfp, name, mp)
matGetVariable(mfp, name)
其中,mafp是已经定义的MAT文件指针,name是指定存储数据的变量名,mp是指向MATLAB工作区mxArray类型变量的指针.
mxArray对象
- 建立和清除mxArray变量的函数
mxArray *mxCreateDoubleScalar(double value)
用于创建数字标量,其中,value用于初始化mxArray变量
mxArray *mxCreateDoubleMatrix(mwSize m, mwSize n, mxComplexityCFlag)
用于创建存储数值变量的mxArray矩阵,其中,m,n指定mxArray矩阵的大小,CFlag指定成员值是否为复数,当CFlag为mxREAL时,成员值是实数.
mxArray *mxCreateString(const char *str)
用于创建存储字符串的mxArray变量,其中,str指向的字符串用于初始化mxArray变量
void mxDestoryArray(mxArray *pm)
用于清除pm指向的mxArray变量
- 验证数据类型的函数
bool mxlsDouble(const mxArray *pm)
bool mxlsNumberic(const mxArray *pm)
其中,pm是指向mxArray变量的指针
- 读写数据的函数
size_t mxGetM(comst mxArray *pm)
void mxSetM(mxArray *pm, mwSize m)
double *mxGetPr(const mxArray *pm)
void mxSetPr(mxArray *pm, double *pr)
其中,pm是指向mxArray变量的指针
- 转换类型的函数
char *mxArrayToString(const mxArray *pm)
其中,pm是指向mxArray变量的指针
生成应用程序并运行
#include "mat.h"
#include <iostream>
using namespace std;
int main()
{
MATFile *pmat; /* 定义MAT文件指针*/
mxArray *pa1, *pa2, *pa3;
//定义要写入的数据
double data[9] = {1.1, 2.2, 3.3, 4.4, 5.5, 6.6, 7.7, 8.8, 9.9};
const char *file = "mattest.mat";//定义要操作的文件
int status; //定义存储函数返回值的变量
/* 打开一个MAT文件,如果不存在则创建一个MAT文件,如果打开失败,则返回 */
cout << "生成文件 : " << file << endl;
pmat = matOpen(file, "w");
if (pmat == NULL) {
cout << "不能创建文件 : " << file << endl;
cout << "(请确认是否有权限访问指定文件夹?)\n";
return(0);
}
/* 创建3个mxArray对象,其中pa1存储一个实数,pa2为3×3的双精度实型矩阵,*/
/* pa3存储字符串,如果创建失败则返回 */
pa1 = mxCreateDoubleScalar(1.234);
if (pa1 == NULL) {
cout << "不能创建变量。\n";
return(0);
}
pa2 = mxCreateDoubleMatrix(3, 3, mxREAL);
if (pa2 == NULL) {
cout << "不能创建矩阵。\n";
return(0);
}
memcpy((void *)(mxGetPr(pa2)), (void *)data, sizeof(data));
pa3 = mxCreateString("MAT文件示例");
if (pa3 == NULL) {
cout << "不能创建字符串。\n";
return(0);
}
/* 向MAT文件中写数据,失败则返回 */
status = matPutVariable(pmat, "LocalDouble", pa1);
if (status != 0) {
cout << "写入局部变量时发生错误。\n " ;
return(0);
}
status = matPutVariableAsGlobal(pmat, "GlobalDouble", pa2);
if (status != 0) {
cout << "写入全局变量时发生错误。\n";
return(0);
}
status = matPutVariable(pmat, "LocalString", pa3);
if (status != 0) {
cout << ": 写入String类型数据时发生错误。\n ";
return(0);
}
/* 清除矩阵 */
mxDestroyArray(pa1);
mxDestroyArray(pa2);
mxDestroyArray(pa3);
/* 关闭MAT文件 */
if (matClose(pmat) != 0) {
cout << "关闭文件时发生错误 " << endl;
return(0);
}
cout << "文件创建成功!\n";
return(1);
}
- 编译完成后,即可生成可执行文件
- 可使用C++编译器
- 可使用 mex -v -client engine MatFile.cpp
10.4在MATLAB中调用其他语言编写的程序
MEX库函数
- 用于MEX程序与MATLAB环境交换数据和仓MATLAB工作空间获取相应信息
- 常用MEX库函数
mexCallMATLAB 用于调用MATLAB函数
mexErrMsgTxt 用于输出matlab工作空间的错误信息
mexEvalString 用于在matlab环境中执行表达式
mexGetVariable 用于mex文件从工作区获取指定变量
mexPutVariable 用于mex文件向工作区输出指定变量
MEX文件源程序的构成
- 入口子程序
定义被MATLAB调用的外部子程序的入口地址,MATLAB系统和计算子程序传递的参数等.
void mexFunction( int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[] )
{
}
其中nlhs定义输出结果的个数,plhs指向用于返回输出结果的对象,nrhs定义输入参数的个数,prhs指向存储输入参数的对象
- 计算子程序
包含所有完成计算功能的程序代码,由入口子程序调用
返回值类型 子程序名(输入形参表)
{
}
MEX文件的编译
mex MEXDemo.cpp
10.5在其他语言程序中调用MATLAB函数
MATLAB引擎的概念
- MATLAB引擎是用于和外部程序结合使用的一组函数和程序库,在其他语言程序中利用MATLAB引擎来调用MATLAB中的函数
- 定义指向MATLAB引擎对象的指针
Engine *mep
其中Engine指定指针类型,mep为指针变量
- C++常用引擎函数包括
Engine *engOpen(const char *startcmd); 用于启动matlab计算引擎,打开matlab工作区,startcmd指定启动方式(Windows需为空),返回引擎句柄
int engClose(Engine *ep); 用于关闭计算引擎所打开的matlab工作区,ep为引擎指针
mxArray *engGetVariable(Engine *ep, const char *name); 用于从引擎工作区读取数据,返回值为指向name变量的指针
int engPutVariable(Engine *ep, const char *name, const mxArray *pm); 用于向引擎工作区输出数据,执行成功返回0,否则为1
int engEvalString(Engine *ep, const char *string); 用于执行matlab命令,执行成功返回0,否则为1
MATLAB引擎的使用
- 创建mxArray变量
mxArray *mxCreateDoubleMatrix(mwSize m, mwSize n, mxComplexityCFlag);
- 给mxArray类型的变量赋值
void * memcpy(void * destinationPtr, const void * sourcePtr, size_t num);
其中destinationPtr, sourcePtr分别为指向目标矩阵,原矩阵的指针,num指定复制的数据个数
- 将变量放入MATLAB引擎所启动的工作区中
#include <engine.h>
#include <iostream>
using namespace std;
int main()
{
//定义一个engine类型的指针ep,用于操作引擎对象。
Engine *ep;
//定义mxArray 类型的指针,用于指向所调用MATLAB函数的输入对象。
mxArray *T = NULL, *R = NULL;
//定义存储数据的变量,并按给定表达式生成数据。
double t[180],r[180];
double a,b;
a=2;b=3;
for (int i=0;i<180;i++) {
t[i]=i*0.1;
r[i]=a+b*t[i]; }
//启动MATLAB计算引擎
//Windows系统中,engOpen函数的参数为空字符串,指定在本机启动计算引擎。
if (!(ep = engOpen(""))) {
cout<< "\n不能启动MATLAB引擎\n";
return 0;
}
//建立MATLAB变量,调用MATLAB函数
T = mxCreateDoubleMatrix(1, 180, mxREAL);
memcpy((void *)mxGetPr(T), (void *)t, sizeof(t));
engPutVariable(ep, "T", T);
R = mxCreateDoubleMatrix(1, 180, mxREAL);
memcpy((void *)mxGetPr(R), (void *)r, sizeof(r));
engPutVariable(ep, "R", R);
engEvalString(ep, "polar(T,R);");
engEvalString(ep, "title('阿基米德螺线');");
//释放内存空间,关闭计算引擎
system("pause");
mxDestroyArray(T);
mxDestroyArray(R);
engClose(ep);
return 1;
}
MATLAB引擎程序的编译与运行
mex -client engine engdemo.cpp