博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
【转】VS2010和Matlab混编尝试
阅读量:4915 次
发布时间:2019-06-11

本文共 6806 字,大约阅读时间需要 22 分钟。

 

1系统环境说明

操作系统:Window8 X64.

Matlab版本:Matlab2012b(Matlab 8.0).

VS版本:VS 2010.

添加系统环境变量:

 

Path变量中增加:C:\Program Files\MATLAB\R2012b\bin\win64;

重启电脑。

2 二次规划算法的Matlab实现

2.1 编程准备工作

    首先为本文建立一个单独的文件夹\QPTEST,再在该文件夹下建立子文件夹\QPMAT。然后启动Matlab并将工作目录指定到\QPMAT下。

2.2 m文件编程

    新建m文件并保存文件名为qpsubp.m,编辑内容如下,代码分析参考文献[1]程序12.1:

 

function [d,mu,lam] = qpsubp(dfk,Bk,Ae,hk,Ai,gk)n=length(dfk);  l=length(hk);   m=length(gk);gamma=0.05; epsilon=1.0e-6; rho=0.5;    sigma=0.2;ep0=0.05;   mu0=0.05*zeros(l,1);    lam0=0.05*zeros(m,1);d0=ones(n,1);   u0=[ep0;zeros(n+l+m,1)];z0=[ep0;d0;mu0;lam0];k=0;z=z0;   ep=ep0; d=d0;   mu=mu0; lam=lam0;    while (k<=150)    dh=dah(ep,d,mu,lam,dfk,Bk,Ae,hk,Ai,gk);    if(norm(dh)
0&&m>0) de=dz(1); dd=dz(2:n+1); du=dz(n+2:n+l+1); dl=dz(n+l+2:n+l+m+1); end if(l==0) de=dz(1); dd=dz(2:n+1); dl=dz(n+2:n+m+1); end if(m==0) de=dz(1); dd=dz(2:n+1); du=dz(n+2:n+l+1); end i=0; while (i<=20) if(l>0&&m>0) dh1=dah(ep+rho^i*de,d+rho^i*dd,mu+rho^i*du,lam+rho^i*dl,... dfk,Bk,Ae,hk,Ai,gk); end if(l==0) dh1=dah(ep+rho^i*de,d+rho^i*dd,mu,lam+rho^i*dl,... dfk,Bk,Ae,hk,Ai,gk); end if(m==0) dh1=dah(ep+rho^i*de,d+rho^i*dd,mu+rho^i*du,lam,... dfk,Bk,Ae,hk,Ai,gk); end if(norm(dh1)<=(1-sigma*(1-gamma*ep0)*rho^i)*norm(dh)) mk=i; break; end i=i+1; if(i==20) mk=10; end end alpha=rho^mk; if(l>0&&m>0) ep=ep+alpha*de; d=d+alpha*dd; mu=mu+alpha*du; lam=lam+alpha*dl; end if(l==0) ep=ep+alpha*de; d=d+alpha*dd; lam=lam+alpha*dl; end if(m==0) ep=ep+alpha*de; d=d+alpha*dd; mu=mu+alpha*du; end k=k+1;end%val = 0.5*d'*Bk*d+dfk'*d; function p=phi(ep,a,b)p=a+b-sqrt(a^2+b^2+2*ep^2); function bet=beta(ep,d,mu,lam,dfk,Bk,Ae,hk,Ai,gk,gamma)dh=dah(ep,d,mu,lam,dfk,Bk,Ae,hk,Ai,gk);bet=gamma*norm(dh)*min(1,norm(dh)); function [dd1,dd2,v1]=ddv(ep,d,lam,Ai,gk)m=length(gk);dd1=zeros(m,m); dd2=zeros(m,m); v1=zeros(m,1);for(i=1:m) fm=sqrt(lam(i)^2+(gk(i)+Ai(i,:)*d)^2+2*ep^2); dd1(i,i)=1-lam(i)/fm; dd2(i,i)=1-(gk(i)+Ai(i,:)*d)/fm; v1(i)=-2*ep/fm;end function A=JacobiH(ep,d,mu,lam,dfk,Bk,Ae,hk,Ai,gk)n=length(dfk); l=length(hk); m=length(gk);A=zeros(n+l+m+1,n+l+m+1);[dd1,dd2,v1]=ddv(ep,d,lam,Ai,gk);if(l>0&&m>0) A=[1, zeros(1,n), zeros(1,l), zeros(1,m); zeros(n,1), Bk, -Ae', -Ai'; zeros(l,l), Ae, zeros(l,l), zeros(l,m); v1,dd2*Ai, zeros(m,l),dd1];endif(l==0) A=[1, zeros(1,n), zeros(1,m); zeros(n,1), Bk, -Ai'; v1,dd2*Ai, dd1];endif(m==0) A=[1, zeros(1,n), zeros(1,l); zeros(n,1), Bk, -Ae'; zeros(l,1), Ae, zeros(l,l)];end function dh=dah(ep,d,mu,lam,dfk,Bk,Ae,hk,Ai,gk)n=length(dfk); l=length(hk); m=length(gk);dh=zeros(n+l+m+1,1);dh(1)=ep;if(l>0&&m>0) dh(2:n+1)=Bk*d-Ae'*mu-Ai'*lam+dfk; dh(n+2:n+l+1)=hk+Ae*d; for(i=1:m) dh(n+l+1+i)=phi(ep,lam(i),gk(i)+Ai(i,:)*d); endendif(l==0) dh(2:n+1)=Bk*d-Ai'*lam+dfk; for(i=1:m) dh(n+1+i)=phi(ep,lam(i),gk(i)+Ai(i,:)*d); endendif(m==0) dh(2:n+1)=Bk*d-Ae'*mu+dfk; dh(n+2:n+l+1)=hk+Ae*d;enddh=dh(:);

 

