首页 > 编程语言 >C++数值计算——矩阵类的实现(一)

C++数值计算——矩阵类的实现(一)

时间:2023-07-20 23:11:46浏览次数:26  
标签:Matrix column ++ 矩阵 Number 数值 int C++ row

本系列博客将利用C++实现一系列数值算法。数值算法离不开矩阵,但是C++并未自带矩阵这一对象,直接使用数组又会带来诸多不便,因此我们需要做一些预备工作————编写一个矩阵类,实现矩阵的基本功能。一般来说,读者可以直接使用Eigen库进行矩阵计算,从头开始造轮子仅仅是为了满足笔者个人的需要。

一、成员组成

回顾矩阵的定义,我们仅需三个量就可以具体描述一个矩阵:行指标,列指标,对应位置的元素。因此我们在类Matrix(下文就如此称呼了,和代码保持一致)中定义三个数据成员:行指标,列指标,一个二重指针。

        typedef unsigned int Index;
        class Matrix{
            private:
                Index Number_of_row;//行数
                Index Number_of_column;//列数
                double **p_Matrix;//二重指针构造矩阵
}

二、基本功能的分析与实现

按一般类的定义,类Matrix需要有构造函数、析构函数和拷贝函数。构造函数生成矩阵时,矩阵的每一个位置都需要被赋值,最合适的默认值莫过于0,因此在用户未指定的情况下,默认每个值为零;如果用户指定了某个值a,则将每个位置赋值a。因此,如下创建构造函数:

        Matrix( Index num_of_row, Index num_of_column){ //一般矩阵,默认为全零矩阵。
            Number_of_row = num_of_row;
            Number_of_column = num_of_column;
            p_Matrix = new double*[num_of_row];
            for( int i = 0; i < num_of_row; i++){
                p_Matrix[i] = new double[num_of_column];
            }
            for( int i = 0; i < num_of_row; i++){
                for( int j = 0; j < num_of_column; j++){
                    p_Matrix[i][j] = 0;
                }
            }
        }
        Matrix( Index num_of_row, Index num_of_column, double value){ //一般矩阵,默认为全为value
            Number_of_row = num_of_row;
            Number_of_column = num_of_column;
            p_Matrix = new double*[num_of_row];
            for( int i = 0; i < num_of_row; i++){
                p_Matrix[i] = new double[num_of_column];
            }
            for( int i = 0; i < num_of_row; i++){
                for( int j = 0; j < num_of_column; j++){
                    p_Matrix[i][j] = value;
                }
            }
        }        

对应的析构函数和拷贝函数如下:

        //析构函数
        ~Matrix(){
            for( int i = 0; i < Number_of_row; i++){
                delete[] p_Matrix[i];
            }
            delete[] p_Matrix;
        }
        //拷贝函数
        Matrix( const Matrix &Copy_Matrix){
            Number_of_row = Copy_Matrix.Number_of_row;
            Number_of_column = Copy_Matrix.Number_of_column;
            for(int i = 0; i < Number_of_row; i++){
                p_Matrix[i] = new double[Number_of_column];
            }
            for( int i = 0; i < Number_of_row; i++){
                for( int j = 0; j < Number_of_column; j++){
                    p_Matrix[i][j] = Copy_Matrix.p_Matrix[i][j];
                }
            }
        }

对于类Matrix而言,它自然必须有能显示和改变元素值的功能,我们将这个需求交给以下两个函数:

        //输出矩阵
        void Print_Matrix(){
            for( int i = 0; i < Number_of_row; i++){
                for( int j = 0; j < Number_of_column; j++){
                    cout << p_Matrix[i][j] << " ";
                }
                cout << endl;
            }            
        }
        //改变元素,或者赋值
        void Change_Value(Index m, Index n, double x){
            if( m >= Number_of_row || n >= Number_of_column){
                cout << "Invalid! The index exceeds the range!" << endl;
            }else{
                p_Matrix[m][n] = x;
            }   
        }

当然,这种赋值的方式极度不友好,我们将在未来改写这一赋值方式。此外,我们常常需要取出某一位置的某一值,我们将这一功能交给下面这个函数:

        //取出某一元素
        friend double Get_element(Matrix &A, int m, int n){
            if(m >= 0 && m < A.Number_of_row && n >= 0 && n < A.Number_of_column){
                return A.p_Matrix[m][n];                
            }
            else{
                cout<<"The index exceeds the range!"<<endl;
                return 0;
            }
        }

