这个类数据类型是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++,数据结构,机器学习)