编程练习:矩阵类

来源:互联网 发布:社会经济发展数据库 编辑:程序博客网 时间:2024/06/11 04:12

自己尝试以模板的形式写了一个基础矩阵类,提供了矩阵运算的基本方法,包括加减乘除、转置、求行列式、求逆,后续还会进行陆续的补充,下面添上源码,可能存在一些不足之处,希望能得到大家的建议。

//头文件Matrix.h/**@copyright yyh 2017*/#pragma once#include "stdafx.h"#define CHUDENG 0 //初等变换#define BANSUI 1//伴随阵#define REC 0//递归求行列式  速度太慢#define TRIA 1//上三角求行列式template<typename T=double>class Matrix//:private myMat{private:    typedef T value_type;    T** data;//存放数据    int cols;//矩阵列    int rows;//矩阵行public:    Matrix();    Matrix(const int &rows, const int &cols);//构造大小为rows*cols的矩阵    Matrix(T *p, int rows, int cols);//用二维数组来构造矩阵    Matrix(const Matrix<T> &m1, const Matrix<T> &m2);//合并两个矩阵    Matrix(const Matrix<T> &m);//深拷贝构造函数    void showMatrix();//输出显示整个矩阵    void zeros();//初始化为0矩阵    double cofactor(int i, int j);//求i,j处的代数余子式    bool unit();//初始化为单位阵    void exchangeRow(const int &i1, const int &i2);//交换矩阵两行    T* operator[](const int &i);//通过下标访问数矩阵元素    Matrix& operator=(const Matrix & m);//重载赋值运算符实现深拷贝    Matrix<T> Trans();//矩阵转置    double det(int method=TRIA);//求矩阵行列式    Matrix<T> operator*(Matrix<T> & m);//矩阵相乘    Matrix<T> operator+(Matrix<T> & m);//矩阵相加    Matrix<T> operator-(Matrix<T> & m);//矩阵相减    template<typename T, typename S> friend Matrix<T> operator*(Matrix<T> & m, S num);//矩阵乘以一个数    template<typename T, typename S> friend Matrix<T> operator*(S num,Matrix<T> & m );//矩阵乘以一个数    template<typename T, typename S> friend Matrix<T> operator/(Matrix<T> & m, S num);//矩阵除以一个数    Matrix<T> inverse(int method=CHUDENG);//矩阵求逆    ~Matrix();};

cpp文件

