MATLAB and Simulink resources for Arduino, LEGO, and Raspberry Pi

# Seeking help creating a transition probability matrix for a markov chain

Asked by John on 3 Jan 2013

Hello,

I was hoping that somebody might be able to help me out in creating a transition probability matrix?

I normally use excel for statistical modelling but this particular problem takes hours to execute using spreadsheets and it is too large and complicated for a spreadsheet .

I have created a variables called 'data' and it contains velocity and acceleration data in 2 columns.

For example

Vel Acc
1   0.28
2   0.28
2   0.00
3   0.28
5   0.56
6   0.28

I was hoping to create a transition probability matrix of the probability of transition from one velocity acceleration pair to another. First of all you would create a frequency matrix counting all the transitions from one velocity acceleration pair to another and convert to a transition probability matrix by dividing by the row total.

Here is a graphical illustration of the matrix.

I would be very grateful if somebody had the time to help me with this. I'm trying to develop my matlab stills but would appreciate if somebody could show me how they would approach the problem.

Kind regards

## Products

No products are associated with this question.

Answer by Roger Stafford on 3 Jan 2013

It would be very similar to the solution I gave in your earlier posting. Let VA be your list of velocities and accelerations.

[uv,~,nv] = unique(VA(:,1));
[ua,~,na] = unique(VA(:,2));
F = accumarray([nv,na],1,[length(nv),length(na)]);
T = bsxfun(@rdivide,F,sum(F,2));

Again, the rows would correspond to velocity values in uv and the columns to corresponding accelerations in ua.

John on 4 Jan 2013

Hello Roger,

Thank you for your help. Apologies for not describing the problem correctly in the first instance.

I tried the code with the sample data provided. The matrix is 222x222 but there are only 107 unique velocity/acceleration pairs listed in lexicographical order hence I am unsure as how to read the matrix.

Apologies for asking such a simple question but am I missing something?

Also could I ask you, if you think that the code below is suitable for simulating a markov chain.

Sean de Wolski another member in the forum suggested it to me but he was unsure if it was the correct method.

Use a for-loop to loop n times for length you want. S
transC = [zeros(size(trans,1),1), cumsum(trans,2)]; %cumulative sum of rows, we will use this to decide on the next step.
n = 10;
states = zeros(1,n); %storage of states
states(1) = 1; %start at state 1 (or whatever)
for ii = 2:n
%Generate a random number and figure out where it falls in the cumulative sum of that state's trasition matrix row
[~,states(ii)] = histc(rand,transC(states(ii-1),:));
end

Kind regards

Roger Stafford on 4 Jan 2013

I set N to the wrong value. It should be the length of u, not the length of n. As it was you should have gotten NaNs on the last 115 rows when normalizing them. Again my apologies. Here is the corrected code. Let me know if there are any further errors.

[u,~,n] = unique(data,'rows');
N = length(u);
F = accumarray([n(1:end-1),n(2:end)],1,[N,N]);
T = bsxfun(@rdivide,F,sum(F,2));

Yes, Sean's code looks valid to me. He correctly uses 'histc' to choose the next state rather than the more inefficient 'find'. I probably would have generated all the 'rand' values in a vector at one time and then used elements from that vector in 'histc' sequentially in the for-loop but I think it makes little difference.

John on 6 Jan 2013

Hello Roger,

Thank you very much for your assistance and for commenting on Sean's code.

All the best