首页 > 代码库 > c++矩阵运算

c++矩阵运算

#pragma once
#include <iostream>
class Matrix
{
public:
    Matrix(int m, int n);             //构建一个m*n的全零矩阵
    Matrix(int n);                 //构建一个n*n的单位矩阵
    Matrix(const Matrix &);         //拷贝构造函数,深拷贝
    Matrix(double* items, int m, int n);//根据数组拷贝一个矩阵
    ~Matrix();

    int getRowNum() const;                //返回矩阵的行数
    int getColNum() const;                //返回矩阵的列数

    Matrix Trans() const;                //将矩阵转置
    //矩阵初等行变换
    //如果j=-1,则对i扩大multiply倍
    //如果j在取值范围内,则将第i行扩大multiply倍加到j行
    void RowSwap(int i, int j, double multiply);
    //交换两行
    void RowSwap(int i, int j);
    double get(int i, int j) const;            //返回矩阵第i行j列元素
    void set(int i, int j, double val);        //设置矩阵第i行j列元素

    Matrix operator +(const Matrix &m);         //两个矩阵相加
    Matrix operator -(const Matrix &m);         //两个矩阵相减
    Matrix operator *(const Matrix &m);         //两个矩阵相乘
    Matrix operator *(const double f);         //矩阵乘以常数,这里是矩阵在前,数字在后
    Matrix Inverse();
    friend std::ostream& operator <<(std::ostream &os, const Matrix &m);//简单重载<<

private:
    double *item;        //指向矩阵首元素的指针
    int rowNum;        //矩阵行数
    int colNum;        //矩阵列数
};
#include "Matrix.h"
#include <iostream>
#include <cmath>

using namespace std;
Matrix::Matrix(int m, int n)
{
    if (m < 0 || n < 0)
    {
        cout << "矩阵大小不能为负\n";
        return;
    }
    rowNum = m;
    colNum = n;
    item = new double[m*n];
    for (int i = 0; i < m*n; i++)
    {
        item[i] = 0;
    }
}

Matrix::Matrix(double* items, int m, int n)
{
    item = items;
    rowNum = m;
    colNum = n;
}
Matrix::Matrix(int n)
{
    rowNum = colNum = n;
    item = new double[n*n];
    for (int i = 0; i < n; i++)
    {
        for (int j = 0; j < n; j++)
        {
            if (i == j)
                set(i, j, 1);
            else
                set(i, j, 0);
        }
    }
}
Matrix::Matrix(const Matrix &M)
{
    colNum = M.colNum;
    rowNum = M.rowNum;
    //这里不能对指针直接赋值,复制对求逆、转置等操作会影响原矩阵
    item = new double[colNum*rowNum];
    for (int i = 0; i < colNum*rowNum; i++)
    {
        item[i] = M.item[i];
    }
}
Matrix::~Matrix()
{
}
double Matrix::get(int i, int j) const
{
    return item[i*colNum + j];
}
void Matrix::set(int i, int j, double value)
{
    item[i*colNum + j] = value;
}
void Matrix::RowSwap(int i, int j, double multiply)
{
    if (j == -1)
    {
        for (int k = 0; k < colNum; k++)
        {
            set(i, k, multiply*get(i, k));
        }
    }
    else
    {
        for (int k = 0; k < colNum; k++)
        {
            set(j, k, multiply*get(i, k) + get(j, k));
        }
    }
}
void Matrix::RowSwap(int i, int j)
{
    Matrix _copy = *this;
    for (int k = 0; k < colNum; k++)
    {
        double swap = _copy.get(j, k);
        set(j, k, _copy.get(i, k));
        set(i, k, swap);
    }
}
Matrix Matrix::Trans() const
{
    Matrix _copy = *this;
    for (int i = 0; i < rowNum; i++)
    {
        for (int j = 0; j < colNum; j++)
        {
            _copy.set(i, j, get(j, i));
        }
    }
    return _copy;
}
int Matrix::getRowNum() const
{
    return rowNum;
}
int Matrix::getColNum() const
{
    return colNum;
}
ostream& operator <<(ostream &os, const Matrix &m)
{
    for (int i = 0; i < m.rowNum; i++)
    {
        for (int j = 0; j < m.colNum; j++)
        {
            os << m.get(i, j);
            if (j != m.colNum - 1) os << " ";
            else os << "\n";
        }
    }
    return os;
}
Matrix Matrix::operator +(const Matrix &m)
{
    if (m.colNum != colNum || m.rowNum != rowNum) return *this;
    Matrix _copy = *this;
    for (int i = 0; i < rowNum; i++)
    {
        for (int j = 0; j < colNum; j++)
        {
            _copy.set(i, j, get(i, j) + m.get(i, j));
        }
    }
    return _copy;
}
Matrix Matrix::operator -(const Matrix &m)
{
    if (m.colNum != colNum || m.rowNum != rowNum) return *this;
    Matrix _copy = *this;
    for (int i = 0; i < rowNum; i++)
    {
        for (int j = 0; j < colNum; j++)
        {
            _copy.set(i, j, get(i, j) - m.get(i, j));
        }
    }
    return _copy;
}
Matrix Matrix::operator *(const double f)
{
    Matrix _copy = *this;
    for (int i = 0; i < rowNum; i++)
    {
        for (int j = 0; j < colNum; j++)
        {
            _copy.set(i, j, get(i, j)*f);
        }
    }
    return _copy;
}
Matrix Matrix::operator *(const Matrix &m)
{
    if (colNum != m.rowNum)
    {
        cout << "无法相乘!";
        return *this;
    }
    Matrix _copy(rowNum, m.getColNum());
    for (int i = 0; i < rowNum; i++)
    {
        for (int j = 0; j < m.colNum; j++)
        {
            double sum = 0;
            for (int k = 0; k < m.rowNum; k++)
            {
                sum += get(i, k)*m.get(k, j);
            }
            _copy.set(i, j, sum);
        }
    }
    return _copy;
}
Matrix Matrix::Inverse()
{
    Matrix _copy = *this;
    //变换结果
    Matrix result(colNum);
    if (colNum != rowNum)
    {
        cout << "矩阵不可逆!" << endl;
        return *this;
    }
    for (int i = 0; i < rowNum; i++)
    {
        int MaxRow = i;
        //首先找到第i列的绝对值最大的数,并将该行和第i行互换
        double max = abs(_copy.get(i, i));
        for (int j = i; j < colNum; j++)
        {
            if (abs(_copy.get(j, j))>max)
            {
                max = abs(_copy.get(j, j));
                MaxRow = j;
            }
        }
        //交换j,i两行
        if (MaxRow != i)
        {
            result.RowSwap(i, MaxRow);
            _copy.RowSwap(i, MaxRow);
        }
        //将第i行做初等行变换,将第一个非0元素化为1
        double r = 1.0 / _copy.get(i, i);
        _copy.RowSwap(i, -1, r);
        result.RowSwap(i, -1, r);
        //消元
        for (int j = 0; j < rowNum; j++)
        {
            if (j == i) continue;
            r = -_copy.get(j, i);
            _copy.RowSwap(i, j, r);
            result.RowSwap(i, j, r);
        }
    }
    return result;
}

 

c++矩阵运算