• c++矩阵运算


    优化了一些算法
    #pragma once
    #include <iostream>
    #include <iomanip>
    #include <string>
    
    #define OVERFLOWED 1E-12
    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();
        static Matrix FromFile(std::string file);
        int getRowNum() const;                //返回矩阵的行数
        int getColNum() const;                //返回矩阵的列数
    
        Matrix Trans() const;                //将矩阵转置
    
        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& operator=(const Matrix& m);
        Matrix Inverse();
        
        friend std::ostream& operator <<(std::ostream &os, const Matrix &m);
    
    private:
        double *item;        //指向矩阵首元素
        int rowNum;        //矩阵行数
        int colNum;        //矩阵列数
    
    private:
        //矩阵初等行变换
        //如果j=-1,则对i扩大multiply倍
        //如果j在取值范围内,则将第i行扩大multiply倍加到j行
        void RowSwap(int i, int j, double multiply);
        //交换两行
        void RowSwap(int i, int j);
        void FlowOver();
    };
    #include "Matrix.h"
    #include <vector>
    #include <cmath>
    #include <fstream>
    #include <sstream>
    
    using namespace std;
    Matrix::Matrix(int m, int n)
    {
        if (m < 0 || n < 0)
        {
            cout << "矩阵大小不能为负
    ";
            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)
    {
        rowNum = m;
        colNum = n;
        item = new double[m*n];
        for (int i = 0; i < colNum*rowNum; i++)
        {
            item[i] = items[i];
        }
    }
    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.0);
                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::operator=(const Matrix & M)
    {
        colNum = M.colNum;
        rowNum = M.rowNum;
        if (item != nullptr) delete[] item;
        item = new double[colNum*rowNum];
        for (int i = 0; i < colNum*rowNum; i++)
        {
            item[i] = M.item[i];
        }
        return *this;
    }
    
    Matrix Matrix::FromFile(std::string file)
    {
        ifstream read(file);
        if (!read.is_open())
        {
            cout << "Matrix::未能打开文件
    ";
        }
        int rows = 0;
        string line;
        vector<double> nums;
        while (getline(read, line))
        {
            istringstream record(line);
            double num = 0.0;
            while (record >> num)  nums.push_back(num);
            rows++;
        }
        return Matrix(&(*nums.begin()), rows, nums.size() / rows);
    }
    
    Matrix::~Matrix()
    {
        delete[] item;
    }
    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;
        _copy.rowNum = this->colNum;
        _copy.colNum = this->rowNum;
        for (int i = 0; i < _copy.rowNum; i++)
        {
            for (int j = 0; j < _copy.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 << std::setw(10) << std::fixed << std::setprecision(12) << m.get(i, j) << " ";
            os << "
    ";
        }
        os.flush();
        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, i))>max)
                {
                    max = abs(_copy.get(j, i));
                    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);
            }
        }
        //result.FlowOver();
        return result;
    }
    void Matrix::FlowOver()
    {
        for (int i = 0; i < rowNum;i++)
        {
            for (int j = 0; j < colNum;j++)
            {
                if (abs(get(i, j)) <= OVERFLOWED) set(i, j, 0);
            }
        }
    }
     
    
    
  • 相关阅读:
    c#实现MD5加密
    AJAX学习笔记 一:简单的XMLHTTPRequest示例和asp.net异步更新。
    客户端JS验证fileupload控件,设置只允许特定的文件类型。
    三层架构下的用户登录检测。
    常用用户注册页面客户端验证脚本。
    Android Debug Bridge 技术实现原理
    Android反编译与防止反编译
    android用sharepreference保存输入框中的内容
    android include 控件详解
    android程序排序算法实现
  • 原文地址:https://www.cnblogs.com/wzxwhd/p/6031444.html
Copyright © 2020-2023  润新知