实施';卷曲的';和';访问'&引用;“链接”;matlab中的函数

实施';卷曲的';和';访问'&引用;“链接”;matlab中的函数,matlab,octave,chaining,Matlab,Octave,Chaining,我在mathworks博客上读到关于matlab函数编程的内容,其中有两个辅助函数: paren = @(x, varargin) x(varargin{:}); curly = @(x, varargin) x{varargin{:}}; 完成这三个字母的第三个明显的主题是: acces = @(x, field) x.(field); 把在matlab中以这种方式实现链接是否是一个好主意的讨论放在一边(注意:octave默认支持链接),paren似乎工作得很好,正如预期的那样;然而,cu

我在mathworks博客上读到关于matlab函数编程的内容,其中有两个辅助函数:

paren = @(x, varargin) x(varargin{:});
curly = @(x, varargin) x{varargin{:}};
完成这三个字母的第三个明显的主题是:

acces = @(x, field) x.(field);
把在matlab中以这种方式实现链接是否是一个好主意的讨论放在一边(注意:octave默认支持链接),
paren
似乎工作得很好,正如预期的那样;然而,
curly
acces
有一个主要缺点;考虑下面的代码:

>> C = {1,2,3,4; 2,3,4,5; 3,4,5,6; 4,5,6,7};
>> A = [curly(C, 3, ':')]
A =
     3
i、 e.预期的序列生成没有发生。
(请注意,此代码在八度音程中的工作方式与预期相同,即
A=[3,4,5,6]

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

>> S = [struct('name', 'john'), struct('name', 'jim')];
>> A = {acces(S, 'name')}
A = 
    'john'
(而八度音阶产生预期的
A={'john','jim'}

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

但是,是否有一种编程方式让matlab执行上述预期操作?
换句话说,有没有一种方法可以像octave那样定义返回序列的
curly
acces
函数(匿名函数的额外奖励:p)?
我要寻找的答案不是琐碎的 “要获取多个参数,请使用varargout”一个。

PS2。我在Matlab2013b上对此进行了测试,所以我不知道这种行为在以后的版本中是否已经“修复”(尽管我非常怀疑)。在最新的matlab online上测试,网址为

免责声明:答案较少,更多的是一些随机思考

这里的问题是,在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, ':');
现在,这并不能真正帮助您的helper匿名函数,因为它需要知道需要多少输出,而这又取决于输入

对于
acces
函数,确定输出数量相对简单,因此您可以轻松执行以下操作:

[A{1:numel(S)}] = acces(S, 'name');
不幸的是,您不能在匿名函数中实现这一点,而且除了通过后续调用
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
对其进行循环以生成结果

% This is really just using parenthesis
curly_sequence_cell = paren;

curly_sequence_array = @(varargin)cell2mat(paren(varargin{:}));
但真正的解决方案只是使用一个临时变量,然后使用典型的MATLAB语法将其索引为:)


我不知道“\u dot”和“\u brace”,知道这很酷!也谢谢你纠正了我的结构语法,我没有费心去查它,哈哈。不错的解决办法,不过我想,这会使可读性比
paren
curly
更差,因为它们已经足够可疑了。。。在matlab中无法避免这个该死的温度变量,是不是:pstill,我真想知道matlab是如何从引擎盖下的单元格/结构创建序列的,这样它在直接调用时可以工作,但在使用
subsref
调用时不能工作。当我尝试subsref时,我感到非常惊讶,但它不起作用。。。在那之前,我的印象是()和{}索引只是subsref的语法糖。。。(例如,在八度音阶上,subsref再次按预期工作并返回一个序列)@tasospapstylianou对
subsref
进行了更多的探索,并在我的答案中添加了一些信息。虽然您可以强制subsref
subsref
为您提供所有值,但要获得逗号分隔的列表仍然不容易。谢谢@Suever!我想这是最接近的,因为它将在matlab上,然后!虽然
[A{:}]=curly(C,3,,:')
是一个相当不错的解决方法@TASOSPAPSTYLEANOU如果你只想要这样一个单元格,只需使用
paren
即可:
a=paren(C,3':')
S = struct('name', {'john', 'jim'});
A = {S.name};