Modify Matrix / multidimensional array with Colon in Colon

22 visualizaciones (últimos 30 días)
Julian
Julian el 3 de Ag. de 2023
Comentada: Dyuman Joshi el 6 de Sept. de 2023
In Matlab I can modify an array with a colon like this:
n = 90;
A = zeros(n,1);
A(1:n) = (1:n).^2;
If I have a two dimensional array, a matrix it gets more complicated but it is still easy to modify all entities with a loop:
n2 = 10;
A = zeros(n,n2);
for index = 1:n2
A(1:n,index) = (index:index+n-1).';
end
or
n2 = 10;
A = zeros(n,n2);
for index = 1:n2
A(1:n,index) = colon(index, index+n-1).';
end
I would like to use a direkt matrix calculation instead of a for loop to increase my speed, since my problem is bigger and I have to do it often.
My approach was:
A(1:n,1:n2) = colon(1:n2, (1:n2)+n-1).';
or
A(1:n,1:n2) = colon(1:n, (1:n)+n2-1);
Matlab also uses "n" and "n2" on the left side, giving me the 90-by-10 size. However, on the right side I only have a 90-by-1 or 1-by-10 size.
My current solution is unfortunately not the colon. I need to use the arrayfun and convert the resulting cell array into a matrix.
A2 = arrayfun(@(a) a:a+n-1, 1:n2, 'UniformOutput', false).';
A = cell2mat(A2).';
In Python I would use nested foor loops and be able to make this multidimensional in a singel line.
My working alternative in Matlab is significantly more computationally expensive and for more dimensions I would have to create a loop or a function that calls itself.
Isn't that somehow easier with "colon"?
  2 comentarios
Stephen23
Stephen23 el 3 de Ag. de 2023
Editada: Stephen23 el 3 de Ag. de 2023
"Isn't that somehow easier with "colon""
I doubt it.
n = 90;
n2 = 10;
A2 = arrayfun(@(a) a:a+n-1, 1:n2, 'UniformOutput', false).';
A = cell2mat(A2).'
A = 90×10
1 2 3 4 5 6 7 8 9 10 2 3 4 5 6 7 8 9 10 11 3 4 5 6 7 8 9 10 11 12 4 5 6 7 8 9 10 11 12 13 5 6 7 8 9 10 11 12 13 14 6 7 8 9 10 11 12 13 14 15 7 8 9 10 11 12 13 14 15 16 8 9 10 11 12 13 14 15 16 17 9 10 11 12 13 14 15 16 17 18 10 11 12 13 14 15 16 17 18 19
Two efficient MATLAB approaches:
B = (0:n2-1) + (1:n).'
B = 90×10
1 2 3 4 5 6 7 8 9 10 2 3 4 5 6 7 8 9 10 11 3 4 5 6 7 8 9 10 11 12 4 5 6 7 8 9 10 11 12 13 5 6 7 8 9 10 11 12 13 14 6 7 8 9 10 11 12 13 14 15 7 8 9 10 11 12 13 14 15 16 8 9 10 11 12 13 14 15 16 17 9 10 11 12 13 14 15 16 17 18 10 11 12 13 14 15 16 17 18 19
C = hankel(1:n,n:n+n2-1)
C = 90×10
1 2 3 4 5 6 7 8 9 10 2 3 4 5 6 7 8 9 10 11 3 4 5 6 7 8 9 10 11 12 4 5 6 7 8 9 10 11 12 13 5 6 7 8 9 10 11 12 13 14 6 7 8 9 10 11 12 13 14 15 7 8 9 10 11 12 13 14 15 16 8 9 10 11 12 13 14 15 16 17 9 10 11 12 13 14 15 16 17 18 10 11 12 13 14 15 16 17 18 19
isequal(A,B,C)
ans = logical
1
The trick to using MATLAB effectively is to not reinvent the wheel: for many common operations there are simple functions or operations that can be used on entire arrays:
"Isn't that somehow easier with "colon""
You seem to be trying to hide a loop inside COLON: it does not work like that.
Julian
Julian el 4 de Ag. de 2023
Thank you a lot Stephen23, your first approach was somehow exactly what I wanted but I did not get it without your help!

Iniciar sesión para comentar.

Respuesta aceptada

recent works
recent works el 4 de Ag. de 2023
You are correct that using the colon operator directly to perform the multidimensional assignment is a bit tricky in MATLAB. The colon operator is designed for creating a linearly spaced vector and may not directly produce the desired multidimensional array.
However, you can achieve the desired result in a more efficient way using array broadcasting and bsxfun (Binary Singleton Expansion Function) in MATLAB. Array broadcasting allows you to perform element-wise operations on arrays with different sizes, expanding the smaller array to match the size of the larger one.
Here's how you can do it without using loops or cell arrays:
n = 90;
n2 = 10;
% Create a 1-by-n vector with values from 1 to n
index = 1:n;
% Create a 1-by-n2 vector with values from 1 to n2
index2 = (1:n2)';
% Perform element-wise addition and broadcasting to create the desired matrix
A = bsxfun(@plus, index2, index - 1);
In this approach, we create two vectors index and index2 using the colon operator. Then, we use bsxfun to add index2 to each element of index, which results in the desired multidimensional matrix A.
This method should be more computationally efficient and avoids the need for loops or cell arrays. It can be easily extended to higher dimensions as well.
  2 comentarios
Julian
Julian el 6 de Sept. de 2023
@recent works Thank you, but how do I use it to get a multidimensional tensor (matrix with more then 2 dimensions)?

Iniciar sesión para comentar.

Más respuestas (0)

Categorías

Más información sobre Matrix Indexing en Help Center y File Exchange.

Productos


Versión

R2023a

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by