在C++中实现矩阵运算
本文博客链接:http://blog.csdn.net/jdh99,作者:jdh,转载请注明.
参考链接:http://sc.dhu.edu.cn/weblearning/math/jisuanfangfa/matlabpg/pg6.htm
环境:
主机:XP
开发环境:mingw
功能:
在C++中实现矩阵运算
说明:
定义了两个类,一个是_Matrix,这是一个二维矩阵类,定义了初始化的方法.另一个是_Matrix_Calc,这个类定义了矩阵的基本运算,包括加,减,乘,转置,求行列式值,求逆矩阵.
源代码:
_Matrix.h:
#ifndef _MATRIX_H #define _MATRIX_H //头文件 #include <stdio.h> #include <stdlib.h> //矩阵数据结构 //二维矩阵 class _Matrix { private: public: int m; int n; float *arr; //初始化 _Matrix(int mm = 0,int nn = 0); //设置m void set_m(int mm); //设置n void set_n(int nn); //初始化 void init_matrix(); //释放 void free_matrix(); //读取i,j坐标的数据 //失败返回-31415,成功返回值 float read(int i,int j); //写入i,j坐标的数据 //失败返回-1,成功返回1 int write(int i,int j,float val); }; //二维运算类 class _Matrix_Calc { private: public: _Matrix_Calc(); //C = A + B //成功返回1,失败返回-1 int add(_Matrix *A,_Matrix *B,_Matrix *C); //C = A - B //成功返回1,失败返回-1 int subtract(_Matrix *A,_Matrix *B,_Matrix *C); //C = A * B //成功返回1,失败返回-1 int multiply(_Matrix *A,_Matrix *B,_Matrix *C); //行列式的值,只能计算2 * 2,3 * 3 //失败返回-31415,成功返回值 float _Matrix_Calc::det(_Matrix *A); //求转置矩阵,B = AT //成功返回1,失败返回-1 int transpos(_Matrix *A,_Matrix *B); //求逆矩阵,B = A^(-1) //成功返回1,失败返回-1 int inverse(_Matrix *A,_Matrix *B); }; #endif
#include "_Matrix.h" //矩阵类方法 //初始化 _Matrix::_Matrix(int mm,int nn) { m = mm; n = nn; } //设置m void _Matrix::set_m(int mm) { m = mm; } //设置n void _Matrix::set_n(int nn) { n = nn; } //初始化 void _Matrix::init_matrix() { arr = new float[m * n]; } //释放 void _Matrix::free_matrix() { delete []arr; } //读取i,j坐标的数据 //失败返回-31415,成功返回值 float _Matrix::read(int i,int j) { if (i >= m || j >= n) { return -31415; } return *(arr + i * n + j); } //写入i,j坐标的数据 //失败返回-1,成功返回1 int _Matrix::write(int i,int j,float val) { if (i >= m || j >= n) { return -1; } *(arr + i * n + j) = val; return 1; } //矩阵运算类方法 //初始化 _Matrix_Calc::_Matrix_Calc() { } //C = A + B //成功返回1,失败返回-1 int _Matrix_Calc::add(_Matrix *A,_Matrix *B,_Matrix *C) { int i = 0; int j = 0; //判断是否可以运算 if (A->m != B->m || A->n != B->n || \ A->m != C->m || A->n != C->n) { return -1; } //运算 for (i = 0;i < C->m;i++) { for (j = 0;j < C->n;j++) { C->write(i,j,A->read(i,j) + B->read(i,j)); } } return 1; } //C = A - B //成功返回1,失败返回-1 int _Matrix_Calc::subtract(_Matrix *A,_Matrix *B,_Matrix *C) { int i = 0; int j = 0; //判断是否可以运算 if (A->m != B->m || A->n != B->n || \ A->m != C->m || A->n != C->n) { return -1; } //运算 for (i = 0;i < C->m;i++) { for (j = 0;j < C->n;j++) { C->write(i,j,A->read(i,j) - B->read(i,j)); } } return 1; } //C = A * B //成功返回1,失败返回-1 int _Matrix_Calc::multiply(_Matrix *A,_Matrix *B,_Matrix *C) { int i = 0; int j = 0; int k = 0; float temp = 0; //判断是否可以运算 if (A->m != C->m || B->n != C->n || \ A->n != B->m) { return -1; } //运算 for (i = 0;i < C->m;i++) { for (j = 0;j < C->n;j++) { temp = 0; for (k = 0;k < A->n;k++) { temp += A->read(i,k) * B->read(k,j); } C->write(i,j,temp); } } return 1; } //行列式的值,只能计算2 * 2,3 * 3 //失败返回-31415,成功返回值 float _Matrix_Calc::det(_Matrix *A) { float value = 0; //判断是否可以运算 if (A->m != A->n || (A->m != 2 && A->m != 3)) { return -31415; } //运算 if (A->m == 2) { value = A->read(0,0) * A->read(1,1) - A->read(0,1) * A->read(1,0); } else { value = A->read(0,0) * A->read(1,1) * A->read(2,2) + \ A->read(0,1) * A->read(1,2) * A->read(2,0) + \ A->read(0,2) * A->read(1,0) * A->read(2,1) - \ A->read(0,0) * A->read(1,2) * A->read(2,1) - \ A->read(0,1) * A->read(1,0) * A->read(2,2) - \ A->read(0,2) * A->read(1,1) * A->read(2,0); } return value; } //求转置矩阵,B = AT //成功返回1,失败返回-1 int _Matrix_Calc::transpos(_Matrix *A,_Matrix *B) { int i = 0; int j = 0; //判断是否可以运算 if (A->m != B->n || A->n != B->m) { return -1; } //运算 for (i = 0;i < B->m;i++) { for (j = 0;j < B->n;j++) { B->write(i,j,A->read(j,i)); } } return 1; } //打印2维矩阵 void printff_matrix(_Matrix *A) { int i = 0; int j = 0; int m = 0; int n = 0; m = A->m; n = A->n; for (i = 0;i < m;i++) { for (j = 0;j < n;j++) { printf("%f ",A->read(i,j)); } printf("\n"); } } //求逆矩阵,B = A^(-1) //成功返回1,失败返回-1 int _Matrix_Calc::inverse(_Matrix *A,_Matrix *B) { int i = 0; int j = 0; int k = 0; _Matrix m(A->m,2 * A->m); float temp = 0; float b = 0; //判断是否可以运算 if (A->m != A->n || B->m != B->n || A->m != B->m) { return -1; } /* //如果是2维或者3维求行列式判断是否可逆 if (A->m == 2 || A->m == 3) { if (det(A) == 0) { return -1; } } */ //增广矩阵m = A | B初始化 m.init_matrix(); for (i = 0;i < m.m;i++) { for (j = 0;j < m.n;j++) { if (j <= A->n - 1) { m.write(i,j,A->read(i,j)); } else { if (i == j - A->n) { m.write(i,j,1); } else { m.write(i,j,0); } } } } //高斯消元 //变换下三角 for (k = 0;k < m.m - 1;k++) { //如果坐标为k,k的数为0,则行变换 if (m.read(k,k) == 0) { for (i = k + 1;i < m.m;i++) { if (m.read(i,k) != 0) { break; } } if (i >= m.m) { return -1; } else { //交换行 for (j = 0;j < m.n;j++) { temp = m.read(k,j); m.write(k,j,m.read(k + 1,j)); m.write(k + 1,j,temp); } } } //消元 for (i = k + 1;i < m.m;i++) { //获得倍数 b = m.read(i,k) / m.read(k,k); //行变换 for (j = 0;j < m.n;j++) { temp = m.read(i,j) - b * m.read(k,j); m.write(i,j,temp); } } } //变换上三角 for (k = m.m - 1;k > 0;k--) { //如果坐标为k,k的数为0,则行变换 if (m.read(k,k) == 0) { for (i = k + 1;i < m.m;i++) { if (m.read(i,k) != 0) { break; } } if (i >= m.m) { return -1; } else { //交换行 for (j = 0;j < m.n;j++) { temp = m.read(k,j); m.write(k,j,m.read(k + 1,j)); m.write(k + 1,j,temp); } } } //消元 for (i = k - 1;i >= 0;i--) { //获得倍数 b = m.read(i,k) / m.read(k,k); //行变换 for (j = 0;j < m.n;j++) { temp = m.read(i,j) - b * m.read(k,j); m.write(i,j,temp); } } } //将左边方阵化为单位矩阵 for (i = 0;i < m.m;i++) { if (m.read(i,i) != 1) { //获得倍数 b = 1 / m.read(i,i); //行变换 for (j = 0;j < m.n;j++) { temp = m.read(i,j) * b; m.write(i,j,temp); } } } //求得逆矩阵 for (i = 0;i < B->m;i++) { for (j = 0;j < B->m;j++) { B->write(i,j,m.read(i,j + m.m)); } } //释放增广矩阵 m.free_matrix(); return 1; }
#include <stdio.h> #include <iostream> #include "_Matrix.h" //带速度变量卡尔曼滤波 using namespace std; //打印2维矩阵 void printf_matrix(_Matrix *A) { int i = 0; int j = 0; int m = 0; int n = 0; m = A->m; n = A->n; for (i = 0;i < m;i++) { for (j = 0;j < n;j++) { printf("%f\t",A->read(i,j)); } printf("\n"); } } int main() { int i = 0; int j = 0; int k = 0; _Matrix_Calc m_c; _Matrix m1(3,3); _Matrix m2(3,3); _Matrix m3(3,3); //初始化内存 m1.init_matrix(); m2.init_matrix(); m3.init_matrix(); //初始化数据 k = 1; for (i = 0;i < m1.m;i++) { for (j = 0;j < m1.n;j++) { m1.write(i,j,k++); } } for (i = 0;i < m2.m;i++) { for (j = 0;j < m2.n;j++) { m2.write(i,j,k++); } } //原数据 printf("A:\n"); printf_matrix(&m1); printf("B:\n"); printf_matrix(&m2); printf("A:行列式的值%f\n",m_c.det(&m1)); //C = A + B if (m_c.add(&m1,&m2,&m3) > 0) { printf("C = A + B:\n"); printf_matrix(&m3); } //C = A - B if (m_c.subtract(&m1,&m2,&m3) > 0) { printf("C = A - B:\n"); printf_matrix(&m3); } //C = A * B if (m_c.multiply(&m1,&m2,&m3) > 0) { printf("C = A * B:\n"); printf_matrix(&m3); } //C = AT if (m_c.transpos(&m1,&m3) > 0) { printf("C = AT:\n"); printf_matrix(&m3); } /* m1.write(0,0,0); m1.write(0,1,1); m1.write(0,2,0); m1.write(1,0,1); m1.write(1,1,1); m1.write(1,2,-1); m1.write(2,0,0); m1.write(2,1,-2); m1.write(2,2,3); */ if (m_c.inverse(&m1,&m3) > 0) { printf("C = A^(-1):\n"); printf_matrix(&m3); } getchar(); return 0; }