Matlab PHD from Generator Matrix - matlab

I am studying phase-type distributions. Basically a phase-type distribution is defined on a directed graph, where the nodes have exponential holding times, and you want to know the distribution of the time before arriving into an absorbing state. As such, a phase-type distribution is defined by an initial probability vector PI and a Generator Matrix D0 (which really just captures the structure of the directed graph). For given PI and D0, the distribution is formally given by
F(t) = 1-PI * exp(D0 * t) * TAU
where TAU is a vector of ones of the same size as PI. For complicated D0, it is almost impossible to find the precise form by hand, because of that matrix exponential. However, using Matlab, one gets a rapid answer:
syms L H t
D0 = [-L , L , 0 , 0 , 0 , 0 , 0 , 0 ;
0 , -L , L , 0 , 0 , 0 , 0 , 0 ;
0 , 0 , -H , H , 0 , 0 , 0 , 0 ;
0 , 0 , 0 , -L , L , 0 , 0 , 0 ;
0 , 0 , 0 , 0 , -L , L , 0 , 0 ;
0 , 0 , 0 , 0 , 0 , -H , H , 0 ;
0 , 0 , 0 , 0 , 0 , 0 , -L , L ;
0 , 0 , 0 , 0 , 0 , 0 , 0 , -L ];
PI = [1, 0, 0, 0, 0, 0, 0, 0];
TAU = ones(8, 1);
DISTR = symfun(1-PI*expm(D0*x)*TAU, [L H t]);
PDF = symfun(diff(DISTR, x), [L H t]);
Here L and H are meant to be two parameters of the subjacent exponentially distributed holding times, and t is the time. My question is, how much can I trust DISTR and PDF? Is Matlab doing this computation exactly or is it a numerical approximation? The output seems certainly analytical (although very messy). For specific L=1 and H=2, you could simply do
PDF(1, 2, x)
to get the associated distribution, with the coefficient being in fractional form. For instance, the above gives
12*exp(-x) - 13*exp(-2*x) - 12*x*exp(-x) - 2*x*exp(-2*x) + 4*x^2*exp(-x) - (4*x^3*exp(-x))/3 + (x^4*exp(-x))/6 - (x^5*exp(-x))/30 + 1
Which seems to be in "exact" form, and does not look like an approximation... Moreover, numerical simulation shows that this formula is at least approximately correct.
Thanks in advance!
S

Related

Combinations of zeros and ones of vector size n [duplicate]

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

How to find the Inverse Kron?

If I know that K = kron ( A , B ),where kron is the Kronecker product of matrices as defined in MATLAB, how can I find A and B from a given matrix K?
for example suppose that
K = [1 0 0 0 ;0 1 0 0 ; 0 1 0 0 ;0 1 0 0 ;1 0 0 0 ;0 1 0 0 ;0 1 0 0 ;0 1 0 0 ;1 0 0 0 ;0 1 0 0 ;0 1 0 0 ;0 1 0 0 ;0 0 1 0 ;0 0 0 1 ;0 0 0 1 ;0 0 0 1 ]
is there any way to find A and B, such that K = kron ( A , B )?
In this case, A and B are as follows:
A = [ 1 0 ; 1 0 ; 1 0 ; 0 1 ]
B = [ 1 0 ; 0 1 ; 0 1 ; 0 1 ]
Short Discussion and Solution Code
You can't find both A and B, given a K, because there could be many possible A's and B's to produce a certain kron matrix, K. Thus, alongwith K, you need either A or B to get the remaining input B or A respectively.
Case #1 Given A and K (kron matrix), you can find B with -
B = K(1:size(K,1)/size(A,1),1:size(K,2)/size(A,2))./A(1)
Case #2 Given B and K (kron matrix), you can find A with -
A = K(1:size(B,1):end,1:size(B,2):end)./B(1)
Thus, if not the entire other input, you would at least need to know the size of it and one of the elements of it, preferably the first element.
Function Code
You can very easily convert that to a function code for an easy plug-n-play usage -
%// INVERSE_KRON Inverse of Kronecker tensor product to find one of the inputs.
% // INVERSE_KRON(K,ARRAY,INPUT_ID) finds one of the inputs used for calculating the
% // Kronecker tensor product given the other input and the ID of that other input.
% // Thus, if K was obtained with K = KRON(A,B), one must use -
% // A = INVERSE_KRON(K,B,2) to find A, and
% // B = INVERSE_KRON(K,A,1) to find B.
function out = inverse_kron(K,array,input_id)
switch input_id
case 1
out = K(1:size(K,1)/size(array,1),1:size(K,2)/size(array,2))./array(1);
case 2
out = K(1:size(array,1):end,1:size(array,2):end)./array(1);
otherwise
error('The Input ID must be either 1 or 2')
end
return;
Typical use case would look like this -
K = kron(A,B); %// Get kron product
A = inverse_kron(K,B,2) %// Recover A
B = inverse_kron(K,A,1) %// Recover B
Note: For a vector case, one other related question and answer could be found here.

