45void set_block(Matrix<T>& dst, std::size_t br, std::size_t bc,
const Matrix<T>& src) {
55 const std::size_t na = A.
D0.rows(), nb = B.
D0.rows();
57 std::vector<T> a(na, zero), b(nb, zero);
58 for (std::size_t i = 0; i < na; ++i)
59 for (std::size_t j = 0; j < na; ++j) a[i] -= A.
D0(i, j);
60 for (std::size_t i = 0; i < nb; ++i)
61 for (std::size_t j = 0; j < nb; ++j) b[i] -= B.
D0(i, j);
62 const std::size_t nab = na * nb, N = nab + nb + na;
65 detail::set_block(M0, 0, 0, S);
67 for (std::size_t i = 0; i < na; ++i)
68 for (std::size_t j = 0; j < nb; ++j) M0(i * nb + j, nab + j) = a[i];
69 for (std::size_t i = 0; i < na; ++i)
70 for (std::size_t j = 0; j < nb; ++j) M0(i * nb + j, nab + nb + i) = b[j];
71 detail::set_block(M0, nab, nab, B.
D0);
72 detail::set_block(M0, nab + nb, nab + nb, A.
D0);
74 std::vector<T> pie(N, zero);
75 for (std::size_t i = 0; i < na; ++i)
76 for (std::size_t j = 0; j < nb; ++j) pie[i * nb + j] = pa[i] * pb[j];
77 std::vector<T> d(N, zero);
78 for (std::size_t j = 0; j < nb; ++j) d[nab + j] = b[j];
79 for (std::size_t i = 0; i < na; ++i) d[nab + nb + i] = a[i];
81 for (std::size_t i = 0; i < N; ++i)
82 for (std::size_t j = 0; j < N; ++j) M1(i, j) = d[i] * pie[j];
89 if (k == 0)
throw InputError(
"mmap_max: k must be positive");
91 throw InputError(
"mmap_max: the two MMAPs must carry the same number of classes");
92 const std::size_t na = a.
order(), nb = b.
order(), n = na * nb;
93 const std::size_t nblk = 1 + 2 *
static_cast<std::size_t
>(k);
94 const std::size_t N = n * nblk;
103 detail::set_block(M0, 0, 0, A0B0);
104 detail::set_block(M0, 0, n, A1IB);
105 detail::set_block(M0, 0, 2 * n, IAB1);
106 for (std::size_t bi = 1; bi + 2 <= nblk - 1; ++bi)
107 detail::set_block(M0, bi * n, bi * n, A0B0);
108 detail::set_block(M0, (nblk - 2) * n, (nblk - 2) * n, IAB0);
109 detail::set_block(M0, (nblk - 1) * n, (nblk - 1) * n, A0IB);
110 for (
unsigned i = 2; i <= k; ++i) {
111 const std::size_t r = (1 + 2 * (i - 2)) * n, c = (3 + 2 * (i - 2)) * n;
112 detail::set_block(M0, r, c, A1IB);
113 detail::set_block(M0, r + n, c + n, IAB1);
118 detail::set_block(out.
D1, n, 0, IAB1);
119 detail::set_block(out.
D1, 2 * n, 0, A1IB);
120 for (
unsigned i = 2; i <= k; ++i) {
121 const std::size_t r = (1 + 2 * (i - 1)) * n, c = (1 + 2 * (i - 2)) * n;
122 detail::set_block(out.
D1, r, c, IAB1);
123 detail::set_block(out.
D1, r + n, c + n, A1IB);
125 for (std::size_t cls = 0; cls < a.
classes(); ++cls) {
129 detail::set_block(Mc, n, 0, IABc);
130 detail::set_block(Mc, 2 * n, 0, AcIB);
131 for (
unsigned i = 2; i <= k; ++i) {
132 const std::size_t r = (1 + 2 * (i - 1)) * n, c = (1 + 2 * (i - 2)) * n;
133 detail::set_block(Mc, r, c, IABc);
134 detail::set_block(Mc, r + n, c + n, AcIB);
136 out.
Dc.push_back(Mc);
Dense linear algebra over the templated number type: products, identity, inverse, and powers.
Mmap< T > mmap_max(const Mmap< T > &a, const Mmap< T > &b, unsigned k)
MMAP of the maximum over k synchronization rounds of two independent MMAPs.
Matrix< T > krons(const Matrix< T > &A, const Matrix< T > &B)
Kronecker sum, MATLAB's krons: kron(A, I_nb) + kron(I_na, B).