Matriz de longitud desconocida en MATLAB?

Intento establecer una matriz cero de longitud variable con dos columnas en las que puedo mostrar los resultados de un ciclo while (con la intención de usarlo para almacenar los datos del paso del método de Euler con pasos de tiempo ajustados). La longitud estará determinada por el número de iteraciones del ciclo.

Me pregunto si hay una manera de hacerlo mientras estoy ejecutando el ciclo o si necesito configurarlo desde el principio y cómo hacerlo.

si el número de columnas es fijo, siempre puede agregar filas a su matriz (dentro del ciclo)

p.ej

while (....) ..... new_row =[xy] ; % new row with values x & y mat = [mat ; new_row]; 

por supuesto, si conoce el número de iteraciones antes del ciclo while, es más eficiente preasignar la matriz

Otro enfoque que tiene en cuenta el rendimiento al mismo tiempo que intenta ahorrar espacio, es preasignar la memoria en grandes lotes, agregando más lotes según sea necesario. Esto es muy adecuado si tiene que agregar una gran cantidad de elementos sin saber cuántos de antemano.

 BLOCK_SIZE = 2000; % initial capacity (& increment size) listSize = BLOCK_SIZE; % current list capacity list = zeros(listSize, 2); % actual list listPtr = 1; % pointer to last free position while rand<1-1e-5 % (around 1e5 iterations on avrg) % push items on list list(listPtr,:) = [rand rand]; % store new item listPtr = listPtr + 1; % increment position pointer % add new block of memory if needed if( listPtr+(BLOCK_SIZE/10) > listSize ) % less than 10%*BLOCK_SIZE free slots listSize = listSize + BLOCK_SIZE; % add new BLOCK_SIZE slots list(listPtr+1:listSize,:) = 0; end end list(listPtr:end,:) = []; % remove unused slots 

EDITAR : como una comparación de tiempo, considere los siguientes casos:

  1. El mismo código que el anterior para 50000 iteraciones.
  2. Preasignación de la matriz completa de antemano: list = zeros(50000,2); list(k,:) = [xy]; list = zeros(50000,2); list(k,:) = [xy];
  3. Agregando dinámicamente vectores a la matriz: list = []; list(k,:) = [xy]; list = []; list(k,:) = [xy];

En mi máquina, los resultados fueron:

1) El tiempo transcurrido es 0.080214 segundos .
2) El tiempo transcurrido es 0.065513 segundos.
3) El tiempo transcurrido es 24.433315 segundos.


Actualizar:

Tras las discusiones en los comentarios, volví a ejecutar algunas pruebas con la última versión de R2014b. La conclusión es que las versiones recientes de MATLAB han mejorado enormemente el rendimiento del crecimiento automático de matrices.

Sin embargo, hay una trampa; la matriz debe crecer a lo largo de la última dimensión (columnas en el caso de las matrices 2D). Es por eso que agregar filas como originalmente se pretendía es aún demasiado lento sin preasignación. Aquí es donde la solución propuesta anteriormente puede ayudar realmente (ampliando la matriz en lotes).

Consulte aquí para ver el conjunto completo de pruebas: https://gist.github.com/amroamroamro/0f104986796f2e0aa618

MATLAB usa tipeo dynamic con administración de memoria automática. Esto significa que no necesita declarar una matriz de un tamaño fijo antes de usarla; puede cambiarla a medida que avanza y MATLAB asignará dinámicamente memoria para usted.

PERO es mucho más eficiente asignar memoria para la matriz primero y luego usarla. Pero si tus progtwigs necesitan este tipo de flexibilidad, hazlo.

Supongo que debes seguir agregando filas a tu matriz. El siguiente código debería funcionar.

 Matrix = []; while size(Matrix,1) <= 10 Matrix = [Matrix;rand(1,2)]; end disp(Matrix); 

Aquí, estamos reasignando dinámicamente el espacio requerido para Matrix cada vez que agrega una nueva fila. Si sabe de antemano, por ejemplo, un límite superior en el número de filas que va a tener, puede declarar Matrix = zeros(20,2) y luego insertar cada fila en la matriz de forma incremental.

 % Allocate space using the upper bound of rows (20) Matrix = zeros(20,2); k = 1; for k = 1:10 Matrix(k,:) = rand(1,2); end % Remove the rest of the dummy rows Matrix(k+1:end,:) = []; 

Otro sabor de lo mismo que Jacob publicó.

 for counter = 1:10 Matrix(counter,:) = rand(1,2); end disp(Matrix); 

Una cosa “agradable” de esto es que puedes adivinar un tamaño mínimo para ayudar a mejorar el rendimiento.

Esto también podría ser de interés: http://www.mathworks.com/help/matlab/math/resizing-and-reshaping-matrices.html#f1-88760

    Intereting Posts