【问题标题】:How to efficiently encode a bit string in MATLAB?如何在 MATLAB 中有效地编码位串?
【发布时间】:2012-06-12 08:27:12
【问题描述】:

我想在 MATLAB 中尽可能高效地将整数向量 (uint8) 存储为(空间)。到目前为止,我正在使用arithenco 对向量进行编码:

bits = arithenco(z, counts);

好消息是它返回一个位向量。坏事是这些位以双精度形式存储。这意味着返回的向量大约是原始 uint8 向量的 64 倍,而整个想法是使事物更小。

那么有没有一种简单(且运行时高效)的方法来编码这些伪位,以便我真正获得空间改进?

我想出的唯一解决方案是使用bitset 将所有这些位再次存储在一个向量中,比如 uint32,但这似乎很麻烦,而且速度不是很快,因为我必须循环明确地覆盖整个位向量。

注意:我不能为此使用 Java API,否则这会相对容易。

【问题讨论】:

    标签: matlab encoding bit-manipulation


    【解决方案1】:

    与您的解决方案类似,但仅使用核心 MATLAB 函数:

    %# some random sequence of bits
    bits = rand(123,1) > 0.5;
    
    %# reshape each 8 bits as a column (with zero-padding if necessary)
    numBits = numel(bits);
    bits8 = false(8, ceil(numBits/8));
    bits8(1:numBits) = bits(:);
    
    %# convert each column to uint8
    bits_packed = uint8( bin2dec(char(bits8'+'0')) );
    

    比较尺寸:

    >> whos bits bits_packed
      Name               Size            Bytes  Class      Attributes
    
      bits             123x1               123  logical              
      bits_packed       16x1                16  uint8          
    

    解压/恢复原始位:

    %# unpack
    b = logical(dec2bin(bits_packed)' - '0');
    b = b(:);
    
    %# sanity check
    isequal(bits, b(1:numBits))
    

    【讨论】:

    • 谢谢!我没有考虑字符转换。我想这甚至可能比我的解决方案更快。
    【解决方案2】:

    经过一番搜索和尝试,我终于想出了这个解决方案:

    bitCount = size(bits, 2);
    bits8 = zeros(ceil(bitCount/8), 8);
    bits8(1:bitCount) = bits;           % Reshape to (pseudo-)8-bit representation
    comp = uint8(bi2de(bits8));         % Convert to efficient byte representation
    

    这里的关键部分是 bi2de 函数,它“将二进制行向量 b 转换为非负十进制整数”。要再次获取这些位,可以使用de2bi 函数。

    【讨论】:

    • 如果这是您正在寻找的完整答案,you can mark it as accepted even if you're the one who answered it.
    • @rolve:不应该将bits8 定义为:bits8 = zeros(8,ceil(bitCount/8));,以便它以正确的顺序(按列)填写。只记得在传递给bi2de之前转置@
    • @Amro 是的,你可能是对的。但是,由于我只想有效地存储这些位,所以它们是在行中还是分布在列中并不重要。将它们转换回 ? 位表示时,我只需要进行正确的整形即可。
    • @rolve:我想你是对的,反正你得到了我的 +1 票。顺便说一下,我发布了一个与你类似的解决方案,但没有使用任何特殊工具箱。
    【解决方案3】:

    您可以将它们转换为logical:

         bitsLogical = logical(bits);
    

    这在内存中应该更有效。 但是你仍然会有转换步骤。所以最好的办法是深入到arithenco 并首先将其更改为返回逻辑。


    编辑 正如 OP 所说的那样,这不会被打包为位,而是被打包为字节。仍然是对double 的改进。

    【讨论】:

    • 感谢您的想法,但逻辑存储为字节,因此仍有 8 位中的 7 位被浪费。
    • @rolve,我不知道。你有这方面的参考吗?
    • 您可以使用 whos (mathworks.ch/help/techdoc/ref/whos.html) 命令检查数据结构的大小。使用它,您将看到单个逻辑的大小为 1 个字节。
    猜你喜欢
    • 2012-04-12
    • 2023-04-09
    • 2010-10-25
    • 1970-01-01
    • 1970-01-01
    • 2013-05-17
    • 2021-03-13
    • 1970-01-01
    相关资源
    最近更新 更多