Cross-Correlation of two signals

I want to find the correlation between two signals x1 and x2.
x1 = [1 1 1 1 1]
x2 = [1 1 1 1 1]
r1 = xcorr(x1,x2) //function in matlab to find cross correlation of x1 and x2
x1 and x2 both look like this
and their cross correlation look like this
I understand that correlation measures the degree of similarity between two signals, giving highest value to the point which corresponds to maximum similarity (the two signals are shifted relative to each other to measure similarity at different points right?). So in that case, the cross correlation should give a high value at all points but this is not so. The maximum value is at 5th position. Why is that? Can someone explain this to me?
You seem to have a slight misunderstanding of how cross-correlation works. Cross-correlation takes one signal, and compares it with shifted versions of another signal. If you recall, the (unnormalized) cross-correlation of two signals is defined as:
(source: jiracek at www-rohan.sdsu.edu)
s and h are two signals. Therefore, we shift versions of the second signal h and take element by element products and sum them all together. The horizontal axis of the cross-correlation plot denote shifts, while the vertical axis denotes the output of the cross-correlation at each shift. Let's compute the cross-correlation by hand for the signal so we can better understand the output that MATLAB is giving us.
To compute the outputs, both signals need to be zero-padded in order to accommodate for the first point when both signals start to overlap. Specifically, we need to zero-pad so that we have N2-1 zeroes to the left of s and N2-1 zeroes to the right of s in order to facilitate our computation of the cross correlation. N2 in this case is the length of h. For each time you calculate the cross correlation given a shift of the signal h, you would create a signal of all zero that is the same size as the zero-padded version of s, then place the original signal h within this larger signal. You would use this new signal to compare with the zero-padded version of s.
Actually, a property of cross-correlation is that it's commutative. If you had one signal that was longer, and a signal that was shorter, it would be easier for you to leave the long signal stationary, while you shifted the shorter one. Bear in mind that you'll certainly get the same results no matter which one you choose the shift, but you should always choose the easier path!
Back to where we were, this is what the first value of the cross correlation looks like (shift = 1).
s = [0 0 0 0 1 1 1 1 1 0 0 0 0]
h = [1 1 1 1 1 0 0 0 0 0 0 0 0]
The second signal slides from left to right, and we start where the right end of h begins to overlap the first signal, which is s. We do a point-by-point multiplication between s and h, and we sum up the elements. In this case, we get:
s ** h = (0)(1) + (0)(1) + (0)(1) + (0)(1) + (1)(1) + (0)(1) + (0)(1) + (0)(1) + (0)(1)
= 1
The ** in this case is (my version of) the cross-correlation operator. Let's look at shift = 2:
s = [0 0 0 0 1 1 1 1 1 0 0 0 0]
h = [0 1 1 1 1 1 0 0 0 0 0 0 0]
Remember, we are shifting towards the right by 1 more and s stays the same. Doing the same calculations as above, we should get:
s ** h = (0)(1) + (0)(1) + (0)(1) + (0)(1) + (1)(1) + (1)(1) + (0)(1) + (0)(1) + (0)(1)
= 2
If you repeat this for the other shifts, you'll see that the values keep increasing by 1, up until we have total overlap, which is the fifth shift (shift = 5). In this case, we get:
s = [0 0 0 0 1 1 1 1 1 0 0 0 0]
h = [0 0 0 0 1 1 1 1 1 0 0 0 0]
When you compute the cross-correlation, we get 5. Now, when we compute the sixth shift (shift = 6), we move to the right by 1, and that's when the cross-correlation starts to drop. Specifically:
s = [0 0 0 0 1 1 1 1 1 0 0 0 0]
h = [0 0 0 0 0 1 1 1 1 1 0 0 0]
If you go ahead and compute the cross-correlation, you'll see that the result is 4. You keep shifting to the right, and you'll see that the values keep decreasing by 1 per shift we take. You get to the final point where there is only one point where both s and h overlap, which is here:
s = [0 0 0 0 1 1 1 1 1 0 0 0 0]
h = [0 0 0 0 0 0 0 0 1 1 1 1 1]
By computing the cross-correlation, we only get the value of 1. You'll also see that this is at shift = 9. Therefore, this explains your graph where the cross-correlation starts to increase, because there is an increasing amount of overlap. It then reaches the maximum at shift = 5 because there is total overlap of the two signals. The cross-correlation then starts to decrease because the amount of overlap is also starting to decrease.
You'll also notice that the total number of shifts that we need to compute is N1 + N2 - 1, and this is a property of cross correlation. N1 and N2 are the lengths of s and h respectively. As such, given that N1 = N2 = 5, we see that the total number of shifts is N1 + N2 - 1 = 9, which also corresponds to the last shift we computed above.
Hope this helps!

