天天看點

寫給學習 matlab 的新手們

發信人: YFER (你好 2008), 信區: Matlab

标  題: [ZZ]寫給學習 matlab 的新手們

發信站: 紫金飛鴻 (2008年01月18日22:24:51 星期五), 站内信件

轉:本人接觸matlab已經有5年多的時間了,一直想寫點東西,但是之前不知道放在哪裡

才能發揮它的最大作用,直到幾天前碰上了這個論壇(有點像諸葛亮遇見姜維,哈哈)

廢話不說,我想借貴論壇寶地,寫一些經驗給使用matlab的新手們,當然了,老大們也

可以看看,不嫌棄我寫得粗糙的話還可以指點一下,先謝過了~~~~

首先我想說的是,matlab跟其他語言不一樣(我用的比較多的程式設計語言,除了matlab就

應該是c或c++了,VB和Delphi也接觸過,我想版面(matlab版)大部分人也差不多),

如果你抱着“把其他語言的思想運用在matlab裡面”的話,那麼我想,即使程式運作不

出錯,也很難把握matlab的精髓,也就很難發揮matlab的作用了。是以,如果你是希望

掌握一門語言、一個工具,使它更有效為你服務的話,那麼,希望本文對你有所幫助,

請精讀;如果你是希望matlab作為VC的附屬品,即你不想在matlab上面花太多功夫,隻

純粹想用matlab來完成VC做不了或很難做成的任務的話,那麼,本文你也應該至少浏覽

一下。

Matlab是一個基于矩陣運算的軟體,這恐怕是衆所周知的事情了,但是,真正在運用的

時候(就是在程式設計的時候),許多人(特别是初學者)往往沒有注意到這個問題,是以

,for循環(包括while循環)滿天飛…………..這不僅是暴殄天物(沒有發揮matlab所

長),還浪費了你寶貴的時間。對此,版友MVH在他的“MATLAB 小技巧”一文中也有所

涉及,雷同的東西我也就不重複了,matlab的“幫助”裡面也有相關的訓示。我這裡想

說的一點是,初學者往往在初始化矩陣的時候注意到這個問題,懂得了使用矩陣而不是

循環來指派,但是,在其他環節上,就很容易疏忽,或者說,仍然沒有擺脫C++的思想

。舉個例子吧,下面的代碼是我的一個師弟寫的,我想他接觸matlab也有2、3年時間了

(在此說明一下,接觸2、3年并不是表示每天都會跟matlab打交道,我本人也不是,隻

是在一年某幾個時間段裡面連續使用),但是仍然會出現類似的問題:

J = 0;

lt = size(imf1,2);

for (i = 1:lt)

    if (abs(imf1(i)) > 1)

        J = 1;

        break

    end

end

上面的代碼實作了一個目的――檢查信号imf1(一個向量)是否存在絕對值大于1的點,

這顯然是基于C++的思想寫出來的。如果在matlab下面,其實用兩個語句就足夠了(當

然,可以合并為一個):

q = find(imf1>1);

J = ~isempty(q);

這樣的修改帶來的好處是很可觀的。

又如:

for j = 1:num

    imf1(start1+j) = 2*li1(j+1) - imf1(start1+j);

end

這是一個對稱翻折的問題,它完全可以用以下這個語句簡潔表示:

imf1(start1+1:start1+num) = 2*li1(2:num+1) - imf1(start1+1:start1+num);

是以,如果是新手,可以先用循環(基于C++的思想)來編寫代碼,然後看看能否用ma

tlab的語言(基于矩陣的思想)來改進。當然,這樣做的前提是你對matlab提供的一些

函數比較熟悉才行,這些函數在matlab的“幫助”那裡搜尋“Functions Used in

Vectorizing”就可以找到一些,其他的也可以找相關的書籍(沒找到?不可能,電子版

總可以下載下傳到的)

對提高matlab程式設計能力的方法,我想主要有以下三個:

1. 查help

2. 多上上論壇,搜尋文章、發文章問人

3. 閱讀别人、特别是牛人的程式

當然了,正如所有的程式語言一樣,“3分課本7分上機”,一定要動手才行,不能光看

。多想、多思考、多嘗試,才是正路。以下技巧就是平日動手程式設計、閱讀别人的文章後

整理出來的(不斷添加中):

1. matlab的運算是基于矩陣的,但是也提供了對應元素的運算,即在運算符前面加上“

點”。例如:

>> a = [1,2;3,4]

a =

     1     2

     3     4

>> b = [-1,-2;-3,0]

b =

    -1    -2

    -3     0

>> a * b

ans =

    -7    -2

   -15    -6

>> a .* b

ans =

    -1    -4

    -9     0

也就是說,沒有加“點”的運算是對整個矩陣而言的,稱為矩陣運算(整體運算),而

加了“點”的運算是對每個元素而言的,稱為點運算(局部運算)。另外,一般情況下

,matlab作點運算(了解為左右兩個對象(矩陣)的對應元素參與該運算)時,兩個矩

