how we get the answer in matrix form in here without drawing transition diagram? - markov-chains

Three white and three black balls are distributed in two urns in such a way that each contains three balls.
By saying that the system is in state i, i = 0,1,2,3, if the first urn contains i white balls. At each step, we draw one ball from each urn and place the ball drawn from the first urn into the second, and conversely with the ball from the second urn.
Xn denote the state of the system after the nth step.
how we get the answer in matrix form in here without drawing transition diagram?? Is it necessary to draw it?? But following is hard to understand that having many letters denote by bla bla..Can any one explain what is going on??
I can get the matrix answer using a transition diagram..But I can't understand how to draw it for a scenario..If it is given each states [i={0,1,2,3}] having some values filling by 1 each raw, then I can draw it. But here it is hard to understand what is denote by Xn, Yn and Zn..
P(Yn = 1|Xn = 0) = 0 P(Zn = 1|Xn = 0) = 1
P(Yn = 1|Xn = 1) = 1/3 P(Zn = 1|Xn = 1) = 2/3
P(Yn = 1|Xn = 2) = 2/3 P(Zn = 1|Xn = 2) = 1/3
P(Yn = 1|Xn = 3) = 1 P(Zn = 1|Xn = 3) = 0
to get the answer in matrix form
P = | 0 1 0 0 |
|1/9 4/9 4/9 0 |
|0 4/9 4/9 1/9 |
|0 0 1 0 |
Actually I can't understand what is happening here with Xn ,Yn and Zn. Isn't it easy to get the answer with a transition diagram?

Related

MATLAB: efficient generation of a large integer matrix of multi-indices

