1. 程式人生 > >使用MATLAB的幾個建議

使用MATLAB的幾個建議

MATLAB是我們常用的工具。而快速學習和熟練掌握MATLAB對於高效完成工作很有意義。本文從親身的經驗出發,介紹一下怎樣學習和使用MATLAB,這些辦法都是已經被若干人證明很不錯的。

1.       學習MATLAB的基礎語法略過了。如果你不太確定,可以在command下邊用一些簡單的數字試一試。如果你習慣用C,那麼注意要將運算矩陣化,什麼叫運算矩陣化呢?就是儘量將迴圈,尤其是帶if的迴圈用矩陣代替。舉個例子:比如把陣列中所有大於1000的資料置為1000,而其它的資料不變,可以寫作x(x>100)=100;如果採用for迴圈加if來做,那麼效率是它的1/4。有時候似乎必須用for解決了,比如將一個1x6的陣列改成2行3列,那麼不妨可以找找庫函式,此例用reshape就可以解決
。如果必須要用迴圈,且對某陣列x的若干下標依次賦值,則一定要先定義x這個陣列,例如可以用x=zeros(1,1000)。否則等於聲明瞭一個不定長度的陣列,效率十分低下。這是絕大多數程式效率損失的原因,當然是有辦法進行檢查的。查的辦法是用MATLAB提供的profiler工具。位於tools->open profiler,工具欄也有圖示。在這個工具上寫入你想執行的函式名或者m檔名,程式就開始執行,執行完畢後,會將其每個語句的執行時間統計出來一下子就可以找到癥結。如果是迴圈體內陣列賦值類的操作,一般是不正常的,你應該看看是否犯了沒有初始化的錯誤。有時候一些函式會佔用掉很多時間,你可以想想有沒有辦法替代它們,如果沒有就進到這個函式內部再去找一找,有時候會有優化的空間。最後的結果往往是絕大部分時間已經耗費在了你很清楚的地方,比如呼叫的底層C函式、卷積運算、矩陣運算等等。

2.       在MATLAB常用的函式中,clear,clc,figure等等要牢記。另外,有時候需要注意某些庫函式的第二個返回值,往往就是你想要的,比如max函式的第一個值時最大的數值,而第二個就是陣列的角標,直接用[value index]=max(x)就可以同時獲得,如果你把第二個數丟了,再用find去找,那就累死了。

3.       學習MATLAB的toolbox函式及其用法不需要看雜七雜八的書,它的幫助足夠了。開啟help->product help,左側列出了很多toolbox,每個toolbox都有幾個子項,Getting Started裡邊具有最權威的上手示例,如果需要長期使用,應該把User’s Guide看一遍

,沒有多少內容,一般一兩天時間就夠了。裡邊具有很多示例的程式碼,有用的部分一定親手試一下。另外對於典型應用,它都有Examples,雖然對於前沿領域來講,這些演算法有點“老”,但是其精煉和高效是其他教材無可比擬的。它會給你展示在這個領域的專家最起碼的實驗技能和討論的主題,甚至可以當做所學專業可能的實驗課本。如果你對上述過程中的具體函式及其實現感興趣,可以到s裡邊找,那裡對每個函式都有詳細的解釋。如果你對這個函式的實現很感興趣,那麼直接在command中寫 “edit 函式名”,你就可以看到它的實現的原始碼。甚至某些圖形工具,例如fdatool、imtool、bertool等等。函式內部有可能巢狀更深層的函式,那麼請你用一個你最熟悉的資料呼叫它,通過除錯+單步跟蹤的方式一步一步查下去,由於資料你是熟悉的,因此你可以很快搞定其內部工作方式

有兩種例外:

其一是MATLAB新的函式啟用的object型別,對其原始碼進行了封裝,通過edit可能看不到什麼東西,那麼怎麼找到它的原始碼呢?有兩個辦法,其一是單步跟蹤,如果還解決不了,那麼可以用上文提到的profiler工具,它會把呼叫到的函式一一列寫,很有可能是最頂層的某個函式進不去,可以在其下的函式上定一個斷點,看看資料跑過來怎樣,再往下一步步跟蹤,基本上就不會有單步跟不到的地方了。

另一個例外是遇到了MATLAB的buildin函式或者C函式,那就真的沒辦法了,因為這兩個函式是沒有原始碼的。

MATLAB庫函式有統一的結構,第一部分是幫助資訊,help可以看到的部分,之後是變數檢查,最後是實現過程。由於很多函式為了通用,實現的細節不是最優的,並且對引數做了太多的檢查,如果你需要更好的效能,可以將其關鍵的語句提煉出來,或者用純粹的矩陣運算表述出來,往往可以起到提速的作用。另外,你也可以把自己的註釋寫在最前邊,這樣就可以通過help查到。

