回覆列表
-
1 # 樂天剪輯
-
2 # 朱慧3757411
資料分析,最簡單的例子,比如你要定義10歲兒童正常身高為多少?你可能先去全國各地收集資料,比如有10000組資料,這個時候用軟體來分析的話就成一個正太分佈,掐頭去尾就是這個區間內正常身高(可能描述的有點粗糙),
-
3 # 五色彩石
一個5跨連續梁的柔度方程矩陣,每天純8個小時,3天列完,用matlab求解矩陣,不到0.1秒結束,手工解該矩陣,先複習線性代數7天,解矩陣7天。不需要什麼奇淫技巧,速度就是最大的技巧。
下邊所有例子如無特殊說明都是在 2016a 上執行,其他版本或有差異,建議自行測試1. 可以用 sprintfc 生成 cellstr: a = magic(3); b = sprintfc("%d",a) b = "8" "1" "6" "3" "5" "7" "4" "9" "2" 2. strfind 可以作用於數值陣列用於查詢子串的位置: k = strfind([2 7 1 3 0 7 1],[7 1]) k = 2 6 3. 可以用 cell 和 函式控制代碼實現類似於函數語言程式設計的操作,以 fibonacci 數列為例: f = {@(f,n)1 @(f,n)f{(n3)+1}(f,n-1) + f{(n4)+1}(f,n-2)}; fib = @(n)f{(n2)+1}(f,n); fib(20) ans = 6765 類似的,構建 if 函式: iff = @(varargin)varargin{find([varargin{1:2:end}],1)*2}; x = 3; iff(x1,1,x2,2,x3,3,x4,4,x5,5) ans = 4 4. regexprep 當替換字串為 ${cmd} 動態表示式時 cmd 可以訪問呼叫時的 caller 工作區:% haha.m function x = haha x = str2double(regexprep("1","1","${num2str(y,16)}")); % command window/命令視窗 y = pi; haha % 注意此處呼叫 haha 函式時並未傳入 y 的值 ans = 3.14159265358979 5. 在 2015b 或 2016a 可以啟用被隱藏的單一維度拓展: builtin("_useSingletonExpansion",1); (1:3)"+(1:3) % 相當於 bsxfun(@plus, (1:3)", 1:3) ans = 2 3 4 3 4 5 4 5 6 (1:3)".^(1:3) % 相當於 bsxfun(@power, (1:3)", 1:3) ans = 1 1 1 2 4 8 3 9 27 除此之外許多(不是全部)的 bsxfun 用法可以簡化為上述形式。這一特性有可能在未來版本中正式釋出6. MATLAB 的一些物件,尤其是圖形物件會有一些隱藏屬性,這些隱藏屬性不能直接看到,但是如果你指定名字的話是可以訪問甚至修改的,比方說以 axes 為例,我們可以修改 axes 的 LooseInset 屬性改變其預設空隙: figure a = axes; a.LooseInset = [0 0 0 0]; % 老版本用 set(a,"LooseInset",[0 0 0 0]) 效果可以自己執行檢視,這裡效果不是重點就不發圖瞭如果你用 get(a) 或者 a.get 中只能看到一部分屬性,其中並沒有 LooseInset。 要想找到類似的隱藏屬性當然可以用 metaclass,不過更直接的方法可能是: struct(a) % 此時要確保 a 沒有被刪除 7. MATLAB 的很多運算子可以被過載,從而實現一些比較方便的功能,之前回答過一個簡單應用的例子:matlab中有沒有類似R中magrittr包的管道操作? - 知乎使用者的回答。這個應該不能算作奇技淫巧吧,不過知道的人可能少一些暫時就寫這麼多吧。還有一些效能方面的,不過感覺那些不算奇技淫巧吧(個人理解是不常見的用法才算(⊙_⊙)?),就不放這裡了----- 2016.5.9 更新 ------8. builtin("_mergesimpts",...),這個用法這裡有介紹:Return Unique Element with a Tolerance,簡單來說可以用來合併相近或者相同的數值的9. anonymousFunction,這個函式功能和 str2func 基本相同,但是他接受兩個輸入,經過嘗試,如果第二個輸入是 "base" 的話不管該函式在哪裡呼叫都可以利用 base 工作區中的變數構建匿名函式:% haha.m function f = haha f = anonymousFunction("@(x)sin(a*x)","base"); a = 2; f = haha; % 此處並未傳入 a f(3)==sin(2*3) ans = 1 10. ismembc ,ismembc2 和 builtin("_ismemberhelper",...)這三個函式都是對有序陣列進行二分查詢,第一個返回邏輯判斷值,第二個返回元素在有序陣列中的位置(如果有重複的就返回最後一次出現的位置),第三個可以返回上述兩個引數(不過第二個是返回首次出現的位置),舉例說明: ismembc([1 3 5],[0 1 1 5 7]) ans = 1 0 1 ismembc2([1 3 5],[0 1 1 5 7]) ans = 3 0 4 [in,loc] = builtin("_ismemberhelper",[1 3 5],[0 1 1 5 7]) in = 1 0 1 loc = 2 0 4 需要注意的是,如果第二個輸入不是單調遞增不會報錯,但是結果是錯誤的。同時,由於是二分查詢,所以要比線性查詢 find(x==y,1) 或者 find(x==y,1,"last") 快很多;順便說一下,如果是行向量的話 strfind(x,y) 通常也要比 find(x==y) 要快一些,兩者都是線性查詢,不需要有序的 x。----- 2016.5.10 更新 ------11. numel 函式可以接受多個引數的,作用可以從例子中看出: a = rand(3,4,5,6); numel(a,1,":",1,":") ans = 24 這相當於:numel(a(1,:,1,:)) 不過由於後者需要先索引矩陣,所以需要的時間較長(且索引的部分越大越長): a = rand(1e3,1e3,10); timeit(@()numel(a,":",":",1)) 警告: 由於執行速度過快,F 的計時可能不準確。嘗試對耗時更長的其他物件計時。 In timeit (line 158) ans = 9.08076504322897e-07 timeit(@()numel(a(:,:,1))) ans = 0.00272672929522135 當然啦,就算不知道第一種用法一般也不會有人用第二種用法,完全可以用 size 函式的結果計算12. cellfun(函式名,....),函式名可以是以下幾個字串:isempty, islogical, isreal, length, ndims, prodofsize,size, isclass其用法在cellfun 的文件中 Backward Compatibility 有介紹,其實功能都很簡單,但是好處是他們比對應的函式控制代碼要快很多: a = repmat({[],"1";23,23},100); timeit(@()cellfun("isempty",a)) ans = 0.000205790268896228 timeit(@()cellfun(@isempty,a)) ans = 0.0268502837700468 13. profile 的 memory 引數,舉例說明:% haha.m a = rand(3000); b = a; b(1) = a(1); 然後 profile 該函式: profile -memory on, haha, profile viewer
可以看到除了原有的執行時間資料之外還多了記憶體資料,而且就這個例子而言,我們可以清楚地看到 MATLAB 的 copy-on-write 特性,不過這裡統計的應該只是在 MATLAB 的記憶體管理範圍內的記憶體使用情況,實際計算中有些記憶體開銷並不是由 MATLAB 管理,所以不會被記錄。(profile 還有一些其他的隱藏特性,更詳細的介紹可以參見Undocumented Matlab中的介紹)14. 可以在 MATLAB 中使用 Java: java.math.BigInteger(2).pow(100) ans = 1267650600228229401496703205376 由於 MATLAB 的介面主要由 java 編寫,所以可以用 java 來豐富 MATLAB 的 GUI 功能。此外,如果是 Windows 的話還可以使用 C#;另外最近幾個版本也可以使用 python(需要自行安裝 python)。15. 我們知道新版本(2014b開始)的圖形介面有較大改動,其中一個改動就是可以用點運算子直接操作和修改圖形物件的屬性,例如: a = uitable("data",magic(3)); 如果要修改其中 2 行 2 列的元素為 0,老版本的話估計要這麼寫: t = get(a,"data"); t(2,2) = 0; set(a,"data",t); 新版本寫起來就方便些: a.Data(2,2) = 0; 不過如果想在老版本上也這麼方便的修改屬性值的話,需要對建立 a 的語句稍作修改: a = handle(uitable("data",magic(3))); 這裡得到的 a 不再是一個數值控制代碼,可以直接用新版本的方法修改屬性----- 2016.5.12 更新 ------16. 可以用 sort 輸出的索引來生成多組隨機排序(或者不放回取樣):tic for i = 1e4:-1:1 a(:,i) = randperm(50); end toc tic [~,b] = sort(rand(50,1e4,"single")); toc 時間已過 0.032115 秒。 時間已過 0.015228 秒。 這裡 a 和 b 都是 10000 組 1:50 的隨機排序17. 直接看例子: zeros(5,0)*zeros(0,3) ans = 0 0 0 0 0 0 0 0 0 0 0 0 0 0 018. 在一些情況下,資料滿足要求且硬碟足夠, v6 模式存取資料比較快:function test a = rand(5000); tic; save data1 a, toc tic; save data2 a -v6, toc tic, c = load("data1"); toc tic, d = load("data2"); toc isequal(c,d) 時間已過 4.374425 秒。 時間已過 1.881225 秒。 時間已過 1.052394 秒。 時間已過 0.088677 秒。19. 用 fft 加速兩個較長陣列的卷積運算,這個算不上 MATLAB 的奇技淫巧,而是數學上的結論:function test a = rand(1,2e5); b = rand(1,3e5); tic, c = conv(a,b); toc tic, l = numel(a) + numel(b) - 1; d = ifft(fft(a,l).*fft(b,l)); toc tic, l = numel(a) + numel(b) - 1; n = 2.^nextpow2(l); e = ifft(fft(a,n).*fft(b,n)); e = e(1:l); toc norm(c-d), norm(c-e) 時間已過 4.580655 秒。 時間已過 0.051598 秒。 時間已過 0.030744 秒。 ans = 2.79282382379074e-07 ans = 2.78964931183402e-07----- 2016.5.13 更新 ------20. 更快的隨機數生成function test rng("default") tic, a = rand(3e3); toc rng(0,"simdTwister") tic, b = rand(3e3); toc 時間已過 0.077385 秒。 時間已過 0.030155 秒。 可以把 rng(0,"simdTwister") 寫在啟動檔案中21. 有時候 floor 比 mod 更快的function test a = randi(1e6,1e6,1); timeit(@()mod(a,3)) % 0.0266399306685575 timeit(@()a-3*floor(a/3)) % 0.0066731423625292 22. 邏輯陣列和標量用.*function test a = rand(1e7,1); timeit(@()2*(a.5) + 3*(a.6)) % 0.136814992133285 timeit(@()2.*(a.5) + 3.*(a.6)) % 0.0661509763579439 23. 邏輯索引function test a = rand(1e7,1); b = a; b(1) = b(1); tic, a(a.5) = a(a.5) + 1; toc % 時間已過 0.221105 秒。 tic, b = b + (b.5); toc % 時間已過 0.049953 秒。