Dado que MATLAB uint32 debe interpretarse como una cadena de bits, ¿cuál es una forma eficiente y concisa de contar cuántos bits distintos de cero hay en la cadena?Calcular el peso de Hamming eficientemente en matlab
Tengo un enfoque ingenuo y funcional que recorre los bits, pero eso es demasiado lento para mis necesidades. (Una implementación C++ usando std :: bitset count() se ejecuta casi instantáneamente).
He encontrado una página muy bonita que enumera varias técnicas de conteo de bits, pero espero que haya una manera fácil de MATLAB.
http://graphics.stanford.edu/~seander/bithacks.html#CountBitsSetNaive
Actualización # 1
Sólo se aplicó el algoritmo de Brian Kernighan de la siguiente manera:
w = 0;
while (bits > 0)
bits = bitand(bits, bits-1);
w = w + 1;
end
rendimiento sigue siendo malo, más de 10 segundos para calcular acaba de 4096^2 Peso cálculos Mi código de C++ que utiliza count() desde std :: bitset hace esto en tiempo de segundo.
Actualización # 2
Aquí es una tabla de tiempos de ejecución de las técnicas que he probado hasta ahora. Lo actualizaré a medida que obtenga ideas/sugerencias adicionales.
Vectorized Scheiner algorithm => 2.243511 sec Vectorized Naive bitget loop => 7.553345 sec Kernighan algorithm => 17.154692 sec length(find(bitget(val, 1:32))) => 67.368278 sec nnz(bitget(val, 1:32)) => 349.620259 sec Justin Scheiner's algorithm, unrolled loops => 370.846031 sec Justin Scheiner's algorithm => 398.786320 sec Naive bitget loop => 456.016731 sec sum(dec2bin(val) == '1') => 1069.851993 sec
comentario: La función DEC2BIN() en MATLAB parece estar muy mal implementado. Funciona extremadamente lento.
comentario: El algoritmo de "bucle bitget Naive" se lleva a cabo de la siguiente manera:
w=0;
for i=1:32
if bitget(val, i) == 1
w = w + 1;
end
end
comentario: La versión desenrollado del bucle del algoritmo de Scheiner es el siguiente:
function w=computeWeight(val)
w = val;
w = bitand(bitshift(w, -1), uint32(1431655765)) + ...
bitand(w, uint32(1431655765));
w = bitand(bitshift(w, -2), uint32(858993459)) + ...
bitand(w, uint32(858993459));
w = bitand(bitshift(w, -4), uint32(252645135)) + ...
bitand(w, uint32(252645135));
w = bitand(bitshift(w, -8), uint32(16711935)) + ...
bitand(w, uint32(16711935));
w = bitand(bitshift(w, -16), uint32(65535)) + ...
bitand(w, uint32(65535));
¿Es posible hacer algún tipo de limpieza con esta pregunta? ¿Pequeña pregunta y mueve las otras cosas a una respuesta resumida, por ejemplo? La pregunta relacionada [aquí] (http://stackoverflow.com/questions/19835495/matlab-fast-way-to-sum-ones-in-binary-numbers) es mucho más fácil de entender que una pequeña. – hhh
-1 pregunta demasiado poco clara y no se realizaron mejoras a pesar del aviso. – hhh
@kay ¿Puede dar el código de la versión vectorizada del "lazo de bitwit ingenuo"? – SebMa