c++版矩阵基本操作,行列式,逆(不限矩阵大小)

2024-05-24 01:18

本文主要是介绍c++版矩阵基本操作,行列式,逆(不限矩阵大小),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

原本是为了编程实现线性回归的,想想,里面太多矩阵操作,尤其是求逆。以前学数值分析时,也用到过列主元高斯消去求解线性方程组,LU分解求解线性方程组。这次,同样是用高斯消去法求矩阵行列式的值,用LU分解求解矩阵的逆,效率上程序执行起来还行,比用python跑一边速度快,结果一致,这也潜在说明python库中矩阵求逆的实现应该也是用的LU分解。至于矩阵的其他一些操作,基本上算简单,当然面的稀疏性矩阵的话,采用三元组的形式表示,运算起来会更好,但这里不考虑,可以放到数据结构数组的表示方式那一章中。下面给出c++实现的代码

#include <iostream>
#include <stdlib.h>
#include <string>
#include <math.h>
#include "loadData.h"
#include <fstream>
#include <sstream>
#include <stack>
using namespace std;
#define MAX_SIZE_OF_TRAINING_SET 100
#define MAX_NUMIT 100
#define ATTR_NUM 3
#define MAX 1000000
#define MIN -100000
#define MAX_MATRIX_COL 1000
#define MAX_MATRIX_ROW 100
class Matrix
{
public:double **mat;int col,row;
public:int loadMatrix(Matrix *matrix,dataToMatrix dtm){int i,j;Data *p;p=dtm.dataSet->next;matrix->mat=(double **)malloc(sizeof(double*)*dtm.col);for(i=0; i<dtm.col&&p!=NULL; i++){matrix->mat[i]=(double *)malloc(sizeof(double)*dtm.row);for(j=0; j<dtm.row; j++){matrix->mat[i][j]=p->attr_double[j];}p=p->next;}matrix->row=dtm.row;matrix->col=dtm.col;return 0;}int initMatrix(Matrix *matrix,int col,int row){matrix->col=col;matrix->row=row;matrix->mat=(double **)malloc(sizeof(double*)*col);int i=0,j=0;for(i=0; i<col; i++){matrix->mat[i]=(double *)malloc(sizeof(double)*row);for(j=0; j<row; j++)matrix->mat[i][j]=0;}return 0;}int initMatrix(Matrix *matrix,int col,int row,double lam){matrix->col=col;matrix->row=row;matrix->mat=(double **)malloc(sizeof(double*)*col);int i=0,j=0;for(i=0; i<col; i++){matrix->mat[i]=(double *)malloc(sizeof(double)*row);for(j=0; j<row; j++){matrix->mat[i][j]=0;if(i==j)matrix->mat[i][j]=lam;}}return 0;}int print(Matrix matrix){int i,j;for(i=0; i<matrix.col; i++){for(j=0; j<matrix.row; j++){cout<<matrix.mat[i][j]<<"  ";}cout<<endl;}}int copy(Matrix matrixA,Matrix *matrixB){int i,j;//matrixB->mat=(double **)malloc(sizeof(double*)*matrixA.col);for(i=0; i<matrixA.col; i++){//matrixB->mat[i]=(double *)malloc(sizeof(double)*matrixA.row);for(j=0; j<matrixA.row; j++){matrixB->mat[i][j]=matrixA.mat[i][j];}}matrixB->col=matrixA.col;matrixB->row=matrixA.row;return 0;}Matrix getOneRow(Matrix matrix,int iRow){Matrix oneRow;oneRow.col=matrix.col;oneRow.row=1;int i=0;initMatrix(&oneRow,oneRow.col,oneRow.row);for(i=0; i<oneRow.col; i++){oneRow.mat[i][0]=matrix.mat[i][iRow-1];}return oneRow;}Matrix getOneCol(Matrix matrix,int iCol){Matrix oneCol;oneCol.row=matrix.row;oneCol.col=1;int i=0;initMatrix(&oneCol,oneCol.col,oneCol.row);for(i=0; i<oneCol.row; i++){oneCol.mat[0][i]=matrix.mat[iCol][i];}return oneCol;}int deleteOneRow(Matrix *matrix,int iRow){int i,j;for(i=iRow; i<matrix->col; i++){//for()//由于传递来的一般是最后一列,所以只需要列数--即可,不需移动,不写了}matrix->row--;}void transposematrix(Matrix matrix,Matrix *matrixT)//矩阵形式的转置{int i=0,j=0;matrixT->col=matrix.row;matrixT->row=matrix.col;//matrixT->mat=(double **)malloc(sizeof(double *)*matrixT->col);for(i=0; i<matrixT->col; i++){//matrixT->mat[i]=(double *)malloc(sizeof(double)*matrixT->row);for(j=0; j<matrixT->row; j++){matrixT->mat[i][j]=matrix.mat[j][i];//cout<<matrixT->mat[i][j]<<"  ";}//cout<<endl;}}int addmatrix(Matrix *addMatrix,Matrix matrix1,Matrix matrix2){if(matrix1.col!=matrix2.col||matrix1.row!=matrix2.row)return -1;int i,j;addMatrix->col=matrix1.col;addMatrix->row=matrix1.row;//addMatrix->mat=(double **)malloc(sizeof(double *)*addMatrix->col);for(i=0; i<matrix1.col; i++){//addMatrix->mat[i]=(double *)malloc(sizeof(double)*addMatrix->row);for(j=0; j<matrix1.row; j++){addMatrix->mat[i][j]=matrix1.mat[i][j]+matrix2.mat[i][j];//cout<<addMatrix->mat[i][j]<<"  ";}//cout<<endl;}return 0;}int submatrix(Matrix *addMatrix,Matrix matrix1,Matrix matrix2){if(matrix1.col!=matrix2.col||matrix1.row!=matrix2.row)return -1;int i,j;addMatrix->col=matrix1.col;addMatrix->row=matrix1.row;//addMatrix->mat=(double **)malloc(sizeof(double *)*addMatrix->col);for(i=0; i<matrix1.col; i++){//addMatrix->mat[i]=(double *)malloc(sizeof(double)*addMatrix->row);for(j=0; j<matrix1.row; j++){addMatrix->mat[i][j]=matrix1.mat[i][j]-matrix2.mat[i][j];//cout<<addMatrix->mat[i][j]<<"  ";}//cout<<endl;}return 0;}int multsmatrix(Matrix *multsMatrix,Matrix matrix1,Matrix matrix2)//矩阵形式的相乘{if(matrix1.row!=matrix2.col)return -1;int i,j,k,l;multsMatrix->col=matrix1.col;multsMatrix->row=matrix2.row;//multsMatrix->mat=(double **)malloc(sizeof(double *)*(multsMatrix->col));for(i=0; i<matrix1.col; i++){// multsMatrix->mat[i]=(double *)malloc(sizeof(double)*(multsMatrix->row));for(j=0; j<matrix2.row; j++){multsMatrix->mat[i][j]=0;}}for(i=0; i<matrix1.col; i++){for(j=0; j<matrix2.row; j++){for(k=0; k<matrix1.row; k++){multsMatrix->mat[i][j]+=matrix1.mat[i][k]*matrix2.mat[k][j];}}}return 0;}//行列式double detmatrix(Matrix matrix){if(matrix.col!=matrix.row)return -1;double det=1;int i=0,j,k;double max=MIN;int swap=-1;double temp;double aij[MAX_MATRIX_COL][MAX_MATRIX_ROW];for(k=0; k<matrix.row-1; k++)//k表示第k次消元,一共需要n-1次{for(i=0; i<matrix.col; i++){if(matrix.mat[i][k]>max)//每一次消元都是比较第k列的元素,选出第k列中最大的一行{swap=i;}}//找到第k次列主元消去的最大行的下标if(swap==-1||matrix.mat[swap][k]==0)return -1;//最大主元为0for(j=0; j<matrix.row; j++){temp=matrix.mat[k][j];matrix.mat[k][j]=matrix.mat[swap][j];matrix.mat[swap][j]=temp;}//第k次消元,选出最大的一行是swap行,与第k行交换for(i=k+1; i<matrix.col; i++){aij[i][k]=matrix.mat[i][k]/matrix.mat[k][k];// 第k次消元,主元素为第k行第k列,把第k行以下的行都进行消元for(j=k; j<matrix.row; j++)//对于k行以下的每一行的每一列元素都减去主行与消元因子的乘积{matrix.mat[i][j]-=aij[i][k]*matrix.mat[k][j];}}}for(i=0; i<matrix.col; i++){det*=matrix.mat[i][i];/*for(j=0; j<matrix.row; j++){cout<<aij[i][j]<<"  ";}cout<<endl;*/}cout<<"det="<<det<<endl;return det;}//高斯消元矩阵求逆,特别注意,LU分解不能进行行列式变换int nimatrix(Matrix *niMatrix,Matrix matrix){if(matrix.col!=matrix.row)return -1;//if(detmatrix(matrix)==0)//这里调用求行列式进行了列主元消去改变了参数矩阵,如何传递不改变是一个问题//return -1;int i=0,j,k;double temp;Matrix cpMatrix;Matrix uMatrix;Matrix lMatrix;Matrix uniMatrix;Matrix lniMatrix;initMatrix(&uniMatrix,matrix.col,matrix.row);initMatrix(&lniMatrix,matrix.col,matrix.row);initMatrix(&cpMatrix,matrix.col,matrix.row);initMatrix(&uMatrix,matrix.col,matrix.row);initMatrix(&lMatrix,uMatrix.col,uMatrix.row);copy(matrix,&cpMatrix);//cout<<"cpMatrix"<<endl;//print(cpMatrix);double aij[MAX_MATRIX_COL][MAX_MATRIX_ROW];for(k=0; k<matrix.row-1; k++)//k表示第k次消元,一共需要n-1次{for(i=k+1; i<matrix.col; i++){aij[i][k]=matrix.mat[i][k]/matrix.mat[k][k];// 第k次消元,主元素为第k行第k列,把第k行以下的行都进行消元for(j=k; j<matrix.row; j++)//对于k行以下的每一行的每一列元素都减去主行与消元因子的乘积{matrix.mat[i][j]-=aij[i][k]*matrix.mat[k][j];}}}copy(matrix,&uMatrix);cout<<"uMatrix"<<endl;print(uMatrix);for(j=0; j<matrix.row; j++){for(i=j+1; i<matrix.col; i++){temp=0;for(k=0; k<j; k++){temp=lMatrix.mat[i][k]*uMatrix.mat[k][j];}lMatrix.mat[i][j]=1/uMatrix.mat[j][j]*(cpMatrix.mat[i][j]-temp);}}for(i=0; i<lMatrix.col; i++){for(j=0; j<lMatrix.row; j++){if(i==j)lMatrix.mat[i][j]=1;if(j>i)lMatrix.mat[i][j]=0;}}cout<<"lMatrix"<<endl;print(lMatrix);Matrix multsMatrix;multsMatrix.initMatrix(&multsMatrix,lMatrix.col,uMatrix.row);matrix.multsmatrix(&multsMatrix,lMatrix,uMatrix);cout<<"lu"<<endl;print(multsMatrix);//计算u逆for(j=0; j<uMatrix.row; j++){for(i=j; i>=0; i--){if(i==j)uniMatrix.mat[i][j]=1/uMatrix.mat[i][j];else{temp=0;for(k=j; k>i; k--){temp+=uMatrix.mat[i][k]*uniMatrix.mat[k][j];}uniMatrix.mat[i][j]=-1/uMatrix.mat[i][i]*temp;}}}cout<<"uniMatrix"<<endl;print(uniMatrix);//Matrix multsMatrix;//matrix.multsmatrix(&multsMatrix,uMatrix,uniMatrix);//cout<<"multsMatrix"<<endl;//print(multsMatrix);//计算l逆for(j=0; j<lMatrix.row; j++){for(i=0; i<lMatrix.col; i++){if(j==i)lniMatrix.mat[i][j]=1;else{temp=0;for(k=j; k<i; k++){temp+=(lMatrix.mat[i][k]*lniMatrix.mat[k][j]);}lniMatrix.mat[i][j]=-temp;}}}cout<<"lniMatrix"<<endl;print(lniMatrix);multsmatrix(&multsMatrix,uniMatrix,lniMatrix);cout<<"luni"<<endl;print(multsMatrix);//initMatrix(niMatrix,multsMatrix.col,multsMatrix.row);copy(multsMatrix,niMatrix);multsmatrix(&multsMatrix,cpMatrix,*niMatrix);cout<<"luluni"<<endl;print(multsMatrix);copy(cpMatrix,&matrix);}
};

这篇关于c++版矩阵基本操作,行列式,逆(不限矩阵大小)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/996960

相关文章

C++统计函数执行时间的最佳实践

《C++统计函数执行时间的最佳实践》在软件开发过程中,性能分析是优化程序的重要环节,了解函数的执行时间分布对于识别性能瓶颈至关重要,本文将分享一个C++函数执行时间统计工具,希望对大家有所帮助... 目录前言工具特性核心设计1. 数据结构设计2. 单例模式管理器3. RAII自动计时使用方法基本用法高级用法

深入解析C++ 中std::map内存管理

《深入解析C++中std::map内存管理》文章详解C++std::map内存管理,指出clear()仅删除元素可能不释放底层内存,建议用swap()与空map交换以彻底释放,针对指针类型需手动de... 目录1️、基本清空std::map2️、使用 swap 彻底释放内存3️、map 中存储指针类型的对象

C++ STL-string类底层实现过程

《C++STL-string类底层实现过程》本文实现了一个简易的string类,涵盖动态数组存储、深拷贝机制、迭代器支持、容量调整、字符串修改、运算符重载等功能,模拟标准string核心特性,重点强... 目录实现框架一、默认成员函数1.默认构造函数2.构造函数3.拷贝构造函数(重点)4.赋值运算符重载函数

SQL Server 查询数据库及数据文件大小的方法

《SQLServer查询数据库及数据文件大小的方法》文章介绍了查询数据库大小的SQL方法及存储过程实现,涵盖当前数据库、所有数据库的总大小及文件明细,本文结合实例代码给大家介绍的非常详细,感兴趣的... 目录1. 直接使用SQL1.1 查询当前数据库大小1.2 查询所有数据库的大小1.3 查询每个数据库的详

C++ vector越界问题的完整解决方案

《C++vector越界问题的完整解决方案》在C++开发中,std::vector作为最常用的动态数组容器,其便捷性与性能优势使其成为处理可变长度数据的首选,然而,数组越界访问始终是威胁程序稳定性的... 目录引言一、vector越界的底层原理与危害1.1 越界访问的本质原因1.2 越界访问的实际危害二、基

c++日志库log4cplus快速入门小结

《c++日志库log4cplus快速入门小结》文章浏览阅读1.1w次,点赞9次,收藏44次。本文介绍Log4cplus,一种适用于C++的线程安全日志记录API,提供灵活的日志管理和配置控制。文章涵盖... 目录简介日志等级配置文件使用关于初始化使用示例总结参考资料简介log4j 用于Java,log4c

C++归并排序代码实现示例代码

《C++归并排序代码实现示例代码》归并排序将待排序数组分成两个子数组,分别对这两个子数组进行排序,然后将排序好的子数组合并,得到排序后的数组,:本文主要介绍C++归并排序代码实现的相关资料,需要的... 目录1 算法核心思想2 代码实现3 算法时间复杂度1 算法核心思想归并排序是一种高效的排序方式,需要用

C++11范围for初始化列表auto decltype详解

《C++11范围for初始化列表autodecltype详解》C++11引入auto类型推导、decltype类型推断、统一列表初始化、范围for循环及智能指针,提升代码简洁性、类型安全与资源管理效... 目录C++11新特性1. 自动类型推导auto1.1 基本语法2. decltype3. 列表初始化3

C++11右值引用与Lambda表达式的使用

《C++11右值引用与Lambda表达式的使用》C++11引入右值引用,实现移动语义提升性能,支持资源转移与完美转发;同时引入Lambda表达式,简化匿名函数定义,通过捕获列表和参数列表灵活处理变量... 目录C++11新特性右值引用和移动语义左值 / 右值常见的左值和右值移动语义移动构造函数移动复制运算符

C++中detach的作用、使用场景及注意事项

《C++中detach的作用、使用场景及注意事项》关于C++中的detach,它主要涉及多线程编程中的线程管理,理解detach的作用、使用场景以及注意事项,对于写出高效、安全的多线程程序至关重要,下... 目录一、什么是join()?它的作用是什么?类比一下:二、join()的作用总结三、join()怎么