2012-03-13 68 views
5

在Matlab中,我试图把匿名函数中的数组:何时使用数组以及何时使用单元阵列?

>> a=[@(k)0.1/(k+1) @(k)0.1/(k+1)^0.501] 
??? Error using ==> horzcat 
Nonscalar arrays of function handles are not allowed; use cell arrays 
instead. 

所以我不知道什么样的元素被允许在一个阵列,并且在单元阵列?

例如,我知道,在一个阵列中,元件可以是数值或字符串。还有什么?

+0

可能是相关的 - http://stackoverflow.com/questions/9055015/difference-between-accessing-cell-elements-using-and-curly-or-normal-brac/9055336#9055336 – 2012-03-13 15:16:38

回答

6

总之:细胞阵列是异构容器,规则阵列是均匀。这意味着在常规数组中,所有元素都是相同类型的,而在单元数组中,它们可以不同。你可以阅读更多关于单元阵列here

使用单元阵列时:

  • 你有你的阵列中的不同类型的
  • 你不知道你是否在未来可能会扩展到其他类型的
  • 您正在使用对象有一个继承模式
  • 您正在使用一系列字符串 - 几乎在任何情况下它最好是char(n,m)
  • 你有一个大阵,你经常更新功能的单个元素 - 由于Matlabs 写入时复制政策
  • 您与函数处理工作(如@Pursuit解释)

身高:规则排列时:

  • 所有的元素都具有相同的类型
  • 要更新整个阵列中的一个镜头 - 像数学运算。
  • 你想拥有类型安全
  • 你会不会改变阵列的数据类型在未来
  • 您与数学矩阵的工作。
  • 你与那些没有继承对象时

更多解释有关写入时复制

当你传递一个数组给一个函数,指针/引用通过。

function foo(x) 
    disp(x); 
end 

x= [1 2 3 4 5]; 
foo(x); %No copy is done here! A pointer is passed. 

但是,当您更改它(或其中的一部分)时,会创建副本。

function foo(x) 
    x(4) = x(4) + 1; 
end 

x= [1 2 3 4 5]; 
foo(x); %x is being copied! At least twice memory amount is needed. 

在单元阵列中,只有单元格被复制。因此,如果您调用一个函数来更改大型数组上的单个元素,则会制作大量副本 - 这会使其变慢。但在单元阵列中,情况并非如此。

+0

谢谢!我想知道“你有一个庞大的数组,并且你经常更新一个函数中的一个元素 - Malab copy-on-write策略”中的“Malab copy-on-write policy”是什么? – Tim 2012-03-14 15:33:20

+0

@Tim,我已经更新了我的答案。 – 2012-03-14 21:53:25

3

函数句柄实际上是这里的例外,原因是如果允许函数句柄成为非单元格数组的一部分,Matlab语法会变得令人惊讶。例如

a = @(x)x+1; 
a(2); %This returns 2 

但是,如果函数处理的阵列,支持,则

b = [@(x)x+1, @(x)x+2]; 
b(2);     %This would return @(x)x+2 
b(3) = @(x)x+3;  %This would extend the size of the array 

所以后来会变成这样被允许?

a(2) = @(x)x+2;  %Would this extend the size of the previously scalar array 

冗长编辑:这是在release notes accompanying release R14,这是第一个版本允许匿名函数记录。在R14之前,您可以创建函数句柄作为m文件函数的参考,并且它们可以放置在非单元阵列中。这些只能使用feval(例如:fnSin = @sin; output = feval(fnSin, pi))来调用。

当引入匿名函数时,Mathworks更新语法以允许使用更简单的调用约定(例如fnSin = @sin; output = fnSin(pi)),该函数在使用函数句柄的非单元阵列时会产生不明确的效果。看起来他们尽力将祖父这种新行为付诸行动,但那些祖父母的条件已经过期(这是2004年)。

+0

谢谢!作为动词的“祖父”是什么意思? – Tim 2012-03-14 13:10:31

+0

http://en.wikipedia.org/wiki/Grandfather_clause – Pursuit 2012-03-14 13:28:08

2

数组只能存储固定长度的数据。例如,double,single,char,logical,integer。 原因是(我猜)它们直接存储在一块内存中。另一方面,单元存储为指针列表,每个指针可指向不同大小的数据。

这就是为什么数组不能存储字符串,功能手柄,数组和多种数据类型。 这些类型可以有不同的长度。例如'bla'有3个字节,'blabla'有6个字节。因此,如果它们存储在同一个内存块中,如果要将'bla'更改为'blabla',则必须将所有剩余的内存移位,这将非常缓慢,因此无法处理。

相关问题