#include <iostream>
#include <array>
template <size_t N, size_t M>
struct Matrix {
std::array<std::array<double, M>, N> data_;
std::array<double, M>& operator [] (size_t index) {
return data_[index];
}
std::array<double, M> operator [] (size_t index) const {
return const_cast<Matrix&>(*this)[index];
}
template <size_t I, size_t J, size_t K>
friend Matrix<I,K> operator* (const Matrix<I,J>&, const Matrix<J,K>&);
};
template <size_t Size>
struct Vector : public Matrix <1,Size> {
double& operator [] (size_t index) {
return Matrix<1,Size>::data_[0][index];
}
double operator [] (size_t index) const {
return const_cast<Vector&>(*this)[index];
}
};
template <size_t I, size_t J, size_t K>
Matrix<I,K> operator* (const Matrix<I,J>& lhs, const Matrix<J,K>& rhs) {
Matrix<I,K> r;
for (size_t i=0; i < I; ++i)
for (size_t k=0; k < K; ++k) {
r[i][k]=0;
for (size_t j=0; j < J; ++j)
r[i][k] += lhs[i][j]*rhs[j][k];
}
return r;
}
template <typename T, size_t N>
std::ostream& operator <<(std::ostream& os, const std::array<T,N>& a) {
os << '(';
size_t i=0;
for (auto x: a) {
if (i++ != 0) os << ',';
os << x;
}
os << ')';
return os;
}
template <size_t N, size_t M>
std::ostream& operator <<(std::ostream& os, const Matrix<N,M>& m) {
return os << m.data_;
}
int main() {
Vector<3> v;
v[0] = 1; v[1] = 2; v[2] = 3;
std::cout << "v=" << v << std::endl;
Matrix<3,2> m;
m[0][0]=1;m[0][1]=2;
m[1][0]=3;m[1][1]=4;
m[2][0]=5;m[2][1]=6;
std::cout << "m=" << m << std::endl;
Matrix<2,4> m1;
m1[0][0]=1;m1[0][1]=2;m1[0][2]=3;m1[0][3]=4;
m1[1][0]=5;m1[1][1]=6;m1[1][2]=7;m1[1][3]=8;
std::cout << "m1=" << m1 << std::endl;
std::cout << "m*m1=" << m*m1 << std::endl;
std::cout << "v*m=" << v*m << std::endl;
}
I2luY2x1ZGUgPGlvc3RyZWFtPgojaW5jbHVkZSA8YXJyYXk+Cgp0ZW1wbGF0ZSA8c2l6ZV90IE4sIHNpemVfdCBNPgpzdHJ1Y3QgTWF0cml4IHsKCSAgc3RkOjphcnJheTxzdGQ6OmFycmF5PGRvdWJsZSwgTT4sIE4+IGRhdGFfOwoJCgkgIHN0ZDo6YXJyYXk8ZG91YmxlLCBNPiYgb3BlcmF0b3IgW10gKHNpemVfdCBpbmRleCkgeyAKCSAgCXJldHVybiBkYXRhX1tpbmRleF07IAoJICB9CgkgIHN0ZDo6YXJyYXk8ZG91YmxlLCBNPiBvcGVyYXRvciBbXSAoc2l6ZV90IGluZGV4KSBjb25zdCB7IAoJICAJcmV0dXJuIGNvbnN0X2Nhc3Q8TWF0cml4Jj4oKnRoaXMpW2luZGV4XTsgCgkgIH0KCSAgCgkgIHRlbXBsYXRlIDxzaXplX3QgSSwgc2l6ZV90IEosIHNpemVfdCBLPgoJICBmcmllbmQgTWF0cml4PEksSz4gb3BlcmF0b3IqIChjb25zdCBNYXRyaXg8SSxKPiYsIGNvbnN0IE1hdHJpeDxKLEs+Jik7Cn07CQoKdGVtcGxhdGUgPHNpemVfdCBTaXplPgpzdHJ1Y3QgVmVjdG9yIDogcHVibGljIE1hdHJpeCA8MSxTaXplPiB7CgkgIGRvdWJsZSYgb3BlcmF0b3IgW10gKHNpemVfdCBpbmRleCkgeyAKCSAgCXJldHVybiBNYXRyaXg8MSxTaXplPjo6ZGF0YV9bMF1baW5kZXhdOyAKCSAgfQoJICBkb3VibGUgb3BlcmF0b3IgW10gKHNpemVfdCBpbmRleCkgY29uc3QgeyAKCSAgCXJldHVybiBjb25zdF9jYXN0PFZlY3RvciY+KCp0aGlzKVtpbmRleF07IAoJICB9Cn07Cgp0ZW1wbGF0ZSA8c2l6ZV90IEksIHNpemVfdCBKLCBzaXplX3QgSz4KTWF0cml4PEksSz4gb3BlcmF0b3IqIChjb25zdCBNYXRyaXg8SSxKPiYgbGhzLCBjb25zdCBNYXRyaXg8SixLPiYgcmhzKSB7CglNYXRyaXg8SSxLPiByOwoJZm9yIChzaXplX3QgaT0wOyBpIDwgSTsgKytpKQoJICAgZm9yIChzaXplX3Qgaz0wOyBrIDwgSzsgKytrKSB7CgkgIAlyW2ldW2tdPTA7CgkgICAgZm9yIChzaXplX3Qgaj0wOyBqIDwgSjsgKytqKQoJICAgICAgcltpXVtrXSArPSBsaHNbaV1bal0qcmhzW2pdW2tdOwoJICB9CgkgIAoJcmV0dXJuIHI7Cn0KCnRlbXBsYXRlIDx0eXBlbmFtZSBULCBzaXplX3QgTj4Kc3RkOjpvc3RyZWFtJiBvcGVyYXRvciA8PChzdGQ6Om9zdHJlYW0mIG9zLCBjb25zdCBzdGQ6OmFycmF5PFQsTj4mIGEpIHsKCW9zIDw8ICcoJzsKCXNpemVfdCBpPTA7Cglmb3IgKGF1dG8geDogYSkgewoJCWlmIChpKysgIT0gMCkgb3MgPDwgJywnOwoJCW9zIDw8IHg7Cgl9CglvcyA8PCAnKSc7CglyZXR1cm4gb3M7Cn0KCnRlbXBsYXRlIDxzaXplX3QgTiwgc2l6ZV90IE0+CnN0ZDo6b3N0cmVhbSYgb3BlcmF0b3IgPDwoc3RkOjpvc3RyZWFtJiBvcywgY29uc3QgTWF0cml4PE4sTT4mIG0pIHsKCXJldHVybiBvcyA8PCBtLmRhdGFfOwp9CgppbnQgbWFpbigpIHsKCVZlY3RvcjwzPiB2OwoJdlswXSA9IDE7IHZbMV0gPSAyOyB2WzJdID0gMzsKCXN0ZDo6Y291dCA8PCAidj0iIDw8IHYgPDwgc3RkOjplbmRsOwoJCglNYXRyaXg8MywyPiBtOwoJbVswXVswXT0xO21bMF1bMV09MjsKCW1bMV1bMF09MzttWzFdWzFdPTQ7CgltWzJdWzBdPTU7bVsyXVsxXT02OwoJc3RkOjpjb3V0IDw8ICJtPSIgPDwgbSA8PCBzdGQ6OmVuZGw7CgkKCU1hdHJpeDwyLDQ+IG0xOwoJbTFbMF1bMF09MTttMVswXVsxXT0yO20xWzBdWzJdPTM7bTFbMF1bM109NDsKCW0xWzFdWzBdPTU7bTFbMV1bMV09NjttMVsxXVsyXT03O20xWzFdWzNdPTg7CglzdGQ6OmNvdXQgPDwgIm0xPSIgPDwgbTEgPDwgc3RkOjplbmRsOwoKCXN0ZDo6Y291dCA8PCAibSptMT0iIDw8IG0qbTEgPDwgc3RkOjplbmRsOwoJc3RkOjpjb3V0IDw8ICJ2Km09IiA8PCB2Km0gPDwgc3RkOjplbmRsOwp9
v=((1,2,3))
m=((1,2),(3,4),(5,6))
m1=((1,2,3,4),(5,6,7,8))
m*m1=((11,14,17,20),(23,30,37,44),(35,46,57,68))
v*m=((22,28))