2012-03-13 8 views
5

En Matlab, yo estaba tratando de poner funciones anónimas en una matriz:¿Cuándo utilizar la matriz y cuándo usar la matriz de celdas?

>> 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. 

así que me pregunto qué tipo de elementos se permiten en una matriz, y en una serie de células?

Por ejemplo, sé que en una matriz, los elementos pueden ser numéricos o cadenas. ¿Qué más?

+0

Podría estar relacionado - http://stackoverflow.com/questions/9055015/difference-between-accessing-cell-elements-using-and-curly-or-normal-brac/9055336#9055336 –

Respuesta

6

En resumen: array célula es una heterogénea contenedor, matriz regular es homogénea. Esto significa que en una matriz regular todos los elementos son del mismo tipo, mientras que en la matriz de celdas, pueden ser diferentes. Puede leer más sobre la matriz de celdas here.

Uso serie de células cuando:

  • Tienes diferentes tipos en la matriz
  • no está seguro de si en el futuro es posible extenderla a otros tipos
  • Se está trabajando con objetos que tienen un patrón de herencia
  • Está trabajando con una matriz de cadenas - casi en cualquier ocasión es preferible char (n, m)
  • usted tiene una gran variedad, y que a menudo actualizar un solo elemento en una función - Debido a Matlabs copia en escritura política
  • Usted está trabajando con asas de función (como se explica @Pursuit)

Prefiero matriz regular cuando:

  • Todos los elementos tienen el mismo tipo
  • está actualizando toda la matriz de una sola vez - como Operaciones matemáticas.
  • Usted quiere tener la seguridad de tipos
  • Usted no va a cambiar el tipo de datos de la matriz en el futuro
  • Se está trabajando con matrices matemáticas.
  • Se está trabajando con objetos que no tienen herencia

Más explicación sobre copia en escritura:

Cuando se pasa una matriz a una función, un puntero/referencia es pasado.

function foo(x) 
    disp(x); 
end 

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

Pero cuando lo cambie (o una parte), se creará una copia.

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. 

En una matriz celular, solamente la célula se copia.

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

x= {1 2 3 4 5}; %Only x{4} will be copied 

Por lo tanto, si se llama a una función que cambia un solo elemento en una amplia gama, que está haciendo una gran cantidad de copias - que hace que sea más lenta. Pero en una matriz de celdas, no es el caso.

+0

¡Gracias! Me pregunto qué es la "política de copiado sobre escritura de Malab" en "Usted tiene una matriz grande, y usted a menudo actualiza un solo elemento en una función - ¿Debido a la política de copia de Malab de Malab"? – Tim

+0

@Tim, he actualizado mi respuesta. –

3

Los identificadores de función son en realidad la excepción aquí, y la razón es que la sintaxis de Matlab se vuelve sorprendente si permite que los identificadores de función formen parte de una matriz que no es de célula. Por ejemplo

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

Pero, si se admiten las matrices de asas de función, entonces

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 

Así se permitiría esto?

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

edición longwinded: Esto está documentado en el release notes accompanying release R14, que fue la primera versión que permite funciones anónimas. Antes de R14, podía crear identificadores de función como referencias a funciones de m-file, y podrían colocarse en arreglos que no sean de celda. Estos solo pueden llamarse usando feval (por ejemplo, fnSin = @sin; output = feval(fnSin, pi)).

Cuando se introdujeron funciones anónimas, Mathworks actualizó la sintaxis para permitir una convención de llamadas más simple (por ejemplo, fnSin = @sin; output = fnSin(pi)) que tuvo el efecto de causar una ambigüedad cuando se usa un conjunto de controladores de funciones que no son de celda. Parece que hicieron todo lo posible para abogar por este nuevo comportamiento, pero esas condiciones de derechos adquiridos ciertamente han expirado (esto fue en 2004).

+0

¡Gracias! ¿Qué significa "abuelo" como verbo? – Tim

+0

http://en.wikipedia.org/wiki/Grandfather_clause – Pursuit

2

Las matrices pueden almacenar solo datos con una longitud fija. Por ejemplo, double, single, char, logical, integer. La razón es que (supongo) se almacenan directamente en un bloque de memoria. Por otro lado, las celdas se almacenan como una lista de punteros, cada puntero puede señalar datos de diferentes tamaños.

Es por eso que las matrices no pueden almacenar cadenas, identificador de función, matrices y múltiples tipos de datos. Ese tipo puede tener diferente longitud. Por ejemplo, 'bla' tiene 3 bytes, 'blabla' tiene 6 bytes. Por lo tanto, si están almacenados en el mismo bloque de memoria, si desea cambiar 'bla' a 'blabla', debería cambiar todo el resto de la memoria, lo que sería muy lento y no se manejaría.

Cuestiones relacionadas