142 env.reject_lqn_stages(
"SolverENV.getGenerator",
143 "the joint generator is assembled from CTMC stage generators");
144 const std::size_t E =
env.nstages();
147 std::vector<std::size_t> nstates(E);
148 for (std::size_t e = 0; e < E; ++e) {
151 nstates[e] = g.
stage_Q[e].rows();
154 std::vector<std::vector<std::size_t>> nph(E, std::vector<std::size_t>(E, 1));
155 for (std::size_t i = 0; i < E; ++i)
156 for (std::size_t j = 0; j < E; ++j)
157 if (i != j &&
env.arc(i, j).enabled) nph[i][j] =
env.arc(i, j).dist.phases();
159 std::vector<std::vector<Matrix<T>>> B(E, std::vector<
Matrix<T>>(E));
160 for (std::size_t e = 0; e < E; ++e)
161 for (std::size_t h = 0; h < E; ++h) {
166 B[e][h] =
Matrix<T>(nstates[e], nstates[h], zero);
167 for (std::size_t i = 0; i < std::min(nstates[e], nstates[h]); ++i) B[e][h](i, i) = one;
170 for (std::size_t e = 0; e < E; ++e)
171 for (std::size_t h = 0; h < E; ++h) {
172 if (h == e)
continue;
174 arc_process(
env, e, h, D0, D1);
175 B[e][e] = krons(B[e][e], D0);
179 for (std::size_t i = 0; i < D1.
rows(); ++i) {
181 for (std::size_t j = 0; j < D1.
cols(); ++j) s += D1(i, j);
182 for (std::size_t j = 0; j < pie.
cols(); ++j) arg(i, j) = T(s * pie(0, j));
184 B[e][h] = kron(B[e][h], arg);
185 const std::size_t nodes =
env.stage(e).model.nodes.size();
187 for (std::size_t f = 0; f < E; ++f) {
188 if (f == h || f == e)
continue;
191 for (std::size_t i = 0; i < ones_pie.
rows(); ++i)
192 for (std::size_t j = 0; j < pfh.
cols(); ++j) ones_pie(i, j) = pfh(0, j);
193 B[e][f] = kron(B[e][f], ones_pie);
198 std::vector<std::size_t> roff(E + 1, 0), coff(E + 1, 0);
199 for (std::size_t e = 0; e < E; ++e) {
200 roff[e + 1] = roff[e] + B[e][e].rows();
201 coff[e + 1] = coff[e] + B[e][e].cols();
203 for (std::size_t e = 0; e < E; ++e)
204 for (std::size_t h = 0; h < E; ++h)
205 if (B[e][h].rows() != B[e][e].rows() || B[e][h].cols() != B[h][h].cols())
206 throw InputError(
"SolverENV.getGenerator: block (" + std::to_string(e + 1) +
"," +
207 std::to_string(h + 1) +
208 ") does not conform to the diagonal blocks (cell2mat)");
209 auto flatten = [&](
const std::vector<std::vector<Matrix<T>>>& C) {
211 for (std::size_t e = 0; e < E; ++e)
212 for (std::size_t h = 0; h < E; ++h)
213 for (std::size_t i = 0; i < C[e][h].rows(); ++i)
214 for (std::size_t j = 0; j < C[e][h].cols(); ++j)
215 M(roff[e] + i, coff[h] + j) = C[e][h](i, j);
221 for (std::size_t e = 0; e < E; ++e)
222 for (std::size_t h = 0; h < E; ++h) {
223 std::vector<std::vector<Matrix<T>>> C(E, std::vector<
Matrix<T>>(E));
224 for (std::size_t a = 0; a < E; ++a)
225 for (std::size_t b = 0; b < E; ++b)
226 C[a][b] = (a != b && a == e && b == h)
228 :
Matrix<T>(B[a][b].rows(), B[a][b].cols(), zero);
229 g.
filt[e][h] = flatten(C);