Matlab - 两个以上输入的单例扩展
Matlab - Singleton expansion for more than two inputs
我有一个接受 2 个以上变量的函数
例如。
testFunction = @(x1, x2, x3, x4) x1.*x2.*x3.*x4;
testFunction2 = @(x1, x2, x3) sin(x1.*x2.^x3);
是否有像 bsxfun
这样的函数允许对具有 2 个以上输入的函数进行单例扩展?
bsxfun
的例子
binaryTestFunction = @(x1, x2) x1.*x2;
x1 = 9*eye(10);
x2 = 3*ones(10,1);
A = bsxfun(binaryTestFunction , x1 , x2);
扩展 x2 向量中的单一维度。
bsxfun
比 repmat 快,而且迭代度很高,因此我想知道我的 testFunction
的单例扩展是否可行。
您可以定义自己的 class 以启用 bsxfun 的自动使用:
classdef bdouble < double
%BDOUBLE double with automatic broadcasting enabled
methods
function obj=bdouble(data)
obj = obj@double(data);
end
function r=plus(x,y)
r=bsxfun(@plus,x,y);
end
function r=minus(x,y)
r=bsxfun(@minus,x,y);
end
function r=power(x,y)
r=bsxfun(@power,x,y);
end
function r=times(x,y)
r=bsxfun(@times,x,y);
end
function r=rdivide(x,y)
r=rdivide(@rdivide,x,y);
end
function r=ldivide(x,y)
r=ldivide(@ldivide,x,y);
end
end
end
用法:
testFunction(bdouble([1:3]),bdouble([1:4]'),bdouble(cat(3,1,1)),bdouble(1))
如果你更喜欢 bsxfun 语法,你可以把它放在上面:
function varargout=nbsxfun(fun,varargin)
varargout=cell(1:nargout);
for idx=1:numel(varargin)
if isa(varargin{idx},'double')
varargin{idx}=bdouble(varargin{idx});
end
end
varargout{1:max(nargout,1)}=fun(varargin{:});
end
示例:
n=nbsxfun(testFunction,[1:3],[1:4]',cat(3,1,1),4)
只是嵌套函数:
testFunction = @(x1, x2, x3, x4) bsxfun(@times, bsxfun(@times, bsxfun(@times, x1, x2), x3), x4);
testFunction2 = @(x1, x2, x3) sin(bsxfun(@power, bsxfun(@times, x1, x2), x3);
请注意,您应该在函数内部实现 bsxfun,而不是依赖于用户使用 bsxfun 调用函数,因此无论如何与函数的交互都是无缝的。
另请注意,当本可以使用直接的逐元素操作时,使用 bsxfun 之间几乎没有速度损失。
文件交换中有一个文件覆盖了数组运算符,因此 bsxfun 自动用于所有运算符,但我不记得它的名字了。我用了一段时间,但后来你 运行 用户不知道这个实现的风险。
我有一个接受 2 个以上变量的函数
例如。
testFunction = @(x1, x2, x3, x4) x1.*x2.*x3.*x4;
testFunction2 = @(x1, x2, x3) sin(x1.*x2.^x3);
是否有像 bsxfun
这样的函数允许对具有 2 个以上输入的函数进行单例扩展?
bsxfun
的例子
binaryTestFunction = @(x1, x2) x1.*x2;
x1 = 9*eye(10);
x2 = 3*ones(10,1);
A = bsxfun(binaryTestFunction , x1 , x2);
扩展 x2 向量中的单一维度。
bsxfun
比 repmat 快,而且迭代度很高,因此我想知道我的 testFunction
的单例扩展是否可行。
您可以定义自己的 class 以启用 bsxfun 的自动使用:
classdef bdouble < double
%BDOUBLE double with automatic broadcasting enabled
methods
function obj=bdouble(data)
obj = obj@double(data);
end
function r=plus(x,y)
r=bsxfun(@plus,x,y);
end
function r=minus(x,y)
r=bsxfun(@minus,x,y);
end
function r=power(x,y)
r=bsxfun(@power,x,y);
end
function r=times(x,y)
r=bsxfun(@times,x,y);
end
function r=rdivide(x,y)
r=rdivide(@rdivide,x,y);
end
function r=ldivide(x,y)
r=ldivide(@ldivide,x,y);
end
end
end
用法:
testFunction(bdouble([1:3]),bdouble([1:4]'),bdouble(cat(3,1,1)),bdouble(1))
如果你更喜欢 bsxfun 语法,你可以把它放在上面:
function varargout=nbsxfun(fun,varargin)
varargout=cell(1:nargout);
for idx=1:numel(varargin)
if isa(varargin{idx},'double')
varargin{idx}=bdouble(varargin{idx});
end
end
varargout{1:max(nargout,1)}=fun(varargin{:});
end
示例:
n=nbsxfun(testFunction,[1:3],[1:4]',cat(3,1,1),4)
只是嵌套函数:
testFunction = @(x1, x2, x3, x4) bsxfun(@times, bsxfun(@times, bsxfun(@times, x1, x2), x3), x4);
testFunction2 = @(x1, x2, x3) sin(bsxfun(@power, bsxfun(@times, x1, x2), x3);
请注意,您应该在函数内部实现 bsxfun,而不是依赖于用户使用 bsxfun 调用函数,因此无论如何与函数的交互都是无缝的。
另请注意,当本可以使用直接的逐元素操作时,使用 bsxfun 之间几乎没有速度损失。
文件交换中有一个文件覆盖了数组运算符,因此 bsxfun 自动用于所有运算符,但我不记得它的名字了。我用了一段时间,但后来你 运行 用户不知道这个实现的风险。