2013-05-28 3 views
1

루프를 반복 할 때마다 2x2 행렬을 생성하는 재귀 프로 시저가 있습니다. 나중에이 행렬 각각을 호출 할 수 있기를 원하지만 효율적으로 모두 저장하는 방법을 모르겠습니다.Matlab : n 2x2 행렬의 효율적인 저장

절차가 n 번 반복되면 2nx2 매트릭스에 저장해야합니까? 그렇다면이 긴 행렬 내에서 j 번째 행렬 (행 2j-1과 2j)을 어떻게 부르겠습니까?

감사합니다.

답변

4

당신은 cell arrays를 사용할 수 있습니다

matrices = cell(n,1); 
for ii = 1:n 

    % generate your matrix 
    matrix_ii = rand(2); 

    % store it for later 
    matrices{ii} = matrix_ii; 

    % [do your stuff] 

end 

j 번째 행렬은 그 다음이다 불러

matrix_j = matrices{j} 

(중괄호 주)

로 간단하게.

(당신이 제안) 또한 대형 2 차원 배열에 저장할 수

matrices = zeros(2*n,2); 
for ii = 1:n 

    % generate your 2x2 matrix 
    matrix_ii = rand(2); 

    % store it for later 
    matrices(2*(ii-1)+[0 1]+1,:) = matrix_ii; 

    % [do your stuff] 

end 

이상과 같이 값을 리콜 :

matrix_j = matrices(2*(j-1)+[0 1]+1,:) 

정도와 같은 3D 배열의

,

matrices = zeros(2,2,n); 
for ii = 1:n 

    % generate your 2x2 matrix 
    matrix_ii = rand(2); 

    % store it for later 
    matrices(:,:,ii) = matrix_ii; 

    % [do your stuff] 

end 

나중에 이렇게 값을 불러 오십시오.

n = 1e5의 방법을 비교
matrix_j = matrices(:,:,j); 

:

Elapsed time is 0.282959 seconds. % cell arrays 
Elapsed time is 0.856801 seconds. % 2*n x 2 matrix 
Elapsed time is 0.293186 seconds. % 2x2xn array 

Memory: 9200000 bytes % Cell arrays 
Memory: 3200000 bytes % 2*n x 2 matrix 
Memory: 3200000 bytes % 2x2xn array 

당신은 당신의 자신의 컴퓨터에서 이러한 것들을 테스트 할 수 있습니다,하지만 큰 차원 배열이 여기하는 가장 좋은 방법입니다 나타납니다.

+3

그러나 메모리 소비량 이 셀 접근법은'2 x 2 x n' 3D 행렬에'n'' 2 x 2' 행렬을 저장하는 것에 비해 약 4 배 더 큽니다. 반면에 셀 접근법은'2 x 2 x n' 행렬에 2D 행렬을 저장하는 것보다 훨씬 빠릅니다. –

+0

@ H.Muster : 실제로.이것은 항상 나를 이상하게 보았습니다. 셀은 "데이터에 대한 포인터를위한 컨테이너 일뿐입니다." 그러나 그것은 진행되지 않습니다 ... 어쨌든, 나는 그것을 완성을 위해 편집 할 것입니다. –

+0

좋은 답변 (+1). 나는 세포 코드와 2x2xn 배열 코드의 경과 시간이 당신과 다르지 않다는 것을 조금 혼란스러워한다. 내 시스템에서는 후자가 훨씬 느립니다. –

1

Rody Oldenhuis은 그의 대답에 행렬을 저장하는 3 가지 훌륭한 대안을 제시했습니다. 나는 그 중 가장 느린 것을 향상시키고 싶었다.

MATLAB 행렬은 행이 아닌 열에 의해 빠르게 인덱싱되므로 키가 큰 행렬 (2 * n-by-2)보다는 큰 와이드 행렬 (2x2 * n)을 만듭니다. 또한 반복에서 색인을 작성하는 것이 단순화 될 수 있습니다.

>> [t,b] = test_2d_matrices_container 
t = 
     0.13963  0.22997  0.23434 
b = 
    9200000  3200000  3200000 
: 여기

이 약간 더 편리 벤치 마크, 그 결과 내가 내 컴퓨터에서 얻을

function [t,b] = test_2d_matrices_container() 
    N = 1e5; 
    f = {@()func_cell(N), @()func_wide_2d_mat(N), @()func_3d_mat(N)}; 

    t = cellfun(@timeit, f); 
    b = cellfun(@get_mem, f); 
end 

function b = get_mem(f) 
    x = feval(f); %#ok<NASGU> 
    S = whos('x'); 
    b = S.bytes; 
end 

function M = func_cell(N) 
    M = cell(N,1); 
    for i=1:N 
     M{i} = rand(2); 
    end 
end 

function M = func_wide_2d_mat(N) 
    M = zeros(2,2*N); 
    for i=1:2:2*N 
     M(:,[i i+1]) = rand(2); 
    end 
end 

function M = func_3d_mat(N) 
    M = zeros(2,2,N); 
    for i=1:N 
     M(:,:,i) = rand(2); 
    end 
end 

결과 (당신은 파일 교환에서 TIMEIT 기능이 필요합니다)

이제 "넓은"2D 행렬의 경우는 3D "슬라이스"방법만큼 빠릅니다 (가볍게 빠르지 만 그 차이는 실제로 무시해도 좋습니다).