KeyError 发表于 2023-12-16 13:20:54

使用140行代码实现C++矩阵

本帖最后由 KeyError 于 2023-12-16 15:13 编辑




C++矩阵1.0

灰常的好用{:10_256:}


#include<cstdlib>
#include<cstring>
#include<iostream>
#define SIZE 10
#define gwidth(m) ((m) -> width)
#define gheight(m) ((m) -> height)
#define number(m, y, x) ((m) -> num[(y)][(x)])

namespace mat{
      void VProduct(unsigned a[], unsigned b[], unsigned &c, int length){
                int i;
                c = 0;
                for(i = 0;i < length;++i){
                        c += a * b;
                }
      }
      
      struct Matrix{
                unsigned int num;
                int width = 0, height = 0;
      };
      void Create(Matrix **num, int x, int y);
      void Input(Matrix *num);
      void Print(Matrix *num);
      void Setting(Matrix *a, Matrix *b);
      void Add(Matrix *a, Matrix *b, Matrix *c);
      void Minus(Matrix *a, Matrix *b, Matrix *c);
      void Product(Matrix *a, Matrix *b, Matrix *c);
      void DProduct(Matrix *a, int b, Matrix *c);
      void DProduct(Matrix *a, Matrix *b, Matrix *c);
      void Power(Matrix *a, int b, Matrix *c);
      void T(Matrix *a, Matrix **b);
      
      // A
      void Add(Matrix *a, Matrix *b, Matrix *c){
                int x, y;
                if((gwidth(a) == gwidth(b) && gwidth(b) == gwidth(c)) && (gheight(a) == gheight(b) && gheight(b) == gheight(c))){
                        for(y = 0;y < gheight(a);++y){
                              for(x = 0;x < gwidth(a);++x){
                                        number(c, y, x) = number(a, y, x) + number(b, y, x);
                              }
                        }
                }else{
                        // std::cerr << "SNE" << std::endl;
                        throw "SizeNotEquality";
                }
      }
      // C
      void Create(Matrix **numn, int x, int y){
                (*numn) = (Matrix *)malloc(sizeof(Matrix));
                if(numn == NULL){
                        std::cerr << "NCSQSB" << std::endl;
                        return;
                }
                gheight(*numn) = y;
                gwidth(*numn) = x;
                memset((*numn) -> num, 0, sizeof((*numn) -> num));
      }
      // D
      void DProduct(Matrix *a, int b, Matrix *c){
                if(gheight(a) == gheight(c) && gwidth(a) == gwidth(c)){
                        for(int y = 0;y < gheight(a);++y){
                              for(int x = 0;x < gwidth(a);++x){
                                        number(c, y, x) = b * number(a, y, x);
                              }
                        }
                }else{
                        // std::cerr << "SNE" << std::endl;
                        throw "SizeNotEquality";
                }
      }
      void DProduct(Matrix *a, Matrix *b, Matrix *c){
                if(gheight(a) == gheight(c) && gwidth(a) == gwidth(c)){
                        for(int y = 0;y < gheight(a);++y){
                              for(int x = 0;x < gwidth(a);++x){
                                        number(c, y, x) = number(b, y % gheight(b), x % gwidth(b)) * number(a, y, x);
                              }
                        }
                }else{
                        // std::cerr << "SNE" << std::endl;
                        throw "SizeNotEquality";
                }
      }
      // I
      void Input(Matrix *numn){
                for(int y = 0;y < gheight(numn);++y){
                        for(int x = 0;x < gwidth(numn);++x){
                              std::cin >> number(numn, y, x);
                        }
                }
      }
      // M
      void Minus(Matrix *a, Matrix *b, Matrix *c){
                int x, y;
                if((gwidth(a) == gwidth(b) && gwidth(b) == gwidth(c)) && (gheight(a) == gheight(b) && gheight(b) == gheight(c))){
                        for(y = 0;y < gheight(a);++y){
                              for(x = 0;x < gwidth(a);++x){
                                        number(c, y, x) = number(a, y, x) - number(b, y, x);
                              }
                        }
                }else{
                        // std::cerr << "SNE" << std::endl;
                        throw "SizeNotEquality";
                }
      }
      // P
      void Power(Matrix *a, int b, Matrix *c){
                Matrix *t, *t2;
                if(gheight(a) == gwidth(a) && gheight(c) == gwidth(c) && gheight(a) == gheight(c)){
                        if(b <= 1){
                              Setting(c, a);
                        }else if(b % 2){
                              Power(a, b / 2, t);
                              Product(t, t, t2);
                              Product(t2, a, c);
                        }else{
                              Power(a, b / 2, t);
                              Product(t, t, c);
                        }
                }else{
                        // std::cerr << "SNE" << std::endl;
                        throw "SizeNotEquality";
                }
      }
      void Print(Matrix *numn){
                for(int y = 0;y < gheight(numn);++y){
                        for(int x = 0;x < gwidth(numn);++x){
                              std::cout << number(numn, y, x) << ' ';
                        }
                        std::cout << std::endl;
                }
      }
      void Product(Matrix *a, Matrix *b, Matrix *c){
                int y, x;
                Matrix *tb;
                if(gwidth(a) == gheight(b) && gheight(a) == gheight(c) && gwidth(b) == gwidth(c)){
                        T(b, &tb);
                        for(x = 0;x < gwidth(b);++x){
                              for(y = 0;y < gheight(a);++y){
                                        VProduct(a -> num, tb -> num, number(c, y, x), gwidth(a));
                              }
                        }
                }else{
                        // std::cerr << "SNE" << std::endl;
                        throw "SizeNotEquality";
                }
      }
      // S
      void Setting(Matrix *a, Matrix *b){
                for(int y = 0;y < gheight(a);++y){
                        for(int x = 0;x < gwidth(a);++x){
                              number(a, y, x) = number(b, y % gheight(b), x % gwidth(b));
                        }
                }
      }
      // T
      void T(Matrix *a, Matrix **b){
                int x, y;
                free(b);
                Create(b, gheight(a), gwidth(a));
                for(y = 0;y < gheight(a);++y){
                        for(x = 0;x < gwidth(a);++x){
                              number(*b, x, y) = number(a, y, x);
                        }
                }
      }
}

