vectores una seleccionar matriz listas identidad extraer elementos datos columna almacenar agregar arrays matlab matrix multidimensional-array iteration

arrays - listas - seleccionar elementos de una matriz matlab



¿Cómo puedo iterar a través de cada elemento en una matriz n-dimensional en MATLAB? (8)

Como se señaló en algunas otras respuestas, puede iterar sobre todos los elementos en una matriz A (de cualquier dimensión) usando un índice lineal de 1 a numel (A) en un único ciclo for. Hay un par de otros trucos que puede usar: ARRAYFUN y CELLFUN .

Supongamos primero que tiene una función que desea aplicar a cada elemento de A (llamado "my_func"). Primero crea un control de función para esta función:

fcn = @my_func;

Si A es una matriz (de tipo double, single, etc.) de dimensión arbitraria, puede usar ARRAYFUN para aplicar "my_func" a cada elemento:

outArgs = arrayfun(fcn,A);

Si A es una matriz de celda de dimensión arbitraria, puede usar CELLFUN para aplicar "my_func" a cada celda:

outArgs = cellfun(fcn,A);

La función "my_func" tiene que aceptar A como entrada. Si hay salidas de "my_func", estas se colocan en OutArgs , que tendrán el mismo tamaño / dimensión que A.

Una advertencia sobre las salidas ... si "my_func" devuelve salidas de diferentes tamaños y tipos cuando opera en diferentes elementos de A , entonces outArgs tendrá que convertirse en una matriz de celdas. Esto se hace llamando a ARRAYFUN o CELLFUN con un par adicional de parámetro / valor:

outArgs = arrayfun(fcn,A,''UniformOutput'',false); outArgs = cellfun(fcn,A,''UniformOutput'',false);

Tengo un problema. Necesito iterar a través de cada elemento en una matriz n-dimensional en MATLAB. El problema es que no sé cómo hacer esto para un número arbitrario de dimensiones. Sé que puedo decir

for i = 1:size(m,1) for j = 1:size(m,2) for k = 1:size(m,3)

y así sucesivamente, pero ¿hay alguna manera de hacerlo por un número arbitrario de dimensiones?


Desea simular n-anidados para bucles.

La iteración a través de la matriz n-dimmensional puede verse como un aumento del número de n dígitos.

En cada dimmension tenemos tantos dígitos como la duración de la dimmension.

Ejemplo:

Supongamos que tenemos matriz (matriz)

int[][][] T=new int[3][4][5];

en "notación" tenemos:

for(int x=0;x<3;x++) for(int y=0;y<4;y++) for(int z=0;z<5;z++) T[x][y][z]=...

para simular esto, debería usar la "notación numérica de n dígitos"

Tenemos un número de 3 dígitos, con 3 dígitos para el primero, 4 para el segundo y cinco para el tercer dígito

Tenemos que aumentar el número, así que obtendríamos la secuencia

0 0 0 0 0 1 0 0 2 0 0 3 0 0 4 0 1 0 0 1 1 0 1 2 0 1 3 0 1 4 0 2 0 0 2 1 0 2 2 0 2 3 0 2 4 0 3 0 0 3 1 0 3 2 0 3 3 0 3 4 and so on

Entonces puede escribir el código para aumentar ese número de n dígitos. Puede hacerlo de tal manera que pueda comenzar con cualquier valor del número y aumentar / disminuir los dígitos por cualquier número. De esta forma, puede simular bucles anidados que comienzan en algún lugar de la tabla y terminan al final.

Sin embargo, esta no es una tarea fácil. No puedo ayudar con la notación matlab desafortunadamente.


La idea de un índice lineal para matrices en matlab es importante. Una matriz en MATLAB es realmente solo un vector de elementos, colgado en la memoria. MATLAB le permite usar un índice de fila y columna, o un índice lineal único. Por ejemplo,

A = magic(3) A = 8 1 6 3 5 7 4 9 2 A(2,3) ans = 7 A(8) ans = 7

Podemos ver el orden en que los elementos se almacenan en la memoria desenrollando la matriz en un vector.

A(:) ans = 8 3 4 1 5 9 6 7 2