2.3 m文件测试

    使用2.2中的程序求解如下二次规划问题:

 

该问题的极小值点为。在Matlab命令窗口中输入如下命令:

dfk=[-6 -2 -12]’;    Bk=[2 1 0;1 4 0;0 0 0];    Ae=[1 1 1];    hk=[-2]’;    Ai=[1 -2 0;1 0 0;0 1 0;0 0 1];    gk=[3 0 0 0]’;    [d,mu,lam]=qpsubp(dfk,Bk,Ae,hk,Ai,gk)

 

输出结果如下:

d =           -0.0000           -0.0000            2.0000mu =          -12.0000lam =           -0.0000          6.0000           10.0000           -0.0000

 

 

2.4 m文件编译

    在Matlab命令行中输入编译命令:mcc -B cpplib:qpsubp qpsubp.m。第一次运行该命令是,Matlab会在本机上搜索可用的编译器,并列于命令窗口内,如下图所示:

 

选择输入1回车,等待编译结果,编译时间较长,编译后的输出提示如下图所示:

 

编译完成后,在\QPMAT文件夹下生成如下文件:

 

其中对于VS调用dll有用的文件包括qpsubp.h、qpsubp.lib与qpsubp.dll。

 

3 VS2010下测试dll

3.1 VS工程设置

启动VS2010,新建项目,项目目录选择\QPTEST,项目名称填QPVS,项目类型为win32下的控制台程序,如下图所示:

将文件\QPMAT文件夹下的qpsubp.h、qpsubp.lib与qpsubp.dll文件拷贝到文件夹\QPVS\QPVS下。由于操作系统和Matlab为64位,所以在VS下只能编译成64位程序才能正常链接到Matlab中的函数,需要在VS中新建一个64位的编译平台,步骤如下:

(1)   进入“配置管理器”

通过项目属性进入。

 

或者直接从工具栏平台的下拉箭头下进入:

 

(2)增加x64平台

 

确定,得到如下结果。

 

为工程添加Matlab的头文件和库文件路径,步骤如下:

项目属性——》VC++目录,如图:

 

包含目录增加:C:\Program Files\MATLAB\R2012b\extern\include

库目录增加:C:\Program Files\MATLAB\R2012b\extern\lib\win64\microsoft

3.2代码编辑

    编辑文件SQVS.cpp。编辑内容如下:

(1)添加头文件与作用域声明

#include 
#include "qpsubp.h"using namespace std;

iostream为C++输入输出流类的头文件,与using namespace std配合后可调用cin、cout,qpsubp.h是调用二次规划dll的头文件。

(2)   链接库文件

#pragma comment(lib,"qpsubp.lib")#pragma comment(lib,"mclmcrrt.lib")

Qpsubp.lib为调用二次规划dll的库文件,mclmcrrt.lib是调用Matlab相关函数的库文件。

(3)   初始化库文件

