在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
#include
//矩阵数据结构
//二维矩阵
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
#include
#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;
}