2009-04-27 40 views
8

Tôi có ma trận có kích cỡ n-by-k, chứa số k mỗi hàng. Tôi muốn sử dụng các số k này làm chỉ mục thành ma trận k chiều. Có cách nào nhỏ gọn để làm như vậy trong MATLAB hoặc tôi phải sử dụng một vòng lặp for?Ký hiệu lập chỉ mục ma trận MATLAB nhỏ gọn

Đây là những gì tôi muốn làm (trong mã giả MATLAB), nhưng theo một cách hơn MATLAB-ish:

for row=1:1:n 
    finalTable(row) = kDimensionalMatrix(indexmatrix(row, 1),... 
      indexmatrix(row, 2),...,indexmatrix(row, k)) 
end 

Trả lời

15

Nếu bạn muốn tránh phải sử dụng một vòng lặp for, đây có lẽ là cách sạch nhất để làm điều đó:

indexCell = num2cell(indexmatrix,1); 
linearIndexMatrix = sub2ind(size(kDimensionalMatrix),indexCell{:}); 
finalTable = kDimensionalMatrix(linearIndexMatrix); 

GIẢI THÍCH:

Dòng đầu tiên đặt mỗi cột của indexmatrix vào các ô riêng biệt của mảng ô sử dụng NUM2CELL. Điều này cho phép chúng ta vượt qua tất cả k cột như một comma-separated list vào SUB2IND, một chức năng có thể chuyển đổi chỉ số subscripted (hàng, cột, vv) vào chỉ số tuyến tính (mỗi phần tử ma trận được đánh số từ 1 đến N, N là tổng số phần tử trong ma trận). Dòng cuối cùng sử dụng các chỉ số tuyến tính này để thay thế vòng lặp for của bạn. Một cuộc thảo luận tốt về lập chỉ mục ma trận (chỉ số, tuyến tính và logic) có thể được tìm thấy here.

một số chi tiết thực phẩm cho rằng ...

Các xu hướng né tránh cho vòng ủng hộ giải pháp vectorized là một cái gì đó nhiều người sử dụng MATLAB (trong đó có tôi) đã trở nên quen với. Tuy nhiên, các phiên bản mới hơn của MATLAB xử lý vòng lặp hiệu quả hơn nhiều. Như đã thảo luận trong this answer đối với một câu hỏi SO khác, việc sử dụng cho các vòng lặp đôi khi có thể dẫn đến mã chạy nhanh hơn bạn sẽ nhận được với một giải pháp được vector hóa.

Tôi chắc chắn KHÔNG nói rằng bạn không nên cố gắng mã hóa mã của bạn nữa, chỉ có mọi vấn đề là duy nhất. Vectorizing sẽ thường là hiệu quả hơn, nhưng không phải luôn là. Đối với vấn đề của bạn, tốc độ thực hiện của vòng lặp so với mã vectơ có thể sẽ phụ thuộc vào giá trị lớn như thế nào nk.

6

Để điều trị các yếu tố của vector indexmatrix(row, :) như subscript riêng biệt, bạn cần các yếu tố dưới dạng mảng ô. Vì vậy, bạn có thể làm điều gì đó tương tự như thế này

subsCell = num2cell(indexmatrix(row, :)); 
finalTable(row) = kDimensionalMatrix(subsCell{:}); 

Để mở rộng các danh sách conLàm danh sách được phân tách bằng dấu phẩy, rất tiếc bạn cần hai dòng riêng biệt. Tuy nhiên, mã này độc lập với k.

+0

Tuyệt vời! Bạn có thể làm cho nó độc lập với số hàng không? – AnnaR

+0

@AnnaR - Tôi vừa đăng câu trả lời xử lý tất cả 'n' hàng' indexmatrix' cùng một lúc. – Shai

0

Chuyển đổi söë thaânh phêìn của bạn vào chỉ số tuyến tính trong một cách hacky

ksz = size(kDimensionalMatrix); 
cksz = cumprod([ 1 ksz(1:end-1)]); 
lidx = (indexmatrix - 1) * cksz' + 1; #' 
% lindx is now (n)x1 linear indices into kDimensionalMatrix, one index per row of indexmatrix 
% access all n values: 
selectedValues = kDimensionalMatrix(lindx); 

Cheers!

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