I have the following vector
vec = [ 255 0 255 0 255 0 255 0 255 0 255 0 255 0 255 0]
vec 1x16 double
and using the following command
polyval(vec', 256);
I get
ans = 3.3896e+038
but when I try to get back my original vector
vec2 = decimal2base(ans, 256)
I get
vec2 = 255 0 255 0 255 1 0 0 0 0 0 0 0 0 0 0
and this is clearly not my original vector.
Whats more if again I run polyval in this vector
polyval(vec2', 256);
I get
ans=
3.3896e+038
I am not entirely sure what sort of mistake I am making as I know that my conversion functions are ok, so it must be a number precision thing.
Ah, large numbers. The value 3.3896e+038 is higher than the maximum integer that can be represented by a double without loss of accuracy.
That maximum number is 2^53 or
>> flintmax('double')
ans =
9.0072e+15
So you are losing accuracy and you cannot reverse the computation.
Doing the computations with uint64 values only:
>> pows = uint64(fliplr(0:numel(vec)-1));
>> sum(uint64(vec).*(uint64(256).^pows),'native')
ans =
18446744073709551615
That's about 1.84e+19. Just a little different from what you get if you use doubles. But wait... that number looks familiar:
>> intmax('uint64')
ans =
18446744073709551615
So, you've maxed out unsigned 64-bit integers too:
>> uint64(256).^pows
ans =
Columns 1 through 5
18446744073709551615 18446744073709551615 18446744073709551615 18446744073709551615 18446744073709551615
Columns 6 through 10
18446744073709551615 18446744073709551615 18446744073709551615 72057594037927936 281474976710656
Columns 11 through 15
1099511627776 4294967296 16777216 65536 256
Column 16
When you get above 255^8 or so, you're passing intmax('uint64') and you can't manage numbers this large, at least not with MATLAB's built-in data types.
see if this returns '1':
polyval(vec(6:end),256)==polyval(vec2(6:end),256);
If so, then it's just a property of '255+1' for that special 'vec'.
Related
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
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'
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.
I have an image with 3 colors in matlab which value 0, 128, and 255. for example:
255 255 255 255 128 255 0 255 255 128 0 255
255 0 255 255 128 255 255 0 255 128 255 255
255 0 255 0 128 255 255 255 255 128 255 0
255 255 0 255 128 255 255 0 255 128 255 255
255 0 0 255 128 0 255 255 0 128 255 0
First, I want to check the pixels of the index (1,1) to (1,5).
If there is pixel value 0 (black), then the pixels of the index (1,1) to (1,5) is changed to 128 (gray), if none, then the pixels are changed to 0 (white).
Second, I want to do these steps again, checking of the index (2,1) to (2,5), (3,1) to (3,5), through to the bottom, then continue to the next, to the index (1,6) to (1,10), (2,6) to (2,10), through to the bottom, then went to the index (1,11) to (1,end), (2,11) to (2,end).
Do you absolutely need to do this sequentially? It sounds like you need to do this for each group of the form (n, (5*m : 5*m +1)). If so, you can do all of the tests simultaneously by reshaping the matrix into a 3d matrix of blocks which are 5 elements wide. Also I am assuming that you meant "if none, then the pixels are changed to 255 (white)", not 0.
Suppose your image is called myImage, then
numBlocks = numel(myImage)/(5*size(myImage,1));
% Generate a 3D matrix each of which is 5 elements long in dimension 2. Note reshape will throw an error if numblocks is fractional
foo = reshape(myImage,size(myImage,1),5,numBlocks);
blackTest = any(foo==0,2);
result = blackTest * 128 + ~blackTest*255; % result for each block
output = reshape(repmat(result,[1 5 1]),size(myImage));
This reorganises your image into a 3d matrix, where each submatrix corresponding to each "layer" of the 3d matrix is 5 elements wide. For the whole 3d matrix it checks whether any of the elements in dimension 2 are zero, leaving a logical matrix foo of length 1 in dimension 2. foo consists of logical ones and zeros, which in MATLAB can also be treated as numerical ones and zeros. So it multiplies foo by 128 (for grey output value) and adds the logical inverse of foo multiplied by 255, to get your white output values. Finally it repeats the matrix back to 5-element-wide blocks and restores it to its original dimensions.
Edit: Note that as mentioned in the code comment, this code won't work if your original image isn't a multiple of 5 pixels wide. To fix this you'd have to create a special case, or use a loop to step through each 5-element-wide block. In fact that might be a better approach all round:
index = 1;
output = zeros(size(myImage));
while index < size(myImage,2)
blockEnd = min(index+4,size(myImage,2));
blackTest = any(myImage(:,index:blockEnd)==0,2);
blackTest = blackTest(:,ones(1,5));
output(1:end,index:blockEnd) = blackTest * 128 + ~blackTest*255;
index = index+5;
end
% generate matrix
rand_data = randi(10,10);
I = zeros(10);
I(rand_data < 6 & rand_data > 3) = 128;
I(rand_data >= 6) = 255;
% here's the code
I = reshape(I',5,[])';
mask = repmat(any(I == 0,2),5,1);
I(mask) = 128;
I(~mask) = 255;
I = reshape(I',10,[])';
This is a follow up question from a previous SO question. Now I have a bit which I have spread it into 8 bits. I have use Amro's solution to spread the bit to 8 bits. Now I want an inverse way to convert the 8bits back to the single bit.
I have only managed to implement the inverse using for loop which take alot of time in the application.
Is there a faster way of doing it?
Since you are using the solution I suggested last time, lets say you have a matrix N-by-8 of these 'bits' where each row represent one 8-bit binary number. To convert to decimal in a vectorized way, its as simple as:
» M = randi([0 1], [5 8]) %# 5 random 8-bit numbers
M =
1 0 1 0 1 0 1 1
0 1 1 0 1 1 1 0
1 1 0 1 1 0 1 1
1 0 0 0 0 1 1 0
1 0 0 1 0 1 1 0
» d = bin2dec( num2str(M) )
d =
171
110
219
134
150
An alternative solution:
d = sum( bsxfun(#times, M, power(2,7:-1:0)), 2)