convert string to binary matrix with 1 bit per column - matlab

How do I convert characters from a file, e.g. 'hello' to a binary matrix like this:
[1 1 0 1 1 0 0 0 1 0 .......]
where each column of the matrix has only a 1 bit value that is 0 or 1.
All I have done so far is converted the string into the matrix of binary where each column has 7 bits of binary.
Example: 'hello'
1 1 0 1 1 0 0 0 1 0

You need a combination of dec2bin and str2num:
First, convert your input into a binary representation:
WORD = 'hello';
WORD_BINARY = dec2bin(WORD,7) % The 7 gives the number of bits
This results in:
WORD_BINARY =
1101000
1100101
1101100
1101100
1101111
This is a string, which now has to be turned into a vector:
for i=1:size(WORD_BINARY,1)
for j=1:size(WORD_BINARY,2)
WORD_OUTPUT(1,(i-1)*size(WORD_BINARY,2)+j) = str2num(WORD_BINARY(i,j))
end
end
WORD_OUTPUT in this case is a <1x40> vector, starting with:
WORD_OUTPUT =
[ 1 1 0 1 0 ...
Edit
If you do not want two for loops, you can use reshape first (but be aware, that reshape orders by column, not row):
WORD = 'hello';
WORD_BINARY = reshape(dec2bin(WORD,7)',1,[]);
% note the <'> after the dec2bin, to transpose the matrix
for j=1:size(WORD_BINARY,2)
WORD_OUTPUT(1,j) = str2num(WORD_BINARY(1,j));
end

Related

Combinations of zeros and ones of vector size n [duplicate]

I have an algorith that the number of possibles combinations of 0 and 1, can reach the number 2^39. Let's say i have n=2 situations, or n1=2^2=4 combinations of 0 and 1: 00,01,10,11.From that i can create an array a=zeros(n,n1) and fill the columns with the possible combinations? That means first column has 00,second 01,third 10,last 11.I want this to be dynamic that means that n can be 1,2,3...,39, show the array will be a=zeros(n,2^n).Thanks for any response!
Just for general understanding: why do you think you need an array of all combinations of all integers from 0 to 2³⁹? That array would consume 39×2³⁹/1000⁴ ≈ 21TB of RAM...last time I checked, only the world's most advanced supercomputers have such resources, and most people working with those machines consider generating arrays like this quite wasteful...
Anyway, for completeness, for any N, this is the simplest solution:
P = dec2bin(0:(2^N)-1)-'0'
But, a little piece of advice: dec2bin outputs character arrays. If you want numerical arrays, you can subtract the character '0', however, that gives you an array of doubles according to the rules of MATLAB:
>> P = dec2bin(0:(2^3)-1)-'0';
>> whos P
Name Size Bytes Class Attributes
P 8x3 192 double
If you want to minimize your memory consumption, generate a logical array instead:
>> P = dec2bin(0:(2^3)-1)=='1';
>> whos P
Name Size Bytes Class Attributes
P 8x3 24 logical
If you want to also speed up the execution, use the standard algorithm directly:
%// if you like cryptic one-liners
B1 = rem(floor((0:pow2(N)-1).' * pow2(1-N:0)), 2) == 1;
%// If you like readability
B = false(N,pow2(N));
V = 0:pow2(N)-1;
for ii = 1:N
B(ii,:) = rem(V,2)==1;
V = (V-B(ii,:))/2;
end
That last one (the loop) is fastest of all solutions for any N (at least on R2010b and R2013a), and it has the smallest peak memory (only 1/Nth of the cryptic one-liner).
So I'd go for that one :)
But, that's just me.
Using ndgrid with a comma-separated list as output (see also here):
[c{1:N}] = ndgrid(logical([0 1]));
c = cat(N+1,c{N:-1:1});
c = reshape(c,[],N);
Example: N=4 gives
c =
0 0 0 0
0 0 0 1
0 0 1 0
0 0 1 1
0 1 0 0
0 1 0 1
0 1 1 0
0 1 1 1
1 0 0 0
1 0 0 1
1 0 1 0
1 0 1 1
1 1 0 0
1 1 0 1
1 1 1 0
1 1 1 1

Python equivalent for Matlab vector slice

I have the following code in Matlab (I do not have Matlab), that apparently constructs integers by sampling sequences of binary values:
velocity_LUT_10bit = zeros(2^10,1);
for n = 1:length(velocity_LUT_10bit),
imagAC = bin2dec(num2str(bitget(n-1,9:-1:6))) - bitget(n-1,10)*2^4; % Imaginary part of autocorrelation: signed 5-bit integer
realAC = bin2dec(num2str(bitget(n-1,4:-1:1))) - bitget(n-1, 5)*2^4; % Real part of autocorrelation: signed 5-bit integer
velocity_LUT_10bit(n) = velNyq_CF*angle((realAC+0.5)/16 + 1i*(imagAC+0.5)/16)/pi;
end;
I am having trouble understanding the bitget() function. From the docs, the first arg is the sampled sequence, while the second arg specifies the range of the sample, but I am confused about what the slicing x:-y:z means. I understand it from the docs as "sample from index x to z, going right to left by strides of y". Is that correct?
What would be the numpy equivalent of bin2dec(num2str(bitget(n-1,9:-1:6)))? I understood I should be using numpy.packbits(), but I am a bit stuck.
In an Octave session:
>> for n=0:3:15,
bitget(n,1:1:5)
end
ans =
0 0 0 0 0
ans =
1 1 0 0 0
ans =
0 1 1 0 0
ans =
1 0 0 1 0
ans =
0 0 1 1 0
ans =
1 1 1 1 0
This is just the binary representation of the number, with a sliced selection of the bits. Octave/Matlab is using the 'start:step:stop' syntax.
The rest converts the numbers to a string and from binary to decimal:
>> num2str(bitget(13,5:-1:1))
ans = 0 1 1 0 1
>> bin2dec(num2str(bitget(13,5:-1:1)))
ans = 13
bitget(n-1,9:-1:6) must be fetching the 9th to 6th bits (powers of 2) in reverse order. So for a number up to 2^10-1, it's pulling out 'bits' 1-4, 5, 6-9, and 10.
I'm not familiar with Python/numpy binary representations, but here's a start:
>> num2str(bitget(100,10:-1:1))
ans = 0 0 0 1 1 0 0 1 0 0
In [434]: np.binary_repr(100,10)
Out[434]: '0001100100'

Select first n of 1 values from a binary vector (0,1) in MATLAB

I have a binary vector, e.g:
x = [1 1 1 0 0 1 0 1 0 0 0 1]
I want to keep the first 4 elements that are '1' (substituting the rest with '0's). In my example the resulting vector should be:
z = [ 1 1 1 0 0 1 0 0 0 0 0 0]
Any help would be much appreciated.
First construct a vector of zeroes, then use find:
z = false(size(x));
z(find(x, 4)) = true;
No need for find for a binary vector. Use cumsum instead!
>> z = x;
>> z(cumsum( z, 2 ) > 4) = 0;
This solution (unlike find-based answers) can process a stack of such binary vectors at once (all you need is to verify that cumsum works on the proper dimension).
Try following:
z=x;
A=find(z);
z(A(5:end))=0;
Idea here is to make all, but first n, 1's to 0's

Create matrix using hashtable MATLAB

I am using hashtable (containers.map ) in MATLAB, and now I want to create a matrix with that information. So when I run my hashtable and then insert my text files for each type I get on my command window something like that:
edit
F = listdlg('PromptString','Different types', 'SelectionMode',...
'single', 'ListString',E, 'Name','Select a type','ListSize',[230 130]);
[files,path] = uigetfile ('*.txt','Select your text files',...
'MultiSelect','on');
where E is just the user's input which in this case is pink, purple and yellow.
%save for each type the user enters the corresponding text files he
%wants to train
%A Map object is a data structure that allows you to retrieve values
%using a corresponding key. Keys can be real numbers or text strings
%and provide more flexibility for data access than array indices,
%which must be positive integers. Values can be scalar or nonscalar arrays.
handles.map (E(F,:)) = files;
handles.map
a = handles.map.values
b = handles.map.keys
handles.map.size
b =
{1x3 cell} {1x6 cell} {1x4 cell}
a =
'pink ' 'purple' 'yellow'
So I want now to the the total number of b to be the number of rows on my matrix m ; so a total number of rows 14 and each bit from a to be a column; so a total of 3 columns. But I want to create a binary matrix where each column will identify different type. Finally I will have created a matrix like that:
m =[1 0 0
1 0 0
1 0 0
0 1 0
0 1 0
0 1 0
0 1 0
0 1 0
0 1 0
0 0 1
0 0 1
0 0 1
0 0 1];
Where the first 3 rows of the matrix says that there are 3text files of type pink, the next 6 rows : 6 text files of type purple and the last 4: 4 text files of type yellow.
I hope that now is more clear. :)
Any help would be appreciated! :) x
So something like this?
val = cellfun(#length, b)';
m = 0;
for v = 1:size(val)
m(end:end+val(v)-1,v) = 1;
end

Grouping strings by matching substring

After running a SPICE simulation I get an .a2d file which I am parsing with Matlab. After parsing the file I get a cell array with the names of the variables
Ex: vars = {'s0';'s1';'s2';'a0';'a1'}
and a data matrix with the signals transitions, where each row represents the data of each signal and columns represent time. All the data is binary, i.e., it's only 0 or 1.
What I want to do is to create an algorithm that detects "words" based on the names stored in vars. For example, s0, s1, and s2 form a 3-bit word 's'; a0 and a1 a 2-bit word 'a'.
Finally, what I need is to break the data matrix into one array for each word (converting from binary to decimal).
I am doing that by hand, but I want to know if there is any way to do it by a script.
Here's a possible solution, putting the final values into the fields of a struct. I've used a regexp to extract the variable names and shifts as you didn't say how long they might be.
% fake data
vars = {'sums4', 'sums2', 'sums1', 'a0', 'a5'};
data(1,:) = logical([0 0 1 0 0 0 1]);
data(2,:) = logical([0 1 1 1 1 0 0]);
data(3,:) = logical([1 0 1 1 0 0 1]);
data(4,:) = logical([0 0 1 0 1 1 1]);
data(5,:) = logical([0 1 1 1 0 0 0]);
output = struct();
for i = 1:length(vars)
matches = regexp(vars{i}, '(\D+)(\d+)', 'tokens');
var = matches{1}{1};
shiftsize = str2num(matches{1}{2});
% initialise if not already present
if (~isfield(output, var))
output.(var) = zeros(1, size(data, 2));
end
% add apropriate shifted value to current values
output.(var) = output.(var) + (bitshift(1, shiftsize) * data(i, :));
end
output ends up with fields named after the string parts of vars
output =
sums: [2 4 22 6 4 0 18]
a: [0 32 33 32 1 1 1]