| 24小時(shí)熱門(mén)版塊排行榜 |
| 查看: 6809 | 回復(fù): 26 | ||||||||||||||||
ychang1金蟲(chóng) (正式寫(xiě)手)
|
[交流]
Matlab心得及學(xué)習(xí)方法(不斷更新) 已有25人參與
|
|||||||||||||||
|
Matlab心得及學(xué)習(xí)方法(不斷更新) P.S. 那些網(wǎng)上轉(zhuǎn)載我的文章不寫(xiě)明出處的傻眼了吧?!老子更新了! 發(fā)現(xiàn)現(xiàn)在很多人(找工作的或者讀博的)都想要學(xué)習(xí)或者正在學(xué)習(xí)Matlab,問(wèn)我要怎么學(xué)習(xí)。其實(shí)我雖然寫(xiě)Matlab代碼的經(jīng)驗(yàn)還算豐富,但是還不能說(shuō)是一個(gè)很好的Matlab編程人員,這里有一些心得,分享給大家希望對(duì)大家有所幫助。 關(guān)于如何學(xué)習(xí)Matlab 我的學(xué)習(xí)方法很簡(jiǎn)單:Matlab是練出來(lái)的,而不是看出來(lái)的。很多人問(wèn)我有沒(méi)有比較好的Matlab教材,我說(shuō)隨便找一本吧,都可以。只要書(shū)里面有最基本的語(yǔ)法和命令,對(duì)于一個(gè)有編程基礎(chǔ)的人,Matlab可以在一個(gè)下午的時(shí)間內(nèi)學(xué)會(huì)。當(dāng)然,僅僅是學(xué)會(huì)。如果想要對(duì)Matlab比較得心應(yīng)手,那么最好的辦法就是練習(xí)。練習(xí)的素材很多,比如對(duì)于學(xué)經(jīng)濟(jì)學(xué)的,可以做一些simulation之類(lèi)的,也可以試著把計(jì)量或者宏觀教材里面的一些算法寫(xiě)寫(xiě)出來(lái)。一開(kāi)始可能很慢,但是當(dāng)你完成了一個(gè)比較大的project的時(shí)候,你的Matlab的功力將會(huì)有巨大的提升。 當(dāng)然,在你寫(xiě)程序之前,多讀一些別人寫(xiě)的好的code是非常有幫助的。 一些Matlab的經(jīng)驗(yàn) 1、適當(dāng)了解一些數(shù)值計(jì)算、數(shù)值分析以及最優(yōu)化的理論 用Matlab的無(wú)非是做數(shù)值計(jì)算或者最優(yōu)化,這也是Matlab的強(qiáng)項(xiàng),Matlab有足夠多的工具箱解決這些問(wèn)題。但是在使用這些工具箱之前,應(yīng)該首先了解一些數(shù)值計(jì)算以及最優(yōu)化的理論。這一點(diǎn)在程序碰到問(wèn)題或者計(jì)算結(jié)果不理想的時(shí)候尤為重要。很多時(shí)候結(jié)果不理想并不是自己的理論出了問(wèn)題,而是盲目或者錯(cuò)誤使用Matlab的工具箱而導(dǎo)致的。比如我曾經(jīng)做過(guò)一個(gè)單純形法的優(yōu)化程序,但是結(jié)果總是不理想,這個(gè)時(shí)候就要返回到單純形法具體是一種什么樣的算法來(lái)考慮這個(gè)問(wèn)題,最后發(fā)現(xiàn)是由于目標(biāo)函數(shù)的某一部分十分平緩導(dǎo)致的。 當(dāng)然更重要的是如果你不理解理論,很多問(wèn)題根本不知道如何處理。有個(gè)學(xué)化學(xué)同學(xué)就曾問(wèn)我一個(gè)程序怎么寫(xiě),說(shuō)matlab肯定可以完成的。了解清楚之后才明白原來(lái)他想做的就是一個(gè)受限最小二乘。但是他不懂得什么是最小二乘(因?yàn)闆](méi)怎么學(xué)過(guò)數(shù)學(xué)),當(dāng)然面對(duì)這個(gè)問(wèn)題無(wú)從下手。 2、理解Matlab中時(shí)間空間的轉(zhuǎn)化 這個(gè)問(wèn)題沒(méi)有人強(qiáng)調(diào),但我覺(jué)著蠻重要。這里的關(guān)鍵點(diǎn)其實(shí)很簡(jiǎn)單,就是盡量減少重復(fù)計(jì)算,哪怕是多項(xiàng)式復(fù)雜度以?xún)?nèi)的計(jì)算。重復(fù)計(jì)算的內(nèi)容應(yīng)該適時(shí)保存到內(nèi)存中,以后直接調(diào)用。一個(gè)程序可能會(huì)重復(fù)運(yùn)行幾千次幾萬(wàn)次,一點(diǎn)點(diǎn)的浪費(fèi)時(shí)間都可能被放大很多?臻g(內(nèi)存)我們是可以擴(kuò)充的,但是時(shí)間不是,所以絕大多數(shù)時(shí)候我們需要放棄空間,獲得時(shí)間上的迅捷。 這里有個(gè)故事,曾經(jīng)在某技術(shù)論壇上看到的,說(shuō)騰訊公司早期做的QQ實(shí)在太過(guò)垃圾,他們追蹤過(guò)QQ的行為,發(fā)現(xiàn)在幾分鐘時(shí)間里重復(fù)調(diào)用了某同一注冊(cè)表項(xiàng)幾百次。顯然注冊(cè)表的內(nèi)容所占內(nèi)存是有限的,甚至是可以忽略的,但是每次讀注冊(cè)表項(xiàng)可能都要讀硬盤(pán),這里的時(shí)間花費(fèi)是很大的,為什么不把這項(xiàng)內(nèi)容直接存儲(chǔ)在內(nèi)存里呢? 一個(gè)比較經(jīng)典的例子:考慮交換兩個(gè)變量a,b的值,有如下寫(xiě)法: c=a; a=b; b=c; 或者: a=a+b; b=a-b; a=a-b; 第一種寫(xiě)法多占了內(nèi)存,因?yàn)樾枰嗌暾?qǐng)一個(gè)c的內(nèi)存空間;第二種寫(xiě)法節(jié)省了內(nèi)存空間,但是卻多了三次計(jì)算時(shí)間。請(qǐng)問(wèn)哪種好?不一定,看你的時(shí)間空間的權(quán)衡。但是具體到這個(gè)例子來(lái)說(shuō),第二種是不推薦的,因?yàn)椋菏紫,第二種程序晦澀難懂,難以維護(hù),內(nèi)存不至于低到不能存儲(chǔ)一個(gè)變量;第二,如果兩個(gè)數(shù)字都特別特別大,計(jì)算a的時(shí)候會(huì)有溢出的危險(xiǎn)。 3、形成良好的編程規(guī)范 我想幾乎所有學(xué)過(guò)編程的人都被這樣告誡過(guò)。比較好的是Matlab自帶的編輯器本身就可以自動(dòng)縮進(jìn)之類(lèi)的,程序十分易讀。但是還有一些東西是有些人不曾注意過(guò)的。比如變量名,一個(gè)好的變量名一定要有清晰的含義,讓人一看就能明白,否則日后的修改維護(hù)必然要花費(fèi)更多的時(shí)間去識(shí)別這些變量名的含義。這一點(diǎn)可以參考http://coolshell.cn/articles/1038.html http://coolshell.cn/articles/1990.html 這里面詳細(xì)列舉了很多命名的規(guī)則和技巧。 還有一點(diǎn)就是注釋。好的注釋可以極大的方便以后的維護(hù)以及代碼的重用。我的習(xí)慣是在代碼的開(kāi)頭都要交代這個(gè)代碼是干什么用的,怎么用等等。在程序中一個(gè)大塊的功能模塊也要加上注釋告訴大家你在做什么。如果某個(gè)語(yǔ)句很復(fù)雜,可以加注釋告訴大家這句到底在干什么。這樣寫(xiě)出來(lái)的程序維護(hù)起來(lái)或者他人使用起來(lái)將非常方便。 另有一篇十分有趣的文章分享給大家:如何寫(xiě)出無(wú)法維護(hù)的代碼 http://coolshell.cn/articles/4758.html 4、如果拿到一個(gè)任務(wù)而又沒(méi)有思路,試著把問(wèn)題分解或者轉(zhuǎn)化。 之所以叫做程序,是因?yàn)槲覀兯龅墓ぷ骶褪歉嬖V計(jì)算機(jī)要做什么,該怎么做。所以如果你的腦子里根本不知道這個(gè)問(wèn)題該怎么解決的時(shí)候,你就更加無(wú)法寫(xiě)出程序。找思路的一般方法是分解問(wèn)題,然后逐個(gè)擊破;蛘咴谔厥馇闆r下,需要把問(wèn)題轉(zhuǎn)化。 分解與轉(zhuǎn)化的第一步是把實(shí)際問(wèn)題轉(zhuǎn)化為數(shù)學(xué)問(wèn)題。這一步可能已經(jīng)做好,可能沒(méi)有。如果沒(méi)有,那么這一步就叫做數(shù)學(xué)建模。絕大多數(shù)問(wèn)題都可以轉(zhuǎn)化為兩類(lèi)問(wèn)題,一類(lèi)是最優(yōu)化問(wèn)題,一類(lèi)是求解問(wèn)題。如果你能知道你在最優(yōu)化什么東西或者求解什么東西,問(wèn)題就簡(jiǎn)單很多。 轉(zhuǎn)化問(wèn)題的第二步是把數(shù)學(xué)問(wèn)題轉(zhuǎn)化為程序(不是代碼)。也就是說(shuō),你要想清楚這個(gè)問(wèn)題(最優(yōu)化或者求解)是怎么一步步實(shí)現(xiàn)的。 這個(gè)過(guò)程可能很簡(jiǎn)單,有現(xiàn)成的方法用,也有可能很復(fù)雜,還可能涉及多種轉(zhuǎn)化。比如我們經(jīng)濟(jì)學(xué)中遇到的求解動(dòng)態(tài)最優(yōu)化,經(jīng)常要把連續(xù)的東西離散化(離散化很重要。。 最后,考慮怎么把你的程序轉(zhuǎn)化為真實(shí)的代碼。這一步說(shuō)簡(jiǎn)單很簡(jiǎn)單,因?yàn)橹灰阕龊昧艘陨蟽刹剑@一步是順其自然的。但是當(dāng)然會(huì)有很多小的細(xì)節(jié),也許這就是所謂的technique。但是我還是覺(jué)著,學(xué)習(xí)編程不是學(xué)習(xí)technique,而是學(xué)習(xí)第二步,雖然本文關(guān)注的更多的是technique。 5、如果程序出錯(cuò)了,而又查不到語(yǔ)法的錯(cuò)誤,使用斷點(diǎn) 編程中最可怕的錯(cuò)誤不是語(yǔ)法,而是邏輯錯(cuò)誤,因?yàn)檫壿嬪e(cuò)誤是最難debug的。一個(gè)很有用的工具就是斷點(diǎn)。 斷點(diǎn)應(yīng)該是debug中最常用的工具。Matlab的編輯器中可以很方便的實(shí)現(xiàn)(在每一行的開(kāi)頭有個(gè)小橫線,單擊一下變成紅點(diǎn),然后就設(shè)置成斷點(diǎn)了)。當(dāng)程序運(yùn)行到斷點(diǎn)之后就會(huì)中斷,然后會(huì)在主窗口顯示K>>的標(biāo)志,這時(shí)你可以輸入命令查看內(nèi)存情況等等。一步步的跟蹤,直到變量值跟你的預(yù)期不一樣,這時(shí)你就可以很容易的找到錯(cuò)誤在什么地方發(fā)生了。 6、如果試了很多辦法還是不能找到錯(cuò)誤,那就嘗試一下終極debug方法,適用于各種語(yǔ)言 真的有這么強(qiáng)大的debug方法么?有的!這個(gè)方法很簡(jiǎn)單,離開(kāi)你的電腦,找一個(gè)人,隨便什么人,說(shuō)一遍你的程序的思路,說(shuō)的越具體越好。多數(shù)情況下,你在闡述的過(guò)程中,程序的錯(cuò)誤就會(huì)突然從你的大腦里冒出來(lái)了。 如果實(shí)在找不到就找大街上的乞討人員吧,給他們十塊錢(qián)他們應(yīng)該很樂(lè)意聽(tīng)你說(shuō)的,并且說(shuō)不定還可以給你一些很好的建議,然后告訴你,十年前他們也在做同樣的工作。 7、 理解通用與專(zhuān)用之間的權(quán)衡 你可以寫(xiě)一個(gè)通用的程序,也可以寫(xiě)一個(gè)專(zhuān)用的程序,這需要你的權(quán)衡。一般情況下,專(zhuān)用的程序你可以研究清楚其結(jié)構(gòu),從而找到最快的算法,而通用的程序則不能達(dá)到這點(diǎn),因?yàn)橐紤]到很多很多特殊的情況。 比如給定一個(gè)分布函數(shù)F(x),我想要寫(xiě)一個(gè)隨機(jī)數(shù)生成器是的生成的隨機(jī)數(shù)的分布函數(shù)為F(x). 方法很簡(jiǎn)單,先生成一個(gè)均勻分布的隨機(jī)數(shù)a,是的a~U(0,1),然后計(jì)算F的反函數(shù)在a處的值。很多人可能會(huì)用fsolve之類(lèi)的辦法,但是這不是最快的。如果我們已經(jīng)知道F是一個(gè)單增的函數(shù),那么這個(gè)解有且僅有一個(gè)。這樣我們就可以直接使用一些算法去解決他。 類(lèi)似的問(wèn)題還有如果我們知道導(dǎo)數(shù),那么求最優(yōu)化最好的方法也許是牛頓法,而不是用單純形法去尋找,那樣既不精確又慢 但是通用的程序也是非常吸引人的,因?yàn)榭梢源蟠蟮臏p少開(kāi)發(fā)的時(shí)間,如果計(jì)算時(shí)間不是首要考慮的問(wèn)題的話。 8、盡量使你的程序更通用 也就是說(shuō),盡量使你的代碼能被重復(fù)利用。這樣可以節(jié)省很多寫(xiě)程序的時(shí)間,而你發(fā)現(xiàn)這些東西都是你寫(xiě)過(guò)很多遍的。 很多人沒(méi)有一個(gè)寫(xiě)通用程序的好的習(xí)慣。比如說(shuō)下面一個(gè)最簡(jiǎn)單的例子: x=randn(10000,1); y2=zeros(10000 ,1); for i=1: 10000 y2(i)=exp(x(i)); end 這樣寫(xiě)的問(wèn)題在于,如果你的x需要改變了,比如改成100維,那么你需要修改不止一次。但是如果你寫(xiě)成這樣: x=randn(10000,1); y2=zeros(length(x),1); for i=1:length(x) y2(i)=exp(x(i)); end 那么是不是僅僅修改一個(gè)地方就可以了呢? 9、 盡量使你的程序模塊化 把需要重復(fù)進(jìn)行的程序盡量寫(xiě)成函數(shù),便于修改和維護(hù)。寫(xiě)成函數(shù)的好處是使你在同一時(shí)間只關(guān)注一個(gè)問(wèn)題,但是如果你把所有的東西都放在一個(gè)程序里,你可能需要考慮的問(wèn)題就不止一個(gè)了。 10、在使用變量之前先進(jìn)行聲明,盡量少使用矩陣變維操作 這不是matlab必須的,但是是十分建議的。比如如果你寫(xiě)下了如下的代碼: for i=1:10000 y=y+i; end 你沒(méi)有聲明y,而是直接試用了它,很可能會(huì)出現(xiàn)問(wèn)題。比如你的內(nèi)存里之前已經(jīng)有y,y=10,那么你的計(jì)算結(jié)果是不是會(huì)大10呢?更有可能的情況是你之前已經(jīng)運(yùn)行了這個(gè)程序,但是你的開(kāi)頭沒(méi)有clear(開(kāi)頭使用clear也是很好的習(xí)慣) 此外,盡量少使用矩陣變維的操作。因?yàn)槊看温暶髯兞炕蛘呔仃囎兙S,Matlab總要申請(qǐng)一個(gè)新內(nèi)存空間,頻繁進(jìn)行變維操作會(huì)很快侵蝕掉你的內(nèi)存空間,這點(diǎn)在大矩陣的時(shí)候特別重要。 11、計(jì)算盡量多的使用矩陣,盡量少的使用循環(huán) 循環(huán)的好處是比較容易想,比較容易些,但是也比較難以維護(hù),最重要的,速度很慢。 比如下面一個(gè)例子: x=randn(10000,1); tic y1=exp(x); toc tic y2=zeros(length(x),1); for i=1:length(x) y2(i)=exp(x(i)); end toc 輸出結(jié)果: Elapsed time is 0.000287 seconds. Elapsed time is 0.000963 seconds. 可見(jiàn)使用矩陣比使用循環(huán)快了三倍。 12、如果進(jìn)行大量的重復(fù)操作,可以考慮使用并行計(jì)算 比如在做Monte Carlo模擬的時(shí)候,你的每次循環(huán)都是獨(dú)立的(每次循環(huán)不影響下一次循環(huán)的結(jié)果),那么可以考慮使用并行處理,如果你的電腦是多核的。 首先,你要用以下命令創(chuàng)建幾個(gè)并行的進(jìn)程: matlabpool local 4 其中4是你的計(jì)算機(jī)核心數(shù)。然后,使用parfor代替for循環(huán)就可以了。但是使用這個(gè)命令一定要注意使用前提和不要每次循環(huán)訪問(wèn)同樣的可變的變量。 13、盡量少的涉及符號(hào)運(yùn)算 Matlab最強(qiáng)大的是其數(shù)值運(yùn)算能力,而不是符號(hào)運(yùn)算。如果你需要處理諸如求導(dǎo)求極限之類(lèi)的工作,用Mathematica或者M(jìn)aple。特別是盡量少的使用符號(hào)定義的函數(shù), 比如用fsolve之類(lèi)的,如果只是計(jì)算一次兩次非常方便,但是如果進(jìn)行大量重復(fù)的此類(lèi)運(yùn)算,其速度很慢,最好研究清楚要解的函數(shù)的性質(zhì),用專(zhuān)門(mén)的算法進(jìn)行處理,matlab大多數(shù)時(shí)候也有專(zhuān)門(mén)的工具箱。 14、壓縮你的內(nèi)存空間 Matlab的內(nèi)存管理方式使得內(nèi)存經(jīng)!八槠保貏e是當(dāng)一個(gè)變量被清除出內(nèi)存,留下的空間又不足以裝下下一個(gè)變量,內(nèi)存就變成了“碎片”,這個(gè)跟硬盤(pán)碎片是一個(gè)道理?梢杂"pack"命令。如果你的內(nèi)存里面有很大的矩陣,不要忘了經(jīng)常用"clear"命令清除不用的矩陣。當(dāng)然pack命令比較耗時(shí),不要再循環(huán)里面或者函數(shù)里面使用。還有一個(gè)辦法就是先用save命令保存內(nèi)存,然后全部清除掉,再用load命令載入。 15、使用稀疏矩陣 如果碰到一個(gè)矩陣很大,但是多數(shù)數(shù)字都是0,試著用sparse命令轉(zhuǎn)化為稀疏矩陣。一個(gè)例子是空間計(jì)量里面的權(quán)重矩陣,一般來(lái)說(shuō)多數(shù)是0,LeSage的空間計(jì)量工具箱里面就是用的稀疏矩陣 源地址: http://blog.renren.com/GetEntry. ... amp;owner=222496841 |
資源收集 | 仿真建模與計(jì)算 | 數(shù)值模擬與仿真 | matlab典型案例及小技巧 |
電子信息 | 資源下載 | 心靈之約 | 阿亮的煩惱生活系列 |
資料來(lái)源 | 拉曼 測(cè)試 增強(qiáng) 應(yīng)用 | EP tech | 信息 |
瞎看的 |