Como puede ver, el 8vo elemento es el número 7. De hecho, la función find devuelve sus resultados como un índice lineal.

find(A>6) ans = 1 6 8

El resultado es que podemos acceder a cada elemento a su vez de una matriz nd general utilizando un solo bucle. Por ejemplo, si quisiéramos cuadrar los elementos de A (sí, sé que hay mejores formas de hacerlo), uno podría hacer esto:

B = zeros(size(A)); for i = 1:numel(A) B(i) = A(i).^2; end B B = 64 1 36 9 25 49 16 81 4

Hay muchas circunstancias donde el índice lineal es más útil. La conversión entre el índice lineal y dos subíndices dimensionales (o superiores) se logra con las funciones sub2ind e ind2sub.

El índice lineal se aplica en general a cualquier matriz en matlab. Entonces puede usarlo en estructuras, arreglos de celdas, etc. El único problema con el índice lineal es cuando se hacen demasiado grandes. MATLAB usa un entero de 32 bits para almacenar estos índices. Entonces, si su matriz tiene más de un total de 2 ^ 32 elementos, el índice lineal fallará. En realidad, solo es un problema si usa matrices dispersas a menudo, cuando ocasionalmente esto puede causar un problema. (Aunque no uso una versión de MATLAB de 64 bits, creo que el problema se ha resuelto para las personas afortunadas que sí lo hacen).


Otro truco es usar ind2sub y sub2ind . En combinación con numel y size , esto puede permitirle hacer cosas como las siguientes, que crean una matriz N-dimensional, y luego configura todos los elementos en la "diagonal" para que sean 1.

d = zeros( 3, 4, 5, 6 ); % Let''s pretend this is a user input nel = numel( d ); sz = size( d ); szargs = cell( 1, ndims( d ) ); % We''ll use this with ind2sub in the loop for ii=1:nel [ szargs{:} ] = ind2sub( sz, ii ); % Convert linear index back to subscripts if all( [szargs{2:end}] == szargs{1} ) % On the diagonal? d( ii ) = 1; end end


Podría hacer una función recursiva hacer el trabajo

  • Deje L = size(M)
  • Deje idx = zeros(L,1)
  • Tome la length(L) como la profundidad máxima
  • Loop for idx(depth) = 1:L(depth)
  • Si su profundidad es de length(L) , realice la operación del elemento; de lo contrario, vuelva a llamar a la función con depth+1

No es tan rápido como los métodos vectorizados si quiere verificar todos los puntos, pero si no necesita evaluar la mayoría de ellos, puede ahorrar bastante tiempo.


Puede usar la indexación lineal para acceder a cada elemento.

for idx = 1:numel(array) element = array(idx) .... end

Esto es útil si no necesita saber en qué i, j, k se encuentra. Sin embargo, si no necesita saber en qué índice se encuentra, probablemente sea mejor que use arrayfun ()


Si profundizas en los otros usos del size , puedes ver que puedes obtener un vector del tamaño de cada dimensión. Este enlace muestra la documentación:

www.mathworks.com/access/helpdesk/help/techdoc/ref/size.html

Después de obtener el vector de tamaño, itere sobre ese vector. Algo como esto (perdón por mi sintaxis ya que no he usado Matlab desde la universidad):

d = size(m); dims = ndims(m); for dimNumber = 1:dims for i = 1:d[dimNumber] ...

Convierta esto en la sintaxis real de Matlab-legal, y creo que haría lo que quiera.

Además, debería poder hacer la indexación lineal como se describe here .


estas soluciones son más rápidas (alrededor del 11%) que el uso de numel ;)

for idx = reshape(array,1,[]), element = element + idx; end

o

for idx = array(:)'', element = element + idx; end

UPD. tnx @rayryeng por error detectado en la última respuesta

Renuncia

La información de temporización a la que se ha hecho referencia en esta publicación es incorrecta e inexacta debido a un error tipográfico fundamental que se cometió (consulte la secuencia de comentarios a continuación y el historial de edición , específicamente, consulte la primera versión de esta respuesta). Caveat Emptor .