三、运算符的重载

考虑矩阵的基本运算:+、-、*(包含数乘与矩阵相乘)与=(赋值),我们需要重载运算符。值得注意的是,在矩阵乘法中我们采用的循环策略,这是考虑到C++从左往右扫描数组的特点,具体可以参考《Matrix Computation》。

        //重载运算符
        //重载加法
        Matrix operator+ (const Matrix &A){
            Matrix tempMatrix(A.Number_of_row, A.Number_of_column);

            if (A.Number_of_column != this->Number_of_column || A.Number_of_row != this->Number_of_row){
                cout << "Matrices are in different size!" << endl;
            }
            else{
                for(int i = 0; i < this->Number_of_row; i++){
                    for(int j = 0; j < A.Number_of_column; j++){
                        tempMatrix.p_Matrix[i][j] = this->p_Matrix[i][j] + A.p_Matrix[i][j];
                    }
                }  
            }
            return tempMatrix;
        }
        //重载赋值
        Matrix &operator=(const Matrix &A){
            if (A.Number_of_column != this->Number_of_column || A.Number_of_row != this->Number_of_row){
                for(int i = 0; i < this->Number_of_row; i++){
                    delete[] p_Matrix[i];
                }
                delete[] p_Matrix;
                p_Matrix = new double*[A.Number_of_row];
                for( int i = 0; i < A.Number_of_row; i++){
                    p_Matrix[i] = new double[A.Number_of_column]; 
                }


                this->Number_of_row = A.Number_of_row;
                this->Number_of_column = A.Number_of_column; 
                for(int i = 0; i < this->Number_of_row; i++){
                    for(int j = 0; j < this->Number_of_column; j++){
                        this->p_Matrix[i][j] = A.p_Matrix[i][j];
                    }
                }
            }
            else{
                for(int i = 0; i < this->Number_of_row; i++){
                    for(int j = 0; j < this->Number_of_column; j++){
                        this->p_Matrix[i][j] = A.p_Matrix[i][j];
                    }
                }                              
            }      
            return *this;      
        }
        //重载减法
        Matrix operator- (const Matrix &A){
            Matrix tempMatrix(A.Number_of_row, A.Number_of_column);

            if (A.Number_of_column != this->Number_of_column || A.Number_of_row != this->Number_of_row){
                cout << "Matrices are in different size!" << endl;
            }
            else{
                for(int i = 0; i < this->Number_of_row; i++){
                    for(int j = 0; j < A.Number_of_column; j++){
                        tempMatrix.p_Matrix[i][j] = this->p_Matrix[i][j] - A.p_Matrix[i][j];
                    }
                }  
            }
            return tempMatrix;
        }      
        //重载乘法
        //数乘
        Matrix operator*(double value){
            Matrix tempMatrix(this->Number_of_row, this->Number_of_column);

            for(int i = 0; i < this->Number_of_row; i++){
                for(int j = 0; j < this->Number_of_column; j++){
                    tempMatrix.p_Matrix[i][j] = value*this->p_Matrix[i][j];
                }
            }
            return tempMatrix;
        }
        friend Matrix operator*(double value, const Matrix &A){
            Matrix tempMatrix(A.Number_of_row, A.Number_of_column);

            for(int i = 0; i < A.Number_of_row; i++){
                for(int j = 0; j < A.Number_of_column; j++){
                    tempMatrix.p_Matrix[i][j] = value*A.p_Matrix[i][j];
                }
            }
            return tempMatrix;            
        }
        //矩阵相乘
        friend Matrix operator*(Matrix &A, Matrix &B){
            Matrix tempMatrix(A.Number_of_row, B.Number_of_column);    
            if(A.Number_of_column != B.Number_of_row){
                cout<<"Invalid!"<<endl;
            }
            else{
                double s;
        
                for(int i = 0; i < A.Number_of_row; i++){
                    for(int k = 0; k < A.Number_of_column; k++){
                        s=A.p_Matrix[i][k];
                        for(int j = 0; j < B.Number_of_column; j++){
                            tempMatrix.p_Matrix[i][j] += s*B.p_Matrix[k][j];
                        }
                    }
                }
            }
            return tempMatrix;
        }