if( !qpsubpInitializeWithHandlers(NULL,0) )    {        std::cout << "Could not initialize the application!" <<            std::endl;        return -1;    }     if(!qpsubpInitialize())    {        std::cout << "Could not initialize the application!" <<            std::endl;        return -1;    }    else    {        cout<<"Application is initialized successfully!"<

(4)定义输入输出变量并城市化(根据m文件测试所用例子)

    

  mwArray mwdfk(3,1,mxDOUBLE_CLASS);    mwArray mwBk(3,3,mxDOUBLE_CLASS);    mwArray mwAe(1,3,mxDOUBLE_CLASS);    mwArray mwhk(1,1,mxDOUBLE_CLASS);    mwArray mwAi(4,3,mxDOUBLE_CLASS);    mwArray mwgk(4,1,mxDOUBLE_CLASS);     mwArray mwd;    mwArray mwmu;    mwArray mwlam;     mwdfk(1,1)=-6;    mwdfk(2,1)=-2;    mwdfk(3,1)=-12;     mwBk(1,1)=2;    mwBk(1,2)=1;    mwBk(1,3)=0;    mwBk(2,1)=1;    mwBk(2,2)=4;    mwBk(2,3)=0;    mwBk(3,1)=0;    mwBk(3,2)=0;    mwBk(3,3)=0;     mwAe(1,1)=1;    mwAe(1,2)=1;    mwAe(1,3)=1;     mwhk(1,1)=-2;     mwAi(1,1)=1;    mwAi(1,2)=-2;    mwAi(1,3)=0;    mwAi(2,1)=1;    mwAi(2,2)=0;    mwAi(2,3)=0;    mwAi(3,1)=0;    mwAi(3,2)=1;    mwAi(3,3)=0;    mwAi(4,1)=0;    mwAi(4,2)=0;    mwAi(4,3)=1;     mwgk(1,1)=3;    mwgk(2,1)=0;    mwgk(3,1)=0;    mwgk(4,1)=0;

(5)地用二次规划函数

qpsubp(3,mwd,mwmu,mwlam,mwdfk,mwBk,mwAe,mwhk,mwAi,mwgk);

(6)输出计算结果

cout<<"d = ["<
<<","<
<<","<
<<"]"<

(7)屏幕停留、终止动态链接库与退出程序

cout <<"Press any key to exit!" <

3.3完整代码

 

#include "stdafx.h"#include 
#include "qpsubp.h" using namespace std; #pragma comment(lib,"qpsubp.lib")#pragma comment(lib,"mclmcrrt.lib") int _tmain(int argc, _TCHAR* argv[]){ if( !qpsubpInitializeWithHandlers(NULL,0) ) { std::cout << "Could not initialize the application!" << std::endl; return -1; } if(!qpsubpInitialize()) { std::cout << "Could not initialize the application!" << std::endl; return -1; } else { cout<<"Application is initialized successfully!"<

 

 

3.4运行结果

 

4参考文献

[1]马昌凤.最优化方法及其Matlab程序设计.北京:科学出版社,2010.

[2]刘维.精通Matlab与C/C++混合程序设计.北京:北京航空航天大学出版社,2007.

转载于:https://www.cnblogs.com/kokomo/p/4103104.html

你可能感兴趣的文章
我的前端学习路线
查看>>
白帽子讲web安全读书笔记(Ⅰ)
查看>>
九.延迟加载
查看>>
实际工作规范和案例框架
查看>>
SQL Server datetime类型转换超出范围的报错
查看>>
XMPP框架 微信项目开发之XMPP配置——MySQL数据库、MySQLworkbench、Openfire服务器的安装与配置...
查看>>
不说狠话,不做软事
查看>>
单端IO标准
查看>>
self.a与_a访问区别
查看>>
《Code Complete》ch.16 控制循环
查看>>
线程安全与资源共享
查看>>
(转)在Linux上的使用开源C++日志库 ---log4cplus
查看>>
清空文件内容
查看>>
Linux系统安装telnet以及xinetd服务
查看>>
火狐浏览器查找配置文件路径
查看>>
向android虚拟机中push文件提示Read-only file system
查看>>
nmon与nmonanalyser 系统性能分析(图表)利器非草稿 分类: ...
查看>>
SQL语句
查看>>
Codeforces 713C Sonya and Problem Wihtout a Legend(单调DP)
查看>>
POJ 1201 Intervals(差分约束)
查看>>