Python equivalent for Matlab vector slice - matlab

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'

Related

How to convert list of binary values to int32 type?

I have a list of binary numbers in little-endian format in MATLAB workspace, and I want to convert them to int32. a is a double vector of zeroes and ones, like so:
a = [0 0 0 1 1 0 0 1 1 1 1 0 1 0 1 0 0 0 0 1 1 0 0 0 1 1 1 1 1 0 0 0];
int32(a) gives me a row vector of the 32 binary values without converting it to 32 bit integer.
The solutions from this related question (which is specific to unsigned integers) can be modified to handle a signed integer. The easiest approach would be to convert the output from there to uint32, then convert to int32 using typecast. Building on this solution:
>> a = [0 0 0 1 1 0 0 1 1 1 1 0 1 0 1 0 0 0 0 1 1 0 0 0 1 1 1 1 1 0 0 0];
>> b = typecast(uint32(sum(pow2(find(a)-1))), 'int32')
b =
int32
521688984
If you know the specific representation used for the bit pattern (my guess would be two's complement), you could avoid using typecast by accounting for the sign bit and complement directly in the calculations.
If a is an N-by-32 matrix, you can simply replace the sum(...) with the vectorized calculations from the linked solution:
b = typecast(uint32(a*(2.^(0:size(a, 2)-1)).'), 'int32');

Generate truth table in MatLab

I want to create a truth table in MatLab with i columns and i2 rows. For example, if i=2, then
T =
[0 0]
[1 0]
[0 1]
[1 1]
Code to do this has already been created here
This is part of a larger project, which requires i large. Efficiency is a concern. Is there more efficient code to create a truth table? Does MatLab have a built in function to do this?
Edit: Sorry about the formatting!
Something like this?
n=2;
d=[0:2^n-1].';
T=dec2bin(d,n)
T =
00
01
10
11
dec2bin will give you a character array, which you can convert to logical, if needed. There's also de2bi that gives you a numeric array directly, but you need a newer version of Matlab and the ordering of the bits is reversed.
Here's Luis Mendo's speedup, which replicates dec2bin (n and d are as above):
T=rem(floor(d*pow2(1-n:0)),2);
ndgrid is very much your friend here:
function t = truthTable(n)
dims = repmat({[false, true]}, 1, n);
[grids{1:n}] = ndgrid(dims{:});
grids = cellfun(#(g)g(:), grids, 'UniformOutput',false);
t = [grids{:}];
First you need to create grids for the number of dimensions in your truth table. Once you have those you can columnize them to get the column vectors you need and you can horizontally concatenate those column vectors to get your truth table.
I imagine the performance of this will be quite competitive.
>> truthTable(2)
ans =
0 0
1 0
0 1
1 1
>> truthTable(4)
ans =
0 0 0 0
1 0 0 0
0 1 0 0
1 1 0 0
0 0 1 0
1 0 1 0
0 1 1 0
1 1 1 0
0 0 0 1
1 0 0 1
0 1 0 1
1 1 0 1
0 0 1 1
1 0 1 1
0 1 1 1
1 1 1 1
>>
>> timeit(#() truthTable(20))
ans =
0.030922626777
EDIT: Use reshape instead of column dereferencing for further performance improvement
function t = truthTable(n)
dims = repmat({[false, true]}, 1, n);
[grids{1:n}] = ndgrid(dims{:});
grids = cellfun(#(g) reshape(g,[],1), grids, 'UniformOutput',false);
t = [grids{:}];
>> timeit(#() truthTable(20))
ans =
0.016237298777
I know this question has been dead a while, but I was wondering the same thing and found a solution I like a lot. Thought I'd share it here:
fullfact(ones(1, i) + 1) - 1

A matlab code I don't understand

I don't understand what does mean (1:65536 < wthresh) in the command below :
cw = reshape(b(:)' .* (1:65536 < threshold), 256, 256);
b is an image of size 256x256 and 65536=256x256. I only know commands like this one:
cw = reshape(b(:)' .* (b < threshold), 256, 256);
meaning we keep only pixels of b that are smaller than 'threshold'.
Just find out with easy examples:
>> (1:10<3)
ans =
1 1 0 0 0 0 0 0 0 0
This produces a vector where the first 2 elements are set to 1 while the rest are 0.
>> b=1:10
b =
1 2 3 4 5 6 7 8 9 10
>> b.*(1:10<3)
ans =
1 2 0 0 0 0 0 0 0 0
This does an element-wise multiplication with vector b. So basically the first threshold-1 elements are kept, while the rest are set to 0. reshape will rearrange the vector to a 256 x 256 matrix again. Since I don't know the expected output, I cannot judge if this is the desired behavior, or if it is a bug in your code.

Using octave to map vector values

Can anyone explain how the following code:
Y(Y==0) = -1
sets all values of 0 to -1. For example for:
Y = [1 1 1 0 0 0 1]
we get:
Y = [1 1 1 -1 -1 -1 1]
What is confusing me is that Y==0 does not return a vector of indices.
An if I try to use the vector Y==0 directly I get the error:
Y([0 0 0 1 1 1 0]) = -1
error: subscript indices must be either positive integers or logicals
I would have naturally opted for:
Y(find(Y==0)) = -1
and would like to know why the above does not use find
TIA
This is called logical indexing. There is some documentation on gnu.org (see 4.6 Logical Values), but the best place to find info about it is probably in the MATLAB documentation.
Your example does not work because you are using an array of doubles, instead of a logical array, to index into Y. Consider the following (using Octave 3.6.2):
>> Y = [1 1 1 0 0 0 1]
Y =
1 1 1 0 0 0 1
>> idx = Y==0
idx =
0 0 0 1 1 1 0
>> idx_not_logical = [0 0 0 1 1 1 0]
idx_not_logical =
0 0 0 1 1 1 0
>> whos
Variables in the current scope:
Attr Name Size Bytes Class
==== ==== ==== ===== =====
Y 1x7 56 double
ans 1x7 7 logical
cmd_path 1x489 489 char
gs_path 1x16 16 char
idx 1x7 7 logical
idx_not_logical 1x7 56 double
Total is 533 elements using 631 bytes
>> Y(idx_not_logical)=-1
error: subscript indices must be either positive integers or logicals
>> Y(idx)=-1
Y =
1 1 1 -1 -1 -1 1
Y==0 returns a bool matrix as shown by:
> typeinfo(Y==0)
ans = bool matrix
That's why you can't index directly with [0 0 0 1 1 1 0], which is a matrix:
> typeinfo([0 0 0 1 1 1 0])
ans = matrix
If you wish to convert to boolean, use logical():
> typeinfo(logical([0 0 0 1 1 1 0]))
ans = bool matrix

Matlab: descending binary to ascending binary like [0 0 1 0] to [0 1 0 0] or 1011 to 1101?

I have arrays that stores only binary numbers like the below, binaries are of the size 1x31. Now I want to make the last bit the first and the first bit the last and so on. The choice of data structure is probably very poor here -- when I learn to play with binaries I probably get rid of the array. The binaries make the ordering of the arrays far easier with a simple sort. Anyway this is puzzle now:
Is there some ready command in Matlab for changing desceding binary to asceding binary?
Input
>> C(21,:)
ans =
(1,11) 1
(1,16) 1
(1,17) 1
>> full(C(21,:))
ans =
Columns 1 through 11
0 0 0 0 0 0 0 0 0 0 1
Columns 12 through 22
0 0 0 0 1 1 0 0 0 0 0
Columns 23 through 31
0 0 0 0 0 0 0 0 0
Goal for the output with some command such as invertDec2Asc
>> invertDec2Asc(C(21,:))
ans =
(1,21) 1
(1,16) 1
(1,15) 1
Try using num2str followed by fliplr
revnum = fliplr( num2str(num) )
Test
num = ['101010';'010101']
revnum = fliplr( num2str(num) )
num =
101010
010101
revnum =
010101
101010
flipud or fliplr is what you're looking for.
Matlab documentation
fliplr([1 0 1 0]) = [0 1 0 1]
fliplr('1010') = '0101'
format of binaries in matlab: '1010', e.g. created with dec2bin(10)