矩阵乘法问题
Matrix Multiplication issues
我实现了一个矩阵class。它使用我的矩阵乘法函数为任意大小的 matrix.When 动态分配内存,它只在特定条件下工作。如果您有两个 N*M 矩阵,则第一个矩阵的 M 必须等于第二个矩阵的 N。
示例:
//matrix constructor 'matrix M(n, m)
matrix A(2, 3), matrix B(3, 4);
//A and B can be multiplied because A_m == B_n
A * B; //this works!
//changing the size of n of the first matrix causes this to fail if n > m
matrix C(4, 3), matrix D(3, 5);
C * D; // program becomes unresponsive for unknown reasons, only happens when C_n > C_m
我的矩阵class和乘法函数。
#include <iostream>
class matrix{
private:
int rows, cols;
public:
int ** data;
int row();
int col();
matrix();
matrix(int, int);
//~matrix();
matrix operator*(matrix M);
matrix operator%(matrix M);
friend std::ostream & operator<<(std::ostream & os, matrix M);
};
函数:
#include "matrix.h"
using std::cout;
using std::endl;
matrix::matrix(int r, int c){
rows = r;
cols = c;
data = new int*[rows];
for (int i = 0; i< rows; i++){
data[i] = new int[cols];
}
for (int i = 0; i < rows; i++){
for (int j = 0; j < cols; j++){
data[i][j] = 0;
}
}
}
matrix::row(){
return rows;
}
matrix::col(){
return cols;
}
matrix matrix::operator*(matrix M){
if (this->col() == M.row()){
matrix result(this->row(), M.col());
int var = 0;
for (int i = 0; i < result.row(); i++){
for (int j = 0; j < result.col(); j++){
for (int k = 0; k < result.row(); k++){
var += this->data[i][k] * M.data[k][j];
}
result.data[i][j] = var;
var = 0;
}
}
return result;
}
else cout << "FAILED";
}
std::ostream & operator<<(std::ostream & os, matrix M){
for (int i = 0; i < M.row(); i++){
os << '|';
for (int j = 0; j < M.col(); j++){
os << M.data[i][j] << ' ';
}
os << "|\n";
}
os << '\n';
return os;
}
为什么程序在这些情况下无法运行?
这 3 个循环正在访问分配给您的代码的块之外的内存。
for (int i = 0; i < result.row(); i++){
for (int j = 0; j < result.col(); j++){
for (int k = 0; k < result.row(); k++){
应该是
for (int i = 0; i < result.row(); i++){
for (int j = 0; j < M.col(); j++){
for (int k = 0; k < M.row(); k++){
var += this->data[i][k] * M.data[k][j];
}
result.data[i][j] = var;
var = 0;
}
}
首先,支持
using std::cout;
using std::endl;
很高兴看到有人没有为了像这样的简单工作而全力以赴。
现在让我们来看看算法。
矩阵 C(4, 3) * 矩阵 D(3, 5) 将给出矩阵结果 (4,5)
for (int i = 0; i < result.row(); i++){
for (int j = 0; j < result.col(); j++){
for (int k = 0; k < result.row(); k++){
解析为
for (int i = 0; i < 4; i++){
for (int j = 0; j < 5; j++){
for (int k = 0; k < 4; k++){
var += this->data[i][k] * M.data[k][j];
Array size: 4 3 3 5
k 将变为 运行 0 .. 3。k 的有效范围是 0 .. 2.
你想要的是:
for (int i = 0; i < result.row(); i++){
for (int j = 0; j < result.col(); j++){
for (int k = 0; k < this->cols; k++){
三点建议:
学习使用调试器。如果您单步执行代码,这类问题就完全微不足道了。
然后学习使用可测试的输入进行测试,这样您就可以看到数学何时不起作用。 0乘以0什么也证明不了
我建议更换
int ** data;
和
std::vector<std::vector<int> > data;
您可以像这样在构造函数中初始化它:
matrix::matrix(int r, int c):rows(r), cols(c), data(r, std::vector<int>(c))
{
}
无需循环将其归零。矢量构造函数为你做这件事。如果你不想用零加载,你可以指定另一个值。
matrix::matrix(int r, int c):
rows(r),
cols(c),
data(r, std::vector<int>(c, <starting value goes here>))
{
}
我希望这段代码能起作用。
#include<iostream>
using namespace std;
template<typename T>
class Matrix{
int rs, cs;
T **mat;
public:
Matrix() { mat = NULL; rs = cs = 0; }
istream& operator>>( Matrix <T> &);
ofstream& operator<<(const Matrix<T> &);
Matrix<T> operator=(const Matrix<T> &);
Matrix<T> operator*(const Matrix<T> &);
void read();
void print();
};
template <typename T>
Matrix<T> Matrix<T>::operator=(const Matrix<T> &a){
if(this->mat!=NULL)
{
for(int i = 0 ; i < this->rs ; i++)
delete []mat;
}
this->rs = a.rs;
this->cs = a.cs;
this->mat = new T*[a.rs];
for(int i = 0 ; i < a.rs; i++)
this->mat[i] = new T[a.cs];
for(int i = 0 ; i < a.rs ; i++){
for(int k = 0 ; k < a.cs; k++)
this->mat[i][k] =a.mat[i][k];
}
return a;
}
template <typename T>
Matrix<T> Matrix<T>::operator*(const Matrix<T> &a){
Matrix<T> b;
b.rs = this->rs;
b.cs = a.cs;
if(this->cs == a.rs){
b.mat = new T*[b.rs];
for(int i = 0 ; i < this->rs; i++)
b.mat[i] = new T[b.cs];
for(int i = 0 ; i < this->rs; i++)
{
for(int k = 0 ; k < a.cs ; k++){
b.mat[i][k] = 0;
for(int j = 0 ; j < this->cs ; j++)
b.mat[i][k] += this->mat[i][j] * a.mat[j][k];
}
}
return b;
}
else
{
cout<<"You can not multiply these matrices"<<endl;
b.mat = new T*[b.rs];
for(int i = 0 ; i < this->rs; i++)
b.mat[i] = new T[b.cs];
for(int i = 0 ; i < b.rs ; i++)
for(int k = 0 ; k < b.cs ; k++)
b.mat[i][k] =0;
return b;
}
}
template <typename T>
ostream& operator<<(ostream &g , Matrix<T> &a);
template <typename T>
istream& operator>>(istream &g , Matrix<T> &a);
int main(){
Matrix <int > A, B, C;
Matrix < double > M, R, S;
cin >> A;
cin>>C;
B = A*C;
cout<<endl<<B<<endl;
}
template <typename T>
ostream& operator<<(ostream &g , Matrix<T> &a){
a.print();
return g;
}
template <typename T>
void Matrix<T>::print(){
for(int i = 0; i < rs ;i++){
for(int k = 0 ; k < cs ; k++){
cout<<mat[i][k]<<" ";
}
cout<<endl;
}
}
template <typename T>
istream& operator>>(istream &g , Matrix<T> &a)
{
a.read();
return g;
}
template <typename T>
void Matrix<T>::read()
{
if (mat!=NULL) {
for(int i = 0 ; i < rs ; i++)
delete []mat;
}
cout<<"Enter row size: ";
cin >> rs;
cout<<"Enter column size: ";
cin>> cs;
int i;
mat = new T*[rs];
for (i = 0; i < rs; i++)
mat[i] = new T[cs];
int j;
for (i = 0; i < rs; i++)
{
for (j = 0; j < cs; j++)
{
cout<<"Element ["<<i<<"]"<<"["<<j<<"] = ";
cin >> mat[i][j];
}
}
}
我实现了一个矩阵class。它使用我的矩阵乘法函数为任意大小的 matrix.When 动态分配内存,它只在特定条件下工作。如果您有两个 N*M 矩阵,则第一个矩阵的 M 必须等于第二个矩阵的 N。 示例:
//matrix constructor 'matrix M(n, m)
matrix A(2, 3), matrix B(3, 4);
//A and B can be multiplied because A_m == B_n
A * B; //this works!
//changing the size of n of the first matrix causes this to fail if n > m
matrix C(4, 3), matrix D(3, 5);
C * D; // program becomes unresponsive for unknown reasons, only happens when C_n > C_m
我的矩阵class和乘法函数。
#include <iostream>
class matrix{
private:
int rows, cols;
public:
int ** data;
int row();
int col();
matrix();
matrix(int, int);
//~matrix();
matrix operator*(matrix M);
matrix operator%(matrix M);
friend std::ostream & operator<<(std::ostream & os, matrix M);
};
函数:
#include "matrix.h"
using std::cout;
using std::endl;
matrix::matrix(int r, int c){
rows = r;
cols = c;
data = new int*[rows];
for (int i = 0; i< rows; i++){
data[i] = new int[cols];
}
for (int i = 0; i < rows; i++){
for (int j = 0; j < cols; j++){
data[i][j] = 0;
}
}
}
matrix::row(){
return rows;
}
matrix::col(){
return cols;
}
matrix matrix::operator*(matrix M){
if (this->col() == M.row()){
matrix result(this->row(), M.col());
int var = 0;
for (int i = 0; i < result.row(); i++){
for (int j = 0; j < result.col(); j++){
for (int k = 0; k < result.row(); k++){
var += this->data[i][k] * M.data[k][j];
}
result.data[i][j] = var;
var = 0;
}
}
return result;
}
else cout << "FAILED";
}
std::ostream & operator<<(std::ostream & os, matrix M){
for (int i = 0; i < M.row(); i++){
os << '|';
for (int j = 0; j < M.col(); j++){
os << M.data[i][j] << ' ';
}
os << "|\n";
}
os << '\n';
return os;
}
为什么程序在这些情况下无法运行?
这 3 个循环正在访问分配给您的代码的块之外的内存。
for (int i = 0; i < result.row(); i++){
for (int j = 0; j < result.col(); j++){
for (int k = 0; k < result.row(); k++){
应该是
for (int i = 0; i < result.row(); i++){
for (int j = 0; j < M.col(); j++){
for (int k = 0; k < M.row(); k++){
var += this->data[i][k] * M.data[k][j];
}
result.data[i][j] = var;
var = 0;
}
}
首先,支持
using std::cout;
using std::endl;
很高兴看到有人没有为了像这样的简单工作而全力以赴。
现在让我们来看看算法。
矩阵 C(4, 3) * 矩阵 D(3, 5) 将给出矩阵结果 (4,5)
for (int i = 0; i < result.row(); i++){
for (int j = 0; j < result.col(); j++){
for (int k = 0; k < result.row(); k++){
解析为
for (int i = 0; i < 4; i++){
for (int j = 0; j < 5; j++){
for (int k = 0; k < 4; k++){
var += this->data[i][k] * M.data[k][j];
Array size: 4 3 3 5
k 将变为 运行 0 .. 3。k 的有效范围是 0 .. 2.
你想要的是:
for (int i = 0; i < result.row(); i++){
for (int j = 0; j < result.col(); j++){
for (int k = 0; k < this->cols; k++){
三点建议:
学习使用调试器。如果您单步执行代码,这类问题就完全微不足道了。
然后学习使用可测试的输入进行测试,这样您就可以看到数学何时不起作用。 0乘以0什么也证明不了
我建议更换
int ** data;
和
std::vector<std::vector<int> > data;
您可以像这样在构造函数中初始化它:
matrix::matrix(int r, int c):rows(r), cols(c), data(r, std::vector<int>(c))
{
}
无需循环将其归零。矢量构造函数为你做这件事。如果你不想用零加载,你可以指定另一个值。
matrix::matrix(int r, int c):
rows(r),
cols(c),
data(r, std::vector<int>(c, <starting value goes here>))
{
}
我希望这段代码能起作用。
#include<iostream>
using namespace std;
template<typename T>
class Matrix{
int rs, cs;
T **mat;
public:
Matrix() { mat = NULL; rs = cs = 0; }
istream& operator>>( Matrix <T> &);
ofstream& operator<<(const Matrix<T> &);
Matrix<T> operator=(const Matrix<T> &);
Matrix<T> operator*(const Matrix<T> &);
void read();
void print();
};
template <typename T>
Matrix<T> Matrix<T>::operator=(const Matrix<T> &a){
if(this->mat!=NULL)
{
for(int i = 0 ; i < this->rs ; i++)
delete []mat;
}
this->rs = a.rs;
this->cs = a.cs;
this->mat = new T*[a.rs];
for(int i = 0 ; i < a.rs; i++)
this->mat[i] = new T[a.cs];
for(int i = 0 ; i < a.rs ; i++){
for(int k = 0 ; k < a.cs; k++)
this->mat[i][k] =a.mat[i][k];
}
return a;
}
template <typename T>
Matrix<T> Matrix<T>::operator*(const Matrix<T> &a){
Matrix<T> b;
b.rs = this->rs;
b.cs = a.cs;
if(this->cs == a.rs){
b.mat = new T*[b.rs];
for(int i = 0 ; i < this->rs; i++)
b.mat[i] = new T[b.cs];
for(int i = 0 ; i < this->rs; i++)
{
for(int k = 0 ; k < a.cs ; k++){
b.mat[i][k] = 0;
for(int j = 0 ; j < this->cs ; j++)
b.mat[i][k] += this->mat[i][j] * a.mat[j][k];
}
}
return b;
}
else
{
cout<<"You can not multiply these matrices"<<endl;
b.mat = new T*[b.rs];
for(int i = 0 ; i < this->rs; i++)
b.mat[i] = new T[b.cs];
for(int i = 0 ; i < b.rs ; i++)
for(int k = 0 ; k < b.cs ; k++)
b.mat[i][k] =0;
return b;
}
}
template <typename T>
ostream& operator<<(ostream &g , Matrix<T> &a);
template <typename T>
istream& operator>>(istream &g , Matrix<T> &a);
int main(){
Matrix <int > A, B, C;
Matrix < double > M, R, S;
cin >> A;
cin>>C;
B = A*C;
cout<<endl<<B<<endl;
}
template <typename T>
ostream& operator<<(ostream &g , Matrix<T> &a){
a.print();
return g;
}
template <typename T>
void Matrix<T>::print(){
for(int i = 0; i < rs ;i++){
for(int k = 0 ; k < cs ; k++){
cout<<mat[i][k]<<" ";
}
cout<<endl;
}
}
template <typename T>
istream& operator>>(istream &g , Matrix<T> &a)
{
a.read();
return g;
}
template <typename T>
void Matrix<T>::read()
{
if (mat!=NULL) {
for(int i = 0 ; i < rs ; i++)
delete []mat;
}
cout<<"Enter row size: ";
cin >> rs;
cout<<"Enter column size: ";
cin>> cs;
int i;
mat = new T*[rs];
for (i = 0; i < rs; i++)
mat[i] = new T[cs];
int j;
for (i = 0; i < rs; i++)
{
for (j = 0; j < cs; j++)
{
cout<<"Element ["<<i<<"]"<<"["<<j<<"] = ";
cin >> mat[i][j];
}
}
}