C++ Matrix类(考试太忙了,新增了正交化的QR分解,求逆运算等)

越来越觉得当初考虑这个类的设计时是不对了,这么写下去扩展性太差了,只有自己看的懂了,考试完重新写一下,添加一些注释
/************************************************************************
	> File Name: Matrix.h
	> Author:keson 
	> Mail:[email protected] 
	> Created Time: 2014年12月22日 星期一 20时08分49秒
 ************************************************************************/

#ifndef _MATRIX_H
#define _MATRIX_H

#include
#include
#include
#include
#include
#include
#include
using namespace std;

class Matrix
{
public:

    Matrix(int i,int j):rowSize(i),colSize(j)
    {
      mat=vector>(i,vector(j));
    }

    //构造函数,读入矩阵,并保存行数和列数
    Matrix(istream &in);
    
    //打印矩阵
    void matPrint();
    
    //获取行数和列数
    int getRowNum() const{return rowSize;}
    int getColNum() const{return colSize;}


    //行列交换
    void changeRow(int ri,int rj);
    void changeCol(int ci,int cj);

    //高斯全主元消元法
    void gaussEliminate();

    //LU 分解
    void LU(vector> &l,vector> &u);

    //求行列式的值
    double gaussDet();

    void inv(vector> &INV);

   
    //获取矩阵
    vector>& getMat()
    {
        return mat;
    }

   
    double getValue(int i,int j)
    {
        return mat[i-1][j-1];
    }


    //获取行元素
    vector getRow(int i);
    
    //获取列元素
    vector getCol(int j);


    //求两向量内积
    double dot(const vector &v1,const vector &v2)
    {
        double ret=0;
        for(int i=0;i &vec)
    {
        double ret;
        for(auto v:vec)
        {
            ret+=v*v;
        }

        return sqrt(ret);
    }
    
    void Schmidt(vector> &q);

    void QR_Schmidt(vector> &Q,vector> &R);


    //矩阵相乘
    Matrix matMulti(const Matrix &mat2);

private:
    vector> mat;
    int rowSize;
    int colSize;
};

//高斯列主元求逆
void Matrix::inv(vector> &INV)
{
    int index=0;
    for(auto &r:INV)
      r[index++]=1;

    int i,j,k,rs,cs;
    double tmp,d;

    for(k=0;k<=rowSize-1;++k)
    {
        d=0.0;
        //选择该列最大元素
        for(i=k;i<=rowSize-1;++i)
        {
            if(fabs(mat[i][k])>d)
            {
                d=mat[i][k];
                rs=i;
            }
        }

        //交换单位矩阵I对应的行和,并按照主元素归一化,注意下标+1对应

        if(k!=rs)
        {
        changeRow(k,rs);
        std::swap(INV[k],INV[rs]);
        }

        tmp=mat[k][k];
        //消元
        for(auto &v:mat[k])
        v=v/tmp;
        for(auto &v:INV[k])
        v=v/tmp;

        for(i=0;i<=rowSize-1;i++)
        {
            if(i!=k)
            {
              tmp=mat[i][k]/mat[k][k];
              for(j=0;j<=colSize-1;++j)
              {
                mat[i][j]=mat[i][j]-tmp*mat[k][j];
                if(fabs(mat[i][j])<=1e-10)
                   mat[i][j]=0;

                INV[i][j]=INV[i][j]-tmp*INV[k][j];
               }
            }
        }
    }
/*
   for(i=0;i<=rowSize-2;i++)
   {
       tmp=mat[i][colSize-1]/mat[rowSize-1][colSize-1];
       for(j=0;j<=colSize-1;j++)
       {
           INV[i][j]=INV[i][j]-tmp*INV[rowSize-1][j];
       }
   }
*/
}

//高斯全主元化为上三角后求行列式的值
double Matrix::gaussDet()
{
    gaussEliminate();
    int ret=1;
    int index=0;
    for(auto v:mat)
    {
        ret*=v[index++];
    }
    return ret;
}

Matrix::Matrix(istream &in)
{
    string line;
    double word;
    vector vec;
    while (getline(in,line))
    {
        istringstream record(line);
        while(record>>word)
          vec.push_back(word);

        mat.push_back(vec);
        colSize=vec.size();
        vec.clear();
    }
    rowSize=mat.size();
}

void Matrix::changeRow(int ri,int rj)
{
    std::swap(mat[ri],mat[rj]);
}

void Matrix::changeCol(int ci,int cj)
{
    for(auto &v:mat)
      std::swap(v[ci],v[cj]);
}

//高斯全主元消元法求上三角
void Matrix::gaussEliminate()
{
    int i,j,k,rs,cs;
    double tmp,d;

    for(k=0;k<=rowSize-2;++k)
    {
        d=0.0;
        for(i=k;i<=rowSize-1;++i)
        {
         for(j=k;j<=colSize-1;++j)
         { 
            if(fabs(mat[i][j])>d)
           {
              d=mat[i][j];
              rs=i;
              cs=j;
           }
         }
        }
       
        if(k!=rs)
        changeRow(k,rs);
        if(k!=cs)
        changeCol(k,cs);
       
        d=mat[k][k];

        for(i=k+1;i<=rowSize-1;++i)
        {
            double tmp=mat[i][k]/mat[k][k];
            for(j=k;j<=colSize-1;++j)
            {
              mat[i][j]=mat[i][j]-tmp*mat[k][j];
              if (fabs(mat[i][j])<=1e-10)
                mat[i][j]=0;
            }
        }
    }
}

/*
 * LU decomposition
 * LU(vector> &l,vector> &u)
 */

 void Matrix::LU(vector> &l,vector> &u)
 {
     int index=0;
     for(auto &r:l)
     {
         r[index++]=1;
     }

     for(auto v:mat)
       u.push_back(v);

     double d=0.0;
     for(int k=0;k> &q)
{

    for(int j=2;j<=colSize;j++)
    {
        double ret;
        double retk;
        for(int k=1;k> &Q,vector> &R)
{
    int index=0;
    for(auto &vec:R)
    {
        vec[index++]=1;
    }

    for(int j=2;j<=colSize;j++)
    {
        double ret;
        double retk;
        for(int k=1;k getRow(int i)
 * return the i row
 */

vector Matrix::getRow(int i)
{
    return mat[i-1];
}

/**
 * vector getCol(int j)
 */
vector Matrix::getCol(int j)
{
    vector col;
    for(auto c:mat)
      col.push_back(c[j-1]);
    return col;
}

/**
 * Matrix multiplication
 * matrix1=m*n   matrix2=n*k   matrix3=m*k
 */

Matrix Matrix::matMulti(const Matrix &matrix2)
{
    if(getColNum()!=matrix2.getRowNum())
    {
        cout<<"The col of mat1 is not equal the row of the mat2"<

你可能感兴趣的:(C++学习)