找回密码
 注册
Simdroid-非首页
查看: 193|回复: 8

关于visual c++与matlab混合编程问题!

[复制链接]
发表于 2009-3-4 09:53:43 | 显示全部楼层 |阅读模式 来自 北京
本帖最后由 ljelly 于 2009-3-11 12:38 编辑

(1) 首先是visual c++设置。
要在VC中成功编译Matlab引擎程序,必须包含引擎头文件engine.h并引入Matlab对应的库文件libmx.lib、libmat.lib、libeng.lib。具体的说,打开一个工程后,做如下设置(以VC6为例):
  1) 通过菜单工程/选项,打开设置属性页,进入Directories页面,在目录下拉列表框中选择Include files,添加路径:"C:\matlab\extern\include"(假定matlab安装在C:\matlab目录)。
  2) 选择Library files,添加路径:C:\matlab\extern\lib\win32\microsoft\msvc60。
  3) 通过菜单工程/设置,打开工程设置属性页,进入Link页面,在Object/library modules编辑框中,添加文件名libmx.lib libmat.lib libeng.lib。
以上步骤1)、2)只需设置一次,而步骤3)对每个工程都要单独设定。
(2) 我贴出我的代码,欢迎大家前来讨论。
#include <iostream>
#include <cmath>
#include "engine.h"
using namespace std;
int main()
{
double Cobj1[8]={0.8,-0.74,0.5,-0.2,-1,0.1,0.3,-0.5};
double Ccon2[8]={-0.5,0.2,-0.35,0.4,0.1,0.45,-0.7,-0.61};
double XX[8]={-1,-1,-1,1,1,-1,1,1};
double x00[2]={0,0};
double Bound_up0[2]={1,1};
double Bound_down0[2]={-1,-1};
const int dim_exp=4;                        // 一次时间的点数
const int dim_var=2;                        // 设计变量的个数
const int dim_obj=2;                        // 目标函数的个数
const int dim_nlcon=2;                      // 约束函数的个数

Engine *ep;               // 定义Matlab引擎指针。
if (!(ep=engOpen(NULL)))  // 测试是否启动Matlab引擎成功。
{
  cout <<"Can't start Matlab engine000!" <<endl;
  exit(0);
}

mxArray *CC1 = mxCreateDoubleMatrix(1,dim_obj*dim_exp, mxREAL);
mxArray *CC2 = mxCreateDoubleMatrix(1,dim_nlcon*dim_exp, mxREAL);
mxArray *XXX = mxCreateDoubleMatrix(1,dim_exp*dim_var, mxREAL);
mxArray *x0  = mxCreateDoubleMatrix(1,dim_var, mxREAL);
mxArray *Bound_up   = mxCreateDoubleMatrix(1,dim_var, mxREAL);
mxArray *Bound_down = mxCreateDoubleMatrix(1,dim_var, mxREAL);
// mxArray *x0_opt = mxCreateDoubleMatrix(1,dim_var, mxREAL);
memcpy(mxGetPr(CC1), Cobj1, (dim_obj*dim_exp)*sizeof(double));
memcpy(mxGetPr(CC2), Ccon2, (dim_nlcon*dim_exp)*sizeof(double));
memcpy(mxGetPr(XXX), XX,    (dim_exp*dim_var)*sizeof(double));
memcpy(mxGetPr(x0), x00,    (dim_var)*sizeof(double));
memcpy(mxGetPr(Bound_up), Bound_up0,    (dim_var)*sizeof(double));
memcpy(mxGetPr(Bound_down), Bound_down0,    (dim_var)*sizeof(double));
// memcpy(mxGetPr(x0_opt), x00,    (dim_var)*sizeof(double));
engPutVariable(ep, "CC1",CC1);
engPutVariable(ep, "CC2",CC2);
engPutVariable(ep, "XXX",XXX);
engPutVariable(ep, "x0",x0);
engPutVariable(ep, "Bound_up",Bound_up);
engPutVariable(ep, "Bound_down",Bound_down);
// engPutVariable(ep, "x0_opt",x0_opt);
engEvalString(ep, "x0_opt=solver_multiobjective(XXX,CC1,CC2,Bound_up,Bound_down,x0);");
double cc[10];
mxArray *squpdate=NULL;
double *sqtr;
squpdate=engGetVariable(ep,"x0_opt");
sqtr=mxGetPr(squpdate);
for(int i=0;i<dim_var;i=i+1)
{
  cc=sqtr;
}
mxDestroyArray(CC1);
mxDestroyArray(CC2);
mxDestroyArray(XXX);
mxDestroyArray(x0);
mxDestroyArray(Bound_up);
mxDestroyArray(Bound_down);
cout <<"Press 'Enter' key to exit!" <<endl;
cin.get();
engClose(ep); //关闭Matlab引擎。
return 0;
}
这个是主程序,下面是matlab调用的函数及其子函数。
(a)solver1=solver_multiobjective
function solver1=solver_multiobjective(XX,CC1,CC2,Bound_up,Bound_down,x0);
n=length(x0);                  % 设计变量的个数
m=length(XX)/n;                % 设计点的个数
dim_obj=length(CC1)/m;         % 目标函数的个数
dim_con=length(CC2)/m;         % 约束函数的个数
% 计算目标函数的系数
k=1;
for ii=1:dim_obj
    for jj=1:m
        C1(ii,jj)=CC1(k);
        k=k+1;
    end