4.       有幾個在原始碼編輯器中的快捷鍵很管用,推薦掌握,ctrl+R註釋選定程式碼,ctrl+T取消註釋,除錯的F5,F10,F11之類,終止執行中的程式ctrl+C。另外,如果你在原始碼編輯器中閱讀原始碼時遇到一個函式想檢視,直接在函式上點右鍵,選擇open selection即可。MATLAB儲存之後的程式碼也是可以撤銷的,甚至可以撤銷到開啟MATLAB時最原始時候的狀態。因此應該常儲存,以便於防止文件丟失。原始碼中可以通過兩個百分號“%%”分割原始碼,甚至只執行一部分,十分有利於比較長的原始碼。

如果在command中想呼叫函式或者變數,敲寫前幾個字母再按tab鍵就可以得到匹配提示。

如果需要檢視變數,尤其是二維的陣列,可以用workspace找到它並雙擊,開啟Variable Editor,這個編輯器可以和Excel互相複製貼上,很是方便

另外,各種窗體的字型和顏色大多是可以改的,在Preferences中有fonts及其他專案,可以關注一下。

最後值得一提的是plot畫出的影象由於是向量圖,如果資料點很多的話,複製到word中很可能會顯示卡殼或很慢,可以先拷貝到畫圖裡邊,然後再貼到word,這樣就是點陣圖了。

5.       如果遇到了大運算量,建議不要運算結束後直接繪圖或者列印結果,而應該採用運算和結果顯示獨立的程式架構。

運算是一個程式,計算後的結果通過save語句儲存成mat檔案,再用另一個程式通過load讀取此檔案,這樣的好處是可以防止結果丟失和篡改。

另外,為了顯示直觀和除錯的方便,可以實時的將計算的進度顯示在command中,比如:

type={'AACH''BSCH''TCH/4.8_1' };

i=3;a=1;

fprintf('Calculating Logical Channel %s using %d antennas\n',cell2mat(type(i)),a);

則可以顯示出

Calculating Logical Channel TCH/4.8_1 using 1 antennas

如果製作了日誌檔案,那就更好了,首先開啟一個檔案,寫入時間戳clock,它是個陣列,代表年月日時分秒之類。

logfid=fopen('log7-26.txt','a+');

fprintf(logfid,'time ');

fprintf(logfid,'%d.',clock);

fprintf(logfid,'\n');

之後依然用fprintf來列印,只不過需要加入logfid控制代碼。

fprintf(logfid,'Calculating Logical Channel %s using %d antennas\n',cell2mat(type(i)),a);

最後fclose(logfid);  用以關閉日誌檔案,幸運的是,如果由於終止運算而沒有執行到這個語句,大多數日誌結果也是存檔了的。

如果需要運算完畢後自動關閉計算機,可以加入這麼一句

!shutdown -s

歎號代表執行一個外部命令,後邊是windows預設的關機程式,可以在執行對話方塊實驗一下,

如果需要停止已經關機,那麼再執行shutdown –a

6.       MATLAB功能實在很多,新功能層出不窮,最好使用新的版本,MATLAB不一定總是對的,很多細節是有失偏頗的,我就遇到了幾次,最嚴重的一次是gaussfir函數出來的結果整個就是不對的,後來發現高版本已經修正了,因此儘量使用更高的版本。有時隨著版本更新,會對你的程式碼提出新的要求,比如用1i代替j代表複數,或者用strcmp而不是~=比較字串等等,它都會用紅線提醒,你可以根據它的提示予以更正。

7.       對於是否使用Simulink,我認為它很直觀,但是缺點是效率不高(主要針對通訊物理層模擬),尤其是蒙特卡洛模擬這種需要大資料量的迴圈模擬。當時曾經嘗試過,學長用Simulink去做,跑5萬點就慢死了,我自己用程式碼來寫,跑到50萬點比他的快很多,後來又通過提取函式內部實現和矩陣優化等方法又有了很大的提升。有時發現迴圈和判斷太多了,只能用C來做。這是MATLAB的很多庫函式的選擇,因此如果你需要更高的效率,也可以這樣來做。MATLAB-C聯合程式設計雖然有利於提高運算效率(甚至可以利用好多核),但是很難除錯C程式碼,在編寫時一定要注意緩衝區溢位之類的問題,因為它會使整個MATLAB崩潰而重啟。因此最好先在VC除錯好,再跟介面連線起來。當然,除錯的時候C程式碼部分沒法單步,但是printf還是可以用的。另外,MATLAB的介面製作工具很好用,而且做出來的東西很贊,建議花點時間學一學,能夠操縱按鈕,讀取複選框和文字的數值基本上就夠用了,它會使你的結果彙報變得很直觀。

【轉】http://blog.21ic.com/user1/3128/archives/2010/71193.html

很抱歉,由於思路未加整理,十分凌亂,謹此獻給常常使用MATLAB的同志們,希望能夠起到一點作用,使大家能善於利用MATLAB開展自己的研究工作。