矩阵类: 这个类数据类型是double,包含了常用的矩阵计算,多数方法经过实践验证
#include
#include // std::ifstream#include
#include
using namespace std;
/*类的定义*/
class Matrix{private:
unsigned row, col, size;
double *pmm;//数组指针
public:
Matrix(unsigned r, unsigned c) :row(r), col(c)//非方阵构造 {
size = r*c;
if (size>0) {
pmm = new double[size];
for (unsigned j = 0; j0) {
pmm = new double[size];
for (unsigned j = 0; j0) {
pmm = new double[size];
for (unsigned j = 0; j>(istream&, Matrix&);
friend ofstream &operator<<(ofstream &out, Matrix &obj); // 输出到文件
friend ostream &operator<<(ostream&, Matrix&); // 输出到屏幕
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(); // 对应元素相乘
unsigned Row()const{ return row; }
unsigned Col()const{ return col; }
Matrix getrow(size_t index); // 返回第index 行,索引从0 算起
Matrix getcol(size_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_ unsigned _iters = 1000);
Matrix eig_vect(_In_opt_ unsigned _iters = 1000);
double norm1();//1范数
double norm2();//2范数
double mean();// 矩阵均值
double*operator[](int i){ return pmm + i*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(row, col);
for (unsigned i = 0; i brow ? 0 : 1; //bb中小于arow的行,同行赋值,等于的错过,大于的加一 for (int j = 0; jmax ? 0 : pmm[i*col + j];
}
}
}
Matrix Matrix::eye()//对角阵{
for (unsigned i = 0; i< row; i++) {
for (unsigned j = 0; j < col; j++) {
if (i == j) {
pmm[i*col + j] = 1.0;
} } }
return *this;}
void Matrix::zeromean(_In_opt_ bool flag){
if (flag == true) //计算列均值 {
double *mean = new double[col];
for (unsigned j = 0; j < col; j++) {
mean[j] = 0.0;
for (unsigned i = 0; i < row; i++)
{
mean[j] += pmm[i*col + j]; }
mean[j] /= row; }
for (unsigned j = 0; j < col; j++) {
for (unsigned i = 0; i < row; i++) {
pmm[i*col + j] -= mean[j];
} }
delete[]mean; }
else //计算行均值 {
double *mean = new double[row];
for (unsigned i = 0; i< row; i++) {
mean[i] = 0.0;
for (unsigned j = 0; j < col; j++) {
mean[i] += pmm[i*col + j]; }
mean[i] /= col; }
for (unsigned i = 0; i < row; i++) {
for (unsigned j = 0; j < col; j++) {
pmm[i*col + j] -= mean[i]; } }
delete[]mean; }}
void Matrix::normalize(_In_opt_ bool flag){
if (flag == true) //计算列均值 {
double *mean = new double[col];
for (unsigned j = 0; j < col; j++) {
mean[j] = 0.0;
for (unsigned i = 0; i < row; i++) {
mean[j] += pmm[i*col + j]; }
mean[j] /= row; }
for (unsigned j = 0; j < col; j++) {
for (unsigned i = 0; i < row; i++) {
pmm[i*col + j] -= mean[j]; } } ///计算标准差
for (unsigned j = 0; j < col; j++) {
mean[j] = 0;
for (unsigned i = 0; i < row; i++) {
mean[j] += pow(pmm[i*col + j],2);//列平方和 }
mean[j] = sqrt(mean[j] / row); // 开方 }
for (unsigned j = 0; j < col; j++) {
for (unsigned i = 0; i < row; i++) {
pmm[i*col + j] /= mean[j];//列平方和 } }
delete[]mean; } else //计算行均值 {
double *mean = new double[row];
for (unsigned i = 0; i< row; i++) {
mean[i] = 0.0;
for (unsigned j = 0; j < col; j++) {
mean[i] += pmm[i*col + j]; }
mean[i] /= col; }
for (unsigned i = 0; i < row; i++) {
for (unsigned j = 0; j < col; j++) {
pmm[i*col + j] -= mean[i]; } } ///计算标准差
for (unsigned i = 0; i< row; i++) {
mean[i] = 0.0;
for (unsigned j = 0; j < col; j++) {
mean[i] += pow(pmm[i*col + j], 2);//列平方和 }
mean[i] = sqrt(mean[i] / col); // 开方 }
for (unsigned i = 0; i < row; i++) {
for (unsigned j = 0; j < col; j++) {
pmm[i*col + j] /= mean[i]; } }
delete[]mean; }}
double Matrix::det(){
if (col == row)
return dets(row, pmm);
else {
cout << ("行列不相等无法计算") << endl;
return 0; }}
/////////////////////////////////////////////////////////////////////
istream &operator>>(istream &is, Matrix &obj){
for (unsigned i = 0; i> obj.pmm[i];
}
return is;}
iostream &operator<<(ostream &out, Matrix &obj){
for (unsigned i = 0; i < obj.row; i++) //打印逆矩阵 {
for (unsigned j = 0; j < obj.col; j++) {
out << (obj[i][j]) << "\t"; }
out << endl; }
return out;
}
ofstream &operator<<(ofstream &out, Matrix &obj)//打印逆矩阵到文件 {
for (unsigned i = 0; i < obj.row; i++) {
for (unsigned j = 0; j < obj.col; j++) {
out << (obj[i][j]) << "\t"; }
out << endl; }
return out;}
Matrix operator+(const Matrix& lm, const Matrix& rm){
if (lm.col != rm.col || lm.row != rm.row) {
Matrix temp(0, 0);
temp.pmm = NULL;
cout << "operator+(): 矩阵shape 不合适,col:" << lm.col << "," << rm.col << ".
row:" << lm.row << ", " << rm.row << endl;
return temp; //数据不合法时候,返回空矩阵 }
Matrix ret(lm.row, lm.col); for (unsigned i = 0; ipmm[j]) {
tem = pmm[i];
pmm[i] = pmm[j];
pmm[j] = tem; } }
else {
if (pmm[i]= 0; --m) {
sum = 0;
for (unsigned j = m + 1; j < col; ++j) {
sum += pmm[m * col + j] * ret.pmm[j * ret.col + count]; }
sum = -sum / pmm[m * col + m];
midSum += sum * sum;
ret.pmm[m * ret.col + count] = sum; }
midSum = sqrt(midSum);
for (unsigned i = 0; i < ret.row; ++i) {
ret.pmm[i * ret.col + count] /= midSum; //每次求出一个列向量
} }
*this = matcopy;//恢复原始矩阵;
return ret;}Matrix Matrix::cov(bool flag){ //row 样本数,column 变量数
if (col == 0) {
Matrix m(0);
return m; }
double *mean = new double[col]; //均值向量
for (unsigned j = 0; j bi) //ai行的代数余子式是:小于ai的行,aa与bb阵,同行赋值 pi = 0;
else
pi = 1; //大于等于ai的行,取aa阵的ai+1行赋值给阵bb的bi行
if (aj>bj) //ai行的代数余子式是:小于ai的行,aa与bb阵,同行赋值 pj = 0; else
pj = 1; //大于等于ai的行,取aa阵的ai+1行赋值给阵bb的bi行
bb[bi*(n - 1) + bj] = pmm[(bi + pi)*n + bj + pj];
} }
if ((ai + aj) % 2 == 0) q = 1;//因为列数为0,所以行数是偶数时候,代数余子式为-1. else q = (-1);
ret.pmm[ai*n + aj] = q*dets(n - 1, bb); //加符号变为代数余子式
} }
delete[]bb;
return ret;}
Matrix Matrix::inverse(){
double det_aa = det(); if (det_aa == 0) {
cout << "行列式为0 ,不能计算逆矩阵。" << endl;
Matrix rets(0);
return rets; }
Matrix adj = adjoint();
Matrix ret(row);
for (unsigned i = 0; i|
原文链接:https://blog.csdn.net/sinat_36219858/article/details/78164606