Most time-efficient conversion from logical matrix to fixed-point vector

30 views (last 30 days)
I have a n-by-m logical matrix A and I need to interpret it as a n-by-1 fi-object vector b, so that each row of A is the binary representation of the corresponding element of b, i.e., bin(b(p)) is equal to char(A(p, :) + 48) for each row p.
The most time-efficient way that I can think to is to use an intermediate conversion to char and assign it to the binary representation of the fi-object vector, as the following example program shows.
n = 1e6; % number of fi objects
m = 16; % number of bits of each fi object
tic;
A = randi(1, [n m], "logical");
t1 = toc(); % measure how long it takes the generation of random data
b = fi(zeros(n,1), false, m, 0);
tic; % measure how long it takes my conversion strategy
b.bin(:) = char(A + 48); % "slow"...how to do it faster?
t2 = toc();
assert(isequal(bin(b), char(A + 48))) % check that the result is what I meant
As a comparison, on an Intel(R) Core(TM) i7-8700 CPU @ 3.20GHz, t1 is about 0.13 seconds whereas t2 is 46.3 seconds, that is, my strategy is about 356x slower than the random number generation.
Am I missing some more time-efficient way to do this?

Accepted Answer

Matt J
Matt J on 6 Apr 2024 at 14:46
n = 1e6; % number of fi objects
m = 16; % number of bits of each fi object
tic;
A = randi([0,1], [n m], "logical");
t1 = toc() % measure how long it takes the generation of random data
t1 = 0.3246
tic; % measure how long it takes my conversion strategy
b = fi(A*2.^(m-1:-1:0)', false, m, 0);
t2 = toc()
t2 = 0.1978
assert(isequal(bin(b), char(A + 48))) % check that the result is what I meant
  3 Comments
Matt J
Matt J on 6 Apr 2024 at 16:58
Edited: Matt J on 6 Apr 2024 at 16:58
You would probably have to break the number into a left register and right register and compose the result as,
b=2^53* b_left +b_right
alelap
alelap on 6 Apr 2024 at 17:41
Edited: alelap on 6 Apr 2024 at 17:53
Good idea!
To avoid increasing word length and subsequent casting, I would prefer pow2 and bitxor instead of multiplication and sum. The following is the code for 54 <= m <= 106.
n = 1e6; % number of fi objects
m = 64; % number of bits of each fi object
tic;
A = randi([0,1], [n m], "logical");
t1 = toc() % measure how long it takes the generation of random data
t1 = 1.3027
tic; % measure how long it takes my conversion strategy
b_left = fi(A(:,1:53)*2.^(53-1:-1:0)', false, m, 0);
b_right = fi(A(:,54:m)*2.^((m-53)-1:-1:0)', false, m, 0);
b = bitxor(pow2(b_left, m-53), b_right);
t2 = toc()
t2 = 1.5858
assert(isequal(bin(b), char(A + 48))) % check that the result is what I meant

Sign in to comment.

More Answers (0)

Products


Release

R2023b

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!