end
% 计算约束函数的系数
k=1;
for ii=1:dim_con
    for jj=1:m
        C2(ii,jj)=CC2(k);
        k=k+1;
    end
end
% 计算实验设计矩阵
k=1;
for ii=1:m
    for jj=1:n
        X(ii,jj)=XX(k);
        k=k+1;
    end
end
save C1 C1;
save C2 C2;
save X X;
solver1=fminimax(@fun_obj,x0,[],[],[],[],Bound_down,Bound_up,@fun_nonlcon);
(b) y=fun_obj(x)
function y=fun_obj(x)
load X;
load C1;
n=length(C1(1,:);
m=length(x);
m1=length(X(1,:);
m2=length(C1(:,1));
if(m~=m1 || m~=m2 || m1~=m2)
    error('wrong input arguments');
end
cc=1;
y=zeros(2,1);
for jj=1:m
    for ii=1:n
        y(jj)=y(jj)+C1(jj,ii)*sqrt(sum(abs(x-X(ii,:))^2+cc^2);
    end
end
(c)
[cnon,cequ]=fun_nonlcon(x)
function [cnon,cequ]=fun_nonlcon(x)
load X;
load C2;
n=length(C2(1,:);
m=length(x);
m1=length(X(1,:);
m2=length(C2(:,1));
if(m~=m1 || m~=m2 || m1~=m2)
    error('wrong input arguments');
end
cc=1;
cnon=zeros(2,1);
for jj=1:m
    for ii=1:n
        cnon(jj)=cnon(jj)+C2(jj,ii)*sqrt(sum(abs(x-X(ii,:))^2+cc^2);
    end
end
cequ=[];
(3)我的运行结果是在sqtr=mxGetPr(squpdate);这一行出现问题:无法知道mxArray对象指针squpdate的大小。
但是在另外的一个程序当中;
#include <iostream>
#include <cmath>
#include "engine.h"
using namespace std;
int main()
{
const int N=50;
double x[N],y[N];
int j = 1;
for (int i=0; i<N; i++) //计算数组x和y
{
  x = (i+1);
  y = sin(x) + j * log(x); //产生-之间的随机数赋给xx;
  j *= -1;
}
Engine *ep; //定义Matlab引擎指针。
if (!(ep=engOpen(NULL))) //测试是否启动Matlab引擎成功。
{
  cout <<"Can't start Matlab engine!" <<endl;
  exit(1);
}
//定义mxArray,为行,N列的实数数组。
mxArray *xx = mxCreateDoubleMatrix(1,N, mxREAL);
mxArray *yy = mxCreateDoubleMatrix(1,N, mxREAL); //同上。
memcpy(mxGetPr(xx), x, N*sizeof(double)); //将数组x复制到mxarray数组xx中。
memcpy(mxGetPr(yy), y, N*sizeof(double)); //将数组x复制到mxarray数组yy中。
engPutVariable(ep, "xx",xx); //将mxArray数组xx写入到Matlab工作空间,命名为xx。
engPutVariable(ep, "yy",yy); //将mxArray数组yy写入到Matlab工作空间,命名为yy。
//向Matlab引擎发送画图命令。plot为Matlab的画图函数,参见Matlab相关文档。
engEvalString(ep, "zz=plus(xx,yy) ");
double cc[100];
mxArray *squpdate=NULL;
double *sqtr;
squpdate=engGetVariable(ep,"zz");
sqtr=mxGetPr(squpdate);
for(i=0;i<N;i=i+1)
{
  cc=sqtr;
}
mxDestroyArray(xx); //销毁mxArray数组xx和yy。
mxDestroyArray(yy);
cout <<"Press any key to exit!" <<endl;
cin.get();
engClose(ep); //关闭Matlab引擎。
return 0;
}

调用的是:
function z=plus(x,y)
for ii=1:length(x)
    z(ii)=x(ii)+y(ii)
end
确能够顺利运行,不知道这是为什么?
另外,我不知道怎么定义mxArray对象的大小(如何定义),请问这个该怎么解决?
 楼主| 发表于 2009-3-6 10:52:03 | 显示全部楼层 来自 北京
Simdroid开发平台
唉,怎么没人理呢,是不是太简单了呀!

评分

1

查看全部评分

回复 不支持

使用道具 举报

发表于 2009-3-6 13:10:02 | 显示全部楼层 来自 新加坡
对于mxArray* 变量,可以通过mxGetM以及mxGetN获得其矩阵大小。有空多看例子是肯定有帮助的学习方法。
回复 不支持

使用道具 举报

 楼主| 发表于 2009-3-6 14:21:52 | 显示全部楼层 来自 北京
谢谢taohe帮顶,
问下从哪里可以看到这些mxArray结构体的函数,如mxGetM,和mxGetN等等。
看了很多例子,都感觉差不多。
回复 不支持

使用道具 举报

发表于 2009-3-6 20:43:36 | 显示全部楼层 来自 新加坡
最权威的资料当然是matlab自带的官方帮助文件了。

例子只能帮助你理解知识内容,可惜不能代替知识学习。
回复 不支持

使用道具 举报

 楼主| 发表于 2009-3-7 13:20:39 | 显示全部楼层 来自 北京
谢谢taohe了,这里的朋友真强,受益匪浅呀!
回复 不支持

使用道具 举报

发表于 2009-3-7 15:48:02 | 显示全部楼层 来自 新加坡
能够参与讨论,也让我受益匪浅,欢迎常来分享心得,讨论技术.
回复 不支持

使用道具 举报

 楼主| 发表于 2009-3-8 12:41:38 | 显示全部楼层 来自 北京
好长时间没有碰matlab了,现在捡起来还是有点难的。
回复 不支持

使用道具 举报

 楼主| 发表于 2009-3-12 21:04:40 | 显示全部楼层 来自 北京
搞不定了,决定还是翻译成c++了。
再次谢谢taohe的热心参与!
回复 不支持

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

Simapps系列直播

Archiver|小黑屋|联系我们|仿真互动网 ( 京ICP备15048925号-7 )

GMT+8, 2024-10-7 11:33 , Processed in 0.051756 second(s), 17 queries , Gzip On, MemCache On.

Powered by Discuz! X3.5 Licensed

© 2001-2024 Discuz! Team.

快速回复 返回顶部 返回列表