92 const std::size_t n1 = d1.
order(), n2 = d2.
order();
93 if (d1.
S.rows() != n1 || d1.
S.cols() != n1 || d2.
S.rows() != n2 || d2.
S.cols() != n2)
94 throw InputError(
"aph_simplify: an (alpha, S) pair has mismatched dimensions");
101 const T atom1 = detail::aph_zero_atom(d1.
alpha);
102 const std::vector<T> exit1 = detail::aph_exit_rates(d1.
S);
103 out.
alpha.assign(n1 + n2, zero);
104 for (std::size_t i = 0; i < n1; ++i) out.
alpha[i] = d1.
alpha[i];
105 for (std::size_t j = 0; j < n2; ++j) out.
alpha[n1 + j] = T(atom1 * d2.
alpha[j]);
107 for (std::size_t i = 0; i < n1; ++i) {
108 for (std::size_t j = 0; j < n1; ++j) out.
S(i, j) = d1.
S(i, j);
109 for (std::size_t j = 0; j < n2; ++j)
110 out.
S(i, n1 + j) = T(exit1[i] * d2.
alpha[j]);
112 for (std::size_t i = 0; i < n2; ++i)
113 for (std::size_t j = 0; j < n2; ++j) out.
S(n1 + i, n1 + j) = d2.
S(i, j);
119 const T atom1 = detail::aph_zero_atom(d1.
alpha);
120 const T atom2 = detail::aph_zero_atom(d2.
alpha);
121 const std::vector<T> exit1 = detail::aph_exit_rates(d1.
S);
122 const std::vector<T> exit2 = detail::aph_exit_rates(d2.
S);
123 const std::size_t np = n1 * n2, n = np + n1 + n2;
124 out.
alpha.assign(n, zero);
125 for (std::size_t i = 0; i < n1; ++i)
126 for (std::size_t j = 0; j < n2; ++j) out.
alpha[i * n2 + j] = T(d1.
alpha[i] * d2.
alpha[j]);
127 for (std::size_t i = 0; i < n1; ++i) out.
alpha[np + i] = T(atom2 * d1.
alpha[i]);
128 for (std::size_t j = 0; j < n2; ++j) out.
alpha[np + n1 + j] = T(atom1 * d2.
alpha[j]);
131 for (std::size_t i = 0; i < n1; ++i)
132 for (std::size_t j = 0; j < n2; ++j) {
133 const std::size_t r = i * n2 + j;
134 for (std::size_t k = 0; k < n1; ++k) out.
S(r, k * n2 + j) += d1.
S(i, k);
135 for (std::size_t k = 0; k < n2; ++k) out.
S(r, i * n2 + k) += d2.
S(j, k);
137 out.
S(r, np + i) = exit2[j];
139 out.
S(r, np + n1 + j) = exit1[i];
141 for (std::size_t i = 0; i < n1; ++i)
142 for (std::size_t j = 0; j < n1; ++j) out.
S(np + i, np + j) = d1.
S(i, j);
143 for (std::size_t i = 0; i < n2; ++i)
144 for (std::size_t j = 0; j < n2; ++j)
145 out.
S(np + n1 + i, np + n1 + j) = d2.
S(i, j);
149 out.
alpha.assign(n1 + n2, zero);
150 for (std::size_t i = 0; i < n1; ++i) out.
alpha[i] = T(p1 * d1.
alpha[i]);
151 for (std::size_t j = 0; j < n2; ++j) out.
alpha[n1 + j] = T(p2 * d2.
alpha[j]);
153 for (std::size_t i = 0; i < n1; ++i)
154 for (std::size_t j = 0; j < n1; ++j) out.
S(i, j) = d1.
S(i, j);
155 for (std::size_t i = 0; i < n2; ++i)
156 for (std::size_t j = 0; j < n2; ++j) out.
S(n1 + i, n1 + j) = d2.
S(i, j);
166 "aph_simplify: the loop pattern is not implemented in the reference either "
167 "(aph_simplify.m leaves its fourth arm commented out)");
AphPair< T > aph_simplify(const AphPair< T > &d1, const AphPair< T > &d2, const T &p1, const T &p2, AphPattern pattern)
Compose two matrix-exponential laws, as aph_simplify.m does.