到此已经实现了矩阵的一些基本功能,在接下来的博客中,我将完善其他矩阵的功能,并且逐步实现一些古老的数值代数算法。

标签:Matrix,column,++,矩阵,Number,数值,int,C++,row
From: https://www.cnblogs.com/wsk2333/p/17569879.html

相关文章

  • 7.20 c++
    //高精度加法#include<bits/stdc++.h>usingnamespacestd;intmain(){chara1[5005],b1[5005];inta[5005],b[5005],c[5005];intla,lb,lc=1,x=0,i;memset(a,0,sizeof(a));memset(b,0,sizeof(b));memset(c,0,sizeof(c));c......
  • c++ day 13
    今天来认识c++里面的迭代器C++迭代器(Iterator)是一种用于遍历容器(如数组、向量、链表等)中元素的抽象概念。它允许你通过简单的接口在容器中移动,并访问容器中的元素,而无需了解底层数据结构的细节。迭代器提供了一种统一的方式来访问不同类型容器的元素,使得代码更加灵活和可复用。......
  • C++Const变量的存储位置
    const变量/对象的存储位置const局部变量const局部基础变量和自定义变量都存储在栈上structdiy_class{inta;intb;diy_class(inta,intb):a(a),b(b){}};intmain(){intb=1;//这个肯定在栈上constinta=10;//比较ab两个变......
  • C++架构师 课程目录
    C++架构师课程目录实现指南规划流程在实现"C++架构师课程目录"之前,我们需要先规划整个流程。以下是实现该功能的步骤:步骤描述1.创建课程目录类创建一个C++类来表示课程目录,并定义相关的成员变量和方法。2.添加课程实现向课程目录中添加课程的功能。3.删除课......
  • Android opencv Mat 创建单位矩阵
    AndroidOpenCVMat创建单位矩阵在计算机视觉和图像处理中,矩阵是一个非常重要的概念。矩阵可以表示图像的像素值、进行图像变换、计算特征向量和特征值等。Android平台上,OpenCV是一个强大的图像处理库,提供了许多矩阵操作的函数和工具。本文将介绍如何使用OpenCV在Android上创建单......
  • Python中如何将列表偶数值求和
    Python中如何将列表偶数值求和在实际的编程过程中,我们经常会遇到需要对一个列表中的偶数值进行求和的问题。Python作为一门强大的编程语言,提供了多种方法来解决这个问题。本文将介绍几种常用的方法,并提供示例来解决一个实际问题。问题描述假设我们有一个包含整数的列表,我们需要......
  • C++ 模板编程技术解析
    一、函数模板函数模板实现通用函数,根据传递类型进行编译时实参推导:template<typenameT>Tadd(Ta,Tb){returna+b;}intmain(){intx=1,y=2;doublem=1.5,n=2.5;intz=add(x,y);doublep=add(m,n);return0;}这里te......
  • C++/C的#pragma参数选项及其解析
    每种C和C++的实现支持对其宿主机或操作系统唯一的功能。例如,一些程序需要精确控制超出数据所在的储存空间,或着控制特定函数接受参数的方式。#pragma指示使每个编译程序在保留C和C++语言的整体兼容性时提供不同机器和操作系统特定的功能。编译指示被定义为机器或操作系统特定的,并且......
  • C/C++ 宏获取当前编译程序工作的CPU指令集平台(综合大全覆盖各类CPU)
    参考:https://blog.csdn.net/liulilittle/article/details/126644547?spm=1001.2101.3001.6650.6&utm_medium=distribute.pc_relevant.none-task-blog-2%7Edefault%7EBlogCommendFromBaidu%7ERate-6-126644547-blog-43935465.235%5Ev38%5Epc_relevant_default_base3&dep......
  • 题解 //「BZOJ2406」矩阵
    赛时公告现在呢?:现在有弹窗了吗「2023-07-1916:45:07」此时无声胜有声。F.「BZOJ2406」矩阵http://222.180.160.110:1024/contest/3825/problem/7这是头一次见识到把矩阵和网络流结合在一起的题目。不过这种处理方式也是我们在学习二分图时的常客了:把行和列连边表示某一元......