3

У меня есть вектор, содержащий значения 0, 1, 2 и 3. Что я хочу сделать, это взять два нижних бита из каждого набора из 16 элементов, взятых из этого вектора, и добавить их все вместе, чтобы получить один uint32. Кто-нибудь знает простой способ сделать это?MATLAB преобразование вектора значений в uint32

Последующее наблюдение: что, если число элементов в векторе не является целым числом, кратным 16?

+0

Просто любопытно, но это проект стеганографии? – Jacob

+0

Нет. Цифровая связь. Я использую функцию модуляции вместе с объектом qammod. У меня есть куча uint32, которую я хочу модулировать с помощью qpsk (или любого другого M-QAM). Это немного сложно объяснить, если вы не понимаете схемы модуляции. – devin

+0

Если nWord не является целым числом, я предполагаю, что это означает, что есть частичное 32-битное слово в конце v? Я полагаю, вы могли бы использовать nWord = floor (размер (v, 1)/16), извлечь первые 16 * nWord значения из v и поставить очередь остальных для обработки со следующей партией входов. – mtrw

ответ

6

Вот Векторизованная версия:

v = floor(rand(64,1)*4); 
nWord = size(v,1)/16; 
sum(reshape([bitget(v,2) bitget(v,1)]',[32 nWord]).*repmat(2.^(31:(-1):0)',[1 nWord ])) 
+5

Векторизация очень умна, я бы не подумал об этом. Вы можете (слегка) оптимизировать это, используя sum (reshape (v, [16 nWord]). * Repmat (2.^(30: (- 2): 0) ', [1 nWord])); , который позволяет избежать битги. – mtrw

+0

Да, это круто! – Jacob

+1

Хорошо, еще одна оптимизация для использования умножения матрицы: uint32 (reshape (v, [16 nWord]) '* (2.^(30: (- 2): 0)')) ' (также я добавил бросить на uint32). И как сказал schnaader в своем ответе, если ваш вектор LSB для MSB, измените вектор экспоненты на 0: 2: 30. – mtrw

0

Я думаю, вы должны взглянуть на bitget и bitshift. Должна быть обеспечена возможность быть что-то вроде этого (псевдо-код MATLAB, как я не работал с Matlab в течение длительного времени):

result = 0; 
for i = 1:16 do 
    result += bitshift(bitget(vector(i), 2:-1:1), 2); 

Обратите внимание, что это даст вам последние биты первого вектора в высокие биты, так что вы можете спускаться я от 16 до 1 вместо

+0

bithift и bitget были командами, которые я использовал раньше, и пытаюсь избежать ... – devin

3

чтобы уточнить, что предлагалось Иаковом в его answer и mtrw в его комментарии, вот наиболее краткая версия, которую я могу придумать (учитывая 1-на-N var iable vec, содержащий значения от 0 до 3):

value = uint32(vec(1:16)*4.^(0:15)'); 

Это относится первый элемент в массиве в качестве наименее значимого бита в результате. Для лечения первого элемента в качестве наиболее значимого бита, используйте следующее:

value = uint32(vec(16:-1:1)*4.^(0:15)'); 

EDIT: Это решает новый пересмотр вопроса ...

Если количество элементов в векторе не кратно 16, тогда последняя серия чисел, которые вы извлекаете из нее, будет иметь менее 16 значений. Вероятно, вы захотите проложить более высокие биты серии нулями, чтобы сделать ее 16-элементным вектором. В зависимости от первого элемента в этой серии является ли бит наименее значащий бит (LSB) или наиболее значимый (MSB), вы будете в конечном итоге обивка серии по-разному:

v = [2 3 1 1 3 1 2 2]; % A sample 8-element vector 
v = [v zeros(1,8)]; % If v(1) is the LSB, set the higher bits to zero 
% or... 
v = [zeros(1,8) v]; % If v(1) is the MSB, again set the higher bits to zero 

Если вы хотите обрабатывать весь вектор все сразу, вот как вы бы это сделать (с любой необходимой нулевой обивкой в ​​комплекте) для случая, когда vec(1) является LSB:

nValues = numel(vec); 
nRem = rem(nValues,16); 
vec = [vec(:) zeros(1,nRem)]; % Pad with zeroes 
vec = reshape(vec,16,[])'; % Reshape to an N-by-16 matrix 
values = uint32(vec*4.^(0:15)'); 

и когда vec(1) является MSB:

nValues = numel(vec); 
nRem = rem(nValues,16); 
vec = [vec(1:(nValues-nRem)) zeros(1,nRem) ... 
     vec((nValues-nRem+1):nValues)]; % Pad with zeroes 
vec = reshape(vec,16,[])'; % Reshape to an N-by-16 matrix 
values = uint32(fliplr(vec)*4.^(0:15)'); 

 Смежные вопросы

  • Нет связанных вопросов^_^