Concatenating multiple cells in a single matrix

I'm trying to hide files in a float64 DCT2 array; I have the stream of bits in a single 1*x array where each cell includes a single bit. I'm already able to concatenate bits into bytes successfully by using a for loop, 8 placeholder variables, and strcat.
for col = 1 : 8 : bitStreamSize(2) - 7
bit0 = bitStream(1,col);
bit1 = bitStream(1,col + 1);
bit2 = bitStream(1,col + 2);
bit3 = bitStream(1,col + 3);
bit4 = bitStream(1,col + 4);
bit5 = bitStream(1,col + 5);
bit6 = bitStream(1,col + 6);
bit7 = bitStream(1,col + 7);
result = strcat(num2str(bit0),num2str(bit2),num2str(bit2),num2str(bit3),num2str(bit4),num2str(bit5),num2str(bit6),num2str(bit7));
result = bin2dec(result);
file(1,((col - 1)/8) + 1) = result;
end
This works fine for when you know how many bits you're dealing with, but now I want to do the same thing somewhere else in my project where the user inputs a number from 1 to 63 and then that number of bits will be concatenated into a single cell. I thought of using a switch statement but MATLAB does not use break; like C++ so I'd have to repeat the code 63 times; this would be a very clunky implementation and it'd be very hard to modify.
Is there a more effecient/modular way of concatenating a given number of bits without having to redo everything for every single possible number?

2 comentarios

Jan
Jan el 9 de Jun. de 2021
Editada: James Tursa el 9 de Jun. de 2021
This is not valid Matlab code:
file = (1,((col - 1)/8) + 1) = result;
I was copying code offhand from another PC so I mess up; I updated the original post.

Iniciar sesión para comentar.

 Respuesta aceptada

Jan
Jan el 9 de Jun. de 2021
Editada: Jan el 18 de Jun. de 2021
The conversion from numeric to string and back to numeric is an expensive indirection.
n = 8;
% p = uint64(2).^(0:n-1); % LSB
p = uint64(2).^(n-1:-1:0); % MSB
file = [];
for col = 1 : n : bitStreamSize(2) - (n - 1)
result = uint64(0);
for k = 0:n-1
result = result + uint64(bitStream(col + k) * p(k + 1));
end
file(end + 1) = result; % Bad: iteratively growing array
end
This can be done faster and nicer without a loop:
n = 8; % Number of bits
B = reshape(bitStream, n, []);
% C = uint64(B) .* bitshift(uint64(1), 0:n-1).'; % LSB
C = uint64(B) .* bitshift(uint64(1), n-1:-1:0).'; % MSB
file = sum(C, 1, 'native');
This uses auto-expanding introduced in Matlab R2016b. With older versions:
C = bsxfun(@times, uint64(B), bitshift(uint64(1), 0:n-1).');
Matlab R2018b does not support a matrix multiplication of UINT64 arrays. If your data has less then 53 bits, you can work with doubles and the code gets really compact:
n = 8; % Number of bits, n <= 52
file = bitshift(1, n-1:-1:0) * reshape(bitStream, n, []); % MSB

3 comentarios

Abdallah Talafhah
Abdallah Talafhah el 15 de Jun. de 2021
Editada: Abdallah Talafhah el 15 de Jun. de 2021
Niether of these worked; I assume I didn't explain my data format well so heres an example:
Lets assume my bit stream consists of the bits of "MAT" using extended ASCII, here's the matrix that corresponds to that:
bitStream = [0,1,0,0,1,1,0,1,0,1,0,0,0,0,0,1,0,1,0,1,0,1,0,0];
When using my method the final matrix looks like this:
file = [77,65,84]
When using the frist method you suggested, the data was just not correct, (e.g. using "MAT"):
file = [178,130,42;2,0,0;4,0,0;8,0,0;16,0,0;32,0,0;64,0,0;128,0,0]
The second method returned an error at the matrix multiplication stating that matrix dimentions must agree. The first part of expression was 1*x while the second part was 8*1.
I think the issue might be because you assumed the order of the bits was different? Mine has the most significant bit first much like how you read a file in a hex editor.
Jan
Jan el 16 de Jun. de 2021
Editada: Jan el 16 de Jun. de 2021
"Niether of these worked;"
My first version cannot run at all, because I could not understand, what this line of your code should do:
file = (1,((col - 1)/8) + 1) = result;
You have fixed this line after I've posted my answer. So please do not blame me to post not working code.
I cannot guess, how you have created
file = [178,130,42;2,0,0;4,0,0;8,0,0;16,0,0;32,0,0;64,0,0;128,0,0]
if you do not show the code you have used. My code did not create the variable file.
With this code, I get [178,130,42] as output:
bitStream = [0,1,0,0,1,1,0,1,0,1,0,0,0,0,0,1,0,1,0,1,0,1,0,0];
bitStreamSize = size(bitStream); % Educated guessing...
n = 8;
p = 2.^(0:n-1);
file = [];
for col = 1 : n : bitStreamSize(2) - (n - 1)
result = uint64(0);
for k = 0:n-1
result = result + uint64(bitStream(col + k) * p(k + 1));
end
file(end + 1) = result;
end
I cannot confirm, that my 2nd method produces an error. Whenever you mention an error in the forum, post a copy of the complete message instead of a rough paraphrasing. An error concering the "matrix multiplication" is unlikely, because my code does not contain a matrix multiplication, but an elementwise mutliplication of arrays. This uses an auto-expanding, which was introduced in Matlab 2016b. Which Matlab version are you using? Did you forget the dot in .* ?
The order of the bits can be changed easily in my code:
p = 2 .^ (0:n-1); % LSB
p = 2 .^ (n-1:-1:1); % MSB
5 times faster with bitshifting instead of the expensive power operation:
p = bitshift(uint64(1), 0:n-1); % LSB
p = bitshift(uint64(1), n-1:-1:0); % MSB
My 2nd code with MSB:
n = 8;
B = reshape(bitStream, n, []);
C = uint64(B) .* bitshift(uint64(1), n-1:-1:0).';
file = sum(C, 1, 'native')
This replies [77, 65, 84] as wanted.
I've modified my answer to consider the bit order.
Claiming, that code provided by voluntary helpers is not working, sounds less polite than saying "thanks".
Adamantly, I didn't give you all the info you need to give me a solution that'd work right away.
The problem with the .* is that I'm using version R2014a and thankfully you included a solution using the bsxfun function.
I adapted it to use MSB like so:
C = bsxfun(@times, uint64(B), bitshift(uint64(1), n-1:-1:0).');
Thanks for your time

Iniciar sesión para comentar.

Más respuestas (0)

Categorías

Productos

Versión

R2014a

Preguntada:

el 9 de Jun. de 2021

Comentada:

el 22 de Jun. de 2021

Community Treasure Hunt

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

Start Hunting!

Translated by