C++矩阵运算类(Matrix.h)

这个类数据类型是double,包含了常用的矩阵计算,多数方法经过实践验证,也难免有不足之处,如有发现欢迎指出。

https://github.com/ims0/comTutor/tree/master/matrix

#include 
#include 
#include 
#include 
using namespace std;
#ifndef _In_opt_
  #define _In_opt_
#endif
#ifndef _Out_
  #define _Out_
#endif


typedef unsigned Index_T;
class Matrix
{
private:
    Index_T m_row, m_col;
    Index_T m_size;
    Index_T m_curIndex;
    double *m_ptr;//数组指针
public:
    Matrix(Index_T r, Index_T c) :m_row(r), m_col(c)//非方阵构造
    {
        m_size = r*c;
        if (m_size>0)
        {
            m_ptr = new double[m_size];
        }
        else
            m_ptr = NULL;
    };
    Matrix(Index_T r, Index_T c, double val ) :m_row(r), m_col(c)// 赋初值val
    {
        m_size = r*c;
        if (m_size>0)
        {
            m_ptr = new double[m_size];
        }
        else
            m_ptr = NULL;
    };
    Matrix(Index_T n) :m_row(n), m_col(n)//方阵构造
    {
        m_size = n*n;
        if (m_size>0)
        {
            m_ptr = new double[m_size];
        }
        else
            m_ptr = NULL;
    };
    Matrix(const Matrix &rhs)//拷贝构造
    {
        m_row = rhs.m_row;
        m_col = rhs.m_col;
        m_size = rhs.m_size;
        m_ptr = new double[m_size];
        for (Index_T i = 0; i>(istream&, Matrix&);

    friend ofstream &operator<<(ofstream &out, Matrix &obj);  // 输出到文件
    friend ostream &operator<<(ostream&, Matrix&);          // 输出到屏幕
    friend Matrix &operator<<(Matrix &mat, const double val);
    friend Matrix& operator,(Matrix &obj, const double val);
    friend Matrix  operator+(const Matrix&, const Matrix&);
    friend Matrix  operator-(const Matrix&, const Matrix&);
    friend Matrix  operator*(const Matrix&, const Matrix&);  //矩阵乘法
    friend Matrix  operator*(double, const Matrix&);  //矩阵乘法
    friend Matrix  operator*(const Matrix&, double);  //矩阵乘法

    friend Matrix  operator/(const Matrix&, double);  //矩阵 除以单数

    Matrix multi(const Matrix&); // 对应元素相乘
    Matrix mtanh(); // 对应元素相乘
    Index_T row()const{ return m_row; }
    Index_T col()const{ return m_col; }
    Matrix getrow(Index_T index); // 返回第index 行,索引从0 算起
    Matrix getcol(Index_T index); // 返回第index 列

    Matrix cov(_In_opt_ bool flag = true);   //协方差阵 或者样本方差
    double det();   //行列式
    Matrix solveAb(Matrix &obj);  // b是行向量或者列向量
    Matrix diag();  //返回对角线元素
    //Matrix asigndiag();  //对角线元素
    Matrix T()const;   //转置
    void sort(bool);//true为从小到大
    Matrix adjoint();
    Matrix inverse();
    void QR(_Out_ Matrix&, _Out_ Matrix&)const;
    Matrix eig_val(_In_opt_ Index_T _iters = 1000);
    Matrix eig_vect(_In_opt_ Index_T _iters = 1000);

    double norm1();//1范数
    double norm2();//2范数
    double mean();// 矩阵均值
    double*operator[](Index_T i){ return m_ptr + i*m_col; }//注意this加括号, (*this)[i][j]
    void zeromean(_In_opt_  bool flag = true);//默认参数为true计算列
    void normalize(_In_opt_  bool flag = true);//默认参数为true计算列
    Matrix exponent(double x);//每个元素x次幂
    Matrix  eye();//对角阵
    void  maxlimit(double max,double set=0);//对角阵
};

/*
类方法的实现
*/

Matrix Matrix::mtanh() // 对应元素 tanh()
{
    Matrix ret(m_row, m_col);
    for (Index_T i = 0; imax ? 0 : m_ptr[i*m_col + j];
        }
    }

}
Matrix Matrix::eye()//对角阵
{

    for (Index_T i = 0; i< m_row; i++)
    {
        for (Index_T j = 0; j < m_col; j++)
        {
            if (i == j)
            {
                m_ptr[i*m_col + j] = 1.0;
            }
        }
    }
    return *this;
}
void Matrix::zeromean(_In_opt_  bool flag)
{
    if (flag == true) //计算列均值
    {
        double *mean = new double[m_col];
        for (Index_T j = 0; j < m_col; j++)
        {
            mean[j] = 0.0;
            for (Index_T i = 0; i < m_row; i++)
            {
                mean[j] += m_ptr[i*m_col + j];
            }
            mean[j] /= m_row;
        }
        for (Index_T j = 0; j < m_col; j++)
        {

            for (Index_T i = 0; i < m_row; i++)
            {
                m_ptr[i*m_col + j] -= mean[j];
            }
        }
        delete[]mean;
    }
    else //计算行均值
    {
        double *mean = new double[m_row];
        for (Index_T i = 0; i< m_row; i++)
        {
            mean[i] = 0.0;
            for (Index_T j = 0; j < m_col; j++)
            {
                mean[i] += m_ptr[i*m_col + j];
            }
            mean[i] /= m_col;
        }
        for (Index_T i = 0; i < m_row; i++)
        {
            for (Index_T j = 0; j < m_col; j++)
            {
                m_ptr[i*m_col + j] -= mean[i];
            }
        }
        delete[]mean;
    }
}

void Matrix::normalize(_In_opt_  bool flag)
{
    if (flag == true) //计算列均值
    {
        double *mean = new double[m_col];

        for (Index_T j = 0; j < m_col; j++)
        {
            mean[j] = 0.0;
            for (Index_T i = 0; i < m_row; i++)
            {
                mean[j] += m_ptr[i*m_col + j];
            }
            mean[j] /= m_row;
        }
        for (Index_T j = 0; j < m_col; j++)
        {

            for (Index_T i = 0; i < m_row; i++)
            {
                m_ptr[i*m_col + j] -= mean[j];
            }
        }
        ///计算标准差
        for (Index_T j = 0; j < m_col; j++)
        {
            mean[j] = 0;
            for (Index_T i = 0; i < m_row; i++)
            {
                mean[j] += pow(m_ptr[i*m_col + j],2);//列平方和
            }
                mean[j] = sqrt(mean[j] / m_row); // 开方
        }
        for (Index_T j = 0; j < m_col; j++)
        {
            for (Index_T i = 0; i < m_row; i++)
            {
                m_ptr[i*m_col + j] /= mean[j];//列平方和
            }
        }
        delete[]mean;
    }
    else //计算行均值
    {
        double *mean = new double[m_row];
        for (Index_T i = 0; i< m_row; i++)
        {
            mean[i] = 0.0;
            for (Index_T j = 0; j < m_col; j++)
            {
                mean[i] += m_ptr[i*m_col + j];
            }
            mean[i] /= m_col;
        }
        for (Index_T i = 0; i < m_row; i++)
        {
            for (Index_T j = 0; j < m_col; j++)
            {
                m_ptr[i*m_col + j] -= mean[i];
            }
        }
        ///计算标准差
        for (Index_T i = 0; i< m_row; i++)
        {
            mean[i] = 0.0;
            for (Index_T j = 0; j < m_col; j++)
            {
                mean[i] += pow(m_ptr[i*m_col + j], 2);//列平方和
            }
            mean[i] = sqrt(mean[i] / m_col); // 开方
        }
        for (Index_T i = 0; i < m_row; i++)
        {
            for (Index_T j = 0; j < m_col; j++)
            {
                m_ptr[i*m_col + j] /= mean[i];
            }
        }
        delete[]mean;
    }
}

double Matrix::det()
{
    if (m_col == m_row)
        return calcDet(m_row, m_ptr);
    else
    {
        cout << ("行列不相等无法计算") << endl;
        return 0;
    }
}
/////////////////////////////////////////////////////////////////////
istream& operator>>(istream &is, Matrix &obj)
{
    for (Index_T i = 0; i> obj.m_ptr[i];
    }
    return is;
}

ostream& operator<<(ostream &out, Matrix &obj)
{
    for (Index_T i = 0; i < obj.m_row; i++) //打印逆矩阵
    {
        for (Index_T j = 0; j < obj.m_col; j++)
        {
            out << (obj[i][j]) << "\t";
        }
        out << endl;
    }
    return out;
}
ofstream& operator<<(ofstream &out, Matrix &obj)//打印逆矩阵到文件
{
    for (Index_T i = 0; i < obj.m_row; i++)
    {
        for (Index_T j = 0; j < obj.m_col; j++)
        {
            out << (obj[i][j]) << "\t";
        }
        out << endl;
    }
    return out;
}

Matrix& operator<<(Matrix &obj, const double val)
{
    *obj.m_ptr = val;
    obj.m_curIndex = 1;
    return obj;
}
Matrix& operator,(Matrix &obj, const double val)
{
    if( obj.m_curIndex == 0 || obj.m_curIndex > obj.m_size - 1 )
    {
        return obj;
    }
    *(obj.m_ptr + obj.m_curIndex) = val;
    ++obj.m_curIndex;
    return obj;
}

Matrix operator+(const Matrix& lm, const Matrix& rm)
{
    if (lm.m_col != rm.m_col || lm.m_row != rm.m_row)
    {
        Matrix temp(0, 0);
        temp.m_ptr = NULL;
        cout << "operator+(): 矩阵shape 不合适,m_col:"
            << lm.m_col << "," << rm.m_col << ".  m_row:" << lm.m_row << ", " << rm.m_row << endl;
        return temp; //数据不合法时候,返回空矩阵
    }
    Matrix ret(lm.m_row, lm.m_col);
    for (Index_T i = 0; im_ptr[j])
                {
                    tem = m_ptr[i];
                    m_ptr[i] = m_ptr[j];
                    m_ptr[j] = tem;
                }
            }
            else
            {
                if (m_ptr[i]= 0; --m)
        {
            sum = 0;
            for (Index_T j = m + 1; j < m_col; ++j)
            {
                sum += m_ptr[m *  m_col + j] * ret.m_ptr[j * ret.m_col + count];
            }
            sum = -sum / m_ptr[m *  m_col + m];
            midSum += sum * sum;
            ret.m_ptr[m * ret.m_col + count] = sum;
        }
        midSum = sqrt(midSum);
        for (Index_T i = 0; i < ret.m_row; ++i)
        {
            ret.m_ptr[i * ret.m_col + count] /= midSum; //每次求出一个列向量
        }
    }
    *this = matcopy;//恢复原始矩阵;
    return ret;
}
Matrix Matrix::cov(bool flag)
{
    //m_row 样本数,column 变量数
    if (m_col == 0)
    {
        Matrix m(0);
        return m;
    }
    double *mean = new double[m_col]; //均值向量

    for (Index_T j = 0; j

 

你可能感兴趣的:(C++,数据结构,机器学习)