#include "stdafx.h"#include "Matrix.h"//构造函数template<typename T>Matrix<T>::Matrix(){    data = NULL;    rows = 0;    cols = 0;}template<typename T>Matrix<T>::Matrix(const int &rows, const int &cols){    data = new T* [rows];    for (int i = 0; i < rows; i++)        data[i] = new T[cols];    this->cols = cols;    this->rows = rows;}//用二维数组来构造矩阵template<typename T>Matrix<T>::Matrix(T *p, int rows, int cols){    this->rows = rows;    this->cols = cols;    data = new T*[rows];    for (int i = 0; i < rows; i++)    {        data[i] = new T[cols];        memcpy(data[i], p + i*cols, sizeof(T)*cols);    }}template<typename T>Matrix<T>::Matrix(const Matrix &m){    this->cols = m.cols;    this->rows = m.rows;    data = new T*[rows];    for (int i = 0; i < rows; i++)    {        data[i] = new T[cols];        memcpy(data[i], m.data[i], sizeof(T)*cols);    }}//矩阵合并构造函数template<typename T>Matrix<T>::Matrix(const Matrix<T> &m1, const Matrix<T> &m2){    if (m1.rows != m2.rows) exit(0);    cols = m1.cols + m2.cols;    rows = m1.rows;    data = new T*[rows];    for (int i = 0; i < rows; i++)    {        data[i] = new T[cols];        memcpy(data[i], m1.data[i], sizeof(T)*m1.cols);        memcpy(data[i]+ m1.cols, m2.data[i], sizeof(T)*m2.cols);    }}//输出显示整个矩阵template<typename T>void Matrix<T>::showMatrix(){    //控制台下有效    for (int i = 0; i < rows; i++)    {        for (int j = 0; j < cols; j++)            cout << data[i][j] << " ";        cout << endl;    }}//重载赋值运算符template<typename T>Matrix<T>& Matrix<T>::operator=(const Matrix<T> & m){    for (int i = 0; i < rows; i++)        delete[] data[i];    delete[]data;    this->cols = m.cols;    this->rows = m.rows;    data = new T*[rows];    for (int i = 0; i < rows; i++)    {        data[i] = new T[cols];        memcpy(data[i], m.data[i], sizeof(T)*cols);    }    return *this;}template<typename T>T* Matrix<T>::operator[](const int &i){    return data[i];}//0矩阵template<typename T>void Matrix<T>::zeros(){    for (int i = 0; i < rows;i++)    for (int j = 0; j < cols; j++)        data[i][j] = 0;}//单位阵template<typename T>bool Matrix<T>::unit(){    if (rows != cols) return false;    this->zeros();    for (int i = 0; i < rows; i++)        data[i][i] = 1;    return true;}//交换矩阵的两行template<typename T>void  Matrix<T>::exchangeRow(const int &i1, const int &i2){    T *tmp = new T[cols];    memcpy(tmp, data[i1], sizeof(T)*cols);    memcpy(data[i1], data[i2], sizeof(T)*cols);    memcpy(data[i2], tmp, sizeof(T)*cols);    delete[]tmp;}//矩阵转置template<typename T>Matrix<T> Matrix<T>::Trans(){    Matrix<T> m(cols, rows);    for (int i = 0; i < rows; i++)    for (int j = 0; j < cols; j++)        m[i][j] = this->data[j][i];    return m;}//求矩阵行列式template<typename T>double Matrix<T>::det(int method){    if (rows != cols) exit(0);    double result=0;    int q = 1;    if (cols == 1){        result = data[0][0];        return result;    }    if (method == REC)    {        for (int i = 0; i < cols; i++)        {            Matrix<T> M(cols - 1, cols - 1);//代数余子式            for (int u = 0; u < M.rows; u++)            for (int v = 0; v < M.cols; v++)            {                if (v < i)                    M[u][v] = data[u + 1][v];                else                    M[u][v] = data[u + 1][v + 1];            }            if (i % 2 == 0) q = 1; else q = -1;            if (data[0][i] == 0) continue;            else                result += data[0][i] * q*M.det();//递归求行列式        }        return result;    }    if (method == TRIA)    {        Matrix<T> M(*this);        for (int i = 0; i < rows; i++)        {            if (M.data[i][i] == 0)            {                for (int j = i + 1; j < rows; j++)                {                    if (M.data[j][i] != 0)                    {                        M.exchangeRow(i, j);                        q = -1;                        goto outer;                    }                }                result = 0;                return result;            }        outer:            for (int u = i+1; u < rows; u++)            {                if (M.data[u][i] == 0) continue;                for (int v = i + 1; v < cols; v++)                {                    M.data[u][v] = M.data[u][v] - M.data[u][i] / M.data[i][i] * M.data[i][v];                }            }        }        result = 1;        for (int i = 0; i < rows; i++)        {            result *= M.data[i][i];        }        return result;    }}//矩阵相乘template<typename T>Matrix<T> Matrix<T>::operator*(Matrix<T> & m){    if (cols != m.rows) exit(0);    Matrix<T> result(rows,m.cols);    for (int i = 0; i < result.rows; i++)    for (int j = 0; j < result.cols; j++)    {        result[i][j] = 0;        for (int k = 0; k < cols; k++)            result[i][j] += data[i][k] * m[k][j];    }    return result;}//矩阵乘以一个数template<typename T,typename S>Matrix<T> operator*(Matrix<T> & m, S num){    Matrix<T> result(m.rows, m.cols);    for (int i = 0; i < m.rows;i++)    for (int j = 0; j < m.cols; j++)    {        result.data[i][j] = num*m.data[i][j];    }    return result;}//矩阵乘以一个数template<typename T, typename S>Matrix<T> operator*(S num,Matrix<T> & m){    return m*num;}//矩阵除以一个数template<typename T, typename S>Matrix<T> operator/(Matrix<T> & m, S num){    Matrix<T> result(m.rows, m.cols);    for (int i = 0; i < m.rows; i++)    for (int j = 0; j < m.cols; j++)    {        result.data[i][j] = m.data[i][j]/num;    }    return result;}//矩阵相加template<typename T>Matrix<T> Matrix<T>::operator+(Matrix<T> & m){    if (cols != m.cols || rows != m.rows) exit(0);    Matrix<T> result(rows,cols);    for (int i = 0; i < result.rows; i++)    for (int j = 0; j < result.cols; j++)    {        result[i][j] = data[i][j] + m[i][j];    }    return result;}//矩阵相减template<typename T>Matrix<T> Matrix<T>::operator-(Matrix<T> & m){    if (cols != m.cols || rows != m.rows) exit(0);    Matrix<T> result(rows, cols);    for (int i = 0; i < result.rows; i++)    for (int j = 0; j < result.cols; j++)    {        result[i][j]= data[i][j] - m[i][j];    }    return result;}//矩阵求逆template<typename T>Matrix<T> Matrix<T>::inverse(int method){    if (rows != cols) exit(0);    Matrix<T> result(rows,cols);    //初等行变换求逆矩阵    if (method == CHUDENG)    {        Matrix m(rows, cols);        m.unit();        Matrix<T> expand_Matrix(*this, m);//定义扩展矩阵,左边为原矩阵,右边为单位阵        //调整矩阵        for (int i = 0; i < rows; i++)        {            if (expand_Matrix[i][i] == 0)//如果某行对角线元素等于0,搜索其它行不为0的元素的值            {                for (int j = i + 1; j < rows; j++)                {                    if (expand_Matrix[j][i] != 0)//交换这两行                    {                        expand_Matrix.exchangeRow(i, j);                        goto outer;                    }                }                exit(0);//矩阵行列式为0,程序退出            }        outer:            for (int j = i+1; j < expand_Matrix.cols; j++)            {                expand_Matrix[i][j] /= expand_Matrix[i][i];            }            expand_Matrix[i][i] = 1;            //把其它行在该列的值变为0            for (int t = 0; t < rows; t++)            {                if (t == i) continue;                for (int j = i + 1; j < expand_Matrix.cols; j++)                {                    expand_Matrix[t][j] = expand_Matrix[t][j] - expand_Matrix[i][j] * expand_Matrix[t][i];                }                expand_Matrix[t][i] = 0;            }        }        for (int i = 0; i < rows;i++)        for (int j = 0; j < cols; j++)        {            result[i][j] = expand_Matrix[i][j + cols];        }        return result;    }    //伴随矩阵法求逆    if (method == BANSUI)    {        double D = this->det();        if (D == 0) exit(0);        for (int i = 0; i < rows;i++)        for (int j = 0; j < cols; j++)        {            result[i][j] = this->cofactor(j, i) / D;        }        return result;    }}//求i,j处的代数余子式template<typename T>double Matrix<T>::cofactor(int i, int j){    if (rows != cols) exit(0);    int p = 0;    if (p % 2 == 0) p = 1; else p = -1;    Matrix<T> M(rows - 1, cols - 1);//代数余子式    for (int u = 0; u < M.rows; u++)    for (int v = 0; v < M.cols; v++)    {        if (u < i&&v< j)            M[u][v] = data[u][v];        else if (u<i&&v>=j)            M[u][v] = data[u][v + 1];        else if (u>=i&&v<j)            M[u][v] = data[u+1][v];        else            M[u][v] = data[u + 1][v+1];    }    return M.det()*p;}//析构函数template<typename T>Matrix<T>::~Matrix(){    for (int i = 0; i < rows; i++)        delete[] data[i];    delete[]data;}
1 0
原创粉丝点击