Mercurial > forge
view main/queueing/inst/ctmc_exps.m @ 9621:bd7fb43a670e octave-forge
Bug fix and enhancements in ctmc_exps()
author | mmarzolla |
---|---|
date | Sat, 10 Mar 2012 16:00:45 +0000 |
parents | ea88fce5f7ff |
children | cdf1dbf20cd4 |
line wrap: on
line source
## Copyright (C) 2008, 2009, 2010, 2011, 2012 Moreno Marzolla ## ## This file is part of the queueing toolbox. ## ## The queueing toolbox is free software: you can redistribute it and/or ## modify it under the terms of the GNU General Public License as ## published by the Free Software Foundation, either version 3 of the ## License, or (at your option) any later version. ## ## The queueing toolbox is distributed in the hope that it will be ## useful, but WITHOUT ANY WARRANTY; without even the implied warranty ## of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ## General Public License for more details. ## ## You should have received a copy of the GNU General Public License ## along with the queueing toolbox. If not, see <http://www.gnu.org/licenses/>. ## -*- texinfo -*- ## ## @deftypefn {Function File} {@var{L} =} ctmc_exps (@var{Q}, @var{tt}, @var{p} ) ## @deftypefnx {Function File} {@var{L} =} ctmc_exps (@var{Q}, @var{p}) ## ## @cindex Markov chain, continuous time ## @cindex Expected sojourn time ## ## With three arguments, compute the expected time @code{@var{L}(t,j)} ## spent in each state @math{j} during the time interval ## @code{[0,@var{tt}(t))}, assuming that at time 0 the state occupancy ## probability was @var{p}. With two arguments, compute the expected ## time @code{@var{L}(j}} spent in each state @math{j} until absorption. ## ## @strong{INPUTS} ## ## @table @var ## ## @item Q ## @math{N \times N} infinitesimal generator matrix. @code{@var{Q}(i,j)} ## is the transition rate from state @math{i} to state @math{j}, @math{1 ## @leq{} i \neq j @leq{} N}. The matrix @var{Q} must also satisfy the ## condition @math{\sum_{j=1}^N Q_{ij} = 0}. ## ## @item tt ## This parameter is a vector used for numerical integration. The first ## element @code{@var{tt}(1)} must be 0, and the last element ## @code{@var{tt}(end)} must be the upper bound of the interval ## @math{[0,t)} of interest (@code{@var{tt}(end) == @math{t}}). ## ## @item p ## Initial occupancy probability vector; @code{@var{p}(i)} is the ## probability the system is in state @math{i} at time 0, @math{i = 1, ## @dots{}, N} ## ## @end table ## ## @strong{OUTPUTS} ## ## @table @var ## ## @item L ## If this function is called with three arguments, @var{L} is a matrix ## of size @code{[length(@var{tt}), N]} where @code{@var{L}(t,j)} is the ## expected time spent in state @math{j} during the interval ## @code{[0,@var{tt}(t)]}. If this function is called with two ## arguments, @var{L} is a vector with @math{N} elements where ## @code{@var{L}(j)} is the expected time spent in state @math{j} until ## absorption, if @math{j} is a transient state. If @math{j} ## is an absorbing state, @code{@var{L}(j) = 0}. ## ## @end table ## ## @end deftypefn ## Author: Moreno Marzolla <marzolla(at)cs.unibo.it> ## Web: http://www.moreno.marzolla.name/ function L = ctmc_exps( Q, varargin ) persistent epsilon = 10*eps; if ( nargin < 2 || nargin > 3 ) print_usage(); endif issquare(Q) || \ usage( "Q must be a square matrix" ); ( norm( sum(Q,2), "inf" ) < epsilon ) || \ error( "Q is not an infinitesimal generator matrix" ); if ( nargin == 2 ) p = varargin{1}; else tt = varargin{1}; p = varargin{2}; endif ( isvector(p) && length(p) == size(Q,1) && all(p>=0) && abs(sum(p)-1.0)<epsilon ) || \ usage( "p must be a probability vector" ); if ( nargin == 3 ) ( isvector(tt) && abs(tt(1)) < epsilon ) || \ usage( "tt must be a vector, and tt(1) must be 0.0" ); tt = tt(:)'; # make tt a row vector p = p(:)'; # make p a row vector ff = @(x,t) (x(:)'*Q+p); fj = @(x,t) (Q); L = lsode( {ff, fj}, zeros(size(p)), tt ); else #{ ## F(t) are the transient state occupancy probabilities at time t. ## It is known that F(t) = p*expm(Q*t) (see function ctmc()). ## The expected times spent in each state until absorption can ## be computed as the integral of F(t) from t=0 to t=inf F = @(t) (p*expm(Q*t)); ## FIXME: this must be restricted to transient states ONLY!!!! ## Since function quadv does not support infinite integration ## limits, we define a new function G(u) = F(tan(pi/2*u)) such that ## the integral of G(u) on [0,1] is the integral of F(t) on [0, ## +inf]. G = @(u) (F(tan(pi/2*u))*pi/2*(1+tan(pi/2*u)**2)); L = quadv(G,0,1); #} ## Find nonzero rows. Nonzero rows correspond to transient states, ## while zero rows are absorbing states. If there are no zero rows, ## then the Markov chain does not contain absorbing states and we ## raise an error N = rows(Q); nzrows = find( any( abs(Q) > epsilon, 2 ) ); if ( length( nzrows ) == N ) error( "There are no absorbing states" ); endif QN = Q(nzrows,nzrows); pN = p(nzrows); LN = -pN*inv(QN); L = zeros(1,N); L(nzrows) = LN; endif endfunction %!demo %! lambda = 0.5; %! N = 4; %! birth = lambda*linspace(1,N-1,N-1); %! death = zeros(1,N-1); %! Q = diag(birth,1)+diag(death,-1); %! Q -= diag(sum(Q,2)); %! tt = linspace(0,10,100); %! p0 = zeros(1,N); p0(1)=1; %! L = ctmc_exps(Q,tt,p0); %! #L2 = 0*L; %! #for i=1:length(tt) %! # L2(i,:) = quadv( @(t) (p0*expm(Q*t)) , 0, tt(i) ); %! #endfor %! plot( tt, L(:,1), ";State 1;", "linewidth", 2, \ %! # tt, L2(:,1), "+;State 1 (quadv);", "markersize", 8, \ %! tt, L(:,2), ";State 2;", "linewidth", 2, \ %! tt, L(:,3), ";State 3;", "linewidth", 2, \ %! tt, L(:,4), ";State 4 (absorbing);", "linewidth", 2); %! legend("location","northwest"); %! xlabel("Time"); %! ylabel("Expected sojourn time"); %!demo %! lambda = 0.5; %! N = 4; %! birth = lambda*linspace(1,N-1,N-1); %! death = 0*birth; %! Q = diag(birth,1)+diag(death,-1); %! Q -= diag(sum(Q,2)); %! p0 = zeros(1,N); p0(1)=1; %! L = ctmc_exps(Q,p0)