Before I start describing my problem, I would like to note that this question is for a project for one of my courses at University, so I do not seek for the solution, rather for a hint or an explanation.
So, lets assume that there are 3 states {1,2,3} and I also have the Transition probability Matrix (3x3). I wrote a matlab script that based on the transition matrix, it creates a vector with N samples for the Markov Chain. Assume that the first state is the state 1. Now, I need to Huffman code this chain based on the conditional distribution pXn |Xn−1 .
If I am not mistaken, I think that I have to create 3 Huffman dictionaries and encode each symbol from the chain above, based on the previous state(?), which means that each symbol is going to be encoded with one out of the three dictionaries I created, but not all of them with the same dictionary.
If the encoding process is correct, how do I decode the coded vector?
I am not really sure if that's how it should be done.
Any ideas would be appreciated.
Thanks in advance!
That's right. There would be a Huffman code for the three symbols p11, p12, and p13, another for p21, p22, p23, etc.
Decoding chooses which code to use based on the current state. There needs to either be an assumption for the starting state, or the starting state needs to be transmitted.
However this case is a little odd, since there is only one Huffman code for three symbols, consisting of 1 bit, 2 bits, and 2 bits. E.g. 0, 10, 11. So the only gain you get is by picking the highest probability for the one-bit symbol.
Well, having solved the problem above, I decided to post the answer with the octave script in case anyone needs it in future.
So, lets assume that there are 5 states {1,2,3,4,5} and I also have the Transition probability Matrix (5x5). I Huffman encoded and decoded the Markov chain for 1000 Monte Carlo experiments.
The Octave Script is:
%starting State of the chain
starting_value = 1;
%Chain Length
chain_length = 100;
%# of Monte Carlo experiments
MC=1000;
%Variable to count all correct coding/encoding experiments
count=0;
%Create unique symbols, and assign probabilities of occurrence to them.
symbols = 1:5;
p1 = [.5 .125 .125 .125 0.125];
p2 = [.25 .125 .0625 .0625 0.5];
p3 = [.25 .125 .125 .25 0.25];
p4 = [.125 0 .5 .25 0.125];
p5 = [0 .5 .25 .25 0];
%Create a Huffman dictionary based on the symbols and their probabilities.
dict1 = huffmandict(symbols,p1);
dict2 = huffmandict(symbols,p2);
dict3 = huffmandict(symbols,p3);
dict4 = huffmandict(symbols,p4);
dict5 = huffmandict(symbols,p5);
% Create the transition matrix for each state
T= [0.5 0.125 0.125 0.125 0.125;
0.25 0.125 0.0625 0.0625 0.5;
0.25 0.125 0.125 0.25 0.25;
0.125 0 0.5 0.25 0.125 ;
0 0.5 0.25 0.25 0];
%Initialize Marcov Chain
chain = zeros(1,chain_length);
chain(1)=starting_value;
for i=1 :MC
comp=[];
dsig=[];
%Create Markov Chain
for i=2:chain_length
this_step_distribution = T(chain(i-1),:);
cumulative_distribution = cumsum(this_step_distribution);
r = rand();
chain(i) = find(cumulative_distribution>r,1);
end
comp=huffmanenco(chain(1),dict1);
%Encode the random symbols.
for i=2:chain_length
if chain(i-1)==1
comp = horzcat(comp,huffmanenco(chain(i),dict1));
elseif chain(i-1)==2
comp = horzcat(comp,huffmanenco(chain(i),dict2));
elseif chain(i-1)==3
comp = horzcat(comp,huffmanenco(chain(i),dict3));
elseif chain(i-1)==4
comp = horzcat(comp,huffmanenco(chain(i),dict4));
elseif chain(i-1)==5
comp = horzcat(comp,huffmanenco(chain(i),dict5));
end
end
%Decode the data. Verify that the decoded data matches the original data.
dsig(1)=starting_value;
comp=comp(length(dict1{1,1})+1:end);
for i=2:chain_length
if dsig(end)==1
temp=huffmandeco(comp,dict1);
comp=comp(length(dict1(temp(1)){1,1})+1:end);
elseif dsig(end)==2
temp=huffmandeco(comp,dict2);
comp=comp(length(dict2(temp(1)){1,1})+1:end);
elseif dsig(end)==3
temp=huffmandeco(comp,dict3);
comp=comp(length(dict3(temp(1)){1,1})+1:end);
elseif dsig(end)==4
temp=huffmandeco(comp,dict4);
comp=comp(length(dict4(temp(1)){1,1})+1:end);
elseif dsig(end)==5
temp=huffmandeco(comp,dict5);
comp=comp(length(dict5(temp(1)){1,1})+1:end);
end
dsig=horzcat(dsig,temp(1));
end
count=count+isequal(chain,dsig);
end
count
The "variable" count is to make sure that in all of the MC experiments, the Markov Chain that was produced was properly encoded and decoded. (Obviously, if count equals to 1000, then all the experiments had correct results)
Related
I have a simple for loop that is used to simulated data,
for t=2:T;
Y_star(t,1,b)=[Y_star(t-1,1,b) X_1_star(t-1,1,b) X_2_star(t-1,1,b) 1]*beta(:,i)+w(t-1)*e(t-1,i);
X_1_star(t,1,b)=Theta(1,1)+Phi(1,:,1)*[X_1_star(t-1,1,b) ; X_2_star(t-1,1,b)]+w(t-1)*v(t-1,1,i);
X_2_star(t,1,b)=Theta(2,1)+Phi(2,:,1)*[X_1_star(t-1,1,b) ; X_2_star(t-1,1,b)]+w(t-1)*v(t-1,2,i);
end;
The issue I am having is this is fine when I have two X variables, however, I would like to write the code so that I can increase the number of variables to change each time, 4 say.
In this case, I would need X_1_star, X_2_star, X_3_star and X_4_star.
I can handle the Phi and Theta coefficients, as well as the w and v and e however I am struggling with creating the matrices for X's.
Any ideas would be greatly, I have tried storing the matrices within cells but I struggled to get this working.
Following the commnets, here is a simple example
%% Simple example
%-------------------------------------------------------------------------%
Phi = [0.9954 0.0195;
0.0012 0.9567];
Theta= [0.007;0.051];
beta = [0.06;-0.10;1.66;-0.88];
N = 1;
e = rand(370,1);
v = randn(370,2);
t = 371;
T = 371;
yy = rand(370,1);
X_1 = rand(370,1);
X_2 = rand(370,1);
B=50;
Y_star=zeros(T,N,B);
X_1_star=zeros(T,N,B);
X_2_star=zeros(T,N,B);
for b=1:B;
Y_star(1,:,b)=yy(1,:);
X_1_star(1,:,b)=X_1(1,:);
X_2_star(1,:,b)=X_2(1,:);
w=randn(T-1,1);
for t=2:T;
for i=1:N;
Y_star(t,i,b)=[Y_star(t-1,i,b) X_1_star(t-1,i,b) ...
X_2_star(t-1,i,b) 1]*beta(:,i)+w(t-1)*e(t-1,i);
X_1_star(t,i,b)=Theta(1,i)+Phi(1,:,i)*[X_1_star(t-1,i,b) ; ...
X_2_star(t-1,i,b)]+w(t-1)*v(t-1,1,i);
X_2_star(t,i,b)=Theta(2,i)+Phi(2,:,i)*[X_1_star(t-1,i,b) ; ...
X_2_star(t-1,i,b)]+w(t-1)*v(t-1,2,i);
end;
end;
disp(b);
end;
I ideally this to do the same thing but not be dependent upon writing X_1 and X_2, as I would like to increase this sometimes to a larger number.
I have tried reshaping as the commnets suggested but not sure how this would or could work in this example.
I think this problem is simply one of matrix algebra.
With the X variables it appears like you are simulating a small VAR model.
Instead of dynamic matrices as the answer above, I think it would make more sense to simulating the x data as a larger matrix instead of vectors.
Here is a simple example,
First, I show you a two variable case, both in the method you use, and by jointly simulating the data...
Then I show with a 3 variable case how to extend this...
All you have to do is take the size of the beta matrix (or alpha) as I guessing these are determined before the matrix...
%Simulating a small VAR model
%% 2 - variable case
rng('default')
b = [0.4 0.5;0.6 0.07];
a = [0.1 0.2];
v=randn(100,2);
x1 = zeros(100,1);
x2 = zeros(100,1);
xm=zeros(100,2);
T=100;
for t=2:T;
x1(t)=a(1)+b(1,:)*[x1(t-1) ; x2(t-1)]+v(t-1,1);
x2(t)=a(2)+b(2,:)*[x1(t-1) ; x2(t-1)]+v(t-1,2);
end;
for t=2:T;
xm(t,:)=a+xm(t-1,:)*b'+v(t-1,:)
end;
[xm x1 x2]
%% 3 - variable case
rng('default')
b = [0.4 0.5 0.1;0.6 0.07 0.1; 0.3 0.4 0.7];
a = [0.1 0.2 0.3];
v=randn(100,size(b,2));
xm=zeros(100,size(b,2));
for t=2:T;
xm(t,:)=a+xm(t-1,:)*b'+v(t-1,:)
end;
I generally find structure arrays more useful for this kind of dynamic indexing (where you don't know how many you'll have of X_1_star, X_2_star...)
I didn't try to reproduce the whole example, but it might go something like this if you're trying to get up to X_4_star:
...
nX=4;
for i=1:N
Y_star(t,i,b)=[Y_star(t-1,i,b) X_1_star(t-1,i,b) ...
X_2_star(t-1,i,b) 1]*beta(:,i)+w(t-1)*e(t-1,i);
for n=1:nX
X(n).star(t,i,b)=...
end
end
I want to construct a 3-dimensional Poisson distribution in Matlab with lambda parameters [0.4, 0.2, 0.6] and I want to truncate it to have support in [0;1;2;3;4;5]. The 3 components are independent.
This is what I do
clear
n=3; %number components of the distribution
supp_marginal=0:1:5;
suppsize_marginal=size(supp_marginal,2);
supp_temp=repmat(supp_marginal.',1,n);
supp_temp_cell=num2cell(supp_temp,1);
output_temp_cell=cell(1,n);
[output_temp_cell{:}] = ndgrid(supp_temp_cell{:});
supp=zeros(suppsize_marginal^n,n);
for h=1:n
temp=output_temp_cell{h};
supp(:,h)=temp(:);
end
suppsize=size(supp,1);
lambda_1=0.4;
lambda_2=0.2;
lambda_3=0.6;
pr_mass=zeros(suppsize,1);
for j=1:suppsize
pr_mass(j)=(poisspdf(supp(j,1),lambda_1).*...
poisspdf(supp(j,2),lambda_2).*...
poisspdf(supp(j,3),lambda_3))/...
sum(poisspdf(supp(:,1),lambda_1).*...
poisspdf(supp(:,2),lambda_2).*...
poisspdf(supp(j,3),lambda_3));
end
When I compute the mean of the obtained distribution, I get lambda_1 and lambda_2 but not lambda_3.
lambda_empirical=sum(supp.*repmat(pr_mass,1,3));
Question: why I do not get lambda_3?
tl;dr: Truncation changes the distribution so different means are expected.
This is expected as truncation itself has changed the distribution and certainly adjusts the mean. You can see this from the experiment below. Notice that for your chosen parameters, this just starts to become noticable around lambda = 0.6.
Similar to the wiki page, this illustrates the difference between E[X] (expectation of X without truncation; fancy word for mean) and E[ X | LB ≤ X ≤ UB] (expectation of X given it is on interval [LB,UB]). This conditional expectation implies a different distribution than the unconditional distribution of X (~Poisson(lambda)).
% MATLAB R2018b
% Setup
LB = 0; % lowerbound
UB = 5; % upperbound
% Simple test to compare theoretical means with and without truncation
TestLam = 0.2:0.01:1.5;
Gap = zeros(size(TestLam(:)));
for jj = 1:length(TestLam)
TrueMean = mean(makedist('Poisson','Lambda',TestLam(jj)));
TruncatedMean = mean(truncate(makedist('Poisson','Lambda',TestLam(jj)),LB,UB));
Gap(jj) = TrueMean-TruncatedMean;
end
plot(TestLam,Gap)
Notice the gap with these truncation bounds and a lambda of 0.6 is still small and is negligible as lambda approaches zero.
lam = 0.6; % <---- try different values (must be greater than 0)
pd = makedist('Poisson','Lambda',lam)
pdt = truncate(pd,LB,UB)
mean(pd) % 0.6
mean(pdt) % 0.5998
Other Resources:
1. Wiki for Truncated Distributions
2. What is a Truncated Distribution
3. MATLAB documentation for truncate(), makedist()
4. MATLAB: Working with Probability Distribution (Objects)
This Question is in continuation to a previous one asked Matlab : Plot of entropy vs digitized code length
I want to calculate the entropy of a random variable that is discretized version (0/1) of a continuous random variable x. The random variable denotes the state of a nonlinear dynamical system called as the Tent Map. Iterations of the Tent Map yields a time series of length N.
The code should exit as soon as the entropy of the discretized time series becomes equal to the entropy of the dynamical system. It is known theoretically that the entropy of the system is log_2(2). The code exits but the frst 3 values of the entropy array are erroneous - entropy(1) = 1, entropy(2) = NaN and entropy(3) = NaN. I am scratching my head as to why this is happening and how I can get rid of it. Please help in correcting the code. THank you.
clear all
H = log(2)
threshold = 0.5;
x(1) = rand;
lambda(1) = 1;
entropy(1,1) = 1;
j=2;
tol=0.01;
while(~(abs(lambda-H)<tol))
if x(j - 1) < 0.5
x(j) = 2 * x(j - 1);
else
x(j) = 2 * (1 - x(j - 1));
end
s = (x>=threshold);
p_1 = sum(s==1)/length(s);
p_0 = sum(s==0)/length(s);
entropy(:,j) = -p_1*log2(p_1)-(1-p_1)*log2(1-p_1);
lambda = entropy(:,j);
j = j+1;
end
plot( entropy )
It looks like one of your probabilities is zero. In that case, you'd be trying to calculate 0*log(0) = 0*-Inf = NaN. The entropy should be zero in this case, so you you can just check for this condition explicitly.
Couple side notes: It looks like you're declaring H=log(2), but your post says the entropy is log_2(2). p_0 is always 1 - p_1, so you don't have to count everything up again. Growing the arrays dynamically is inefficient because matlab has to re-copy the entire contents at each step. You can speed things up by pre-allocating them (only worth it if you're going to be running for many timesteps).
I have a state space system with matrices A,B,C and D.
I can either create a state space system, sys1 = ss(A,B,C,D), of it or compute the transfer function matrix, sys2 = C*inv(z*I - A)*B + D
However when I draw the bode plot of both systems, they are different while they should be the same.
What is going wrong here? Does anyone have a clue? I know btw that the bodeplot generated by sys1 is correct.
The system can be downloaded here: https://dl.dropboxusercontent.com/u/20782274/system.mat
clear all;
close all;
clc;
Ts = 0.01;
z = tf('z',Ts);
% Discrete system
A = [0 1 0; 0 0 1; 0.41 -1.21 1.8];
B = [0; 0; 0.01];
C = [7 -73 170];
D = 1;
% Set as state space
sys1 = ss(A,B,C,D,Ts);
% Compute transfer function
sys2 = C*inv(z*eye(3) - A)*B + D;
% Compute the actual transfer function
[num,den] = ss2tf(A,B,C,D);
sys3 = tf(num,den,Ts);
% Show bode
bode(sys1,'b',sys2,'r--',sys3,'g--');
Edit: I made a small mistake, the transfer function matrix is sys2 = C*inv(z*I - A)*B + D, instead of sys2 = C*inv(z*I - A)*B - D which I did wrote done before. The problem still holds.
Edit 2: I have noticted that when I compute the denominator, it is correct.
syms z;
collect(det(z*eye(3) - A),z)
Your assumption that sys2 = C*inv(z*I- A)*B + D is incorrect. The correct equivalent to your state-space system (A,B,C,D) is sys2 = C*inv(s*I- A)*B + D. If you want to express it in terms of z, you'll need to invert the relationship z = exp(s*T). sys1 is the correct representation of your state-space system. What I would suggest for sys2 is to do as follows:
sys1 = ss(mjlsCE.A,mjlsCE.B,mjlsCE.C,mjlsCE.D,Ts);
sys1_c = d2c(sys1);
s = tf('s');
sys2_c = sys1_c.C*inv(s*eye(length(sys1_c.A)) - sys1_c.A)*sys1_c.B + sys1_c.D;
sys2_d = c2d(sys2_c,Ts);
That should give you the correct result.
Due to inacurracy of the inverse function extra unobservable poles and zeros are added to the system. For this reason you need to compute the minimal realization of your transfer function matrix.
Meaning
% Compute transfer function
sys2 = minreal(C*inv(z*eye(3) - A)*B + D);
What you are noticing is actually a numerical instability regarding pole-zero pair cancellations.
If you run the following code:
A = [0, 1, 0; 0, 0, 1; 0.41, -1.21, 1.8] ;
B = [0; 0; 0.01] ;
C = [7, -73, 170] ;
D = 1 ;
sys_ss = ss(A, B, C, D) ;
sys_tf_simp = tf(sys_ss) ;
s = tf('s') ;
sys_tf_full = tf(C*inv(s*eye(3) - A)*B + D) ;
zero(sys_tf_simp)
zero(sys_tf_full)
pole(sys_tf_simp)
pole(sys_tf_full)
you will see that the transfer function formulated by matrices directly has a lot more poles and zeros than the one formulated by MatLab's tf function. You will also notice that every single pair of these "extra" poles and zeros are equal- meaning that they cancel with each other if you were to simply the rational expression. MatLab's tf presents the simplified form, with equal pole-zero pairs cancelled out. This is algebraically equivalent to the unsimplified form, but not numerically.
When you call bode on the unsimplified transfer function, MatLab begins its numerical plotting routine with the pole-zero pairs not cancelled algebraically. If the computer was perfect, the result would be the same as in the simplified case. However, numerical error when evaluating the numerator and denominators effectively leaves some of the pole-zero pairs "uncancelled" and as many of these poles are in the far right side of the s plane, they drastically influence the output behavior.
Check out this link for info on this same problem but from the perspective of design: http://ctms.engin.umich.edu/CTMS/index.php?aux=Extras_PZ
In your original code, you can think of the output drawn in green as what the naive designer wanted to see when he cancelled all his unstable poles with zeros, but the output drawn in red is what he actually got because in practice, finite-precision and real-world tolerances prevent the poles and zeros from cancelling perfectly.
Why is an unobservable / uncontrollable pole? I think this issue comes only because the inverse of a transfer function matrix is inaccurate in Matlab.
Note:
A is 3x3 and the minimal realization has also order 3.
What you did is the inverse of a transfer function matrix, not a symbolic or numeric matrix.
# Discrete system
Ts = 0.01;
A = [0 1 0; 0 0 1; 0.41 -1.21 1.8];
B = [0; 0; 0.01];
C = [7 -73 170];
D = 1;
z = tf('z', Ts)) # z is a discrete tf
A1 = z*eye(3) - A # a tf matrix with a direct feedthrough matrix A
# inverse it, multiply with C and B from left and right, and plus D
G = D + C*inv(A1)*B
G is now a scalar (SISO) transfer function.
Without "minreal", G has order 9 (funny, I don't know how Matlab computes it, perhaps the "Adj(.)/det(.)" method). Matlab cannot cancel the common factors in the numerator and the denominator, because z is of class 'tf' rather than a symbolic variable.
Do you agree or do I have misunderstanding?
I have the following Markov chain:
This chain shows the states of the Spaceship, which is in the asteroid belt: S1 - is serviceable, S2 - is broken. 0.12 - the probability of destroying the Spaceship by a collision with an asteroid. 0.88 - the probability of that a collision will not be critical. Need to find the probability of a serviceable condition of the ship after the third collision.
Analytical solution showed the response - 0.681. But it is necessary to solve this problem by simulation method using any modeling tool (MATLAB Simulink, AnyLogic, Scilab, etc.).
Do you know what components should be used to simulate this process in Simulink or any other simulation environment? Any examples or links.
First, we know the three step probability transition matrix contains the answer (0.6815).
% MATLAB R2019a
P = [0.88 0.12;
0 1];
P3 = P*P*P
P(1,1) % 0.6815
Approach 1: Requires Econometrics Toolbox
This approach uses the dtmc() and simulate() functions.
First, create the Discrete Time Markov Chain (DTMC) with the probability transition matrix, P, and using dtmc().
mc = dtmc(P); % Create the DTMC
numSteps = 3; % Number of collisions
You can get one sample path easily using simulate(). Pay attention to how you specify the initial conditions.
% One Sample Path
rng(8675309) % for reproducibility
X = simulate(mc,numSteps,'X0',[1 0])
% Multiple Sample Paths
numSamplePaths = 3;
X = simulate(mc,numSteps,'X0',[numSamplePaths 0]) % returns a 4 x 3 matrix
The first row is the X0 row for the starting state (initial condition) of the DTMC. The second row is the state after 1 transition (X1). Thus, the fourth row is the state after 3 transitions (collisions).
% 50000 Sample Paths
rng(8675309) % for reproducibility
k = 50000;
X = simulate(mc,numSteps,'X0',[k 0]); % returns a 4 x 50000 matrix
prob_survive_3collisions = sum(X(end,:)==1)/k % 0.6800
We can bootstrap a 95% Confidence Interval on the mean probability to survive 3 collisions to get 0.6814 ± 0.00069221, or rather, [0.6807 0.6821], which contains the result.
numTrials = 40;
ProbSurvive_3collisions = zeros(numTrials,1);
for trial = 1:numTrials
Xtrial = simulate(mc,numSteps,'X0',[k 0]);
ProbSurvive_3collisions(trial) = sum(Xtrial(end,:)==1)/k;
end
% Mean +/- Halfwidth
alpha = 0.05;
mean_prob_survive_3collisions = mean(ProbSurvive_3collisions)
hw = tinv(1-(0.5*alpha), numTrials-1)*(std(ProbSurvive_3collisions)/sqrt(numTrials))
ci95 = [mean_prob_survive_3collisions-hw mean_prob_survive_3collisions+hw]
maxNumCollisions = 10;
numSamplePaths = 50000;
ProbSurvive = zeros(maxNumCollisions,1);
for numCollisions = 1:maxNumCollisions
Xc = simulate(mc,numCollisions,'X0',[numSamplePaths 0]);
ProbSurvive(numCollisions) = sum(Xc(end,:)==1)/numSamplePaths;
end
For a more complex system you'll want to use Stateflow or SimEvents, but for this simple example all you need is a single Unit Delay block (output = 0 => S1, output = 1 => S2), with a Switch block, a Random block, and some comparison blocks to construct the logic determining the next value of the state.
Presumably you must execute the simulation a (very) large number of times and average the results to get a statistically significant output.
You'll need to change the "seed" of the random generator each time you run the simulation.
This can be done by setting the seed to be "now" (or something similar to that).
Alternatively you could quite easily vectorize the model so that you only need to execute it once.
If you want to simulate this, it is fairly easy in matlab:
servicable = 1;
t = 0;
while servicable =1
t = t+1;
servicable = rand()<=0.88
end
Now t represents the amount of steps before the ship is broken.
Wrap this in a for loop and you can do as many simulations as you like.
Note that this can actually give you the distribution, if you want to know it after 3 times, simply add && t<3 to the while condition.