2011-05-05 7 views
14

Estoy escribiendo una función MATLAB para leer datos en una matriz n-dimensional (tamaño de dimensión variable). Necesito poder acceder a un punto específico en la Matriz (para escribir o leer, por ejemplo), pero no sé de antemano cuántos índices especificar.Use un vector como índice para una matriz

Actualmente tengo un vector current_point que repito para especificar cada índice y un vector max_points que especifica el tamaño de la matriz. Así, si por ejemplo yo quería una matriz de 3 dimensiones de tamaño 1000-by-15-por-3, max_points = [1000 15 3], y current_point itera de [1, 1, 1] a [1000, 15, 3] ([1, 1, 1] ->[1000, 1, 1] ->[1, 2, 1] ->[1000, 2, 1] -> ...) . Lo que me gustaría ser capaz de hacer es alimentar current_point como un índice de la matriz de esta manera:

output_matrix(current_point) = val 

Pero al parecer algo así como output_matrix([1 2 3]) = val se acaba de establecer outputmatrix(1:3) = 30. No puedo usar variables ficticias porque a veces la matriz necesitará 3 índices, otras veces 4, otras veces 2, etc., así que realmente necesito un vector de longitud variable. ¿Hay una manera simple de usar un vector como puntos en un índice?

+0

Esto es esencialmente * * un duplicado de [MATLAB notación compacta matriz de indexación] (http://stackoverflow.com/questions/792683/compact-matlab-matrix-indexing-notación), aunque tal vez esta pregunta sea un poco más simple que ese caso. – gnovice

+0

Sabía que esto debe haber sido preguntado antes, pero no lo pude encontrar con mi plugin dupe. Supongo que dejaré que la respuesta se mantenga, ya que el título de la pregunta es más directo que el otro y podría ser más fácil de buscar. – abcd

+0

Pensé que debía haber sido preguntado en algún momento, pero por los títulos no estaba viendo nada. Buenas respuestas de ustedes dos. Pensé que habría algo simple como eso. – Paul

Respuesta

17

El uso de la función sub2ind para crear un linear index es la solución típica a este problema, como se muestra en este closely-related question. También puede llamar al compute a linear index yourself en lugar de llamar al sub2ind.

Sin embargo, su caso puede ser más simple que los de las otras preguntas a las que me he vinculado. Si solo indexa un punto único con su vector current_point (es decir,es solo un vector de elementos n de subíndices en su matriz n-dimensional), luego puede usar una solución simple donde convierte current_point a una matriz de celdas de subíndices usando la función num2cell y úsela para crear un comma-separated list de índices. Por ejemplo:

current_point = [1 2 3 ...];  % A 1-by-n array of subscripts 
subCell = num2cell(current_point); % A 1-by-n cell array of subscripts 
output_matrix(subCell{:}) = val; % Update the matrix point 

La operación subCell{:} crea el equivalente de escribir subCell{1}, subCell{2}, ..., que es el equivalente de escribir current_point(1), current_point(2), ....

3

Puede usar la función sub2ind para obtener el índice lineal del subíndice.

Ejemplo:

A=magic(4) 

A = 

    16  2  3 13 
    5 11 10  8 
    9  7  6 12 
    4 14 15  1 

selectElement={2,3}; %# get the element at position 2,3 in A. 
indx=sub2ind(size(A),selectElement{:}); 
A(indx) 

ans = 

    10 

En el ejemplo anterior, he almacena los subíndices (puede ser cualquier número de dimensiones) como un cell. Si lo tiene almacenado como un vector, simplemente use num2cell() para convertirlo en una celda.

Ahora puede asignar fácilmente un valor a esto como A(indx)=value;. He usado variables diferentes a la suya para mantener la respuesta general, pero la idea es la misma y solo necesita reemplazar los nombres de las variables.

También mencionó en su publicación que está realizando un bucle desde (1,1,1) hasta algún valor, (1000,15,3) y asignando un valor a cada uno de estos puntos. Si está recorriendo las columnas, puede reemplazar toda esta operación con una solución vectorizada.

Deje que finalElement={1000,15,3} sea el último paso del ciclo. Al igual que antes, encontrar el índice lineal como

index=sub2ind(size(A),finalElement{:}); 

Ahora bien, si usted tiene los valores que se asignan en el bucle se almacena como un único vector, values, sólo tiene que asignarlo en un solo paso como

A(1:index)=values; 
10

Sé que es demasiado tarde, pero para cualquiera que encuentre este tema. la manera más fácil que funciona para mí es usar: diag(A (x(:),y(:)));

lamentablemente esto sólo funciona si usted necesita para obtener los valores de la matriz, no para cambiar los valores

+2

¿Puede explicar esto aún más, no lo entiendo, pero parece que podría ser una solución sencilla y simple – Leo

+0

Impresionante ... funciona perfecto! +1 – bluebox

Cuestiones relacionadas