陣的維數和長度都要求是同大小的,且此時要在運算法前面添加“點”,但是在某些情

況下該“點”可以省略,例如一個标量a和一個向量b(或者矩陣)相加、相減、相乘、b

/a時都可以不需要加點,表示b中每個元素都和a進行運算(即點運算的效果)

2. 強烈建議大家在命名自己的函數名(更加準确應該說m檔案名)時,在名稱前面加上

my 等個人專用辨別,即假如你要把你的函數命名為conv,則最好寫成 myConv,否則容

易與matlab自帶的函數(m檔案)名字重複而導緻“Attempt to execute SCRIPT conv

as a function”的錯誤!當你碰到這個錯誤時,可以在指令視窗中輸入 which conv

all 來看看到底有否重複命名了該函數,有的話,建議把自己命名的檔案改名,保留

matlab 自帶的檔案。此外,命名檔案名時,必須符合辨別符的規範,即不能以數字開頭

等等,否則會出現莫名其妙的錯誤!

3. 條件判斷中,y==0, a-b==0這類語句應該盡量減少使用,除非你可以保證y、a、b在

整個計算過程中是整數,否則兩個浮點數相減、或者一個浮點數不可能完全等于0

4. 循環變量遞減時必須顯式給出步長,即 i = 5:-1:-5 (假設步長為-1),如果遞增

時且步長為1,則可以省略,簡寫作 i = -5:5

5. 在引号環境下的語句中,如果需要使用單引号,則要寫成兩個單引号的形式,不能用

一個雙引号代替!例如:

...'callback','[imp,Fs,bits]=wavread(''temp.wav'');'  檔案名 temp.wav 外面的

是兩個單引号

6. 如果你編寫的函數帶有輸入參數(例如 x ),則跟其他語言一樣,這隻是形式參數

,是以不能通過直接運作該函數(或者m檔案)來測試,這樣會出現 ??? Input

argument "x" is undefined. 的錯誤。一定要從其他地方(如指令視窗或者其他函數對

其調用)來傳遞真實值,此時 x 才是實際參數。如果你有C語言的程式設計經驗,指令視窗

就相當于main函數;如果沒有,以下是舉例:

myPlus.m:

[Copy to clipboard] [ - ]

CODE:

function d = myPlus(a,b)

d = a + b;

指令視窗:

[Copy to clipboard] [ - ]

CODE:

>> x = 2;

>> y = 5;

>> z = myPlus(x,y)

此外,和每一種程式設計語言一樣,所有定義的變量都有一定的作用域。雖然matlab 宣稱變

量不需要定義即可以直接使用,但是,事實上任何程式設計語言的變量都需要先定義才能使

用,是以 matlab 也不例外(看來真的是“ matlab 宣稱變量不需要定義”惹的禍),

隻不過所不同的是并非使用 int x 這種方式來定義,而是使用一個簡單的指派語句包含

定義+初始化。是以,如果直接使用未定義的變量(最常用的是在“=”右邊首次出現)

,則會出現“Undefined function or variable” 的錯誤!例如:

[Copy to clipboard] [ - ]

CODE:

function y = myTest(x)

z = x * 2;

y = t + z;

則運作時 matlab 會報錯:Undefined function or variable t !此時當實際參數傳遞

給輸入變量 x 後, x、z 就被定義了,但是 t  卻沒有。

是以,強烈建議在使用變量之前(特别是循環中使用數組),先預配置設定空間,這樣容易

減少很多莫名其妙的錯誤,具體做法參見以下圖檔:

  preallocate.bmp (222.48 KB)

2007-5-18 10:55

7. 如何調試程式:編好程式(沒有文法錯誤),設定斷點(m檔案編輯視窗中菜單

Debug 有 Set/Clear breakpoint),運作程式(菜單 Debug 有 Run 或 Save & Run)

,此時 matlab 會停在斷點處,各變量的值可以通過滑鼠停留在變量名上觀察到,或者

在指令視窗中敲入變量名後得到

8. 對于matlab自帶函數(指令)的問題,請多利用matlab的幫助功能。即在指令視窗中

輸入: help eval 或者 doc eval。更多的幫助指令請參閱以下連結的文章:[轉帖]MAT

LAB中的幫助指令

9. 對于 mat 檔案的讀取,由于存放的是結構體數組,是以調用 A = load('*.mat') 後

,得到的 A 并非原始資料,而是一個結構體,此時需要使用".域名" 才能正确得到資料

,例如:

[Copy to clipboard] [ - ]

CODE:

A =load('*.mat');

後得到:

    A =

          Signal: [85x7794x64 single]

      TargetChar: [1x85 char]

        Flashing: [85x7794 single]

    StimulusCode: [85x7794 single]

    StimulusType: [85x7794 single]

則用:

[Copy to clipboard] [ - ]

CODE:

B = fieldnames(A);

可得到各結構體的域名。

如果要獲得各域中(下以 Signal 為例)的資料,必須用:

[Copy to clipboard] [ - ]

CODE:

