Effective Matlab—编写高效的Matlab代码

来源:互联网 发布:dj小可网络电音歌曲 编辑:程序博客网 时间:2024/06/16 02:34
关于Matlab的讨论很多,这里我们不讨论具体的API细节,而是集中于高效使用Matlab这一主题,因此本文假设读者已经有了matlab的基本知识(本文不会对API的接口进行专门介绍,这部分可以通过matlab的help文档来解决),并且已经使用matlab一段时间。不能免俗的,本文被命名为Effective Matlab(向Effective C++致敬)。

1. 善用矩阵操作
Matlab对矩阵运算进行了深度优化,因此对于Matlab程序,矩阵操作的效率高于for循环。
1.1 使用repmat
repmat的作用在于对矩阵进行复制,通过repmat,我们可以将一部分for循环改写为矩阵运算,例如
以下函数实现了对数据的“均值归零,方差归一”。

function M = ZeroMeanOneVar(X,x_mean,x_var)index = x_var<0.0000001;x_var(index) = 1;% x_mean(index) = 0; num = size(X,2);X_mean = repmat(x_mean, 1, num); %复制x_mean为1行num列M = X - X_mean;clear X_mean;X_var = repmat(x_var, 1, num);M = M ./ X_var;clear X_var;flag = isnan(M); M(flag) = 0;end

需要指出的是,通过repmat将for循环转为矩阵运算会增加内存消耗,这种技巧的另外一个名字叫“空间换时间”。

1.2 使用meshgrid
meshgrid的作用在于生成2维或者3维网格,例如我们需要绘制Z = x*exp(-x^2 - y^2), x和y的取值范围均为
[-5, 5]。

x=-5 : .01 : 5;y=x;[X,Y] = meshgrid(x,y);Z = X .* exp(-X.^2 - Y.^2); mesh(X,Y,Z)

x=-5 : .01 : 5;
y=x;
[X,Y] = meshgrid(x,y);
Z = X .* exp(-X.^2 - Y.^2);
 
mesh(X,Y,Z)


2. 考虑数值稳定性
2.1 用SVD代替eig
矩阵运算必须时刻牢记数值稳定性,例如eig()运算的数值稳定性不如SVD(), 而求特征值和特征向量对于机器学习中的常见算法PCA来说是必须的,下面展示了一个在PCA算法中应用SVD代替eig的例子。
 % x_poa已经经过减均值操作    St = X_pca * X_pca';    [Vt Dt v] = svd(St);    eig_value_unsort = diag(Dt);    [eig_value  eig_index]  = sort(eig_value_unsort, 'descend' );    energy = sum(eig_value);       for i=1:dim        kept_energy = sum(eig_value(1:i));        if kept_energy > energy*0.98            fprintf( '%d dims can preserve 0.98 energy' ,i);            break ;        end    end       W_pca = zeros(dim,pca_dim);  %W_pca????????????????    for i = 1:pca_dim        W_pca(:, i) = Vt(:,eig_index(i));    end

2.2 左除和右除
在matlab中,如果有以下操作:
Inv(A)*B, 建议用左除A\B代替。
A*Inv(B),  建议用右除A/B代替。

A右除B,相当于A右乘B的逆矩阵,A左除B,相当于A的逆矩阵左乘B



0 0
原创粉丝点击