while循环正在改变每个对象而不是迭代

时间:2016-02-14 07:11:32

标签: c++ vector matrix-multiplication

#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> 

1 个答案:

答案 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)