您的位置:首页 > 编程语言 > MATLAB

matlab函数 bsxfun(高效代码)

2015-09-15 15:11 513 查看

bsxfun是一个matlab自版本R2007a来就提供的一个函数,作用是”applies an element-by-element binary operation to arrays a and b, with singleton expansion enabled.”

函数功能:两个数组间元素逐个计算的二值操作

使用方法:C=bsxfun(fun,A,B)

两个数组A合B间元素逐个计算的二值操作,fun是函数句柄或者m文件,也可以为如下内置函数:

@plus 加

@minus 减

@times 数组乘《Simulink与信号处理》

@rdivide 左除

@ldivide 右除

@power 数组幂乘

@max 二值最大值

@min 二值最小值

@rem 余数

@mod 求模

@atan2 四象限反正切

@hypot 平方和的平方根

@eq 等于

@ne 不等于

@lt 小于www.iLoveMatlab.cn

@le 小于或等于

@gt 大于

@ge 大于或等于

@and 逻辑并

@or 逻辑或

@xor 逻辑异或

三种方法对比:

function test_dist(m, n)
    X = rand(m,n);
    D = use_bsxfun(X);
    D = use_repmat(X);
    D = use_for(X);
end

function D=use_bsxfun(X)
    v = dot(X,X);
    D = bsxfun(@plus,v,v')-2*(X'*X);
end

function D=use_repmat(X)
    v = dot(X,X);
    D = repmat(v,length(v),1) + repmat(v',1,length(v)) - 2*(X'*X);
end

function D=use_for(X)
    D = zeros(size(X,2));
    for i=1:size(D,1)
        for j=i+1:size(D,2)
            D(i,j) = sum((X(:,i)-X(:,j)).^2);
        end
    end
    D = max(D,D');
end


应用举例:

假设我们有数据A和B, 每行是一个样本,每列是一个特征。我们要计算高斯核,既:

k(||x-xc||)=exp{- ||x-xc||^2/(2*σ)^2) } 其中xc为核函数中心,σ为函数的宽度参数 , 控制了函数的径向作用范围。

当然可以用双重for实现(如果第一直觉是用三重for的话…)。

[code]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秒。

考虑下面向量化后的版本:

[code]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倍。

如要判断两者结果是不是一样,可以如下

[code]assert(all(all(abs(K1-K2)<1e-12)))


[code]C = bsxfun(fun,A,B) appliesthe element-by-element binary operation specified
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: