转动一个双输入功能分为在MATLAB可变长度输入功能的聪明的方式 [英] Clever ways of turning a two-input function into a variable-length-input function in matlab

查看:230
本文介绍了转动一个双输入功能分为在MATLAB可变长度输入功能的聪明的方式的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这仅仅是出于兴趣的问题。假设我有一个接受方矩阵,并输出方阵的大小相同(或更一般地,它的输入的类型和尺寸是相同的作为其输出类型和尺寸)的二进制函数:

This is just a question out of interest. Suppose I have a binary function that accepts square matrices and outputs square matrices of the same size (or more generally, it's input type and size are the same as its output type and size):

function C = myfunc(A,B)

一个例子是在mtimes funcion。有哪些不同和巧妙的把这个变成一个可变长度的输入功能

An example would be the mtimes funcion. What are some different and clever ways of turning this into a variable length input function

function C = myfunc_multi(varargin)

这样

myfunc(A{1},myfunc(A{2},myfunc(A{3},...myfunc(A{end-1},A{end})...))) == 
    myfunc_multi(A{:})

这是已经到了我(编辑:除了递归或循环):第一个通用的解决方案。

This is the first general solution that has come to me (edit: besides recursion or a loop):

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

然后你可以用一些测试它像

then you can test it with something like

A = {rand(3) rand(3) rand(3) rand(3) rand(3)};
multioutput(@mtimes,A{:})-A{1}*A{2}*A{3}*A{4}*A{5}

进行测试。任何其他方式,你能想到的?

to test it. Any other ways you can think of?

推荐答案

有可能是没有很好的理由,以避免明显的递归结构。它操作简单,易于阅读和维护,并应具有pretty不错的表现。

There is probably no good reason to avoid the obvious recursive construct. It is simple, easy to read and maintain, and should have pretty good performance.

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

不太一样优雅,但(也许*)需要较少的内存是循环结构

Not quite as elegant, but (perhaps*) requiring less memory is the loop construct

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

当然,你的问题移除考虑这些构造......所以没有真正做到这一点,我可以看到一个很好的方式。

Of course, your question removed those constructs from consideration ... so there's not really a good way to do it that I can see.

要蜡哲学一分钟,这是事实,许多Matlab的操作可以进行使用矢量调用要快得多。有时候,这是PTED为避免环路不惜一切代价国米$ P $。但是,避免与调用循环来cellfun,arrayfun,或(请无)的eval,通常不会提高性能。有时它是因其他原因做正确的事......但它并不能帮助矢量化你的code,使其更快。

To wax philosophical for a minute, it is true that many Matlab operations can be made much much faster by using vectorized calls. Sometimes this is interpreted as "avoid loops at all costs". However, avoiding loops with calls to cellfun, arrayfun, or (please no) eval, does not usually increase performance. Sometimes it is the right thing to do for other reasons ... but it does not help "vectorize your code to make it faster".

*的也许上面很简单,因为我不知道Matlab的懒惰写入时复制和其他优化将如何以及prevent的内存使用量这似乎是用递归解决方案的潜在危险。

*The "perhaps" above is simply because I'm not sure how well Matlab's lazy copy-on-write and other optimizations would prevent the memory usage which seems like a potential hazard with the recursive solution.

这篇关于转动一个双输入功能分为在MATLAB可变长度输入功能的聪明的方式的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