如何在给定矩阵中找到整数的最接近匹配?

时间:2017-09-24 16:23:48

标签: matlab matrix type-conversion distance unsigned-integer

我有两个矩阵。矩阵A(2048,64)和矩阵B(10000,64)。这些矩阵的每个元素中的值是一个二进制位,因此每一行都是64位二进制值的表示,因此矩阵的每一行的幅度都在2^632^0之间;最重要的位分别为最低位。

问题:

对于A的每一行,我想在B中找到绝对数字意义上最接近它的值。

A(i,1:64)视为十进制值Xi的二进制表示,并将B(j,1:64)视为十进制值Yj的二进制表示。因此,在第一步,我想找到最好的j,以使X1A(1,1:64)Yj处的元素具有最接近的数值,即abs(X1-Yj)j的所有可能值中最小化。

下面的图片来自here,它很好地描述了我的问题,但区别在于我的每个值都包含在一个包含64个元素的矩阵的行中。

我尝试将64位值转换为十进制,但dec2bin仅支持最多56位的值。

same scenario for rows with 1 column only

2 个答案:

答案 0 :(得分:2)

您可以将64位数字分成两个32位,b1b2,将它们转换为十进制值d1d2,然后将它们合并转换为具有足够精度来保存结果的uint64值。

bin2uint64 = @(b) uint64(bin2dec(b(:,1:32)))*(2^32) + uint64(bin2dec(b(:,33:64))); 

(这假设您的数据格式与bin2dec所需的格式相同,即char的向量。如果您有数值向量,只需添加b = char(b+'0');

给定初始值

>> b = 1100110010111100101101111010100010101010010011010010000110011010
>> d = bin2uint64(b)
d = 14752868414398472602
>> r = dec2bin(d, 64)
r = 1100110010111100101101111010100010101010010011010010000110011010
>> any(b-r)
ans = 0

由于b-r给出全零,因此值相同。您可以将整个nx64矩阵作为b传递,它会立即转换所有值。

>> bin2uint64(char(randi([0 1], 20, 64) + '0'))
ans =

   4169100589409210726
   8883634060077187622
  15399652840620725530
  12845470998093501747
  14561257795005665153
   1133198980289431407
  13360302497937328511
    563773644115232568
   8825360015701340662
   2543400693478304607
  11786523850513558107
   8569436845019332309
   2720129551425231323
   5937260866696745014
   4974981393428261150
  16646060326132661642
   5943867124784820058
   2385960312431811974
  13146819635569970159
   6273342847731389380

你会注意到我手动将我的随机数组转换为char。假设您的输入是数字,则必须先进行转换:

Achar = char(A + '0');

是的,这很痛苦,MATLAB应该在bin2dec中包含目标类型参数,但他们没有。现在,您可以使用链接的解决方案来查找匹配项。

答案 1 :(得分:2)

转换您的值:

假设您的矩阵AB包含数字01,您可以轻松地将行转换为{{3使用uint64bitset函数(以及sum实现小的效率提升)没有精度损失的数据类型:

result = sum(bsxfun(@(bit, V) bitset(uint64(0), bit, V), 64:-1:1, A), 2, 'native');

bsxfun相比,对于10,000行矩阵,这个速度快4倍以上:

% Sample data:
A = randi([0 1], 10000, 64);

% Test functions:
bin2uint64 = @(b) uint64(bin2dec(b(:,1:32)))*(2^32) + uint64(bin2dec(b(:,33:64)));
beaker_fcn = @(A) bin2uint64(char(A+'0'));
gnovice_fcn = @(A) sum(bsxfun(@(b, V) bitset(uint64(0), b, V), 64:-1:1, A), 2, 'native');

% Accuracy test:
isMatch = isequal(beaker_fcn(A), gnovice_fcn(A));  % Return "true"

% Timing:
timeit(@() beaker_fcn(A))

ans =
   0.022865378234183

timeit(@() gnovice_fcn(A))

ans =
   0.005434031911843

计算最接近的匹配:

您提供solution from beaker来查找AB的最近匹配项。但是,您使用 unsigned 整数类型的事实需要进行一些修改。具体而言,订单在减去由link to some solutions引起的值时很重要。例如uint64(8) - uint64(1)为您提供7,但uint64(1) - uint64(8)为您提供0

以下是无符号整数的修改解决方案,适用于您提供的示例数据:

A = uint64([1 5 7 3 2 8]);
B = uint64([4 12 11 10 9 23 1 15]);
delta = bsxfun(@(a, b) max(a-b, b-a), A(:), reshape(B, 1, []));
[~, index] = min(delta, [], 2);
result = B(index)

result =
  1×6 uint64 row vector

   1   4   9   4   1   9   % As expected!