Let d and p be two integers. I need to generate a large matrix A of integers, having d columns and N=nchoosek(d+p,p) rows. Note that nchoosek(d+p,p) increases quickly with d and p, so it's very important that I can generate A quickly. The rows of A are all the multi-indices with components from 0 to p, such that the sum of the components is less than or equal to p. This means that, if d=3 and p=3, then A is an [N=nchoosek(3+3,3)=20x3] matrix with the following structure:
A=[0 0 0;
1 0 0;
0 1 0;
0 0 1;
2 0 0;
1 1 0;
1 0 1;
0 2 0;
0 1 1;
0 0 2;
3 0 0;
2 1 0;
2 0 1;
1 2 0;
1 1 1;
1 0 2;
0 3 0;
0 2 1;
0 1 2;
0 0 3]
It is not indispensable to follow exactly the row ordering I used, although it would make my life easier (for those interested, it's called graded lexicographical ordering and it's described here:
http://en.wikipedia.org/wiki/Monomial_order).
In case you are curious about the origin of this weird matrix, let me know!
Solution using nchoosek and diff
The following solution is based on this clever answer by Mark Dickinson.
function degrees = monomialDegrees(numVars, maxDegree)
if numVars==1
degrees = (0:maxDegree).';
return;
end
degrees = cell(maxDegree+1,1);
k = numVars;
for n = 0:maxDegree
dividers = flipud(nchoosek(1:(n+k-1), k-1));
degrees{n+1} = [dividers(:,1), diff(dividers,1,2), (n+k)-dividers(:,end)]-1;
end
degrees = cell2mat(degrees);
You can get your matrix by calling monomialDegrees(d,p).
Solution using nchoosek and accumarray/histc
This approach is based on the following idea: There is a bijection between all k-multicombinations and the matrix we are looking for. The multicombinations give the positions, where the entries should be added. For example the multicombination [1,1,1,1,3] will be mapped to [4,0,1], as there are four 1s, and one 3. This can be either converted using accumarray or histc. Here is the accumarray-approach:
function degrees = monomialDegrees(numVars, maxDegree)
if numVars==1
degrees = (0:maxDegree).';
return;
end
degrees = cell(maxDegree+1,1);
degrees{1} = zeros(1,numVars);
for n = 1:maxDegree
pos = nmultichoosek(1:numVars, n);
degrees{n+1} = accumarray([reshape((1:size(pos,1)).'*ones(1,n),[],1),pos(:)],1);
end
degrees = cell2mat(degrees);
And here the alternative using histc:
function degrees = monomialDegrees(numVars, maxDegree)
if numVars==1
degrees = (0:maxDegree).';
return;
end
degrees = cell(maxDegree+1,1);
degrees(1:2) = {zeros(1,numVars); eye(numVars);};
for n = 2:maxDegree
pos = nmultichoosek(1:numVars, n);
degrees{n+1} = histc(pos.',1:numVars).';
end
degrees = cell2mat(degrees(1:maxDegree+1));
Both use the following function to generate multicombinations:
function combs = nmultichoosek(values, k)
if numel(values)==1
n = values;
combs = nchoosek(n+k-1,k);
else
n = numel(values);
combs = bsxfun(#minus, nchoosek(1:n+k-1,k), 0:k-1);
combs = reshape(values(combs),[],k);
end
Benchmarking:
Benchmarking the above codes yields that the diff-solution is faster if your numVars is low and maxDegree high. If numVars is higher than maxDegree, then the histc solution will be faster.
Old approach:
This is an alternative to Dennis' approach of dec2base, which has a limit on the maximum base. It is still a lot slower than the above solutions.
function degrees = monomialDegrees(numVars, maxDegree)
Cs = cell(1,numVars);
[Cs{:}] = ndgrid(0:maxDegree);
degrees = reshape(cat(maxDegree+1, Cs{:}),(maxDegree+1)^numVars,[]);
degrees = degrees(sum(degrees,2)<=maxDegree,:);
I would solve it this way:
ncols=d;
colsum=p;
base=(0:colsum)';
v=#(dm)permute(base,[dm:-1:1]);
M=bsxfun(#plus,base,v(2));
for idx=3:ncols
M=bsxfun(#plus,M,v(idx));
end
L=M<=colsum;
A=cell(1,ncols);
[A{:}]=ind2sub(size(L),find(L));
a=cell2mat(A);
%subtract 1 because 1 based indexing but base starts at 0
a=a-1+min(base);
It builds up a p-dimensional matrix which contains the sum. The efficiency of this code depends on sum(L(:))/numel(L), this quotient tells you how much of the created matrix is actually used for solutions. If this gets low for your intput, there probably exits a better solution.
Here is a very easy way to do it:
L = dec2base(0:4^3-1,4);
idx=sum(num2str(L)-'0',2)<=3;
L(idx,:)
I think the first line can be very time efficient for creating a list of candidates, but unfortunately I don't know how to reduce the list in an efficient way after that.
So the second line works, but could use improvement performance wise.

Flexible Array in matlab

i have some cities, these cities have some neighbors and count of these neighbors are not similar.
i have a function:
function [cityN,neighbor,neghbor2:neghborN]] = makeneighbor(x,y)
cityN=x;
neighbor=y;
end % this function is false and i just told what is in my mind
for example:
//city1 have 2 neighbors:
[city1,neighbor1,neghbor2]
//but city2 have 4 neighbors:
[city2,neighbor1,neghbor2,neighbor3,neghbor4]
//and city3 have just a neighbor
[city3,neighbor1]
i need a flixeble array for this, many thanks...
You could use an adjacency matrix
cities = {'City1','City2', 'City3', 'City4'}
A =
0 1 0 1 (1 is neighbours with 2 and 4)
1 0 1 0 (2 is neighbours with 1 and 3)
0 1 0 0 (3 is only neighbours with 2)
1 0 0 0 (4 is only neighbours with 4)
(A should be of type logical)
Then, for any city, the list of neighbours is:
n = strfind('City1',cities);
neighbours = cities(A(n,:));
And the list with itself and neighbours would be
self_neighbours = [cities(n),cities(A(n,:))];
The count of number of neighbours is just:
num_neighbours = sum(A(n,:));
The advantages of keeping a list of who is neighbours with who in something like an adjacency matrix is that it makes it much easier to perform calculations. If you have access to the Bioinformatics Toolbox, you also then can use this to do various useful things:
b = biograph(A,cities); %makes biograph object
view(b); % shows connection between cities
[dist,path,pred] = shortestpath(b,1,3); % finds path between 1 and 3
Not sure is this is exactly what you need, but:
all_cities = {}
all_cities{end+1} = {'New York','Boston', 'Mscow'}
all_cities{end+1} = {'Moscow','Town1', 'St.Petersburg'}
All cities is a cell array that contains all cities. Every alement of this cell array is cell array too. Every nested cell array contains as a first element the main city, from the second element to the last one neighbors are stored.
Say, if we speak about New York,
new_york = all_cities{1};
new_york_neighbors = new_york{2:end};
You also should check if new_york_neighbors is empty while processing it. Use function isempty()
I am not quite sure if I understood your question. To handle different array sizes you could return a struct for your makeneighbor function with 1 field that contains the city name and a second field that contains a cell array with all neighborhoods:
function [] = main_func()
x1 = 'new york';
y1 = {'brooklyn'; 'queens'};
city1 = makeneighbor(x1, y1);
x2 = 'los angeles';
y2 = {'hollywood'; 'downtown'; 'mid-city'; 'bel air'};
city2 = makeneighbor(x2, y2);
% acces to cities
city1.name
city1.neighbor
city2.name
city2.neighbor
end
% function that returns a struct
function city = makeneighbor(x, y)
% generate struct with two fields
city.name = x;
city.neighbor = y;
end

Get the neighbors of a matrix element

I have a matrix and for each element I want to get the index of its surrounding elements. All these results have to be stored into a matrix in the following way. Each row of the matrix corresponds to a matrix element and each of the columns of this matrix contain s the neighbor indexes. For example, for a 4x4 matrix we will get a 16x8 result array. Some of the matrix elements do not have 8 neighbors.
There is an example, I think it is working, I there any way to avoid for loop?:
ElementNeighbors = [];
for n = 1:numel(Matrix)
NeighborsMask = [ n-1 n+1 n+size(matrix,1) n-size(Matrix,1) n-size(Matrix,1)-1 n-size(Matrix,1)+1 ...
n+size(Matrix,1)-1 n+size(Matrix,1)+1 ];
ElementNeighbors = [ElementNeighbors ; NeighborsMask ];
end
ElementNeighbors (ElementNeighbors ==0|ElementNeighbors <0) = NaN;
Given the linear indices of a matrix M(n,m), you can convince yourself that the top left neighbor of element M(i,j) = M(i-1, j-1) = M(i-1 + n * (j-2))
In "linear index" space that means the offset of this element is
-n-1
Doing this for all other locations, we find
-n-1 | -1 | n-1
-n | x | n => [-n-1, -n, -n+1, -1, +1, +n-1, +n, +n+1]
-n+1 | +1 | n+1
Thus you can create a vector offset with the above values (replacing n with the first dimension). For example, if M is (5x4), then
offset = [-6 -5 -4 -1 1 4 5 6];
You then create all the indices:
indices = bsxfun(#plus, (1:m*n), offset(:));
bsxfun is a cool shorthand for "do this function on these elements; where one element has a singleton dimension and the other doesn't, expand accordingly". You could do the same with repmat, but that creates unnecessary intermediate matrices (which can sometimes be very large).
That command will create a (8 x m*n) matrix of indices of all 8 neighbors, including ones that may not really be the neighbors... something you need to fix.
Several possible approaches:
pad the matrix before you start
don't care about wrapping, and just get rid of the elements that fall off the edge
create a mask for all the ones that are "off the edge".
I prefer the latter. "Off the edge" means:
going up in the top row
going left in the left column
going down in the bottom row
going right in the right column
In each of these four cases there are 3 indices that are 'invalid'. Their position in the above matrix can be determined as follows:
mask = zeros(size(M));
mask(:,1) = 1;
left = find(mask == 1);
mask(:,end) = 2;
right = find(mask == 2);
mask(1,:) = 3;
top = find(mask == 3);
mask(end,:) = 4;
bottom = find(mask == 4);
edgeMask = ones(8,m*n);
edgeMask(1:3, top) = 0;
edgeMask([1 4 6], left) = 0;
edgeMask([3 5 8], right) = 0;
edgeMask(6:8, bottom) = 0;
Now you have everything you need - all the indices, and the "invalid" ones. Without loops.
If you were feeling ambitious you could turn this into a cell array but it will be slower than using the full array + mask. For example if you want to find the average of all the neighbors of a value, you can do
meanNeighbor = reshape(sum(M(indices).*edgeMask, 1)./sum(edgeMask, 1), size(M));
EDIT re-reading your question I see you wanted a M*N, 8 dimension. My code is transposed. I'm sure you can figure out how to adapt it...
ATTRIBUTION #Tin helpfully suggested many great edits to the above post, but they were rejected in the review process. I cannot totally undo that injustice - but would like to record my thanks here.
EXTENDING TO DIFFERENT REGIONS AND MULTIPLE DIMENSIONS
If you have an N-dimensional image matrix M, you could find the neighbors as follows:
temp = zeros(size(M));
temp(1:3,1:3,1:3) = 1;
temp(2,2,2) = 2;
offsets = find(temp==1) - find(temp==2);
If you want a region that is a certain radius in size, you could do
sz = size(M);
[xx yy zz] = meshgrid(1:sz(1), 1:sz(2), 1:sz(3));
center = round(sz/2);
rr = sqrt((xx - center(1)).^2 + (yy - center(2)).^2 + (zz - center(3)).^2);
offsets = find(rr < radius) - find(rr < 0.001);
You can probably figure out how to deal with the problem of edges along the lines shown earlier for the 2D case.
Untested - please see if you notice any problems with the above.

haltonset: understanding skip and leap

If i read the doc of how to construct a Halton quasi-random point set and it mentions that it's possible to 'skip' the first values and then retain the 'leap' values.
Don't understand what the 'skip' and 'leap' really mean.
Have tried the following:
>> p = haltonset(1,'Skip',50,'Leap',10); d = haltonset(1,'Skip',51,'Leap',9);
>> p(2:10), d(1:9)
ans =
0.7344
0.0703
0.7891
0.4766
0.5859
0.1797
0.9922
0.3164
0.6602
ans =
0.7969
0.7344
0.8828
0.5391
0.8516
0.6484
0.9609
0.6172
0.7539
>> p(2:10) == d(1:9)
ans =
0
0
0
0
0
0
0
0
0
Thought that it might be that that this would save 10 values to p and 9 to d. Also thought that d would have the same values as p. But this was not the case.
I then tested if the 'leap' would be the same as a normal way to make a vector
- ex: (1:leap:10)
>> p = haltonset(1,'Skip',50,'Leap',1); d = haltonset(1,'Skip',50,'Leap',2);
>> p(1:2:10)==d(1:5)
ans =
1
0
0
0
0
>> p = haltonset(1,'Skip',0,'Leap',1); d = haltonset(1,'Skip',0,'Leap',2);
>> p(1:2:10)==d(1:5)
ans =
1
0
0
0
0
but this seemed not to be the case..
Can anybody give a plain English explanation of how to interpreted the 'skip' and 'leap' variables.
I find the following description to be very clear [quoting this documentation page]:
Imagine a simple 1-D sequence that produces the integers from 1 to 10.
This is the basic sequence and the first three points are [1,2,3]:
Now look at how Scramble, Leap, and Skip work together:
Scramble: Scrambling shuffles the points in one of several
different ways. In this example, assume a scramble turns the sequence
into 1,3,5,7,9,2,4,6,8,10. The first three points are now [1,3,5]:
Skip: A Skip value specifies the number of initial points to
ignore. In this example, set the Skip value to 2. The sequence is now
5,7,9,2,4,6,8,10 and the first three points are [5,7,9]:
Leap: A Leap value specifies the number of points to ignore for
each one you take. Continuing the example with the Skip set to 2, if
you set the Leap to 1, the sequence uses every other point. In this
example, the sequence is now 5,9,4,8 and the first three points are
[5,9,4]:
EDIT:
Let me show with an example:
%# create 1D sequences (x: picked, .: ignored)
p00 = haltonset(1,'Skip',0,'Leap',0); %# xxxxxxxxxxxxxxx
p50 = haltonset(1,'Skip',5,'Leap',0); %# .....xxxxxxxxxx
p02 = haltonset(1,'Skip',0,'Leap',2); %# x..x..x..x..x..
p52 = haltonset(1,'Skip',5,'Leap',2); %# .....x..x..x..x
%# each pair of these are equal
[p50(1:10) p00(6:15)] %# skip vs. noskip
[p02(1:5) p00(1:3:13)] %# leap vs. noleap
[p52(1:4) p00(6:3:15)] %# skip+leap vs. noskip+noleap
In general:
skip = 50;
leap = 10;
p00 = haltonset(1,'Skip',0,'Leap',0);
p = haltonset(1,'Skip',skip,'Leap',leap);
num = 9;
[p(1:num) p00(skip+1:leap+1:num*leap+num-leap+skip)]

matlab fxn: find contiguous regions and return bounds in struct array

This is half a question and half a challenge to the matlab gurus out there:
I'd like to have a function take in a logical array (false/true) and give the beginning and ending of all the contiguous regions containing trues, in a struct array.
Something like this:
b = getBounds([1 0 0 1 1 1 0 0 0 1 1 0 0])
should return
b = 3x1 struct array with fields:
beg
end
and
>> b(2)
ans =
beg: 4
end: 6
I already have an implementation, but I don't really know how to deal with struct arrays well so I wanted to ask how you would do it - I have to go through mat2cell and deal, and when I have to deal with much larger struct arrays it becomes cumbersome. Mine looks like this:
df = diff([0 foo 0]);
a = find(df==1); l = numel(a);
a = mat2cell(a',ones(1,l))
[s(1:l).beg] = deal(a{:});
b = (find(df==-1)-1);
b = mat2cell(b',ones(1,l))
[s(1:l).end] = deal(b{:});
I don't see why you are using mat2cell, etc. You are making too much of the problem.
Given a boolean row vector V, find the beginning and end points of all groups of ones in the sequence.
V = [1 0 0 1 1 1 0 0 0 1 1 0 0];
You get most of it from diff. Thus
D = diff(V);
b.beg = 1 + find(D == 1);
This locates the beginning points of all groups of ones, EXCEPT for possibly the first group. So add a simple test.
if V(1)
b.beg = [1,b.beg];
end
Likewise, every group of ones must end before another begins. So just find the end points, again worrying about the last group if it will be missed.
b.end = find(D == -1);
if V(end)
b.end(end+1) = numel(V);
end
The result is as we expect.
b
b =
beg: [1 4 10]
end: [1 6 11]
In fact though, we can do all of this even more easily. A simple solution is to always append a zero to the beginning and end of V, before we do the diff. See how this works.
D = diff([0,V,0]);
b.beg = find(D == 1);
b.end = find(D == -1) - 1;
Again, the result is as expected.
b
b =
beg: [1 4 10]
end: [1 6 11]
By the way, I might avoid the use of end here, even as a structure field name. It is a bad habit to get into, using matlab keywords as variable names, even if they are only field names.
This is what I went with:
df = diff([0 foo 0]);
s = struct('on',num2cell(find(df==1)), ...
'off',num2cell(find(df==-1)-1));
I forgot about num2cell and the nice behavior of struct with cell arrays.