我有两个矩阵。矩阵A(2048,64)
和矩阵B(10000,64)
。这些矩阵的每个元素中的值是一个二进制位,因此每一行都是64位二进制值的表示,因此矩阵的每一行的幅度都在2^63
和2^0
之间;最重要的位分别为最低位。
对于A
的每一行,我想在B
中找到绝对数字意义上最接近它的值。
将A(i,1:64)
视为十进制值Xi
的二进制表示,并将B(j,1:64)
视为十进制值Yj
的二进制表示。因此,在第一步,我想找到最好的j
,以使X1
或A(1,1:64)
与Yj
处的元素具有最接近的数值,即abs(X1-Yj)
在j
的所有可能值中最小化。
下面的图片来自here,它很好地描述了我的问题,但区别在于我的每个值都包含在一个包含64个元素的矩阵的行中。
我尝试将64位值转换为十进制,但dec2bin
仅支持最多56位的值。
答案 0 :(得分:2)
您可以将64位数字分成两个32位,b1
和b2
,将它们转换为十进制值d1
和d2
,然后将它们合并转换为具有足够精度来保存结果的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)
假设您的矩阵A
和B
包含数字值0
和1
,您可以轻松地将行转换为{{3使用uint64
和bitset
函数(以及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来查找A
中B
的最近匹配项。但是,您使用 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!