现在的位置: 首页 > 自动控制 > 工业·编程 > 正文

在C++中实现矩阵运算

2016-01-09 21:36 工业·编程 ⁄ 共 8944字 ⁄ 字号 暂无评论

说明:

定义了两个类,一个是_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 

_Matrix.cpp:
#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; 

main.cpp:(测试代码)

#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; 

给我留言

留言无头像?