On this website http://www.bilsen.com/aic/cabac.shtml there is a nice example showing how arithmetic coding works. One thing that bugs me is how this:
0.647705
got converted to this:
0.101001011101?
Clearly it's not a "typical" decimal to binary number conversion.
0.647705 • 2 = 1 + 0.295410.
0.295410 • 2 = 0 + 0.590820.
0.590820 • 2 = 1 + 0.181640.
0.181640 • 2 = 0 + 0.363280.
0.363280 • 2 = 0 + 0.726560.
0.726560 • 2 = 1 + 0.453120.
0.453120 • 2 = 0 + 0.906240.
0.906240 • 2 = 1 + 0.812480.
0.812480 • 2 = 1 + 0.624960.
0.624960 • 2 = 1 + 0.249920.
0.249920 • 2 = 0 + 0.499840.
0.499840 • 2 = 0 + 0.999680.
The sequence of bits produced is 1 0 1 0 0 1 0 1 1 1 0 0. Then, since we are stopping on the last one, we see the remainder, .999680, is more than ½, so we round the last bit up from 0 to 1. The result is .1010010111101.
Related
I am writing a program that is a Game of Thrones Game similar to minesweeper. The user is asked for the size of the kingdom and depending on the size has a certain amount of knights. I create a matrix (size by size) of zeros to pre-allocate and assign the same amount of kings as there are knights to random places in the matrix. I now have made a new function that i call in the main script that i want to iterate through the matrix and assign new values to each element based on how many kings are in the neighboring spots for example:
_ 1 2 3 4 5 6 7 8
1 * 1 1 1 1 0 0 0
2 1 2 2 * 2 2 1 1
3 1 2 * 3 * 2 * 1
4 * 3 1 2 1 2 1 1
5 * 2 0 0 0 0 0 0
6 1 0 0 1 1 2 1 1
7 1 1 1 1 * 2 * 1
8 1 * 1 1 1 2 1 1
The problem is I really do not know how to actually count the neighboring kings and change the values in my matrix. I have started with some for loops for the sides but i am not sure how to proceed. The main scrips and the function are bellow Thank you!
Main Script:
clear all;close all;clc;
%display menu of options to play gam or exit
choice = menu('Choose an option', 'Exit Program', 'Start New Game');
%choise 1 is to exit the program
while choice ~= 1
switch choice
case 0
disp('Error - please choose one of the options.')
choice = menu('Choose an option', 'Exit Program', 'Start New Game');
%choice two is to start a new game
case 2
disp('Welcome to the GAME of THRONES!');
name = input('State your name, Your Grace: ','s');
size = input(['How vast is your Kindom ', name , ' your Grace?: ']);
Kings = floor((size^2)/6);
A = [name, ' Your Grace, you have ' num2str(Kings), ' Knights left to defeat ' num2str(Kings), ' Kings'];
disp(A);
game_choices = menu('Choose an option','Show the Kingdoms','Enter a new Coordinat');
switch game_choices
case 1 %Show the board
mymat = zeros(size);%matrix of users size
Kr=randsample(size^2,Kings);%vector of random positions for the kings
for i= 1:Kings
mymat([Kr(i)])=999;%put kings into mat of zeros in there random assignments
end
makeBoard(size);
%cell array game board
case 2 %enter a new coordinate
end
end
choice = menu('Choose an option', 'Exit Program', 'Start New Game');
end
Function i do not know how to write:
function [ mymatG ] = countTheKings( mymat )
%this function counts the kings and puts the numbers where they should be
%should have 2 for loops
for i = 1:size
for j = 1:size
%top
mymat(1,j)=
%bottom
mymat(size,j)=
%left side
mymat(i,1)=
%right side
mymat(i,size)=
end
A classic way to count the number of neighbors is to use convolution. 2D Convolution, in the discrete world, shifts a matrix ("kernel") over a bigger matrix and for each shift, the overlap is computed. The overlap is defined as the sum of the element-wise multiplication of the kernel and the data underneath of it. The resulting value is then used to replace the value that the kernel is centered on.
We can design the kernel to "detect" neighbors. We want it to have ones in spots that you consider to be neighbors and zeros in spots that you don't consider to be neighbors. This would probably look like this if you don't want your kings to consider themselves a neighbor.
1 1 1
1 0 1
1 1 1
This matrix will be centered at every point on your board and element-wise multiplication with the board will be performed and all elements will be summed up.
For example, if this was centered at the following data
1 2 3
4 5 6
7 8 9
It would be processed as:
(1 * 1) + (2 * 1) + (3 * 1) + (4 * 1) + (5 * 0) + (6 * 1) + (7 * 1) + (8 * 1) + (9 * 1)
1 + 2 + 3 + 4 + 0 + 6 + 7 + 8 + 9
40
So we can also use convolution of this "kernel" to count the number of 1's in a binary matrix.
So for this data
1 0 1
0 0 0
1 0 0
When we apply our kernel to this we get
(1 * 1) + (0 * 1) + (1 * 1) + (0 * 1) + (0 * 0) + (0 * 1) + (1 * 1) + (0 * 1) + (0 * 1)
1 + 0 + 1 + 0 + 0 + 0 + 1 + 0 + 0
3
If you imagine that the binary data we applied this kernel to was 1 where there is a king and 0 where there isn't, this is the number of kings that surround a given element.
So what we can do is take the kernel from the beginning of our question, and create a binary matrix that is 1's where there is a king and 0's otherwise. The result will be the size of your board and the values will be the number of neighboring kings.
kernel = [1 1 1;
1 0 1;
1 1 1];
mymat = [9 0 0 0 0 0 0 0
0 0 0 9 0 0 0 0
0 0 9 0 9 0 9 0
9 0 0 0 0 0 0 0
9 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0
0 0 0 0 9 0 9 0
0 9 0 0 0 0 0 0];
isKing = mymat == 9;
nKingNeighbors = conv2(double(isKing), kernel, 'same');
%// 0 1 1 1 1 0 0 0
%// 1 2 2 2 2 2 1 1
%// 1 2 1 3 1 2 0 1
%// 1 3 1 2 1 2 1 1
%// 1 2 0 0 0 0 0 0
%// 1 1 0 1 1 2 1 1
%// 1 1 1 1 0 2 0 1
%// 1 0 1 1 1 2 1 1
If you didn't want to consider diagonal entries to be neighbors you could simply change your kernel to be.
0 1 0
1 0 1
0 1 0
So if we take this back to your example, we could write your countTheKings function as
function mymatG = countTheKings(mymat)
kernel = [1 1 1
1 0 1
1 1 1];
mymatG = conv2(double(mymat == 999), kernel, 'same');
end
Here is an animation showing what the 2D convolution is actually doing. The kernel is shown in red and you can see the values of nKingNeighbors being filled in as the kernel is shifted over the image.
I have a vector test2 that includes NaN 0 and 1 in random order (we cannot make any assumption).
test2 = [NaN 1 1 1 0 0 0 NaN NaN NaN 0 0 0 1 1 1 0 1 1 1 ];
I would like to group the elements containing consecutive 1 and to have in the separte vectors start and finish the first and last index of the groups.
In this case start and finish should be:
start = [2 14 18];
finish = [4 16 20];
I tried to adapt the code provided here coming up with this solution that is not working...could you help me with the right solution and tell me why the one I tried doesn't work?
a = (test2 ==1);
d = diff(a);
start = find([a(1) d]==1); % Start index of each group
finish = find([d - a(end)]==-1); % Last index of each group
start =
2 14 18
finish =
2 3 5 6 7 8 9 10 11 12 14 15 18 19
I am using MATLAB R2013b running on Windows.
I tried also using MATLAB R2013a running on ubuntu.
a = (test2 ==1)
d=diff([0 a 0])
start=find(d==1)
finish=find(d==-1)-1
Padding a zero at the beginning and end is the easiest possibility. Then the special cases where a group starts at index 1 or ends at last index don't cause problems.
Full output:
>> test2 = [NaN 1 1 1 0 0 0 NaN NaN NaN 0 0 0 1 1 1 0 1 1 1 ]
test2 =
Columns 1 through 16
NaN 1 1 1 0 0 0 NaN NaN NaN 0 0 0 1 1 1
Columns 17 through 20
0 1 1 1
>> a = (test2 ==1)
a =
Columns 1 through 16
0 1 1 1 0 0 0 0 0 0 0 0 0 1 1 1
Columns 17 through 20
0 1 1 1
>> d=diff([0 a 0])
d =
Columns 1 through 16
0 1 0 0 -1 0 0 0 0 0 0 0 0 1 0 0
Columns 17 through 21
-1 1 0 0 -1
>> start=find(d==1)
start =
2 14 18
>> finish=find(d==-1)-1
finish =
4 16 20
>>
The problem is the line finish = find([d - a(end)]==-1);, in particular that a(end) == 1. There are two steps to correcting this. First, change the problem line to finish = find(d==-1); This tells MATLAB, "Look for the elements where the difference between adjacent elements is -1". In other words, the vector shifts from 1 to 0 or NaN. If you run the code, you'll get
start = 2 14 18
finish = 4 16
Now, you'll notice the last element isn't detected (i.e. we should get finish(3) == 20. This is because the length of d is one less than the length of test2; the function diff cannot calculate the difference between the last element and the non-existant last+1 element!
To remedy this, we should modify a:
a = [(test2 == 1) 0];
And you will get the right output for start and finish.
I have this so far:
data = 14
out = dec2bin(data, 4)
which gives:
out = 1110
But I want to get binary number in this format:
out = [1 1 1 0]
Thanks for help!
You're looking for de2bi with the 'left-msb' option.
data = 14
out = de2bi(data, 4,'left-msb')
Which requires the Communication Systems Toolbox though. Alternatively use your original approach with the fundamental dec2bin with the following addition:
data = 14
out = double( dec2bin(data, 4) ) - 48
out =
1 1 1 0
You're looking for de2bi,
bi2de
functions.
It requires the Communication Systems Toolbox.
If you don't have it, you can work define these functions at the begining of your code as:
de2bi = #(x) dec2bin(x)>48;
bi2de = #(x) x*2.^(size(x,2)-1:-1:0)';
Test:
dec = 1:10
bin = de2bi(dec)
dec = bi2de(bin)
Output:
dec =
1 2 3 4 5 6 7 8 9 10
bin =
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
dec =
1
2
3
4
5
6
7
8
9
10
P.S. If, by some reason, you don't want to use dec2bin at all, you can define de2bi function as:
In Matlab/Octave:
de2bi = #(x) 2.^[(floor(log2(max(x(:)))):-1:1),0];
de2bi = #(x) rem(x(:),2*de2bi(x))>(de2bi(x)-1);
In Octave only (as far as Octave allows default values for anonymous functions):
By default returns the same as in the previous example, but optional bit position parameter is available:
de2bi = #(dec,bit=[(1+floor(log2(max(dec(:))))):-1:2, 1]) rem(dec(:),2.^bit)>(2.^(bit-1)-1);
%Call examples:
x=0:10;
n=3:-1:1;
de2bi(x)
de2bi(x,n) % returns only the three least significant bits
P.S. More common answer provided here: dec2base with independent bits/digits calculation
Yet another way: Use "bitget":
data = 14
out = bitget (data, 4:-1:1)
out =
1 1 1 0
I have a 333x1 vector of values ('data') and each of the cells in the vector correspond to a range of 1 of 13 subcategories. The identities of each of these subcategories are stored in a separate identity matrix ('id'). I'd like to calculate the sum of the values within the original data matrix that have a similar identity.
e.g. pretending for this example that 'data' and 'id' are 8x1 vectors
data = [1;1;1;0;0;0;1;1]
id = [1;2;1;2;3;3;1;3]
sum of id 1: 1 + 0 + 1 + 0 + 0 + 0 + 1 + 0 = 3
sum of id 2: 0 + 1 + 0 + 0 + 0 + 0 + 0 + 0 = 1
sum of id 3: 0 + 0 + 0 + 0 + 0 + 0 + 0 + 1 = 1
I'm sure that there is a really easy fix for this, however I can't seem to work it out.
Thanks for your time
Mac
A simple solution would be:
numCategories = 13;
totals = zeros(numCategories,1);
for idnum = 1:numCategories
totals(idnum) = sum((id==idnum).*data);
end
EDIT: As knedlsepp pointed out in the comments, the accumarray function accomplishes exactly what the above code does in one line.
accumarray(id,data);
I want to concatenate last four bits of binary into a number i have tried the following code
x8=magic(4)
x8_n=dec2bin(x8)
m=x8_n-'0'
which gives me the following output
m =
1 0 0 0 0
0 0 1 0 1
0 1 0 0 1
0 0 1 0 0
0 0 0 1 0
0 1 0 1 1
0 0 1 1 1
0 1 1 1 0
0 0 0 1 1
0 1 0 1 0
0 0 1 1 0
0 1 1 1 1
0 1 1 0 1
0 1 0 0 0
0 1 1 0 0
0 0 0 0 1
now i want to take every last 4 bits it each row and convert it into an integer
n = 4; %// number of bits you want
result = m(:,end-n+1:end) * pow2(n-1:-1:0).'; %'// matrix multiplication
Anyway, it would be easier to use mod on x8 directly, without the intermediate step of m:
result = mod(x8(:), 2^n);
In your example:
result =
0
5
9
4
2
11
7
14
3
10
6
15
13
8
12
1
This could be another approach -
n = 4; %%// number of bits you want
out = bin2dec(num2str(m(:,end-n+1:end)))
Output -
out =
0
5
9
4
2
11
7
14
3
10
6
15
13
8
12
1