#undef gwidth
#undef gheight
#undef number




输入与输出

void Create(Matrix **num, int x, int y);
创建一个矩阵,存储在num指向的指针中。
用法:
Create(&[指向矩阵的指针], [横向长度], [纵向长度]);

void Setting(Matrix *a, Matrix *b);
将a设为b。
(在b长度不够时循环填充,如a是3*3,
b是
{{1, 2},
{3, 4}},那么a将被赋值为
{{1, 2, 1},
{3, 4, 3},
{1, 2, 1}})

void Input(Matrix *num);
输入一个矩阵并将它存在num中。

void Print(Matrix *num);
打印num。


void Add(Matrix *a, Matrix *b, Matrix *c);
计算a+b,并将结果存储在c中。

void Minus(Matrix *a, Matrix *b, Matrix *c);
计算a-b,并将结果存在c中。

void Product(Matrix *a, Matrix *b, Matrix *c);
计算a*b,将结果存在c中。

void DProduct(Matrix *a, Matrix *b, Matrix *c);
计算a与b的点积,将结果存在c中。

void DProduct(Matrix *a, int b, Matrix *c);
计算a与标量b的点积,并将结果存在c中。

void T(Matrix *a, Matrix **b);
计算a的转置矩阵,将结果存储在b指向的指针中。

FishC 发表于 2023-12-16 13:21:16

这段代码实现了一个简单的矩阵库,其中有一些函数用来创建矩阵、输入矩阵、输出矩阵、矩阵相加、矩阵相减、矩阵乘法、标量乘法、矩阵自乘、矩阵求幂、矩阵转置等。以下是对这些函数的详细解释。

- Create函数:用来创建一个指定大小的矩阵。参数num是一个指向指针的指针,x和y分别表示矩阵的宽度和高度。

- Input函数:用来输入矩阵的元素值。

- Print函数:用来输出矩阵的元素值。

- Setting函数:用来设置矩阵a的值为矩阵b的值。

- Add函数:用来计算两个矩阵的和,并将结果保存在矩阵c中。

