首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> VC >> 關於VC++

VC 與 MATLAB 聯合程式設計 (十) — 綜合實例二:神經網路應用

     編輯:關於VC++

開發環境

  • VC 6.0
  • MATLAB 6.5

實作目標

在 VC 中呼叫 MATLAB 神經網路工具箱,完成資料檢驗與預測。範例程式碼取自碩士論文片段,故不提供完整原始碼,重點示範如何透過 COM 元件實現 VC 與 MATLAB 資料交換。

MATLAB 端函數設計

1. 檢驗函數 SJHSJY.m

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);
... 後處理 % 必須為非負

輸入:P, T, me, eg, lr, P2, T2, S1
輸出:w1, b1, w2, b2, ET, a2

2. 預測函數 SJHSYC.m

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, P2, me, eg, lr, S1
輸出:a2 (預測結果)

建立 COM 元件

在 MATLAB 中將上述兩個函數封裝為 COM 元件,步驟請參考《淺析 VC 與 MATLAB 聯合程式設計 (三)》。

VC 專案建立與 COM 元件引入

  1. 新建以對話方塊為基礎的 MFC 專案。
  2. 引入 COM 元件 (參考同上文件),完成後在 ClassView 中會出現 ISJHSJY 與 ISJHSYC 兩個類別,分別對應兩個 MATLAB 函數。

ClassView 顯示新增類別

圖 1:ClassView 中新增的介面類別

介面參數檢視

ISJHSJY 參數細節

圖 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。

關鍵程式碼:VC 端資料轉換與呼叫

1. 建立輸入 VARIANT 陣列 (以 4×6 二維陣列為例)

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 型一維陣列指標

2. COM 初始化、建立物件、呼叫函數、結果轉回 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

圖 3

結果圖 4

圖 4

結果圖 5

圖 5

結果圖 6

圖 6

結果圖 7

圖 7

結果圖 8

圖 8

結語

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

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved