大佬教程收集整理的这篇文章主要介绍了C++矩阵运算类(Matrix.h),大佬教程大佬觉得挺不错的,现在分享给大家,也给大家做个参考。
@H_390_7@matrix(Index_T r,Index_T C) :m_row(r),m_col(C)//非方阵构造 Matrix(Index_T r,Index_T c,double val ) :m_row(r),m_col(C)// 赋初值val Matrix(Index_T n) :m_row(n),m_col(n)//方阵构造
Matrix(const Matrix &rhs)//拷贝构造
Matrix &operator=(const Matrix&); //如果类成员有指针必须重写赋值运算符,必须是成员
friend istream &operator>>(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,1)"> val); friend Matrix operator+(const Matrix&,1)">const Matrix&); friend Matrix operator-(operator*(矩阵乘法 friend Matrix double,1)">doublE); 矩阵乘法 friend Matrix operator/(矩阵 除以单数 Matrix multi(const Matrix&); 对应元素相乘 Matrix mtanh(); 对应元素相乘 Index_T row()const{ return m_row; } Index_T col() 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(); 返回对角线元素 @H_933_16@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 = ); 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_ true);默认参数为true计算列 void normalize(_In_opt_ 默认参数为true计算列 Matrix exponent(double X);每个元素x次幂 Matrix eye();对角阵 void maxlimit(double max,1)">double set=0);对角阵@H_696_186@
#include <iostream> #include <fstream> #include <stdlib.h> #include <cmath> using namespace std; #ifndef _In_opt_ #define _In_opt_ #endif #ifndef _Out_ #define _Out_ 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,m_col(C)非方阵构造 { m_size = r*c; if (m_size>0) { m_ptr = new [m_size]; } else m_ptr = NULL; }; Matrix(Index_T r,double val ) :m_row(r),m_col(C) 赋初值val NULL; }; Matrix(Index_T n) :m_row(n),m_col(n)方阵构造 { m_size = n*n; NULL; }; Matrix(const Matrix &rhs)拷贝构造 { m_row = rhs.m_row; m_col = rhs.m_col; m_size = rhs.m_size; m_ptr = [m_size]; for (Index_T i = 0; i<m_size; i++) m_ptr[i] = rhs.m_ptr[i]; } ~@H_933_16@matrix() { if (m_ptr != NULL) { delete[]m_ptr; m_ptr = NULL; } } Matrix &如果类成员有指针必须重写赋值运算符,必须是成员 friend istream &对角阵 }; /* 类方法的实现 */ Matrix Matrix::mtanh() 对应元素 tanh() { Matrix ret(m_row,m_col); 0; i<ret.m_size; i++) { ret.m_ptr[i] = tanh(m_ptr[i]); } ret; } * 递归调用 */ double calcDet(Index_T n,1)">double *&aa) { if (n == 1) return aa[]; double *bb = double[(n - 1)*(n - 1)];创建n-1阶的代数余子式阵bb double sum = 0.0; for (Index_T Ai = 0; Ai<n; Ai++) { for (Index_T Bi = 0; Bi < n - 1; Bi++)把aa阵第一列各元素的代数余子式存到bb { Index_T offset = Bi < Ai ? 0 : 1; bb中小于Ai的行,同行赋值,等于的错过,大于的加一 for (Index_T j = 0; j<n - 1; j++) { bb[Bi*(n - 1) + j] = aa[(Bi + offset)*n + j + ]; } } int flag = (Ai % 2 == 0 ? 1 : -1);因为列数为0,所以行数是偶数时候,代数余子式为1. sum += flag* aa[Ai*n] * calcDet(n - 1,bb);aa第一列各元素与其代数余子式积的和即为行列式 } []bb; sum; } Matrix Matrix::solveAb(Matrix &obj) { Matrix ret(m_row,); if (m_size == 0 || obj.m_size == ) { cout << "solveAb(Matrix &obj):this or obj is null" << endl; ret; } if (m_row != obj.m_sizE) { cout << solveAb(Matrix &obj):the row of two matrix is not equal! ret; } double *Dx = double[m_row*@H_933_16@m_row]; 0; i<m_row; i++0; j<m_row; j++) { Dx[i*m_row + j] = m_ptr[i*m_row + j]; } } double D = calcDet(m_row,DX); if (D == Cramer法则只能计算系数矩阵为满秩的矩阵 ret; } ) { ) { Dx[i*m_row + j] = m_ptr[i*m_row + j]; } } ) { Dx[i*m_row + j] = obj.m_ptr[i]; obj赋值给第j列 } for( int i=0;i<m_row;i++) print { for(int j=0; j<m_row;j++) { cout<< Dx[i*m_row+j]<<"\t"; } cout<<endl; } ret[j][0] = calcDet(m_row,DX) / D; } []Dx; ret; } Matrix Matrix::getrow(Index_T indeX)返回行 { Matrix ret(); 一行的返回值 0; i< m_col; i++) { ret[0][i] = m_ptr[(indeX) *m_col + i] ; } ret; } Matrix Matrix::getcol(Index_T indeX)返回列 1); 一列的返回值 0; i< m_row; i++) { ret[i][0] = m_ptr[i *m_col + index]; } ret; } Matrix Matrix::exponent(double X)每个元素x次幂 0; j < m_col; j++) { ret[i][j]= pow(m_ptr[i*m_col + j],X); } } void Matrix::maxlimit(set){ ) { m_ptr[i*m_col + j] = m_ptr[i*m_col + j]>max ? 0 : m_ptr[i*m_col + j]; } } } Matrix Matrix::eye()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 = [m_col]; ) { mean[j] = ; 0; i < m_row; i++) { mean[j] += m_ptr[i*m_col + j]; } mean[j] /= m_row; } ) { ) { m_ptr[i*m_col + j] -= mean[j]; } } []mean; } else 计算行均值 [m_row]; ) { mean[i] = ) { mean[i] += m_ptr[i*m_col + j]; } mean[i] /= m_col; } mean[i]; } } []mean; } } void Matrix::normalize(_In_opt_ [m_col]; mean[j]; } } ///计算标准差 ) { mean[j] += pow(m_ptr[i*m_col + j],2);列平方和 } mean[j] = sqrt(mean[j] / m_row); 开方 } ) { m_ptr[i*m_col + j] /= mean[j]; } } mean[i]; } } ) { mean[i] += pow(m_ptr[i*m_col + j],1)"> } mean[i] = sqrt(mean[i] / m_col); ) { m_ptr[i*m_col + j] /= Matrix::det() { if (m_col == m_row) ); { cout << (行列不相等无法计算") <<return ; } } ///////////////////////////////////////////////////////////////////// istream& operator>>(istream &is,Matrix &obj) { 0; i<obj.m_size; i++is >> obj.m_ptr[i]; } return is; } ostream& operator<<(ostream &0; i < obj.m_row; i++) 打印逆矩阵 0; j < obj.m_col; j++out << (obj[i][j]) << \t"; } out << endl; } out; } ofstream& 打印逆矩阵到文件 { 0; i < obj.m_row; i++; } Matrix& operator<<(Matrix &obj,1)"> val) { *obj.m_ptr = val; obj.m_curIndex = obj; } Matrix& val) { if( obj.m_curIndex == 0 || obj.m_curIndex > obj.m_size - ) { obj; } *(obj.m_ptr + obj.m_curIndeX) = val; ++obj.m_curIndex; obj; } Matrix const Matrix& lm,1)"> rm) { if (lm.m_col != rm.m_col || lm.m_row != rm.m_row) { Matrix temp(0,1)">); temp.m_ptr = NULL; cout << operator+(): 矩阵shape 不合适,m_col:" << lm.m_col << ,1)">" << rm.m_col << . m_row:" << lm.m_row << " << rm.m_row <<return temp; 数据不合法时候,返回空矩阵 } Matrix ret(lm.m_row,lm.m_col); ) { ret.m_ptr[i] = lm.m_ptr[i] + rm.m_ptr[i]; } ret; } Matrix operator-(): 矩阵shape 不合适,1)">" <<lm.m_col<<"<<rm.m_col<<"<< lm.m_row <<"<< rm.m_row << endl; ) { ret.m_ptr[i] = lm.m_ptr[i] -const Matrix& rm) if (lm.m_size == 0 || rm.m_size == 0 || lm.m_col !=operator*(): 矩阵shape 不合适,rm.m_col); 0; i<lm.m_row; i++0; j< rm.m_col; j++for (Index_T k = 0; k< lm.m_col; k++)lm.m_col == rm.m_row { ret.m_ptr[i*rm.m_col + j] += lm.m_ptr[i*lm.m_col + k] * rm.m_ptr[k*rm.m_col + j]; } } } double val,1)">矩阵乘 单数 { Matrix ret(rm.m_row,1)">) { ret.m_ptr[i] = val *const Matrix&lm,1)">double val) { Matrix ret(lm.m_row,1)"> lm.m_ptr[i]; } ret; } Matrix 矩阵除以 单数 ) { ret.m_ptr[i] = lm.m_ptr[i]/val; } ret; } Matrix Matrix::multi(const Matrix&rm) 对应元素相乘 if (m_col != rm.m_col || m_row !=@H_933_16@multi(const Matrix&rm): 矩阵shape 不合适,1)">" << m_col << " << m_row << } Matrix ret(m_row,1)">) { ret.m_ptr[i] = m_ptr[i] * ret; } Matrix& Matrix:: rhs) { if (this != &rhs) { m_row = rhs.m_size; NULL) [] m_ptr; m_ptr = ) { m_ptr[i] = rhs.m_ptr[i]; } } ||matrix||_2 求A矩阵的2范数 Matrix::norm2() { double norm = 0; i < m_size; ++i) { norm += m_ptr[i] * m_ptr[i]; } return ()sqrt(norm); } Matrix::norm1() { i) { sum += abs(m_ptr[i]); } sum; } Matrix::mean() { (m_ptr[i]); } return sum/@H_933_16@m_size; } void Matrix::sort( tem; for (Index_T j = i + 1; j<m_size; j++true) { if (m_ptr[i]>@H_933_16@m_ptr[j]) { tem = m_ptr[i]; m_ptr[i] = m_ptr[j]; m_ptr[j] = tem; } } { if (m_ptr[i]< tem; } } } } } Matrix Matrix::diag() { m_col) { Matrix m(); cout << diag():m_row != m_col m; } Matrix m(m_row); ) { m.m_ptr[i*m_row + i] = m_ptr[i*m_row + i]; } m; } Matrix Matrix::T() { Matrix tem(m_col,m_row); 0; j<m_col; j++) { tem[j][i] = m_ptr[i*m_col + j]; (*this)[i][j] } } tem; } void Matrix::QR(Matrix &Q,Matrix &R) { 如果A不是一个二维方阵,则提示错误,函数计算结束 m_col) { printf(ERROE: QR() parameter A is not a square matrix!\n); ; } const Index_T N = m_row; double *a = [n]; double *b = [n]; 0; j < N; ++j) (Gram-Schmidt) 正交化方法 0; i < N; ++i) 第j列的数据存到a,b a[i] = b[i] = m_ptr[i * N + j]; 0; i<j; ++i) 第j列之前的列 { R.m_ptr[i * N + j] = 0; // for (Index_T m = 0; m < N; ++@H_933_16@m) { R.m_ptr[i * N + j] += a[m] * Q.m_ptr[m *N + i]; R[i,j]值为Q第i列与A的j列的内积 } @H_933_16@m) { b[m] -= R.m_ptr[i * N + j] * Q.m_ptr[m * N + i]; // } } ; 0; i < N; ++i) { norm += b[i] * b[i]; } norm = ()sqrt(norm); R.m_ptr[j*N + j] = norm; 向量b[]的2范数存到R[j,j] i) { Q.m_ptr[i * N + j] = b[i] / norm; Q 阵的第j列为单位化的b[] []a; []b; } Matrix Matrix::eig_val(_In_opt_ Index_T _iters) { 0 || m_row != m_col) { cout << 矩阵为空或者非方阵! endl; Matrix rets( rets; } if (det() == 0) cout << "非满秩矩阵没法用QR分解计算特征值!" << endl; Matrix rets(0); return rets; } m_row; Matrix matcopy(*this);备份矩阵 Matrix Q(N),R(N); 当迭代次数足够多时,A 趋于上三角矩阵,上三角矩阵的对角元就是A的全部特征值。*/ 0; k < _iters; ++k) { cout<<"this:\n"<<*this<<endl; QR(Q,R); *this = R*Q; cout<<"Q:\n"<<Q<<endl; cout<<"R:\n"<<R<<endl; } Matrix val = diag(); *this = matcopy;恢复原始矩阵; val; } Matrix Matrix::eig_vect(_In_opt_ Index_T _iters) { if (det() == ) { cout << 非满秩矩阵没法用QR分解计算特征向量! endl; Matrix rets(); rets; } Matrix matcopy(*备份矩阵 Matrix eigenValue = eig_val(_iters); Matrix ret(m_row); const Index_T NUM = m_col; eValue; sum,midSum,diag; Matrix copym(*for (Index_T count = 0; count < NUM; ++count) { 计算特征值为eValue,求解特征向量时的系数矩阵 *this = copym; eValue = eigenValue[count][count]; 0; i < m_col; ++i)A-lambda*I { m_ptr[i * m_col + i] -= eValue; } cout<<*this<<endl; 将 this为阶梯型的上三角矩阵 0; i < m_row - 1; ++i) { diag = m_ptr[i*m_col + i]; 提取对角元素 for (Index_T j = i; j < m_col; ++j) { m_ptr[i*m_col + j] /= diag; 【i,i】元素变为1 1; j<m_row; ++j) { diag = m_ptr[j * m_col + i]; for (Index_T q = i; q < m_col; ++q)消去第i+1行的第i个元素 { m_ptr[j*m_col + q] -= diag*m_ptr[i*m_col + q]; } } } 特征向量最后一行元素置为1 midSum = ret.m_ptr[(ret.m_row - 1) * ret.m_col + count] = for (int m = m_row - 2; m >= 0; --@H_933_16@m) { sum = 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); 0; i < ret.m_row; ++i) { ret.m_ptr[i * ret.m_col + count] /= midSum; 每次求出一个列向量 } } * ret; } Matrix Matrix::cov(@H_933_16@m_row 样本数,column 变量数 if (m_col == ) { Matrix m( m; } double[m_col]; 均值向量 0; j<m_col; j++) init { mean[j] = ; } Matrix ret(m_col); @H_933_16@mean ) { mean[j] += m_ptr[i*m_col + j]; } mean[j] /= m_row; } Index_T i,k,j; for (i = 0; i<m_col; i++) 第一个变量 for (j = i; j<m_col; j++) 第二个变量 { for (k = 0; k<m_row; k++) 计算 { ret[i][j] += (m_ptr[k*m_col + i] - mean[i])*(m_ptr[k*m_col + j] - mean[j]); } ) { ret[i][j] /= (m_row-); } { ret[i][j] /= (m_row); } } } 补全对应面 for (j = 0; j<i; j++) { ret[i][j] = ret[j][i]; } } ret; } * 返回代数余子式 double CalcAlgebraicCofactor( Matrix& srcMat,Index_T ai,Index_T aj) { Index_T temMatLen = srcMat.row()-; Matrix temMat(temMatLen); for (Index_T bi = 0; bi < temMatLen; bi++for (Index_T bj = 0; bj < temMatLen; bj++) { Index_T rowOffset = bi < ai ? ; Index_T colOffset = bj < aj ? ; temMat[bi][bj] = srcMat[bi + rowOffset][bj + colOffset]; } } int flag = (ai + aj) % return flag * temMat.det(); } * 返回伴随阵 Matrix Matrix::adjoint() { m_col) { return Matrix(); } Matrix adjointMat(m_row); for (Index_T ai = 0; ai < m_row; ai++for (Index_T aj = 0; aj < m_row; aj++) { adjointMat.m_ptr[aj*m_row + ai] = CalcAlgebraicCofactor(*); } } adjointMat; } Matrix Matrix::inverse() { double detOfMat = det(); if (detOfMat == 行列式为0,不能计算逆矩阵。); } return adjoint()/detOfMat; }@H_696_186@
以上是大佬教程为你收集整理的C++矩阵运算类(Matrix.h)全部内容,希望文章能够帮你解决C++矩阵运算类(Matrix.h)所遇到的程序开发问题。
如果觉得大佬教程网站内容还不错,欢迎将大佬教程推荐给程序员好友。
本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。