1% r = CheckMERepresentation(alpha, A, prec)
3% Checks
if the given vector and matrix define a valid matrix-
4% exponential representation.
8% alpha : matrix, shape (1,M)
9% Initial vector of
the matrix-exponential distribution
11% A : matrix, shape (M,M)
12% Matrix parameter of
the matrix-exponential distribution
14% prec : double, optional
15% Numerical precision. The
default value
is 1e-14.
20% True,
if the matrix
is a square matrix,
the vector and
21%
the matrix have
the same size,
the dominant eigenvalue
26% This procedure does not check
the positivity of
the density!
27% Call
'CheckMEPositiveDensity' if it
is needed, but keep in
28% mind that it can be time-consuming,
while this procedure
31function r = CheckMERepresentation (alpha, A, prec)
33 global BuToolsVerbose;
34 global BuToolsCheckPrecision;
35 if isempty(BuToolsCheckPrecision)
36 BuToolsCheckPrecision = 1e-14;
39 if ~exist(
'prec',
'var')
40 prec = BuToolsCheckPrecision;
43 if size(A,1)~=size(A,2)
45 fprintf ('CheckMERepresentation: The matrix
is not a square matrix!\n');
51 if length(alpha)~=size(A,1)
53 fprintf ('CheckMERepresentation: The vector and
the matrix have different sizes!\n');
59 if sum(alpha)<-prec*length(alpha) || sum(alpha)>1+prec*length(alpha)
61 fprintf ('CheckMERepresentation: The sum of
the vector elements
is less than zero or greater than one (precision: %g)!\n',prec);
67 if max(real(eig(A)))>=prec
69 fprintf ('CheckMERepresentation: There
is an eigenvalue of
the matrix with non-negative real part (at precision %g)!\n',prec);
76 [~,ix] = sort(abs(real(ev)));
79 % The dominant real part need not be attained by a single eigenvalue, and
80 %
the sort above breaks such a tie arbitrarily. A concentrated matrix
81 % exponential of order 2n+1 puts its whole spectrum on
the line
82 % Re = -mu1, so
the arbitrary pick returns a complex eigenvalue and
the
83 % test below rejects a valid ME even though
the real eigenvalue -mu1
is
84 % equally dominant. Among
the eigenvalues attaining
the dominant real
85 % part, prefer a real one: "
the dominant eigenvalue
is real"
is a
86 % statement about
the spectrum, not about which tied eigenvalue
the sort
87 % happened to return. This only widens
the accepted set, and only in
the
88 % tied case, which BuTools itself reports as a warning below rather than
89 % as a rejection. Matches native Python butools.ph.check and
90 % jline.lib.butools.ph.CheckMERepresentation.
91 domre = abs(real(maxev));
92 domtol = max(prec, 1e-8*domre);
93 tied = ev(abs(abs(real(ev)) - domre) <= domtol);
94 realtied = tied(abs(imag(tied)) <= domtol);
96 maxev = real(realtied(1));
99 % Value-based rather than isreal(maxev): eig returns a complex array as
100 % soon as one eigenvalue
is complex, so isreal()
is false for a real-valued
101 % entry of that array and
the dominant eigenvalue of any ME with an
102 % oscillating component would be declared non-real. jline.lib.butools
103 % CheckMERepresentation and native Python already test
the imaginary part.
104 if abs(imag(maxev)) > prec
106 fprintf ('CheckMERepresentation: The dominant eigenvalue of
the matrix
is not real!\n');
112 % Nested rather than a single && expression: BuToolsVerbose
is a global that
113 %
is [] until lineStart or BuToolsInit runs, and `scalar && []`
is a hard
114 % error in MATLAB. The left operand here
is true exactly when
the spectrum
115 % has a repeated dominant modulus, which
is the common case for an Erlang
116 % (ME.fromErlang(2,2) has eigenvalues -2,-2), so
the short circuit that hides
117 %
the problem for a generic ME does not fire and validity checking dies on a
118 % verbosity flag. `if []`
is simply false, so
the nested form
is safe
119 % whether or not
the global has been initialised.
120 if sum(abs(ev(1:end))==abs(maxev)) > 1
122 fprintf ('CheckMERepresentation warning: There are more than one eigenvalue with
the same absolute value as
the largest eigenvalue!\n');