Побитовое или над массивом в Matlab?

У меня есть большой массив двоичных чисел, и я хочу выполнить побитовое ИЛИ над одним измерением массива:

X = [ 192, 96,  96,  2,  3
       12, 12, 128, 49, 14
       ....
    ];
union_of_bits_on_dim2 = [
       bitor(X(:,1), bitor(X(:,2), bitor(X(:,3), ... )))
    ];
ans = 
    [ 227
      191 
      ... ]

Есть ли простой способ сделать это? Я на самом деле работаю над n-мерным массивом. Я попробовал bi2de, но он выравнивает мой массив, и поэтому подписка усложняется.

Я мог бы сделать это легко, если бы в Matlab была функция fold, но я не думаю, что это так.


ОК, @Divakar запросил исполняемый код, поэтому, чтобы было ясно, вот многословная версия, которая может работать для 2D-массива.

function U=union_of_bits_on_dim2(X)
U=zeros(size(X,1),1);
for i=1:size(X,2)
  U=bitor(U,X(:,i));
end

Наверняка это будет сделано без зацикливания? Я, конечно, надеялся, что bitor может принимать произвольное количество аргументов. Тогда это можно было сделать с помощью mat2cell.


person Sanjay Manohar    schedule 26.02.2015    source источник
comment
Не могли бы вы опубликовать исполняемый код для получения union_of_bits_on_dim2?   -  person Divakar    schedule 26.02.2015
comment
OK привел пример с использованием цикла   -  person Sanjay Manohar    schedule 26.02.2015
comment
Какие типы данных являются вашими числами? двойной | интервал8 | интервал16 | интервал32 | интервал64 | uint8 | uint16 | uint32 | uint64? Или вам просто нужно обычное двоичное представление целых чисел без знака?   -  person knedlsepp    schedule 26.02.2015


Ответы (2)


Один векторный подход -

[m,n] =  size(X)  %// Get size of input array
bd = dec2bin(X)-'0' %// Get binary digits

%// Get cumulative "OR-ed" version with ANY(..,1)
cum_or = reshape(any(permute(reshape(bd,m,n,[]),[2 3 1]),1),8,[]) 

%// Finally convert to decimals
U = 2.^(7: -1:0)*cum_or
person Divakar    schedule 26.02.2015
comment
Спасибо, это работает. Но это сложнее, чем я надеялся! (и тем более с n измерениями) - person Sanjay Manohar; 26.02.2015
comment
@SanjayManohar С этими изменениями и перестановками, я думаю, это могло бы выглядеть именно так! Но если у вас будет возможность, сообщите нам о каких-либо ускорениях, которые вы можете получить с этим? Спасибо! - person Divakar; 26.02.2015

Я не знаю ни одной функции, которая может сделать это автоматически. Однако вы можете зациклиться на интересующем вас измерении:

function result = bitor2d(A)
    result = A(1,:);
    for i=2:size(A,1)
        result = bitor(result,A(i,:));
    end
end

Если ваш массив имеет более двух измерений, вам нужно подготовить его только к двум.

function result = bitornd(A,whichdimension)
    B = shiftdim(A,whichdimension-1); % change dimensions order
    s = size(B);
    B = reshape(B,s(1),[]);  % back to the original shape
    result = bitor2d(B);
    s(1) = 1;
    result = reshape(result,s); % back to the original shape
    result = shiftdim(result,1-whichdimension); % back to the original dimension order
end
person fffred    schedule 26.02.2015
comment
Спасибо, я не слышал о shiftdim, который очень полезен. - person Sanjay Manohar; 26.02.2015