使用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指向的指针中。 这段代码实现了一个简单的矩阵库,其中有一些函数用来创建矩阵、输入矩阵、输出矩阵、矩阵相加、矩阵相减、矩阵乘法、标量乘法、矩阵自乘、矩阵求幂、矩阵转置等。以下是对这些函数的详细解释。
- 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 小助理,如未能正确解答您的问题,请继续追问。 竞赛中没啥用,因为竞赛中我们都是自己直接过程实现的。 呦吼 求逆能来吗{:10_307:}不过实际情况下稍微大一点的数据求逆就是禁忌 zhangjinxuan 发表于 2023-12-19 14:54
竞赛中没啥用,因为竞赛中我们都是自己直接过程实现的。
话说你们竞赛对于矩阵,会讲代数方面的东西吗?应该不会吧,估计就是基本的应用 yinda_peng 发表于 2023-12-24 22:44
话说你们竞赛对于矩阵,会讲代数方面的东西吗?应该不会吧,估计就是基本的应用
矩阵乘法,例如斐波那契数列,可以用矩阵乘法做到 O(k^3 log n),这里 k = 2。 zhangjinxuan 发表于 2023-12-25 08:05
矩阵乘法,例如斐波那契数列,可以用矩阵乘法做到 O(k^3 log n),这里 k = 2。
嗯,我想也是,就是一些简单应用 想看 欢迎来到 mark......甲鱼哥哥
页:
[1]