实施'卷曲'和'访问' "链" matlab中的函数

时间:2016-09-21 23:48:42

标签: matlab octave chaining

我在mathworks博客上阅读了关于matlab中函数式编程的this article,其中有两个辅助函数:

paren = @(x, varargin) x(varargin{:});
curly = @(x, varargin) x{varargin{:}};

完成三重奏的明显第三个(并与五个字母的主题保持一致)将是:

acces = @(x, field) x.(field);

讨论在matlab中以这种方式实现链接是否是一个好主意(注意:octave默认支持链接),paren似乎运行良好,如预期的那样;但是,curlyacces有一个主要缺点;请考虑以下代码:

>> C = {1,2,3,4; 2,3,4,5; 3,4,5,6; 4,5,6,7};
>> A = [curly(C, 3, ':')]
A =
     3

即。预期的序列生成并没有发生 (请注意,此代码在Octave中按预期工作,即A = [3,4,5,6]

同样,acces不会在matlab中生成序列

>> S = [struct('name', 'john'), struct('name', 'jim')];
>> A = {acces(S, 'name')}
A = 
    'john'

(而Octave产生预期的A = {'john', 'jim'}

我理解差异可能更多的是在 a。方面的实现问题。函数如何在matlab与octave中返回内容,和/或 b。如何序列是用两种语言的单元格和结构生成的。

但是,是否有一种编程方式让matlab执行上述预期操作?
换句话说,有没有办法定义返回序列的curlyacces函数(匿名函数的额外奖励:p)像八度音程一样?

<小时/> PS。我正在寻找的答案并非微不足道 &#34;要获得多个参数,请使用varargout&#34; 一个 PS2。 我在Matlab 2013b上对此进行了测试,所以我不知道这种行为是否已被修复&#34;在后来的版本中(虽然我非常怀疑)。http://matlab.mathworks.com

上在线测试最新的matlab

1 个答案:

答案 0 :(得分:4)

免责声明:较少的答案和更多的随机沉思

这里的问题是,在MATLAB中,单个函数(匿名或其他)无法以点引用和{}索引的方式返回逗号分隔列表。

即使是MATLAB用于执行引用的内部函数也无法这样做:

subsref(S, substruct('.', 'name'))
%   john

builtin('_dot', S, 'name')              % Only works pre-2015b
%   jim

subsref(C, substruct('{}', {3 ':'}))
%   3

builtin('_brace', C, 3, ':')            % Only works pre-2015b
%   3

但是 MATLAB中单个函数可以做什么,返回多个输出。这正是subsref和其他内置函数返回您希望的多个值的方式

S = struct('name', {'john', 'jim'});

[val1, val2] = subsref(S, substruct('.', 'name'));
[val1, val2] = builtin('_dot', S, 'name');

C = num2cell(magic(3));

[val1, val2, val3] = subsref(C, substruct('{}', {3, ':'}));
[val1, val2, val3] = builtin('_brace', C, 3, ':');

现在这并没有真正帮助你的助手匿名功能,因为它需要知道预期有多少输出,而这又取决于输入。

对于acces功能,它可以相对直接地确定输出数量,因此您可以轻松地执行以下操作:

[A{1:numel(S)}] = acces(S, 'name');

不幸的是,你无法在匿名函数中执行此操作,并且除了通过对{{的后续调用包装它之外,还没有简单的方法来获取非单元格数组。 1}}

cell2mat

可以创建一些匿名函数来执行这些不同的操作,但它们很混乱。

[A{1:numel(S)}] = acces(S, 'name');
A = cell2mat(A);

对于您的access_cell = @(s,n)arrayfun(@(x)acces(x,n), s, 'uniform', 0); access_array = @(s,n)arrayfun(@(x)acces(x,n), s, 'uniform', 1); ,您可以使用curly将单元格数组的子集作为单元格抓取,然后使用paren循环遍历它以产生结果。

cellfun

真正的解决方案只是使用一个临时变量,然后使用典型的MATLAB语法将其索引:)

% This is really just using parenthesis
curly_sequence_cell = paren;

curly_sequence_array = @(varargin)cell2mat(paren(varargin{:}));