实现“卷曲"和“访问"“链接". Matlab中的函数 [英] Implementing 'curly' and 'access' "chaining" functions in matlab

查看:93
本文介绍了实现“卷曲"和“访问"“链接". Matlab中的函数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我阅读了

I read this article on the mathworks blog about functional programming in matlab, and two of the helper functions there were:

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

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

The obvious third one to complete the trio (and in keeping with the five-letter theme) would be:

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

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

Putting the discussion of whether it's a good idea to implement chaining in this manner or not in matlab aside (note: octave supports chaining by default), paren seems to work well, as expected; however, curly and acces have a major drawback; consider the following code:

>> 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])

i.e. the expected sequence generation didn't happen.
(note that this code works as expected in Octave, i.e. A = [3,4,5,6] )

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

Equally, acces does not produce a sequence in matlab

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

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

(whereas Octave produces the expected A = {'john', 'jim'} )

我了解,区别可能更多地取决于实现方面. a.函数如何在Matlab和octave中返回内容,和/或 b..是从两种语言的单元格和结构生成的.

I understand that the difference is probably more a matter of implementation in terms of a. how functions return stuff in matlab vs octave, and/or b. how sequences are generated from cells and structs in the two languages.

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


PS.我在寻找的答案并不平凡 使用varargout获取多个参数".一个.
PS2. 我在Matlab 2013b上对此进行了测试,因此我不知道此行为是否已在更高版本中修复"(尽管我对此表示高度怀疑).在最新的matlab网上进行了测试,网址为

However, is there a programmatic way to get matlab to perform the intended operation above?
In other words, is there a way to define curly and acces functions that return a sequence (extra bonus for anonymous function :p ) like octave does?


PS. The answer I'm looking for is not the trivial "to get multiple arguments out use varargout" one.
PS2. I tested this on Matlab 2013b, so I'm not aware if this behaviour has been "fixed" in later versions (though I highly doubt it). Tested on latest matlab online at http://matlab.mathworks.com

推荐答案

免责声明:答案更少,一些随机的想法更多

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

The issue here is that, in MATLAB, a single function (anonymous or otherwise) is incapable of returning a comma-separated list the way that dot referencing and {} indexing can.

即使MATLAB的内部函数也无法执行引用:

Even MATLAB's internal functions for performing the referencing are incapable of doing so:

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和其他内置函数返回您希望的多个值的方式

But what a single function can do in MATLAB, is return multiple outputs. This is precisely how subsref and the other built-ins return the multiple values you're hoping for

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, ':');

现在,这实际上并不能帮助您的助手匿名功能,因为它需要知道需要多少输出,而这又取决于输入.

Now this doesn't really help your helper anonymous function since it requires knowledge of how many outputs to expect and that in turn depends on the inputs.

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

For your acces function, it's relatively straight forward to determine the number of outputs so you could easily do something like:

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

不幸的是,您不能在匿名函数中执行此操作,并且除了通过对cell2mat

Unfortunately, you can't do that inside of an anonymous function, and there's also no easy way to get a non-cell array out apart from wrapping this with a follow-up call to cell2mat

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

可以创建一些匿名函数来执行这些各种操作,但是它们很杂乱.

You could create some anonymous functions to do these various operations, but they are messy.

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遍历它以产生结果.

As for your curly you could instead use paren to grab a subset of the cell array as a cell and then loop through it with cellfun to yield the result.

% This is really just using parenthesis
curly_sequence_cell = paren;

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

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

But the real solution is just use a temporary variable and then index into that using the typical MATLAB syntax :)

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

这篇关于实现“卷曲"和“访问"“链接". Matlab中的函数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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