2014-10-29 14 views
5

Giả sử tôi có ma trận 3-dimensional và đã tính max dọc theo thứ nguyên thứ hai và muốn lấy chỉ số tuyến tính của giá trị tối đa. Tuy nhiên, max-function chỉ trả về các bảng con cùng một chiều.Chỉ số tuyến tính tối đa của ma trận đa chiều - MATLAB

A = randn([5,5,5]);  % Generate random matrix 
[M, Ind] = max(A,[],2); % Take the max along dimension 2 

Làm thế nào để chuyển index-linear indexing, chẳng hạn rằng

M == A(Ind) 

trở thành sự thật?

Mục đích của tôi cho vấn đề này là tôi có twomulti-dimensional ma trận và cần tính max trong số first một. Sau đó, tôi muốn truy cập các giá trị trong ma trận second ở chính xác những vị trí mà tôi đã tìm thấy giá trị tối đa trong số first.

+0

Nếu bạn quan tâm về hiệu suất, đây là một thử nghiệm nhanh cho giải pháp được đăng ở đây - https://ideone.com/cOV5D3 – Divakar

Trả lời

2

Một cách là sử dụng sub2ind:

A = randn([5,5,5]);  
[M, col] = max(A,[],2); 

[m,n,o] = size(A); 

dim1 = mod((0:m*o-1)', m)+1; 
dim2 = col(:); 
dim3 = ceil((1:m*o)/m)'; 

ind = sub2ind(size(A), dim1, dim2, dim3) 

xác minh nó hoạt động với

isequal(M(:), A(ind)) 

để có được chúng để có hình dạng giống như M:

reshape(ind, m, 1, o) 
+1

Nhận xét tuyệt vời, với sự trợ giúp của bạn, tôi có thể quản lý vấn đề. Tôi đã gặp khó khăn khi hiểu các tham số sub2ind nhu cầu. Tuy nhiên, tôi có thể mở rộng giải pháp này đến thậm chí năm chiều trong ma trận A. – dast

+1

Không vấn đề gì :) Đừng quên [chấp nhận] (http://meta.stackexchange.com/questions/5234/how-does-accepting-an -answer-work) Một trong những câu trả lời này mặc dù ... – Dan

0

Giả sử AB là hai ma trận bạn có và bạn cần phải nhận được max chỉ số từ A và sử dụng những chỉ số để chỉ số thành B cho kết quả mong muốn. Một cách tiếp cận để đạt được cùng có thể là như thế này -

%// Your code to get Ind 
A = randn([5,5,5]);  % Generate random matrix 
[M, Ind] = max(A,[],2); % Take the max along dimension 2 

%// ------- Solution code ------------- 

%// Get the size of A 
[n1,n2,n3] = size(A) 

%// Linear indices corresponding to column and third dimension indices 
col_dim3_lin_idx = bsxfun(@plus,(Ind-1)*n1,permute([0:n3-1]*n1*n2,[1 3 2])) 

%// Finally get the overall linear indices 
linear_index = bsxfun(@plus,col_dim3_lin_idx,[1:n1]') %//' 

%// Get the corresponding elements from B 
out = B(linear_index) 

cách Hơi khác nhau để có các chỉ số tuyến tính mong muốn như là một mảng 2D sẽ là như thế này -

[n1,n2,n3] = size(A) %// Get the size of A 
idx = bsxfun(@plus,bsxfun(@plus,squeeze((Ind-1)*n1),[0:n3-1]*n1*n2),[1:n1]') 

idx(:) sẽ là vector cột của các chỉ số tuyến tính với phương pháp mới này, mà bạn có thể lập chỉ mục thành B tức là B(idx(:)) để có đầu ra mong muốn dưới dạng vectơ cột.

+0

Cảm ơn cho câu trả lời, tuy nhiên , Tôi đoán giải pháp với sub2ind có thể nhanh hơn vì mã của bạn yêu cầu hoạt động bsxfun và hoán vị, điều này có thể làm chậm mã. Tuy nhiên, tôi đã không đánh giá nó. – dast

+0

@ Tôi nghĩ bạn nên thử tất cả các giải pháp này và xem cho chính mình để so sánh thời gian chạy. Ngoài ra, hãy để tôi hỏi bạn - Định dạng đầu ra cho các chỉ số tuyến tính là gì? Bạn đang tìm cách để có một vector cột của các chỉ số hoặc giữ nó với cùng kích thước như Ind, đó là một mảng 'N x 1 x M'. – Divakar

+0

Có, các chỉ số tuyến tính phải là một vectơ cột. Mảng N x 1 x M là hàm max trả về. – dast

1

Tạo các chỉ số cho các thứ nguyên khác.

Trong dim 1 chỉ số cần phải thay đổi nhanh nhất: [1,2,...,size(A,1)]size(A,3) này lần:

idx1 = repmat((1:size(A,1))',size(A,3),1); 

Trong mờ 2 chỉ số được cho bởi Ind.

Trong mờ 3, chỉ số cần thay đổi chậm nhất: [1,1,...,1] cho size(A,1) lần và sau đó [2,2,...,2] và cứ như vậy cho đến size(A,3).

idx3 = ones(size(A,1),1)*(1:size(A,3)); 

Tiếp cận các giá trị duy nhất:

M_ = A(sub2ind(size(A),idx1(:),Ind(:),idx3(:))); 

Hãy so sánh: trường hợp

M(:) == M_ 
+2

Hãy giải thích cách giải quyết vấn đề này. –

+0

Đã chỉnh sửa. Hy vọng nó bây giờ rõ ràng hơn. – Steffen

+0

Giải pháp này khá giống với giải pháp của Dan, nhờ giải thích về hình dạng tham số (idx1, idx3, ...) – dast

1

3-chiều:

[m, n, p] = size(A); 
[M, Ind] = max(A,[],2); 
LinInd = bsxfun(@plus, (1:m).', (0:p-1)*m*n); %'// 
LinInd = LinInd(:) + (Ind(:)-1)*m; 

Các mong muốn chỉ số tuyến tính là LinInd. Điều này tạo ra

A(LinInd) == M(:) 

với tất cả true mục (lưu ý bạn cần (:) ở phía bên tay phải để so sánh có ý nghĩa).

chung trường hợp đa dimensonal:

d = 3; %// dimension along which max will be computed 
s = size(A); 
sLow = prod(s(1:d-1)); 
sHigh = prod(s(d+1:end)); 
[M, Ind] = max(A,[],d); 
LinInd = bsxfun(@plus, (1:sLow).', (0:sHigh-1)*sLow*s(d)); %'// 
LinInd = LinInd(:) + (Ind(:)-1)*sLow; 
+0

Giải pháp khá ngắn. Tuy nhiên có thể khó khăn để mở rộng đến nhiều thứ nguyên. Tôi đã không nói điều này trong tập vấn đề, nhưng tuy nhiên, cố gắng quản lý các vấn đề theo cách tổng quát. Cảm ơn. – dast

+0

Trên thực tế, thật dễ dàng để mở rộng. Xem câu trả lời cập nhật –

+0

Trường hợp đa chiều hoạt động tốt cho tôi. Cảm ơn! – gtownescapee

Các vấn đề liên quan