#include "nn/Matrix.hh" namespace qing { template Matrx::Matrx(): row(0), col(0) {} template Matrx::Matrx(const long row, const long col) : row(row), col(col) { /* 该构造函数用于从头开始构造 */ arr = std::vector(col * row); } template Matrx::Matrx(const long row, const long col, const std::vector& src) : row(row), col(col) { /* 该构造函数用于通过已有的vector进行构造 */ arr = src; } template const T& Matrx::get(long row, long col) const { /* 访问器 - 访问矩阵元素 */ return arr[col * this->row + row]; } template T& Matrx::witch(long row, long col) { /* 访问器 - 访问矩阵元素 */ return arr[col * this->row + row]; } template const std::vector& Matrx::get_data() const{ /* 访问器 - 用于获取原始数据 */ return arr; } template const long Matrx::get_col() const { /* 获取列数 */ return col; } template const long Matrx::get_row() const { /* 获取行数 */ return row; } template bool Matrx::has_same_shape(const Matrx& other) { /* 两个矩阵是否具有相同形状 */ return other.get_col() == this->get_col() || other.get_row() == this->get_row(); } template bool Matrx::has_dot_shape(const Matrx& other) { /* 具有矩阵乘法的形状 */ return this->get_col() == other.get_row(); } template void Matrx::assert_same_shape(const Matrx& other) { /* 断言两个矩阵具有相同形状 */ if (!has_same_shape(other)) throw std::invalid_argument("The shapes of matrix are not same."); } template void Matrx::assert_dot_shape(const Matrx& other) { /* 断言两个矩阵具有点积前置形状 */ if (!has_dot_shape(other)) { throw std::invalid_argument("The shapes of matrix can not be dot."); } } template Matrx Matrx::operator+(const Matrx& other) { /* 加法操作符重定义 - 矩阵加法 */ assert_same_shape(other); /* 检查两个矩阵形状是否一致 */ std::vector v0 = this->get_data(); std::vector vec = other.get_data(); for (auto it = v0.begin(), it_or = vec.begin(); it != v0.end(); ++it, ++it_or ) { *it += *it_or; } return Matrx{this->get_row(), this->get_col(), v0}; } template Matrx Matrx::operator+(T& item) { /* 矩阵加法广播 */ auto matrix = *this; for (auto it = arr.begin(); it != arr.end(); ++it) { *it += item; } return matrix; } template Matrx Matrx::operator-(const Matrx& other) { /* 操作符重载 - 矩阵减法 */ assert_same_shape(other); /* 检查两个矩阵形状是否一致 */ std::vector v0 = this->get_data(); std::vector vec = other.get_data(); for (auto it = v0.begin(), it_or = vec.begin(); it != v0.end(); ++it, ++it_or ) { *it -= *it_or; } return Matrx{this->get_row(), this->get_col(), v0}; } template Matrx Matrx::operator-(T& item) { /* 操作符重载 - 矩阵减法广播 */ auto matrix = *this; for (auto it = arr.begin(); it != arr.end(); ++it) { *it -= item; } return matrix; } template const Matrx Matrx::operator*(const Matrx& other) { /* 操作符重载 - 矩阵乘法 */ assert_dot_shape(other); /* 它们的形状是否能够点积 */ auto matrix = Matrx(this->get_row(), other.get_col()); for (long i=0; iget_row(); ++i) {/* 点积运算 */ for (long j=0; jget_col(); ++k) { sum += this->get(i, k) * other.get(k, j); } matrix.witch(i, j) = sum; } } return matrix; } template Matrx Matrx::operator*(T& item) { /* 操作符重载 - 矩阵乘法广播 */ std::vector vec = this->get_data(); for (auto it = vec.begin(); it != vec.end(); ++it) { *it *= item; } return Matrx{this->get_row(), this->get_col(), vec}; } template Matrx Matrx::operator/(T& item) { /* 操作符重载 - 矩阵除法广播 */ std::vector vec = this->get_data(); for (auto it = vec.begin(); it != vec.end(); ++it) { *it /= item; } return Matrx(this->get_row(), this->get_col(), vec); } template class Matrx; /* 显式实例化 */ template class Matrx; }