在 VC 中呼叫 MATLAB 神經網路工具箱,完成資料檢驗與預測。範例程式碼取自碩士論文片段,故不提供完整原始碼,重點示範如何透過 COM 元件實現 VC 與 MATLAB 資料交換。
SJHSJY.mfunction [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);
... 後處理 % 必須為非負
輸入:P, T, me, eg, lr, P2, T2, S1
輸出:w1, b1, w2, b2, ET, a2
SJHSYC.mfunction [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, P2, me, eg, lr, S1
輸出:a2 (預測結果)
在 MATLAB 中將上述兩個函數封裝為 COM 元件,步驟請參考《淺析 VC 與 MATLAB 聯合程式設計 (三)》。
ISJHSJY 與 ISJHSYC 兩個類別,分別對應兩個 MATLAB 函數。
圖 1:ClassView 中新增的介面類別

圖 2:ISJHSJY 介面參數定義
ISJHSJY 的呼叫原型:
HRESULT sjhsjy(
long nargout, // 輸出參數個數
VARIANT *w1, VARIANT *b1, // 輸出參數
VARIANT *w2, VARIANT *b2,
VARIANT *ET, VARIANT *a2,
VARIANT P, VARIANT T, // 輸入參數
VARIANT me, VARIANT eg,
VARIANT lr, VARIANT P2,
VARIANT T2, VARIANT S1
);
透過 VARIANT 型別可方便在 VC 與 MATLAB 間交換陣列資料,詳細用法請查閱 MSDN。
SAFEARRAYBOUND rgsabound[2];
rgsabound[0].lLbound = 0; rgsabound[0].cElements = 4;
rgsabound[1].lLbound = 0; rgsabound[1].cElements = 6;
VARIANT TTT; VariantInit(&TTT);
TTT.vt = VT_R8 | VT_ARRAY;
TTT.parray = SafeArrayCreate(VT_R8, 2, rgsabound);
TTT.parray->pvData = HH2; // HH2 為 double 型一維陣列指標
if (FAILED(CoInitialize(NULL))) { MessageBox(_T("COM 初始化失敗")); return; }
ISJHSJY *pClass = NULL;
HRESULT hr = CoCreateInstance(CLSID_SJHSJY, NULL, CLSCTX_ALL, IID_ISJHSJY, (void**)&pClass);
if (SUCCEEDED(hr))
{
long nOut = 6;
HRESULT hr1 = pClass->sjhsjy(nOut, &w1, &b1, &w2, &b2, &et, &a2,
PP, TTT, me, eg, lr, P2, T2, S1);
if (!SUCCEEDED(hr1)) { MessageBox(_T("請輸入正確資料")); return; }
// 將 VARIANT 陣列資料複製到 double 陣列
memcpy(W1, w1.parray->pvData, 420 * sizeof(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(_T("%f \r\n %f \r\n %f\r\n %f\r\n"), ET[0], ET[1], ET[2], ET[3]);
}
else { MessageBox(_T("COM 元件建立失敗!")); exit(0); }
pClass->Release();
CoUninitialize();

圖 3

圖 4

圖 5

圖 6

圖 7

圖 8
本程式介面由 VC 撰寫,演算法呼叫 MATLAB 神經網路工具箱,透過打包部署可在未安裝 MATLAB 的機器上執行,安裝檔僅 3 MB。這樣既能善用 VC 建立友善介面,又能利用 MATLAB 避免撰寫複雜演算法,大幅提升開發效率。歡迎交流討論 (QQ: 44760299)。