Convert a column vector with values in {1,...,K} to a K-column matrix with a 1 in the appropriate column

Say I have a vector y like
2
4
3
10
and I want to obtain a matrix like
0 1 0 0 0 0 0 0 0 0
0 0 0 1 0 0 0 0 0 0
0 0 1 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 1
What's the simplest/cleanest/"best" way of doing this in octave/matlab? I came up with:
repmat(y, 1, 10) == repmat(1:10, 4, 1)
Anyone have a better approach than this? It makes sense to me after having thought about it but I feel like it's a bit hard to parse for someone reading the code (though idk, I'm relatively new to vectorization, and a lot of vectorized code feels like that to me).
If you want your result to be sparse you can simply
n = numel( y ); % number of rows in resulting matrix
k = max(y(:)); % if you do not know k (num of columns) in advance
U = sparse( 1:n, y, 1, n, k );
If you want your result to be a full matrix
U = zeros( n, k );
U( sub2ind([n k], 1:n, y ) ) = 1;

Count the occurrence of consecutive 1s in 0-1 data in MATLAB

I have a set of 1s and 0s. How do I count the maximum number of consecutive 1s?
(For example, x = [ 1 1 0 0 1 1 0 0 0 1 0 0 1 1 1 ....]). Here the answer is 3 because the maximum number of times 1 occurs consecutively is 3.
I was looking at some search and count inbuilt function, however I have not been successful.
Try this:
max( diff( [0 (find( ~ (x > 0) ) ) numel(x) + 1] ) - 1)
Here's a solution but it might be overkill:
L = bwlabel(x);
L(L==0) = [];
[~,n] = mode(L)
Sometimes it's better to write your own function with loops ; most of the time it's cleaner and faster.
Another possibility:
x = randi([0 1], [1 100]); %# random 0/1 vector
d = diff([0 x 0]);
maxOccurence = max( find(d<0)-find(d>0) )
which is inspired by an answer to a somewhat similar question...
Cody Problem 15 is find maximum consecutive ones in a 'binary' string.
This works quite nicely. As you can tell I'm quite pleased with it!
Cody size 19
max(cellfun(#numel,strsplit(x,'0')));