- Minus函数:用来计算两个矩阵的差,并将结果保存在矩阵c中。

- Product函数:用来计算两个矩阵的乘积,并将结果保存在矩阵c中。

- DProduct函数:用来计算一个矩阵与一个标量的乘积,并将结果保存在矩阵c中。

- DProduct函数:用来计算两个矩阵的点积,并将结果保存在矩阵c中。

- Power函数:用来计算一个矩阵的幂,并将结果保存在矩阵c中。

- T函数:用来计算矩阵的转置,并将结果保存在指定的矩阵指针b中。

这段代码的使用示例如下:

#include "matrix.h"
using namespace mat;

int main(){
    Matrix *a, *b, *c;
    Create(&a, 3, 3); // 创建一个3x3的矩阵a
    Create(&b, 3, 3); // 创建一个3x3的矩阵b
    Create(&c, 3, 3); // 创建一个3x3的矩阵c
   
    Input(a); // 输入矩阵a的元素值
    Input(b); // 输入矩阵b的元素值
   
    Add(a, b, c); // 计算矩阵a和矩阵b的和,结果保存在矩阵c中
    Print(c); // 输出矩阵c的元素值
   
    Minus(a, b, c); // 计算矩阵a和矩阵b的差,结果保存在矩阵c中
    Print(c); // 输出矩阵c的元素值
   
    Product(a, b, c); // 计算矩阵a和矩阵b的乘积,结果保存在矩阵c中
    Print(c); // 输出矩阵c的元素值
   
    DProduct(a, 2, c); // 计算矩阵a与标量2的乘积,结果保存在矩阵c中
    Print(c); // 输出矩阵c的元素值
   
    DProduct(a, b, c); // 计算矩阵a和矩阵b的点积,结果保存在矩阵c中
    Print(c); // 输出矩阵c的元素值
   
    Power(a, 2, c); // 计算矩阵a的平方,结果保存在矩阵c中
    Print(c); // 输出矩阵c的元素值
   
    T(a, &b); // 计算矩阵a的转置,结果保存在矩阵b中
    Print(b); // 输出矩阵b的元素值

    return 0;
}

这段代码定义了一个名为mat的命名空间,并在该命名空间中定义了矩阵的各种操作函数。在main函数中,我们先使用Create函数创建了三个3x3的矩阵a、b和c,然后分别进行了输入、输出、加法、减法、乘法、标量乘法、点积、求幂和转置等操作,并通过Print函数输出结果。

以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。

zhangjinxuan 发表于 2023-12-19 14:54:55

竞赛中没啥用,因为竞赛中我们都是自己直接过程实现的。

纯良少年 发表于 2023-12-24 17:45:14

呦吼

yinda_peng 发表于 2023-12-24 22:37:00

求逆能来吗{:10_307:}不过实际情况下稍微大一点的数据求逆就是禁忌

yinda_peng 发表于 2023-12-24 22:44:15

zhangjinxuan 发表于 2023-12-19 14:54
竞赛中没啥用,因为竞赛中我们都是自己直接过程实现的。

话说你们竞赛对于矩阵,会讲代数方面的东西吗?应该不会吧,估计就是基本的应用

zhangjinxuan 发表于 2023-12-25 08:05:17

yinda_peng 发表于 2023-12-24 22:44
话说你们竞赛对于矩阵,会讲代数方面的东西吗?应该不会吧,估计就是基本的应用

矩阵乘法,例如斐波那契数列,可以用矩阵乘法做到 O(k^3 log n),这里 k = 2。

yinda_peng 发表于 2023-12-25 09:54:55

zhangjinxuan 发表于 2023-12-25 08:05
矩阵乘法,例如斐波那契数列,可以用矩阵乘法做到 O(k^3 log n),这里 k = 2。

嗯,我想也是,就是一些简单应用

Gordon1 发表于 2024-1-27 13:32:36

想看

fancotse 发表于 2024-2-15 23:38:28

欢迎来到

yanqiuzhen 发表于 2024-2-16 22:31:46

mark......甲鱼哥哥
页: [1]
查看完整版本: 使用140行代码实现C++矩阵