[英]Matrix multiplication (with different dimensions)
For Math class in school I need to create an application that does something (just anything) with matrices. 对于学校的数学课,我需要创建一个对矩阵进行某些操作(几乎所有操作)的应用程序。 I decided to create a matrix calculator.
我决定创建一个矩阵计算器。 I have a Matrix class which contains a 2D array, an row integer and a column integer.
我有一个Matrix类,其中包含2D数组,行整数和列整数。 I created the following function to multiply two matrices:
我创建了以下函数来将两个矩阵相乘:
public: Matrix* multiply(Matrix* other)
{
Matrix* temp = new Matrix(other->r, other->c);
for(int i = 0; i < this->r; i++)
{
for(int j = 0; j < this->c; j++)
{
for(int k = 0; k < other->c; k++)
temp->mat[i][j] += this->mat[i][k] * other->mat[k][j];
}
}
return temp;
}
This works perfectly, but only if I multiply matrices with the same dimensions (eg Mat4x4*Mat4x4 or Mat2x4*Mat2x4). 这是完美的,但前提是我要乘以相同尺寸的矩阵(例如Mat4x4 * Mat4x4或Mat2x4 * Mat2x4)。 I understand I can't just multiply an Mat4x4 with an Mat9X2 or anything, but I do know the second matrix's columns should be equal to the first matrix's rows (so a Mat2x2 should be able to multiply with a Mat2x1) and that the answer will have the dimensions of the second matrix.
我知道我不能只将Mat4x4与Mat9X2或其他任何东西相乘,但我确实知道第二个矩阵的列应等于第一个矩阵的行(因此Mat2x2应该能够与Mat2x1相乘),并且答案将是具有第二个矩阵的尺寸。 How could (or should) I make the function so it will multiply the matrices with the same and with different dimensions?
我如何(或应该)制作函数,以便它将具有相同和不同维数的矩阵相乘?
Thanks in advance 提前致谢
A solution for your program would be to make the temp dimensions not the others dimension but this->r
, other->c
in order to make the dimensions valid with the outputs from the matrix multiplication. 您的程序的解决方案是使temp维而不是
this->r
维,而是this->r
, other->c
,以便使这些维对矩阵乘法的输出有效。
Hope this helps. 希望这可以帮助。
The following code contains a Matrix
class implementation meant to show a few features of C++ (like unique pointers, random numbers, and stream formatting). 以下代码包含一个
Matrix
类实现,旨在显示C ++的一些功能(如唯一指针,随机数和流格式)。 I often use it when I want to explain a little bit about the language. 当我想对语言进行一些解释时,我经常使用它。 Maybe it can help you.
也许可以帮到您。
#include <cassert>
#include <iostream>
#include <iomanip>
#include <memory>
#include <random>
// Pedagogical implementation of matrix type.
class Matrix {
public:
// Create a rows-by-cols matrix filled with random numbers in (-1, 1).
static Matrix Random(std::size_t rows, std::size_t cols) {
Matrix m(rows, cols);
std::random_device rd;
std::mt19937 gen(rd());
std::uniform_real_distribution<double> dis(-1, 1);
for (std::size_t row = 0; row < rows; ++row) {
for (std::size_t col = 0; col < cols; ++col) {
m(row, col) = dis(gen);
}
}
return m;
}
// Build an uninitialized rows-by-cols matrix.
Matrix(std::size_t rows, std::size_t cols)
: m_data { std::make_unique<double[]>(rows * cols) },
m_rows { rows },
m_cols { cols }
{
assert(m_rows > 0);
assert(m_cols > 0);
}
// Return number of rows
std::size_t rows() const { return m_rows; }
// Return number of columns
std::size_t cols() const { return m_cols; }
// Value at (row, col)
double operator()(std::size_t row, std::size_t col) const {
assert(row < rows());
assert(col < cols());
return m_data[row * cols() + col];
}
// Reference to value at (row, col)
double& operator()(std::size_t row, std::size_t col) {
assert(row < rows());
assert(col < cols());
return m_data[row * cols() + col];
}
// Matrix multiply
Matrix operator*(const Matrix& other) const {
assert(cols() == other.rows());
Matrix out(rows(), other.cols());
for (std::size_t i = 0; i < rows(); ++i) {
for (std::size_t j = 0; j < other.cols(); ++j) {
double sum { 0 };
for (std::size_t k = 0; k < cols(); ++k) {
sum += (*this)(i, k) * other(k, j);
}
out(i, j) = sum;
}
}
return out;
}
private:
std::unique_ptr<double[]> m_data; // will cleanup after itself
const std::size_t m_rows;
const std::size_t m_cols;
};
// Pretty-print a matrix
std::ostream& operator<<(std::ostream& os, const Matrix& m) {
os << std::scientific << std::setprecision(16);
for (std::size_t row = 0; row < m.rows(); ++row) {
for (std::size_t col = 0; col < m.cols(); ++col) {
os << std::setw(23) << m(row, col) << " ";
}
os << "\n";
}
return os;
}
int main() {
Matrix A = Matrix::Random(3, 4);
Matrix B = Matrix::Random(4, 2);
std::cout << "A\n" << A
<< "B\n" << B
<< "A * B\n" << (A * B);
}
Possible output: 可能的输出:
$ clang++ matmul.cpp -std=c++17 -Ofast -march=native -Wall -Wextra
$ ./a.out
A
1.0367049464391398e-01 7.4917987082978588e-03 -2.7966084757805687e-01 -7.2325095373639048e-01
2.2478938813996119e-01 8.4194832286446353e-01 5.3602376615184033e-01 7.1132727553003439e-01
1.9608747339865196e-01 -6.4829263198209253e-01 -2.7477471919710350e-01 1.2721104074473044e-01
B
-8.5938605801284385e-01 -6.2981285198013204e-01
-6.0333085647033191e-01 -6.8234173530317577e-01
-1.2614486249714407e-01 -3.3875904433100934e-01
-6.9618174970366520e-01 6.6785401241316045e-01
A * B
4.4517888255515814e-01 -4.5869338680118737e-01
-1.2639839804611623e+00 -4.2259184895688506e-01
1.6871952235091500e-01 4.9689953389829533e-01
It turnes out the order of the rows and columns got me heckin' bamboozled. 事实证明,行和列的顺序让我难以理解。 The formula was correct.
公式是正确的。 Sorry for unnecessary post.
抱歉,不必要的帖子。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.