#include <stdio.h>
#include <iostream>
#include "Vector.h"
#include <string.h>
#include <math.h>
#include "Matrix.h"
#include <list>
using namespace std;
// format for a Matrix
char* Matrix::printM(){
char* s = new char[5000*1024];
int i;
for(i=0;i < this->dimension.rows;i++){
int j;
for(j=0;j< this->dimension.columns;j++){
Vector* tmp = this->columns[j];
int x = this->dimension.columns - 1;
if(j == 0){
char buffer[500];
//it0oa(v->coordinate[i],buffer,sizeof(int));
snprintf(buffer,5000,"%f",tmp->coordinate[i]);
strncat(s,"|", 1+ strlen(s));
strncat(s,buffer, strlen(s) + strlen(buffer));
strncat(s,",",strlen(s) + 1);
}else if(j == x){
char buffer[500];
snprintf(buffer,5000,"%f",tmp->coordinate[i]);
strncat(s,buffer,strlen(s) + strlen(buffer));
strncat(s,"|\n",strlen(s)+2);
}else{
char buffer[500];
snprintf(buffer,5000,"%f",tmp->coordinate[i]);
strncat(s,buffer,strlen(s) + strlen(buffer));
strncat(s,",",strlen(s) + 1);
}
}
}
return s;
}
Matrix::Matrix(int di,int de){
this->dimension.rows =de;
this->dimension.columns =di;
this->columns.assign(di,new Vector(de));
}
Matrix::Matrix(std::vector<Vector*> v, int di){
this->dimension.columns = v.size();
this->columns = v;
int it;
this->dimension.rows = v[0]->dimension;
}
Matrix& Matrix::operator+(const Matrix& v){
Matrix* mt = new Matrix(this->dimension.columns,6);
mt->dimension = this->dimension;
int i;
for(i=0;i< mt->dimension.columns;i++){
//mt->columns.push_back(&(*this->columns[i] + *v.columns[i]));
mt->columns[i] = &(*this->columns[i] + *v.columns[i]);
printf("%s\n",mt->columns[0]->printV());
}
return *mt;
}
Matrix& Matrix::operator-(const Matrix& v){
Matrix* mt = new Matrix(this->dimension.columns,7);
mt->dimension = this->dimension;
int i;
for(i=0;i< mt->dimension.columns;i++){
//mt->columns.push_back(&(*this->columns[i] + *v.columns[i]));
mt->columns[i] = &(*this->columns[i] - *v.columns[i]);
printf("%s\n",mt->columns[0]->printV());
}
return *mt;
}
Matrix& Matrix::operator*(const double& v){
Matrix* mt = new Matrix(this->dimension.columns,7);
mt->dimension = this->dimension;
int i;
for(i=0;i< mt->dimension.columns;i++){
//mt->columns.push_back(&(*this->columns[i] + *v.columns[i]));
mt->columns[i] = &(*this->columns[i] * v);
//printf("%s\n",mt->columns[0]->printV());
}
return *mt;
}
std::vector<Vector*> Matrix::row_equiv(Matrix* m){
std::list<Vector*> result;
int i;
for(i=0;i< m->dimension.rows;i++){
std::list<double> lists;
lists.push_back(m->dimension.columns);
int j;
for(j=0;j< m->dimension.columns;j++){
Vector* tmp = m->columns[j];
lists.push_back(tmp->coordinate[i]);
}
j=0;
//std::initializer_list<double> list_h = lists;
Vector* tmp = new Vector(lists);
result.push_back(tmp);
}
std::vector<Vector*> x{std::begin(result),std::end(result)};
return x;
}
Matrix* Matrix::transpose(){
std::vector<Vector*> b = row_equiv(this);
Matrix* mt = new Matrix(b,this->dimension.rows);
return mt;
}
Matrix* Matrix::upperTriangular(){
std::vector<Vector*> tmp = row_equiv(this);
if(this->is_square()){
int j;
for(j=0;j<this->dimension.columns;j++){
double pivot = tmp[j]->coordinate[j];
int i;
for(i=j+1;i<this->dimension.rows;i++){
tmp[i] = &((*tmp[i]) - (*tmp[j] * (tmp[i]->coordinate[j]/pivot)));
}
}
}else if(this->dimension.rows > this->dimension.columns){
//printf("Hello world,\n");
int j;
for(j=0;j<this->dimension.columns;j++){
double pivot = tmp[j]->coordinate[j];
printf("%f\n",pivot);
int i;
for(i=j+1;i< this->dimension.rows;i++){
tmp[i] = &((*tmp[i]) + (*tmp[j] * (tmp[i]->coordinate[j]/-1*pivot)));
printf(" The vector is %s\n",tmp[i]->printV());
}
}
}else if(this->dimension.rows < this->dimension.columns){
printf("Not Hello World!");
}
Matrix* result = new Matrix(tmp,this->dimension.rows);
return result->transpose();
}
// This is supposed to give me the multiplication of matrices but it's not working right now.
Matrix& Matrix::operator*(const Matrix& v){
if(this->dimension.columns == v.dimension.rows){
Matrix* mt = new Matrix(v.dimension.columns,this->dimension.rows);
mt->dimension.rows = this->dimension.rows;
std::vector<Vector*> tmp = row_equiv(this);
std::vector<Vector* > result(v.dimension.columns, new Vector(this->dimension.rows));
for(auto i =0; i < tmp.size();i++){ //for each rows of the first matrix
int j =0;
while(j< this->dimension.columns){ //for each columns of the second matrix
//printf("%f and %f\n",tmp[i]->dimension,this->columns[j]->dimension);
//double x = *tmp[i] * *v.columns[j];
//printf("%f\n",x);
//mt->columns[j]->coordinate[i] = (*tmp[i] * *v.columns[j]); // This line is giving me problems.
//printf("THis is after the code\n");
result[j]->coordinate[i] = (*tmp[i] * *v.columns[j]);
printf("%s and %s %f and %s %s an j = %d\n",tmp[i]->printV(),v.columns[j]->printV(),result[j]->coordinate[i],result[j]->printV(),result[0]->printV(),j);
j++;
}
printf("%s\n",result[0]->printV());
}
return *mt;
}
Matrix* mt = new Matrix(3,2);
return *mt;
}
问题在于这段代码
Matrix& Matrix::operator*(const Matrix& v){
if(this->dimension.columns == v.dimension.rows){
Matrix* mt = new Matrix(v.dimension.columns,this->dimension.rows);
mt->dimension.rows = this->dimension.rows;
std::vector<Vector*> tmp = row_equiv(this);
std::vector<Vector* > result(v.dimension.columns, new Vector(this->dimension.rows));
for(auto i =0; i < tmp.size();i++){ //for each rows of the first matrix
int j =0;
while(j< this->dimension.columns){ //for each columns of the second matrix
//printf("%f and %f\n",tmp[i]->dimension,this->columns[j]->dimension);
//double x = *tmp[i] * *v.columns[j];
//printf("%f\n",x);
//mt->columns[j]->coordinate[i] = (*tmp[i] * *v.columns[j]); // This line is giving me problems.
//printf("THis is after the code\n");
result[j]->coordinate[i] = (*tmp[i] * *v.columns[j]);
printf("%s and %s %f and %s %s an j = %d\n",tmp[i]->printV(),v.columns[j]->printV(),result[j]->coordinate[i],result[j]->printV(),result[0]->printV(),j);
j++;
}
printf("%s\n",result[0]->printV());
}
return *mt;
}
Matrix* mt = new Matrix(3,2);
return *mt;
}
该函数应该将2个矩阵相乘。
这条线每次运行都会改变result[0]
,我不知道为什么。结果是Vector *的向量,而while循环应该遍历向量的Vector(列表)并更改第i个组件,但每次循环通过它都会更改前一个Vector。
result[j]->coordinate[i] = (*tmp[i] * *v.columns[j])
这是实施:
for(auto i=0; i < this->dimension.rows;i++){
for(auto j=0; j<v.dimension.columns;j++){
for(auto k=0; k< this->dimension.rows;k++){
result[j]->coordinate[i] += this->columns[i]->coordinate[k] * v.columns[k]->coordinate[j];
printf("j = %d, %s and %s\n",j,result[j]->printV(), result[0]->printV());
}
}
}
当j = 1时,结果[0]也会改变,我不知道为什么。这是输出。
j = 0, <2.000000,0.000000> and <2.000000,0.000000>
j = 0, <2.000000,0.000000> and <2.000000,0.000000>
j = 1, <2.000000,0.000000> and <2.000000,0.000000>
j = 1, <1.000000,0.000000> and <1.000000,0.000000>
j = 2, <1.000000,0.000000> and <1.000000,0.000000>
j = 2, <1.000000,0.000000> and <1.000000,0.000000>
j = 0, <1.000000,-1.000000> and <1.000000,-1.000000>
j = 0, <1.000000,-1.000000> and <1.000000,-1.000000>
j = 1, <1.000000,-1.000000> and <1.000000,-1.000000>
j = 1, <1.000000,1.000000> and <1.000000,1.000000>
j = 2, <1.000000,1.000000> and <1.000000,1.000000>
j = 2, <1.000000,1.000000> and <1.000000,1.000000>
答案 0 :(得分:0)
矩阵乘法的定义不同。它需要3个嵌套for循环 - 而不仅仅是两个:
对于每对(i,j)
,您需要迭代k
的所有值,并执行以下伪代码:
result = zeros(a.rows,b.cols)
for i = 0:a.rows-1
for j = 0:b.cols-1
for k = 0:a.cols-1
result(i,j) += a(i,k) * b(k,j)