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吗?