LINE Solver
MATLAB API documentation
Loading...
Searching...
No Matches
ctmc_transient.m
1%{ @file ctmc_transient.m
2 % @brief Transient analysis of a continuous-time Markov chain using ODE solvers
3 %
4 % @author LINE Development Team
5%}
6
7%{
8 % @brief Transient analysis of a continuous-time Markov chain using ODE solvers
9 %
10 % @details
11 % Computes the transient state probabilities using ODE solvers.
12 %
13 % @par Syntax:
14 % @code
15 % [pi, t] = ctmc_transient(Q, pi0)
16 % [pi, t] = ctmc_transient(Q, pi0, t0, t1)
17 % [pi, t] = ctmc_transient(Q, pi0, t0, t1, useStiff, reltol, timestep)
18 % @endcode
19 %
20 % @par Parameters:
21 % <table>
22 % <tr><th>Name<th>Description
23 % <tr><td>Q<td>Infinitesimal generator matrix
24 % <tr><td>pi0<td>Initial probability distribution vector
25 % <tr><td>t0<td>(Optional) Start time
26 % <tr><td>t1<td>(Optional) End time
27 % <tr><td>useStiff<td>(Optional) Boolean to use stiff ODE solver (ode15s) instead of ode23. Default: false
28 % <tr><td>reltol<td>(Optional) Relative tolerance for the ODE solver. Default: 1e-3
29 % <tr><td>timestep<td>(Optional) Fixed time step for the output
30 % </table>
31 %
32 % @par Returns:
33 % <table>
34 % <tr><th>Name<th>Description
35 % <tr><td>pi<td>State probability vectors at each time point
36 % <tr><td>t<td>Time points corresponding to the probabilities
37 % </table>
38%}
39function [pi,t]=ctmc_transient(Q,pi0,t0,t1,useStiff,reltol,timestep)
40if ~exist('useStiff','var')
41 useStiff = false;
42end
43if ~exist('reltol','var')
44 reltol = 1e-3;
45end
46if ~exist('timestep','var')
47 timestep = [];
48end
49if nargin==2
50 t1=pi0;
51 t0=0;
52 pi0=ones(1,length(Q));pi0=pi0/sum(pi0);
53end
54if nargin==3
55 t1=t0;
56 t0=0;
57end
58
59odeoptions = odeset('RelTol', reltol);
60
61% Use fixed intervals if timestep parameter is specified
62if ~isempty(timestep) && timestep > 0
63 t = t0:timestep:t1;
64 if t(end) ~= t1
65 t = [t, t1]; % Ensure t1 is included
66 end
67 if useStiff
68 [t,pi]=ode15s(@ctmc_transientode, t, pi0, odeoptions);
69 else
70 [t,pi]=ode23(@ctmc_transientode, t, pi0, odeoptions);
71 end
72else
73 % Original adaptive stepping behavior
74 if isinf(t1)
75 nonZeroRates = abs(Q(Q~=0));
76 nonZeroRates = nonZeroRates( nonZeroRates >0 );
77 T = abs(100/min(nonZeroRates)); % solve ode until T = 100 events with the slowest rate
78 if useStiff
79 [t,pi]=ode15s(@ctmc_transientode, [t0,T], pi0, odeoptions);
80 else
81 [t,pi]=ode23(@ctmc_transientode, [t0,T], pi0, odeoptions);
82 end
83 else
84 if useStiff
85 [t,pi]=ode15s(@ctmc_transientode, [t0,t1], pi0, odeoptions);
86 else
87 [t,pi]=ode23(@ctmc_transientode, [t0,t1], pi0, odeoptions);
88 end
89 end
90end
91%[t,pi]=ode113(@ctmc_transientode,[t0,t1],pi0);
92
93function dpidt=ctmc_transientode(t,pi)
94pi=pi(:)';
95dpidt=pi*Q;
96dpidt=dpidt(:);
97end
98
99end