S = A.(B{1});

此外,不建議使用 load *; 這種方式讀取 mat 檔案(讀取 dat 等其他格式的檔案也是

類似),因為此時讀取後的變量名是存儲時設定的,假若檔案并非您本人存儲,則無法

獲悉這個變量名,通過這種方式是無法在讀取時候指定資料存放在哪個變量中的,這樣

将會導緻下文不知道使用哪個變量名,甚至會導緻出錯!是以,強烈建議采用A =

load('*.mat'); 方式進行讀取,當然了,如果檔案是您本人存儲的,則用前面的方式比

較簡便,這另當别論。下面以 dat 檔案作為例子說明:

clear all

>> a = magic(4);  b = ones(2, 4) * -5.7;  c = [8 6 4 2];

>> save -ascii 1_data.dat

>> load 1_data.dat

因為這種方式的讀取是把資料預設存放在以“不含字尾的檔案名”命名的變量中(這裡

為 1_data),但是由于 1_data 不是合法的辨別符,是以 matlab 自動改成 X1_data(

不同版本的matlab可能不同),即讀取出來的資料事實上是存放在 X1_data 變量中。如

果使用 m 檔案方式程式設計(即 load 1_data.dat 後有分号),則這個變量名根本不會顯

示出來,也就是說,對它的改名你是毫不知情的,這時候下文繼續使用 1_data 的話,

就會産生錯誤。

10. matlab 對中文的檔案路徑(不光是檔案名)不太支援,特别是 6.5 版本。

11. 函數不能在指令視窗中定義,隻能在 m 檔案中定義。否則出現: ??? Error:

Function definitions are not permitted at the prompt or in scripts. 的錯誤!

最後,整理一下常用的快捷鍵(用【】表示)或指令:

1. 在指令視窗(Command Window)中:

1) 【上、下鍵】――切換到之前、之後的指令,可以重複按多次來達到你想要的指令

2) clc――清除指令視窗顯示的語句,此指令并不清空目前工作區的變量,僅僅是把屏

幕上顯示出來的語句清除掉

3) clear――這個才是清空目前工作區的變量指令,常用語句clear all來完成

4) 【Tab】鍵――(轉自版友心燈)在[email protected]看到的:在command視窗,輸

入一個指令的前幾個字元,然後按tab鍵,會彈出前面含這幾個字元的所有指令,找到你

要的指令,回車,就可以自動完成。目前讨論結果是:matlab6.5版本中,如果候選指令

超過100個,則不顯示。而在matlab7以後版本中,則沒有這個限制,均可正常提示

5) 【Ctrl+C】(或【Ctrl+Break】)――(轉自版友yangjin_ren)在matlab程式運作

過程中,可能由于程式編寫的失誤,導緻程式不停的運作,在指令視窗輸入“Ctrl+C”

可以将運作的程式停下來,而不需要将整個Matlab程式關掉。不過進行此操作的前提是

能夠激活切換到指令視窗才行,呵呵。

2. 在編輯器(Editor)中:

1) 【Tab】(或【Ctrl+]】)――增加縮進(對多行有效)

2) 【Ctrl+[】--減少縮進(對多行有效)

3) 【Ctrl+I】--自動縮進(即自動排版,對多行有效)

4) 【Ctrl+R】――注釋(對多行有效)

5) 【Ctrl+T】――去掉注釋(對多行有效)

6) 【Ctrl+B】――括号配對檢查(對版本6.5有效,但版本7.0以上無效,matlab把這項

功能自動內建到編輯器裡面了,即在m檔案編輯視窗中會自動進行括号配對檢查,并在窗

口右側有紅橙綠三燈提示,具體請參考以下文章:http://www.simwe.com/forum/thread

-746722-1-4.html )

7) 【F12】――設定或取消斷點

8) 【F5】――運作程式

其餘的例如在Debug狀态下的快捷鍵就不多說了,自己看菜單Debug吧

累了, 有時間再寫吧。希望大家多交流~~~~~~

Coming: (以下東西都是一年前做的了,不知道能否記起,呵呵)——已經全部完成

1) 關于神經網絡的――調用matlab的nntool指令後的使用問題(我做的時候沒有看過其

他書籍或資料,是自己閉門造車的結果,如果寫之前發現其他書籍有相關介紹的話就不

寫了)

2) 關于外部接口的――matlab與C++Builder的接口,想詳細介紹如何利用matcom

4.5在C++Builder中調用matlab的代碼以及matcom的一些技巧。由于我不是搞項目開發的

(搞科研、搞課題的),是以對VC不熟悉,大學的時候學過一點,不過我想對于搞科研

來說C++Builder就足夠了,免去很多麻煩,Builder在界面設計和資料庫連接配接上面(我

隻接觸過這兩方面)還是做得不錯的。同樣,如果發現其他書籍上有類似的東西就不寫

3) GUI方面也寫寫吧,隻是一點點心得或者體會,呵呵,這個相對簡單些,篇幅相對要

少些。 

繼續閱讀