문제가 있습니다. MATLAB에서 n 차원 행렬의 모든 요소를 반복해야합니다. 문제는 임의의 차원에 대해이 작업을 수행하는 방법을 모른다는 것입니다. 내가 말할 수 있다는 걸 알아
for i = 1:size(m,1)
for j = 1:size(m,2)
for k = 1:size(m,3)
등등, 그러나 임의의 수의 차원에 대해 수행하는 방법이 있습니까?
문제가 있습니다. MATLAB에서 n 차원 행렬의 모든 요소를 반복해야합니다. 문제는 임의의 차원에 대해이 작업을 수행하는 방법을 모른다는 것입니다. 내가 말할 수 있다는 걸 알아
for i = 1:size(m,1)
for j = 1:size(m,2)
for k = 1:size(m,3)
등등, 그러나 임의의 수의 차원에 대해 수행하는 방법이 있습니까?
답변:
선형 인덱싱을 사용하여 각 요소에 액세스 할 수 있습니다.
for idx = 1:numel(array)
element = array(idx)
....
end
이것은 i, j, k, 현재 상태를 알 필요가없는 경우에 유용합니다. 그러나 현재 어떤 인덱스에 있는지 알 필요가 없다면 arrayfun ()을 사용하는 것이 좋습니다.
I = cell(1, ndims(array)); [I{:}] = ind2sub(size(array),idx);
있습니다..
MATLAB에서 배열에 대한 선형 인덱스의 개념은 중요한 것입니다. MATLAB의 배열은 실제로 메모리에 묶인 요소의 벡터 일뿐입니다. MATLAB에서는 행 및 열 인덱스 또는 단일 선형 인덱스를 사용할 수 있습니다. 예를 들면
A = magic(3)
A =
8 1 6
3 5 7
4 9 2
A(2,3)
ans =
7
A(8)
ans =
7
배열을 벡터로 풀어서 요소가 메모리에 저장되는 순서를 볼 수 있습니다.
A(:)
ans =
8
3
4
1
5
9
6
7
2
보시다시피 8 번째 요소는 숫자 7입니다. 실제로 find 함수는 결과를 선형 인덱스로 반환합니다.
find(A>6)
ans =
1
6
8
결과적으로 단일 루프를 사용하여 일반 nd 배열의 각 요소에 차례로 액세스 할 수 있습니다. 예를 들어 A의 요소를 제곱하려는 경우 (예, 더 나은 방법이 있다는 것을 알고 있습니다) 다음과 같이 할 수 있습니다.
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
선형 인덱스가 더 유용한 상황이 많이 있습니다. 선형 인덱스와 2 차원 (또는 더 높은) 첨자 간의 변환은 sub2ind 및 ind2sub 함수를 사용하여 수행됩니다.
선형 인덱스는 일반적으로 matlab의 모든 배열에 적용됩니다. 따라서 구조체, 셀형 배열 등에 사용할 수 있습니다. 선형 인덱스의 유일한 문제는 너무 커질 때입니다. MATLAB은 32 비트 정수를 사용하여 이러한 인덱스를 저장합니다. 따라서 배열에 총 2 ^ 32 개 이상의 요소가있는 경우 선형 인덱스는 실패합니다. 희소 행렬을 자주 사용하는 경우에만 문제가됩니다. 가끔 이로 인해 문제가 발생합니다. (64 비트 MATLAB 릴리스를 사용하지 않지만, 운이 좋은 사람들을 위해 문제가 해결되었다고 생각합니다.)
x = ones(1,2^33,'uint8'); x(2^33)
예상대로 작동합니다.
몇 가지 다른 답변에서 지적했듯이 단일 for 루프 에서 to to 까지 선형 인덱스 를 A
사용하여 (모든 차원의) 행렬의 모든 요소를 반복 할 수 있습니다 . 또한 사용할 수있는 몇 가지 기능이 있습니다. 및 .1
numel(A)
arrayfun
cellfun
먼저 A
(라고하는 my_func
) 의 각 요소에 적용하려는 함수가 있다고 가정 해 보겠습니다 . 먼저이 함수에 대한 함수 핸들 을 만듭니다 .
fcn = @my_func;
경우 A
(두 번 등, 단일 유형의) 임의의 차원의 매트릭스를, 당신은 사용할 수 있습니다 arrayfun
적용하는 my_func
각 요소 :
outArgs = arrayfun(fcn, A);
경우 A
A는 셀 어레이 임의의 차원, 당신은 사용할 수 있습니다 cellfun
적용 할 my_func
각 셀에 :
outArgs = cellfun(fcn, A);
함수 my_func
는 A
입력 으로 받아 들여야 합니다. 의 출력이 있으면 my_func
에 배치 outArgs
되며 A
.
만약 출력에 한 가지주의 ... my_func
다른 크기 및 형태의 반환 출력은 다른 요소에서 동작 할 때 A
, 다음 outArgs
세포 배열로 만들 수있을 것이다. 이것은 어느 쪽인지를 호출하여 수행됩니다 arrayfun
또는 cellfun
추가 매개 변수 / 값 쌍 :
outArgs = arrayfun(fcn, A, 'UniformOutput', false);
outArgs = cellfun(fcn, A, 'UniformOutput', false);
또 다른 트릭은 ind2sub
및 sub2ind
. 와 결합 numel
하고 size
, 이것은이 N 차원 배열을 생성하고 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
이러한 솔루션은 사용하는 것보다 더 빠릅니다 (약 11 %) numel
.
for idx = reshape(array,1,[]),
element = element + idx;
end
또는
for idx = array(:)',
element = element + idx;
end
UPD. 마지막 답변에서 감지 된 오류에 대한 tnx @rayryeng
이 게시물이 참조 한 타이밍 정보는 근본적인 오타로 인해 부정확하고 정확하지 않습니다 (아래 댓글 스트림과 편집 기록 참조 -특히이 답변의 첫 번째 버전을 확인하십시오). 경고 Emptor .
1 : array(:)
와 동일합니다 1 : array(1)
. 이것은 모든 요소를 반복하지 않으므로 런타임이 빠릅니다. 또한 부동 소수점 숫자를 rand
생성 하므로 명령문이 초기 값이 1 인 증가 벡터를 찾고 끝 값 이 증가 하는 범위 가 1을 제외한 부동 소수점 숫자로 끝나는 벡터를 찾으려고 할 때 빈 배열이 생성됩니다. 1의 단계. 이러한 가능한 벡터가 없으므로 빈 벡터가 생성됩니다. 귀하의 루프가 실행되지 않습니다, 그래서 당신의 주장은 거짓입니다. -1 표. 죄송합니다. 1 : array(:)
[0,1)
for
reshape(...)
.
1 : array(:)
를 만든 후 명령 프롬프트 에 on 을 입력 합니다 array
. 빈 행렬을 얻습니까? 그렇다면 코드가 작동하지 않습니다. 당신이 허위 정보를 제공했기 때문에 나는 내 투표를 떠납니다.
의 다른 용도를 더 자세히 살펴보면 size
실제로 각 차원 크기의 벡터를 얻을 수 있음을 알 수 있습니다. 이 링크는 문서를 보여줍니다.
www.mathworks.com/access/helpdesk/help/techdoc/ref/size.html
크기 벡터를 얻은 후 해당 벡터를 반복합니다. 다음과 같은 것 (대학 때부터 Matlab을 사용하지 않았으므로 내 구문을 용서하십시오) :
d = size(m);
dims = ndims(m);
for dimNumber = 1:dims
for i = 1:d[dimNumber]
...
이것을 실제 Matlab-legal 구문으로 만들면 원하는 것을 할 것이라고 생각합니다.
또한 여기에 설명 된대로 선형 인덱싱을 수행 할 수 있어야합니다 .
n-nested for 루프를 시뮬레이션하려고합니다.
n 차원 배열을 반복하는 것은 n 자리 숫자를 증가시키는 것으로 볼 수 있습니다.
각 차원에서 우리는 차원의 길이만큼 자릿수를가집니다.
예:
array (matrix)가 있다고 가정합니다.
int[][][] T=new int[3][4][5];
"for notation"에는 다음이 있습니다.
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]=...
이를 시뮬레이션하려면 "n 자리 숫자 표기법"을 사용해야합니다.
첫 번째는 3 자리, 두 번째는 4 자리, 세 번째 자리는 5 자리 숫자입니다.
숫자를 늘려야하므로 시퀀스를 얻을 수 있습니다.
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
따라서 이러한 n 자리 숫자를 늘리는 코드를 작성할 수 있습니다. 숫자 값으로 시작하여 숫자로 숫자를 늘리거나 줄일 수있는 방식으로 할 수 있습니다. 이렇게하면 테이블 어딘가에서 시작하여 끝이 아닌 중첩 된 for 루프를 시뮬레이션 할 수 있습니다.
하지만 이것은 쉬운 일이 아닙니다. 나는 matlab 표기법을 불편하게 도울 수 없습니다.