LINE Solver
MATLAB API documentation
Loading...
Searching...
No Matches
QInPow.m
1classdef QInPow
2 properties
3 matrices = {}
4 power = 0
5 process
6 end
7
8 methods
9 function obj = QInPow(proc)
10 if nargin == 0
11 return;
12 end
13
14 obj.process = proc;
15 obj.power = 1;
16 a0 = proc.all_A_0();
17 ap = proc.all_A_plus();
18 am = proc.all_A_minus();
19 if isempty(a0) || isempty(ap) || isempty(am)
20 return;
21 end
22
23 obj.matrices = cell(1, max([numel(am) + 1, numel(a0), numel(ap)]));
24 obj.matrices{1} = {a0{1}, ap{1}};
25
26 im = 1;
27 i0 = 2;
28 ip = 2;
29 for k = 2:numel(obj.matrices)
30 obj.matrices{k} = {am{im}, a0{i0}, ap{ip}};
31 im = min(im + 1, numel(am));
32 i0 = min(i0 + 1, numel(a0));
33 ip = min(ip + 1, numel(ap));
34 end
35 end
36
37 function check(obj)
38 if isempty(obj.process) || isempty(obj.process.all_A_0())
39 libqbd.raise_error('Infinitesimal generator matrix is empty.');
40 end
41 end
42
43 function ret = inc_power(obj, step)
44 ret = libqbd.QInPow();
45 ret.power = obj.power + 1;
46 ret.process = obj.process;
47 ret.matrices = cell(1, numel(obj.matrices) + 1);
48
49 for k0 = (obj.power + 1):(numel(ret.matrices) - 1)
50 true_k0 = min(k0, numel(obj.matrices) - 1);
51 ret.matrices{k0 + 1} = {obj.matrices{true_k0 + 1}{1} * obj.process.get_A_minus(k0 - obj.power) * step};
52 end
53
54 for k0 = 0:(numel(ret.matrices) - 1)
55 true_k0 = min(k0, numel(obj.matrices) - 1);
56 blocks = obj.matrices{true_k0 + 1};
57 if isempty(ret.matrices{k0 + 1})
58 ret.matrices{k0 + 1} = {};
59 end
60 for j0 = 0:(numel(blocks) - 1)
61 m = zeros(size(blocks{j0 + 1}));
62 if k0 >= obj.power
63 col = k0 + j0 - obj.power;
64 else
65 col = j0;
66 end
67
68 left = max(j0 - 1, 0);
69 right = min(j0 + 1, numel(blocks) - 1);
70 if col == 0
71 A = {obj.process.get_A_0(0), obj.process.get_A_minus(1)};
72 else
73 A = {obj.process.get_A_plus(col - 1), obj.process.get_A_0(col), obj.process.get_A_minus(col + 1)};
74 end
75
76 z_up = max(col - 1, 0);
77 z_left = max(k0 - obj.power, 0);
78 pos = 0;
79 if z_up < z_left && col ~= 0
80 pos = 1;
81 end
82
83 for i0 = left:right
84 m = m + blocks{i0 + 1} * A{pos + 1} * step;
85 pos = pos + 1;
86 end
87 ret.matrices{k0 + 1}{end + 1} = m;
88 end
89 end
90
91 for k0 = 0:(numel(ret.matrices) - 1)
92 true_k0 = min(k0, numel(obj.matrices) - 1);
93 ret.matrices{k0 + 1}{end + 1} = obj.matrices{true_k0 + 1}{end} * obj.process.get_A_plus(k0 + obj.power) * step;
94 end
95 end
96
97 function obj = mull_by_const(obj, cons)
98 for k = 1:numel(obj.matrices)
99 for j = 1:numel(obj.matrices{k})
100 obj.matrices{k}{j} = obj.matrices{k}{j} * cons;
101 end
102 end
103 end
104
105 function obj = add_identity_matrix(obj)
106 pos0 = 0;
107 for k0 = 0:(numel(obj.matrices) - 1)
108 m = obj.matrices{k0 + 1}{pos0 + 1};
109 obj.matrices{k0 + 1}{pos0 + 1} = m + eye(size(m));
110 if k0 < obj.power
111 pos0 = pos0 + 1;
112 end
113 end
114 end
115
116 function obj = plus_assign(obj, right)
117 if obj.power >= right.power
118 for k0 = 0:(numel(obj.matrices) - 1)
119 rk0 = min(k0, numel(right.matrices) - 1);
120 if k0 < (right.power + 1)
121 first = 0;
122 else
123 first = (numel(obj.matrices{k0 + 1}) - numel(right.matrices{rk0 + 1})) / 2;
124 end
125 for j0 = first:(first + numel(right.matrices{rk0 + 1}) - 1)
126 obj.matrices{k0 + 1}{j0 + 1} = obj.matrices{k0 + 1}{j0 + 1} + right.matrices{rk0 + 1}{j0 - first + 1};
127 end
128 end
129 else
130 tmp = obj;
131 obj = right;
132 obj = obj.plus_assign(tmp);
133 end
134 end
135
136 function ret = mull_by_vector(obj, pi)
137 ret = cell(1, numel(pi));
138 for k = 1:numel(pi)
139 ret{k} = zeros(1, numel(pi{k}));
140 end
141
142 c = 0;
143 for k = numel(pi):(min(numel(obj.matrices), numel(pi) + obj.power) - 1)
144 ret{end + 1} = zeros(1, size(obj.matrices{k + 1}{1}, 1));
145 c = c + 1;
146 end
147 for k = 1:(obj.power - c)
148 ret{end + 1} = zeros(1, size(obj.matrices{end}{1}, 1));
149 end
150
151 matrix_num = 0;
152 col_num = 0;
153 for k0 = 0:(numel(pi) - 1)
154 pi_k = libqbd.as_row_vector(pi{k0 + 1});
155 if k0 > obj.power
156 col_num = col_num + 1;
157 end
158 for j0 = 0:(numel(obj.matrices{matrix_num + 1}) - 1)
159 ret{col_num + j0 + 1} = ret{col_num + j0 + 1} + pi_k * obj.matrices{matrix_num + 1}{j0 + 1};
160 end
161 if (matrix_num + 1) < numel(obj.matrices)
162 matrix_num = matrix_num + 1;
163 end
164 end
165
166 while numel(ret) > 1 && max(ret{end}) <= 0.0
167 ret(end) = [];
168 end
169 end
170 end
171end