2013-06-13 20 views
5

Có tương đương với bsxfun cho dữ liệu không phải là số không?Sử dụng `bsxfun` cho dữ liệu phi số

Ví dụ, tôi muốn so sánh tất cả các cặp của chuỗi lưu trữ trong hai tế bào mảng:

>> a = {'aa', 'bb', 'cc'}; 
>> b = {'dd', 'aa'}; 
>> bsxfun(@strcmp, a, b'); % not working for cells :-(
+3

Tôi luôn kết thúc vòng lặp ... Bạn có thể thử gửi yêu cầu nâng cao này cho TMW. – Oleg

Trả lời

3

Tôi sợ không có tương đương như thế cho tế bào mảng :-(

As far như tôi có thể nhìn thấy, bạn có thể:

  1. gợi ý và sử dụng Thực hiện theo Oleg của vòng
  2. sử dụng triển khai hiện có như mAryCellFcn hoặc csxfun từ Trao đổi tệp.
  3. Cuộn chức năng của riêng bạn. Ví dụ, đây là một biến thể của ý tưởng của Robert mà làm việc cho đầu vào của bất kỳ kích thước (dưới sự hạn chế của bsxfun, tất nhiên) và một chức năng nhị phân tùy ý func:

    function C = mybsxfun(func, A, B) 
        idx_A = reshape(1:numel(A), size(A)); 
        idx_B = reshape(1:numel(B), size(B)); 
        C = bsxfun(@(ii, jj)func(A(ii), B(jj)), idx_A, idx_B); 
    

    Nếu chức năng của bạn có thể hoạt động trên toàn bộ phần tử mảng di động -wise, bạn có thể thực hiện một mở rộng singleton trên mảng di động của bạn đầu tiên, và sau đó cho chúng ăn trực tiếp đến chức năng func:

    mask = bsxfun(@or, true(size(A)), true(size(B))); 
    idx_A = bsxfun(@times, mask, reshape(1:numel(A), size(A))); 
    idx_B = bsxfun(@times, mask, reshape(1:numel(B), size(B))); 
    C = func(A(idx_A), B(idx_B)); 
    

    phương pháp thứ hai có thể nhanh hơn nếu func được tối ưu hóa cho các hoạt động vectorized trên mảng di động.

+2

'csxfun' không tốt; đó chỉ là 'cellfun' và không có gì khác. 'mAryCellFcn' có vẻ tốt ... –

+0

@RodyOldenhuis Cảm ơn vì đã chú ý điều đó! –

+1

@EitanT, +1, đẹp nhất! –

2

Làm thế nào về

[str,ia,ib] = intersect(a,b) 

?

+1

(nhưng sau đó một lần nữa, tôi đoán Shai đang tìm kiếm một cách tiếp cận chung có thể thay thế 'bsxfun' cho hơn là chỉ so sánh các chuỗi này) –

+0

@RobertP. - bạn đúng rồi. Tôi đã sử dụng 'strcmp' làm ví dụ. – Shai

4

Tôi thích Rody's solution, nhưng bạn có thể cũng làm một workaround như thế này:

ia=(1:length(a)).'; ib=1:length(b); 
a=a(:); 
bsxfun(@(ii,jj) strcmp( a(ii),b(jj)) ,ia, ib); 
+0

+1. Điều này sẽ không cung cấp kích thước chính xác cho các mảng 2D/3D. Tuy nhiên, tôi đã điều chỉnh câu hỏi của bạn để hoạt động trên các mảng ô giống như 'bsxfun' ban đầu (hy vọng bạn không phiền). –

+0

@EitanT, tất nhiên là không! –

2

Như thông báo lỗi nói, chỉ phát sóng làm việc với nhiều loại số. Dưới đây là các lựa chọn thay thế khác:

a = {'aa', 'bb', 'cc'}; 
b = {'dd'; 'aa'}; 

%# obviously doesnt work 
%#bsxfun(@strcmp, a, b) 

%# do the singleton expansion ourselves 
strcmp(repmat(a,size(b)), repmat(b,size(a))) 

%# if you dislike REPMAT, we can use Tony's trick 
strcmp(a(ones(size(b)),:), b(:,ones(size(a)))) 

%# we could also use CELLFUN 
cell2mat(cellfun(@(s)strcmp(a,s), b, 'UniformOutput',false)) 
Các vấn đề liên quan