本文使用的工具:VC6.0+MATLAB6.5
在本章中實現的是在VC中調用MATLAB神經網絡工具箱,文章中用到的程序是一篇碩士論文的一部分,因此沒有提供源程序,目的是通過這個例子介紹如何在VC中調用利用com組件,實現VC和MATLAB數據的交換。首先在MATLAB中完成兩個神經網絡函數,一個用來檢驗,一個用來預測。
1、檢驗函數:
function [w1,b1,w2,b2,ET,a2]=SJHSJY(P,T,me,eg,lr,P2,T2,S1)
[Pn,meanp,stdp,Tn,meant,stdt]=prestd(P,T); %預處理
[w1,b1,w2,b2]=initff(Pn,S1,''tansig'',Tn,''purelin''); %數據初始化
df=10;
tp=[df me eg lr];
[w1,b1,w2,b2,tp,tr]=trainbpx(w1,b1,''tansig''); %樣本訓練
P2n=trastd(P2,meanp,stdp);
......後處理 %必須為非負
該函數的功能為BP神經網絡檢驗誤差,P,T,me,eg,lr,P2,T2,S1 為輸入參數;w1,b1,w2,b2,ET,a2 為輸出參數。
2、預測函數:
function [a2]=SJHSYC(P,T,P2,me,eg,lr,S1)
[Pn,meanp,stdp,Tn,meant,stdt]=prestd(P,T);
[w1,b1,w2,b2]=initff(Pn,S1,''tansig'',Tn,''purelin'');
........
參數輸出
P,T,me,eg,lr,P2,T2,S1為輸入參數 a2為輸出參數,即為所要的結果
3、在MATLAB中將該兩個函數做成COM組件,具體方法可以參考淺析VC與MATLAB聯合編程<三>。
4、新建基於對話框的VC工程,在VC中引入COM組件,具體方法可以參考淺析VC與MATLAB聯合編程<三>,完成後可以在CLASSView中看到多了兩個新類ISJHSJY和ISJHSYC,如圖1所示,它們分別實現函數SJHSJY.m和SJHSYC.m的功能。
圖1
仔細查看類ISJHSJY的參數,如圖2所示
圖2
在類ISJHSJY中 有調用函數格式說明:
ISJHSJY __RPC_FAR * This,
/* [in] */ long nargout,
/* [out][in] */ VARIANT __RPC_FAR *w1,
/* [out][in] */ VARIANT __RPC_FAR *b1,
/* [out][in] */ VARIANT __RPC_FAR *w2,
/* [out][in] */ VARIANT __RPC_FAR *b2,
/* [out][in] */ VARIANT __RPC_FAR *ET,
/* [out][in] */ VARIANT __RPC_FAR *a2,
/* [in] */ VARIANT P,
/* [in] */ VARIANT T,
/* [in] */ VARIANT me,
/* [in] */ VARIANT eg,
/* [in] */ VARIANT lr,
/* [in] */ VARIANT P2,
/* [in] */ VARIANT T2,
/* [in] */ VARIANT S1);
其中nargout 為輸出參數的個數; w1,b1,w2,b2,ET,a2為 Variant型輸出參數; P,T,me,eg,lr,P2,T2,S1為Variant型輸入參數;
可以看出通過Variant型數據,可以很方便的在VC和MATLAB之間建立起數據交換,關於Variant數據類型可以查看MSDN幫助文檔或VC類庫手冊。
5、關鍵代碼:
SAFEARRAYBOUND rgsabound1[2];
rgsabound1[0].lLbound=0;
rgsabound1[1].lLbound=0;
rgsabound1[0].cElements=4;
rgsabound1[1].cElements=6;
VariantInit(&TTT);
TTT.vt=VT_R8|VT_ARRAY;
TTT.parray=SafeArrayCreate(VT_R8,2,rgsabound1);
TTT.parray->pvData=HH2;
以上代碼用來在VC中將輸入參數轉換為Variant型,建立Variant型4×6二維數組,其中HH2為double型一維數組,TT為函數中的一個輸入參數,為Variant型;程序中,輸入參數和輸出參數基本都為二維數組。
6、調用代碼:
if(FAILED(CoInitialize(NULL)))//COM初始化
{MessageBox("Error");
}
ISJHSJY *pclass=NULL;
HRESULT hr=CoCreateInstance(CLSID_SJHSJY,NULL, CLSCTX_ALL, IID_ISJHSJY, (void **)&pclass);
if(SUCCEEDED(hr))
{
long int u=6;
HRESULT hr1=pclass->sjhsjy(u,&w1,&b1,&w2,&b2,&et,&a2,PP,TTT,me,eg,lr,P2,T2,S1);//函數調用
if(!SUCCEEDED(hr1)){MessageBox("請輸入正確數據");return;}//函數調用失敗
if(SUCCEEDED(hr1))
{
memcpy(W1,w1.parray->pvData,420*sizeof(double));//將Variant型結果數據轉換成double型
memcpy(W2,w2.parray->pvData,240*sizeof(double));
memcpy(B1,b1.parray->pvData,60*sizeof(double));
memcpy(B2,b2.parray->pvData,4*sizeof(double));
memcpy(ET,et.parray->pvData,4*sizeof(double));
memcpy(A2,a2.parray->pvData,4*sizeof(double));
m_edit7.Format("%f \r\n %f \r\n %f\r\n %f\r\n ",ET[0],ET[1],ET[2],ET[3]);
}
}
else {MessageBox("COM組件調用失敗!","提示",MB_ICONHAND);exit(0);}//COM組件調用失敗
pclass->Release();
CoUninitialize();//結束COM
7、程序運行結果:
圖3
圖4
圖5
圖6
圖7
圖8
本程序界面采用VC編寫,算法調用的是MATLAB神經網絡工具箱,通過打包,能在沒有安裝MATLAB的機器上安裝運行,安裝文件僅3M,雖MATLAB也有神經網絡GUI,但是不能脫離MATLAB環境,通過在VC中調用MATLAB,即能夠充分利用VC建立友好的界面,又可以利用MATLAB避免編寫復雜的算法,大大提高編程效率。本人的QQ:44760299。目前也還在學習中歡迎大家一起討論。