?? vc++中使用matlab的c++數學庫和mcc生成的程序.txt
字號:
inData=mxGetPr(prhs[0]);
M=mxGetM(prhs[0]);
N=mxGetN(prhs[0]);
plhs[0]=mxCreateDoubleMatrix(M,N,mxREAL);
outData=mxGetPr(plhs[0]);
for(i=0;i<M;i++)
for(j=0;j<N;j++)
xREAL);
outData=mxGetPr(plhs[0]);
for(i=0;i<M;i++)
for(j=0;j<N;j++)
outData[j*M+i =inData[(N-1-j)*M+i];
}
當然,Matlab里使用到的并不是只有double類型這一種矩陣,還有字符串類型、稀疏矩
陣、結構類型矩陣等等,并提供了相應的處理函數。本文用到編制mex程序中最經常遇到
的一些函數,其余的詳細情況清參考Apiref.pdf。
第二章、
第五節、用c編寫mex程序[五]
通過前面兩部分的介紹,大家對參數的輸入和輸出方法應該有了基本的了解。具備了這
些知識,就能夠滿足一般的編程需要了。但這些程序還有些小的缺陷,以前面介紹的re
由于前面的例程中沒有對輸入、輸出參數的數目及類型進行檢查,導致程序的容錯性很
#include "mex.h"
void mexFunction(int nlhs, mxArray *plhs[],
int nrhs, const mxArray *prhs[])
{
double *inData;
double *outData;
int M,N;
//異常處理
if(nrhs!=1)
mexErrMsgTxt("USAGE: b=reverse(a)\n");
if(!mxIsDouble(prhs[0]))
mexErrMsgTxt("the Input Matrix must be double!\n");
inData=mxGetPr(prhs[0]);
M=mxGetM(prhs[0]);
N=mxGetN(prhs[0]);
plhs[0]=mxCreateDoubleMatrix(M,N,mxREAL);
outData=mxGetPr(plhs[0]);
for(i=0;i<M;i++)
for(j=0;j<N;j++)
outData[j*M+i =inData[(N-1-j)*M+i];
}
在上面的異常處理中,使用了兩個新的函數:mexErrMsgTxt和mxIsDouble。MexErrMsgT
xt在給出出錯提示的同時退出當前程序的運行。MxIsDouble則用于判斷mxArray中的數據
是否double類型。當然Matlab還提供了許多用于判斷其他數據類型的函數,這里不加詳
述。
需要說明的是,Matlab提供的API中,函數前綴有mex-和mx-兩種。帶mx-前綴的大多是對
mxArray數據進行操作的函數,如mxIsDouble,mxCreateDoubleMatrix等等。而帶mx前綴
的則大多是與Matlab環境進行交互的函數,如mexPrintf,mxErrMsgTxt等等。了解了這
一點,對在Apiref.pdf中查找所需的函數很有幫助。
至此為止,使用C編寫mex函數的基本過程已經介紹完了。下面會在介紹幾個非常有用的
函數調用。如果有足夠的時間,也許還會有一個更復雜一些的例程。
第二章、
第六節、用c編寫mex程序[六]
我們之所以使用Matlab,很重要的考慮是Matlab提供了相當豐富的矩陣運算函數和各
種toolbox。在編制mex函數時,有時我們也會遇到一些操作,在Matlab下,只需要一個
為了在mex函數里調用Matlab命令,我們就需要用到一個函數mexCallMATLAB,原型如下:
int mexCallMATLAB(int nlhs, mxArray *plhs[], int nrhs, mxArray *prhs[],
const char *command_name);
有了前面的基礎,使用這個函數就顯得十分容易了。下面給出一個例程,功能是將輸入
#include "mex.h"
void mexFunction(int nlhs, mxArray *plhs[],
int nrhs, const mxArray *prhs[])
{
int nrhs, const mxArray *prhs[])
{
{
double *inData;
mxArray *IN[1];
mxArray *OUT[1];
double *outData;
int M,N;
int i,j;
//異常處理
if(nrhs!=1)
mexErrMsgTxt("USAGE: b=rot(a)\n");
if(nrhs!=1)
mexErrMsgTxt("USAGE: b=rot(a)\n");
if(!mxIsDouble(prhs[0]))
mexErrMsgTxt("the Input Matrix must be double!\n");
//計算轉置
if(mexCallMATLAB(1,OUT,1,prhs,"'"))
mexErrMsgTxt("Error when compute!\n");
//根據輸入參數數目決定是否顯示
if(nlhs==0)
mexCallMATLAB(0,IN,1,OUT,"disp");
if(mexCallMATLAB(1,OUT,1,prhs,"'"))
mexErrMsgTxt("Error when compute!\n");
//根據輸入參數數目決定是否顯示
if(nlhs==0)
mexCallMATLAB(0,IN,1,OUT,"disp");
else
plhs[0]=OUT[0];
}
關于這個例子,相信大家一看就明白,我就不多說了。
第三章、Matcom的使用
3.1 概述
3.1.1 Matcom能作什么
Matcom是一個十分有用的.m文件翻譯器(Replacement),它的主要優點我認為有
以下幾點:
1>它提供了matlab中.m文件與其他高級語言的接口,使.m文件可以編譯為脫離
matlab環境獨立執行的可執行性程序,這樣
。提高了代碼的復用率
。提高了代碼的執行速度
。使純文本的.m文件變為二進制的可執行程序,增加了知識保護的安全性
2>它提供了近千個數學函數,對于其他高級語言編譯器來說,提供了一個豐富
的數學庫,基本上在matlab上能用的常用函數都可以在高級語言中直接調用。
數學函數主要包括:
。矩陣屬性函數
。矩陣生成函數
數學函數主要包括:
。矩陣屬性函數
。矩陣生成函數
。矩陣生成函數
。矩陣操作函數
。矩陣變換函數
。數學函數
。特殊函數
。數值函數
。串函數
。繪圖函數
。顏色函數
。函數函數
。存盤及讀文件
。系統資源函數
。系統操作函數
。判斷函數(Is函數族)
。付氏變換
等等,可參見本文附錄
3>提供了.m文件的方便快捷的編譯調適環境,可以step, watch,breakpoint等各種
調試手段。
3.1.2 Matcom的工作原理
Matcom的矩陣運算部分是基于一個名為Matrix<Lib>的C++數學庫,這個庫提供了
絕大多數的關于矩陣類、矩陣操作函數、數值計算函數、數學函數等的定義,在
Matcom中是以lib目錄下的*.lib以及windows/system/對應名稱的dll文件提供的。
Matcom的另一大部分就是圖形部分,它是用一種非常流行的繪圖OCX控件Teechart來
實現的,這種控件對于一般的繪圖功能都可以實現,但也存在一定缺陷。在
Matcom4.5版本中使用的是TeeChart3.0。繪圖函數功能主要在lib文件和
window/system/ago*.dll中定義的。
Matcom編譯.m文件是先將.m文件按照與matcom的Cpp庫的對應關系,翻譯為CPP源
代碼,然后用對應版本的C編譯器將該CPP文件編譯為exe或dll文件,所以,在第一次
運行時讓指定C Complier的路徑是必需的,否則將無法編譯。指定好的C Complier的
信息寫在Matcom/bin/matcom.ini文件中。
3.1.3 Matcom的不足
Matcom并不是全能的,對于大多數Matlab函數都可以進行CPP實現,但有些由于其
功能有限,只能期待以后的版本來不斷補充了。
總的來說,matcom有以下缺欠:
1.對class數據類型部分支持
2.eval,feval,clear等語句不能在C中實現(如果實現的話,一個文本編輯器就可以成為
一個matlab了:))
3.圖形窗口有些不僅如人意,如fill3,hide等語句無法實現,surf等語句也無法畫出象
matlab中哪樣精細的圖像來,特別是色彩比較難看:(
等等。。。。。。
3.1.4 Matcom下載地址及網絡資源
下載地址是版上詢問最多的問題,再次建議大家能到教育網的搜索引擎
http://pccms.pku.edu.cn:8000/
http://search.igd.edu.cn
http://soft.cs.uestc.edu.cn/search.php
搜索關鍵字matcom或MIDEVA,可以查找教育網上的最新的matcom資源
Matcom的開發者Mathtools公司地址是
http://www.mathtools.net/上面也提供了免費下載服務(他們還會給你一個
evaluation key),如果你從哪里下載,他們會給你定期發email告訴最新
的動態。
大家可以定期到公司主頁看看有沒有版本更新
FIND: 83 C4 08 85 C0 75 05
REP : -- -- -- -- -- EB --
如果還想去掉figure標題欄上的[Evaluation software]:
FIND: 43 61 70 74 75 72 65 00 20 5B
REP : -- -- -- -- -- -- -- -- -- 00
huangfh (hoho)對60分鐘時間的破解, 就比較完整了:
FIND : 2B D1 81 FA 10 0E 00 00 7E 10
REP : -- -- -- -- -- -- -- -- EB --
3.2.2 Matcom 4.5 的安裝
感謝energy的破解,Matcom4.5的口令為FREE-4.5-1193046-80295111
matcom4.5在安裝時需要你輸入口令,mideva在window的注冊表中
HKEY_CURRENT_USER\Software\MathTools\Matcom\4.50\License\
下面添加一個鍵,鍵名默認,鍵值為FREE-4.5-1193046-80295111
你如果刪除它,再次啟動matcom的時候,就會再次詢問口令。
不過好在如果通過這個口令之后,程序發布時就不再有限制了,也
就是在這個注冊后的系統中編譯的程序,發布時就不用代一個注冊文件了
3.3 用Matcom翻譯m文件
直接調適M文件:在主界面上打開.m文件的主文件,在菜單中選擇compile to exe
or dll 就可以了,你也可以設置斷點后,就可以查看變量的值,這些將在主窗口
的一側出現,雙擊就可得到其當前值。
編譯后的cpp、exe、dll文件都在matcom 當前工作目錄下,如果是debug模式,就
在dubug目錄下找,否則就在Release目錄下找。
3.4 在CB中C++與Matlab語言混編
這種方法是我最喜歡的方法,因為這樣不但可以發揮matcom強大的數學計算功能,
還可以結合可視化編譯環境來進行界面開發,可以制作完整的應用計算軟件,交付用
戶使用。我所用的可視IDE是Inprise公司的C++Builder 3.0/4.0,matcom版本為4.0/4.5,注意,在CB4.0上只能使用matcom4.5版本。
在進行編程之前你需要作如下準備工作
1.選擇菜單New\Console Wizard\Console Exe,建立一個Win32位DOS程序
2.將matcom\lib\matlib.h拷貝到CB\include目錄下
將matcom\lib\v4500b.lib拷貝到CB\lib目錄下
3.選擇菜單Project\Add to project\選擇lib\v4500.lib
于是程序變為
#pragma hdrstop
#include <condefs.h>
#include "stdio.h"
#include "matlib.h"
//---------------------------------------------------------------------------
USELIB("v4500b.lib");
//---------------------------------------------------------------------------
#pragma argsused
int main(int argc, char **argv)
{
/*****************************************/
// Please Write Your Code Here */
/*****************************************/
return 0;
}
3.選擇菜單Project\Add to Reportaries\ 將該工程存為Project中的一個模板。
OK,現在可以進行你所需要的工作了。
用菜單你存為的模板建立一個新的工程,在代碼段寫
dMm(a); //define a Matrix class
a=zeros(3); //Let the matrix be a 3*3 zero matrix
disp(a); //Display the matrix
運行一下看看,程序會打印出3*3的0零陣
稍微復雜一點的程序
dMm(a);dMm(b);dMm(c); //聲明三個矩陣
a=rand(3,2); //生成3*2隨機陣
b=zeros(3,2);
c=a+b; //矩陣相加
c(1,c_p)=a(2,c_p); //matlab中寫為c(1,:)=a(2,:)
c=ctranspose(c); //矩陣轉置
disp(c);printf("\n");
disp(a);printf("\n");
getch();
c(colon(1,1,3))=a(colon(1,2,5)); //matlab中寫為c([1:1:3])=a([1:2:5])
disp(c);
getch();
可以發現在matlab中常用的一些表示都可以在matcom中找到對應,并且同樣
方便有效。
再舉一個繪圖的例子,就用matcom自己帶的例子吧
subplot(121.0); //subplot(1,2,1)
surf((CL(peaks(25.0)))); //surf(peaks(25))
subplot(122.0); //subplot(1,2,2)
pcolor((CL(peaks(25.0)))); //pcolor(peaks(25))
colormap(TM("copper")); //colormap('copper')
drawnow() //必須有這句,否則只畫一個圖出來
//這是我問他們的技術支持搞到的
可以看到基本上是一句對一句,沒有什么多余的話。所以習慣編寫
matlab程序的同志寫matcom C的語句來也應該沒有什么問題。
(但上面這個程序確實有問題,在mideva中編譯后第二個subplot
是可以正常畫出來的,但在CB中編譯就只畫一個subplot,具體
原因希望大家討論,我現在也在試,mideva編譯該語句的指令是
bcc32 文件名 -IC:\MATCOM45\lib -H=matlib.csm -v -a4 -5 -e
EXEFLAGS= -WC
DLLFLAGS= -WD
我想CB中可能要改option,大家試試看。
總的說來,決大多數的matlab的語句都可以輕松移植到CB中來,所以就可以直接在
CB中寫matlab程序了,只是大家要注意幾個關鍵的函數
colon(xstart,xstep,xstop) == xstart:xstep:xstop
(CL(A1),A2,A3....) == (A1,A2,A3,...)一個矩陣行,大多數
多參數輸入函數都用到CL
(BR(a1),a2,a3....) == (a1,a2,a3...)
TM("a string") == 'a string' TM將char *變為串矩陣
c_p == : 整行或整列
i_o == [out =fun(in)就寫為fun(in, i_o, out)
其他的大家編幾個程序就清楚了。
3.6 程序的發布
matcom可以用C編譯器把.m文件編譯為為stand_alone的程序,所以,基本上
不需要matlab系統,但一些必要的dll文件還是需要的,這些dll在window\system\
下面,(在4.5版本中)大概有ago4500.dll,v4500v.dll,opengl32.dll, glu32.dll等
四個文件
如果用的是4.0版本,發布時要把ago.dll,mlib4...dll(計不清楚了),opengl32.dll和
glu32.dll打到安裝盤中,大概3M,然后在window目錄安裝一個名字叫mt_eval.txt的
文本文件,里面寫1/1/1999-1/1/2010-64562264即可
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -