函数bsxfun
【功能描述】两个数组间元素逐个计算.
【应用场合】当我们想对一个矩阵A的每一列或者每一行与同一个长度相等的向量a进行某些操作(比较大小,乘除等)时,我们只能用循环方法或者利用repmat函数将要操作的向量a复制成和A一样尺寸的矩阵,进而进行操作。从MATLAB R2007a开始,再遇到类似的问题时,我们有了简洁高效的方法,即利用bsxfun函数。
【函数描述】C=bsxfun(fun,A,B):两个数组间元素逐个计算,fun是函数句柄或者m文件,也可以为如下内置函数
@plus 加
@minus 减
@times 数组乘
@rdivide 左除
@ldivide 右除
@power 数组幂乘
@max 二值最大值
@min 二值最小值
@rem 余数
@mod 求模
@atan2 四象限反正切
@hypot 平方和的平方根
@eq 等于
@ne 不等于
@lt 小于www.iLoveMatlab.cn
@le 小于或等于
@gt 大于
@ge 大于或等于
@and 逻辑并
@or 逻辑或
@xor 逻辑异或
应用举例1:
在此例子中,bsxfun函数用来计算矩阵A每一列减去其对应列的平均值.
A = magic(5)
A =
17 24 1 8 15
23 5 7 14 16
4 6 13 20 22
10 12 19 21 3
11 18 25 2 9
A = bsxfun(@minus, A, mean(A))
A =
4 11 -12 -5 2
10 -8 -6 1 3
-9 -7 0 7 9
-3 -1 6 8 -10
-2 5 12 -11 -4
如何将一个矩阵的每行或每列元素分别扩大不同的倍数?如[1 2 3;4 5 6 ;7 8 9],第一列元素乘以1,第二列元素以2,第三列元素乘以4。
利用bsxfun函数,可以给出下列代码:
a = [1,2,3;4,5,6;7,8,9];
acol = bsxfun(@times,a,[1 2 4])
假设我们有数据A和B, 每行是一个样本,每列是一个特征。我们要计算高斯核,既:
k(||x-xc||)=exp{- ||x-xc||^2/(2*σ)^2) } 其中xc为核函数中心,σ为函数的宽度参数 , 控制了函数的径向作用范围。
当然可以用双重for实现(如果第一直觉是用三重for的话…)。
K1 = zeros(size(A,1),size(B,1));
for i = 1 : size(A,1)
for j = 1 : size(B,1)
K1(i,j) = exp(-sum((A(i,:)-B(j,:)).^2)/beta);
end
end
使用2,000×1,000大小的A和B, 运行时间为88秒。
考虑下面向量化后的版本:
sA = (sum(A.^2, 2));
sB = (sum(B.^2, 2));
K2 = exp(bsxfun(@minus,bsxfun(@minus,2*A*B', sA), sB')/beta);
使用同样数据,运行时间仅0.85秒,加速超过100倍。
如要判断两者结果是不是一样,可以如下
assert(all(all(abs(K1-K2)<1e-12)))
C = bsxfun(fun,A,B)
Matlab中repmat函数用法
【功能描述】复制和平铺矩阵
格式 B = repmat(A,m,n) %将矩阵A复制m×n块,即B由m×n块A平铺而成。
B = repmat(A,[m n]) %与上面一致
B = repmat(A,[m n p…]) %B由m×n×p×…个A块平铺而成
repmat(A,m,n) %当A是一个数a时,该命令产生一个全由a组成的m×n矩阵。
B=repmat(A,m,n):把矩阵A复制n*m份,并堆叠构成矩阵B,矩阵B的大小为[size(A,1)*m, size(A,2)*n]。