Octave / MATLAB 中的 deal() 函数有啥意义?

Posted

技术标签:

【中文标题】Octave / MATLAB 中的 deal() 函数有啥意义?【英文标题】:What is the point of the deal() function in Octave / MATLAB?Octave / MATLAB 中的 deal() 函数有什么意义? 【发布时间】:2014-06-13 16:09:08 【问题描述】:

一些参考代码使用了deal()这个函数,比如

[a, b, c] = deal (1,2,3)

如文档(for Octave 和 for MATLAB)中所述,该函数只是将输入复制到输出。 为什么在这种情况下甚至一般情况下使用 deal() 我正在尝试学习“更正确”的 MATLAB/Octave 用法,并想知道我是否遗漏了一些重要的东西。或许,是这样的用法吗……

传统风格或惯用语,代替像a=1, b=2, c=3 这样的简单赋值或像[a,b,c] = 1,2,3: 这样更神秘的单元阵列列表解包,但比Python argument unpacking 更受限制,如this question? 对一些更优雅的功能有用 - 例如,“深”与“浅”复制,如果这里甚至存在这样的概念,如果 deal() 与复杂/可变参数一起使用?

我也理解单参数[a,b,c]=deal(42),但本质上是a=b=c=42[a,b,c]=deal(x)x 分配给所有,而不是x 的元素。

或者也许只是我过度考虑了这个函数的琐碎使用。

【问题讨论】:

这是一个非常简单的函数,输入edit deal 并查看代码。您不需要交易,我从未使用过,也从未错过。 我猜你回答了你自己的问题。据我所知,除了可读性之外,没有其他理由使用deal()。您提出的“深”与“浅”复制问题在这里(至少在 Octave 中)无关紧要,因为解释器足够聪明,可以检测何时需要将 a = b 实际复制到内存中。 C中有类似的函数吗? @BrysonS。 -- C 中没有类似的函数,原因有几个。 MATLAB deal 函数接受各种输入(标量、逗号分隔列表、元胞数组、结构体数组访问器……),因此您必须执行类似tagged unions 的操作。或者你可以使用一些古怪的可变参数或 C++。多个输出值是一个问题,因此您必须返回数组、结构或指针,......但这似乎太复杂了。应用程序是什么? 【参考方案1】:

我偶尔使用deal 的一个非常有用的方法是创建返回多个输出参数的匿名函数。例如,

>> f = @(x) deal(x^2,x^3);
>> [a,b] = f(3)
a =
     9
b =
    27

编辑,因为人们似乎发现这种模式可能有用,请注意一个怪癖,因为您必须返回完整数量的输出。特别是不能使用a = f(3),否则会报错。要仅检索单个输出,请使用 [a,~] = f(3)[~,b] = f(3)。用于抑制输出参数的~ 语法从大约 R2007a 左右就已经存在(恐怕我记不起确切的时间了)——在旧版本中,您需要始终返回两个输出。希望对你有用。

【讨论】:

确实很聪明,而且我没有立即看到任何其他方法;玩弄一些索引和 cs-list 似乎无法正常工作。这应该在 anonymous functions 或 deal 的文档上! C 中有这样的东西吗? @BrysonS。 -- 请参阅我在问题本身下对您的类似评论的回复。【参考方案2】:

首先,您的命名示例适用于 octave,但不适用于 matlab!

octave:1> a=b=c=42
a =                   42
octave:2> [a,b,c] = 1,2,3:
a =                    1
b =                    2
c =                    3


>> a=b=c=42
 a=b=c=42
    |
Error: The expression to the left of the equals sign is not a valid target for an assignment.

>> [a,b,c] = 1,2,3:
 [a,b,c] = 1,2,3:
                  |
Error: Unbalanced or unexpected parenthesis or bracket.

如何以及何时使用deal() 不能一概而论。这取决于你的脚本、你的数据结构、你想要做什么以及结果应该是什么样子等等。

>> m=rand(3,3);
>> [a,b,c]=m;
Too many output arguments.

>> [a,b,c]=reshape(m,[],1);
Error using reshape
Too many output arguments.

>> [a,b,c]=deal(reshape(m,[],1));
>> 

因此,有些函数设计为 nargout = 1,您可以轻松地将输出分配到“一行”中的多个变量。

如果一个函数的 nargouts 多于 1,它就会变得有趣

>> [x,y,z]=qr(m)

x =

   -0.7004    0.6471   -0.3012
   -0.1144   -0.5183   -0.8475
   -0.7045   -0.5592    0.4370


y =

   -1.3776   -0.7928   -1.2897
         0   -0.6388   -0.0796
         0         0   -0.3499


z =

     1     0     0
     0     0     1
     0     1     0

>> [x,y,z]=deal(qr(m))

x =

   -1.3776   -1.2897   -0.7928
    0.0673   -0.3588   -0.1418
    0.4143   -0.1886    0.6229


y =

   -1.3776   -1.2897   -0.7928
    0.0673   -0.3588   -0.1418
    0.4143   -0.1886    0.6229


z =

   -1.3776   -1.2897   -0.7928
    0.0673   -0.3588   -0.1418
    0.4143   -0.1886    0.6229

>> 

但是,重复变量(例如,为了更好地概览)并没有其他语言中的那么糟糕(关于内存浪费)。 Matlab 使用写入时复制 - 请参阅 https://en.wikipedia.org/wiki/Copy-on-write 和 http://www.matlabtips.com/copy-on-write/

还有 - afaik - 八度音阶:

octave:1> memory

 Memory used by Octave:   24.4414 MB 
 Physical Memory (RAM): 7586.74 MB 

octave:2> tic, m=rand(10000,10000); toc
Elapsed time is 5.52749 seconds.
octave:3> memory

 Memory used by Octave:   787.531 MB 
 Physical Memory (RAM): 7586.74 MB 

octave:4> tic, n=m; toc
Elapsed time is 4.19617e-05 seconds.
octave:5> memory

 Memory used by Octave:   787.535 MB 
 Physical Memory (RAM): 7586.74 MB 

octave:6> whos
Variables in the current scope:

   Attr Name        Size                     Bytes  Class
   ==== ====        ====                     =====  ===== 
        m       10000x10000              800000000  double
        n       10000x10000              800000000  double

Total is 200000000 elements using 1600000000 bytes

【讨论】:

关于 MAT 与 Oct 部分:古怪;感谢您的比较。我从the MATLAB docs 获得了单元格列表语法[a,b,c,d] = C:...“匿名”单元格数组的索引在MAT 中不起作用...?我的 Octave 缺少 memory.m;找到here。在上述之后,我将 n 的一个元素设置为 tic, n(1234,2345)=42; toc 需要 ~1sec 然后 Memory used by Octave: ... 加倍——确实是牛!感谢您的提示。

以上是关于Octave / MATLAB 中的 deal() 函数有啥意义?的主要内容,如果未能解决你的问题,请参考以下文章

在 MATLAB/Octave 中查找 N 维数组中的所有局部最小值

ILNumerics 等效于 MatLab/Octave 语句

Octave 和MATLAB的区别?会用MATLAB的话,还用学Octave吗?

通过将数字分组到一个范围内在 matlab / octave 中绘图

有人用过octave吗?能替代matlab吗

如何从 GTK+2 C 代码中调用 matlab/octave 函数