这只是一个有趣的问题。假设我有一个二进制函数,它接受方形矩阵并输出相同大小的方形矩阵(或者更一般地说,它的输入类型和大小与其输出类型和大小相同):
function C = myfunc(A,B)
一个例子是mtimes funcion。将此变为可变长度输入函数有哪些不同且巧妙的方法
function C = myfunc_multi(varargin)
这样
myfunc(A{1},myfunc(A{2},myfunc(A{3},...myfunc(A{end-1},A{end})...))) ==
myfunc_multi(A{:})
这是我遇到的第一个通用解决方案(编辑:除了递归或循环):
function C = multioutput(functionhandle, varargin)
n = length(varargin);
funcstr = functiontostring(functionhandle);
str = regexprep(arrayfun(@num2str,1:n-1),'(.)',[funcstr '(varargin{$1},']);
C = eval(sprintf('%svarargin{%d}%s',str,n,repmat(')',1,n-1)));
end
然后你可以用类似
的东西来测试它A = {rand(3) rand(3) rand(3) rand(3) rand(3)};
multioutput(@mtimes,A{:})-A{1}*A{2}*A{3}*A{4}*A{5}
来测试它。你还能想到其他任何方式吗?
答案 0 :(得分:5)
可能没有充分的理由避免明显的递归构造。它简单易读,易于维护,性能非常好。
function out = aggregate_inputs(fHandle, varargin)
if nargin>3
out = fHandle(varargin{1},aggregate_inputs(fHandle,varargin{2:end}));
elseif nargin <= 3
out = fHandle(varargin{:});
end
不太优雅,但(可能*)需要更少的内存是循环结构
function accumulate = aggregate_inputs(fHandle,varargin)
if nargin<=3
accumulate = fHandle(varargin{:});
else
accumulate = fHandle(varargin{end-1},varargin{end});
for ix = (length(varargin)-2):-1:1
acumulate = fHandle(varargin{ix}, accumulate);
end
end
当然,你的问题已经从考虑中删除了这些结构......所以我看不到真正有效的方法。
为了给哲学留一分钟,通过使用向量化调用,可以更快地制作许多Matlab操作。有时这被解释为“不惜一切代价避免循环”。但是,通过调用cellfun,arrayfun或(请不)eval来避免循环通常不会提高性能。有时候出于其他原因这是正确的做法......但它无助于“将代码矢量化以使其更快”。
*上面的“或许”仅仅是因为我不确定Matlab的懒惰写入和其他优化会如何阻止内存使用,这似乎是递归解决方案的潜在危险。