金蟲(chóng) (正式寫(xiě)手)

鐵蟲(chóng) (小有名氣)
至尊木蟲(chóng) (職業(yè)作家)
|

銀蟲(chóng) (小有名氣)

木蟲(chóng) (正式寫(xiě)手)

鐵桿木蟲(chóng) (著名寫(xiě)手)
我是傻子

| 最具人氣熱帖推薦 [查看全部] | 作者 | 回/看 | 最后發(fā)表 | |
|---|---|---|---|---|
|
[考博] 26博士申請(qǐng) +3 | 1042136743 2026-03-17 | 3/150 |
|
|---|---|---|---|---|
|
[考研] 085601專(zhuān)碩,總分342求調(diào)劑,地區(qū)不限 +4 | share_joy 2026-03-16 | 4/200 |
|
|
[考研] 268求調(diào)劑 +7 | 好運(yùn)連綿不絕 2026-03-12 | 8/400 |
|
|
[考研] 299求調(diào)劑 +4 | △小透明* 2026-03-17 | 4/200 |
|
|
[碩博家園] 湖北工業(yè)大學(xué) 生命科學(xué)與健康學(xué)院-課題組招收2026級(jí)食品/生物方向碩士 +3 | 1喜春8 2026-03-17 | 5/250 |
|
|
[考研] 312求調(diào)劑 +4 | 陌宸希 2026-03-16 | 5/250 |
|
|
[考研] 085601求調(diào)劑 +4 | Du.11 2026-03-16 | 4/200 |
|
|
[考研] 332求調(diào)劑 +6 | Zz版 2026-03-13 | 6/300 |
|
|
[考研] 【0856】化學(xué)工程(085602)313 分,本科學(xué)科評(píng)估A類(lèi)院;瘜W(xué)工程與工藝,誠(chéng)求調(diào)劑 +7 | 小劉快快上岸 2026-03-11 | 8/400 |
|
|
[考研] 梁成偉老師課題組歡迎你的加入 +8 | 一鴨鴨喲 2026-03-14 | 10/500 |
|
|
[考研] 271求調(diào)劑 +12 | 生如夏花… 2026-03-11 | 14/700 |
|
|
[考研] 285化工學(xué)碩求調(diào)劑(081700) +9 | 柴郡貓_ 2026-03-12 | 9/450 |
|
|
[論文投稿] 有沒(méi)有大佬發(fā)小論文能帶我個(gè)二作 +3 | 增銳漏人 2026-03-17 | 4/200 |
|
|
[基金申請(qǐng)]
今年的國(guó)基金是打分制嗎?
50+3
|
zhanghaozhu 2026-03-14 | 3/150 |
|
|
[考研] 337一志愿華南理工0805材料求調(diào)劑 +7 | mysdl 2026-03-11 | 9/450 |
|
|
[考研] 求材料調(diào)劑 +5 | 隔壁陳先生 2026-03-12 | 5/250 |
|
|
[考研] 281求調(diào)劑 +9 | Koxui 2026-03-12 | 11/550 |
|
|
[考研] 290求調(diào)劑 +7 | ADT 2026-03-12 | 7/350 |
|
|
[考研] 321求調(diào)劑(食品/專(zhuān)碩) +3 | xc321 2026-03-12 | 6/300 |
|
|
[考研] 333求調(diào)劑 +3 | 152697 2026-03-12 | 4/200 |
|