一、运算速度

  • 优先使用内建函数,尤其在遇到很多for循环情况时,多使用内建函数来代替循环,如:bsxfun、arrayfun、spfun、structfun,因为内建函数 使用C来进行构造,速度比循环快。
  • 使用向量化的处理方式,而不是循环。
  • 多重循环次数不同时,外循环小于内循环次数。
  • 使用有效算法:比如A\Binv(A)*B运算要快得多。
  • 函数比脚本快,因为函数被编译为P代码,只装入内存一次,脚本需要逐行运行,每次都要装入内存。
  • Matlab按行处理命令,所以一行最好只写一个操作命令。
  • 大型矩阵预先定义维数。动态定维很费时间。可以先创建一个小矩阵,然后用repmat构建。
  • 复数写成a+bi而不是a+b*i的形式,这样matlab将其认为是复数常数,否则会将其解释为一个没有定义数据结构和数组大小的变量。
  • 用profiler和profile函数监控代码运行时间。
  • 如果还是慢,换python、fortran、C吧。

二、内存使用

Matlab使用堆管理内存,运行会产生内存碎片,有很多闲置空间。 Pack命令,可以将内存中Matlab变量暂存在磁盘,然后再用空间的连续空间来存储变量。出现put of memory时,通过pack来重新分配内存,但是因为交换数据,所以速度慢。 同时可以周期性将数据存入磁盘进行保存,然后从内存去除变量再继续计算。对于大部分元素为0的矩阵,保存为稀疏矩阵,因为其占用内存少,且比满秩矩阵运算快,可以用sparse函数进行转换。

三、部分函数及向量化操作

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
`A(:)` 返回矩阵所有元素,构成一列向量
	>>A=rand(2)
	A =
    	0.8523    0.6717
    	0.9833    0.1392
	>>A(:)'
    	0.8523    0.9833    0.6717    0.1392
`a(~sum(abs(a),2),:)=[];a(:,~sum(abs(a),1))=[]` 去掉矩阵中全为0的行或者列
	>>a(1:size(A),1:size(A))=A
    	0.8523    0.6717         0
	0.9833    0.1392         0
	0         0         	 0
	>>a(~sum(abs(a),2),:)=[];a(:,~sum(abs(a),1))=[]
	0.8523    0.6717
	0.9833    0.1392
`accumarray` 类似于sum(A(subs))=val,subs提供位置,val提供值,然后把相同位置的值加起来,空位置默认补0.
	>>val = [1, 2, 3, 4];
	>>subs=[ 1,2; 1,1; 2,1; 1,1];
	>>A=accumarray(subs,val);
	6     1
	3     0
	>>subs = [1 1; 2 1; 2 3; 2 1; 2 3];
	>>A = accumarray(subs, 1, [2 4]); %表示val为2行4列值为1的矩阵
	1     0     0     0
	2     0     2     0
`array(and(array>a,array<b))=0`
	>>array=rand(3)
	0.3816    0.6117    0.1935
	0.8145    0.6756    0.0181
	0.0446    0.8328    0.5398
	>>array(and(array>0.5,array<0.8))=0
	0.3816         0    0.1935
	0.8145         0    0.0181
	0.0446    0.8328         0
`arrayfun` 用于对数组中每个元素进行相同的函数操作
	>>s(1).f1 = rand(3, 6);
	>>s(2).f1 = magic(12);
	>>s(3).f1 = ones(5, 10);
	>>counts = arrayfun(@(x) numel(x.f1), s); %计算每个矩阵个数
	>>counts =
	18   144    50
	>>[nrows, ncols] = arrayfun(@(x) size(x.f1), s); %计算每个矩阵行列值
	nrows =
	3    12     5
	ncols =
	6    12    10
	>>t = s;t(1).f1(:)=0;u = s;u(2).f1(:)=0;
	>>same = arrayfun(@(x,y) isequal(x.f1, y.f1), u, t)
	0    0    1
`bsxfun` 对数组间元素逐个进行计算
	>>A = magic(3)
	A =
	8     1     6
	3     5     7
	4     9     2
	>>mean(A)
	ans =
	5     5     5
	>>A = bsxfun(@minus, A, mean(A)) %相当于A-mean(A)
	 3    -4     1
	-2     0     2
	-1     4    -3
	>>a=randn(3,1),b=randn(1,2)
	a =	
	-1.5723
	0.3676
	-0.1402
	b =
	-0.0153    0.2528
	>>c=bsxfun(@plus,a,b) %将a和b先复制扩展,再做运算
	c =
   	-1.5876   -1.3195
     0.3523    0.6204
   	-0.1555    0.1126

cellfun 类似于arrayfun,对数组进行相同运算 spfun 对稀疏矩阵非零值进行运算 sparse 生成稀疏矩阵函数 intersect 取交集 unique 取各自独立的部分 union 取并集 fig=plot(A); delete(fig) 删除某个图像 unique 统计互异元素出现的次数
diag 生成对角阵和提取对角元素 flipud 上下对称交换 fliplr 左右对称交换 rot90(A,n) 逆时针旋转90°,n次 numel(A) 返回单元个数 regexp 用于对字符串进行查找,大小写敏感 regexpi 用于对字符串进行查找,大小写不敏感 regexprep 用于对字符串进行查找并替换 randn 产生正态随机数 randn 产生正态随机矩阵 randsrc 产生随机数组 unidrnd 产生一组离散均匀随机数 isequal 判断若干个给定的数组容量是否是相等的 ~= cumtrapz 基于梯形法则的数值积分公式 dbstop if error 遇到错误时,终止M文件运行,并停在错误行,dbcount 从断点处恢复运行 system 执行windows命令,批处理,exe都可以,命令前加!也可以 see more from高大上的知乎