当前位置: 首页 > news >正文

简易C语言矩阵运算库

参考网址:

异想家纯C语言矩阵运算库 - Sandeepin - 博客园

这次比opencv快⑥倍!!!

参考上述网址,整理了一下代码:

//main.c#include <stdio.h>
#include <stdlib.h>
#include <string.h>#include "matlib.h"typedef struct 
{int x;int y;
} Point_t;typedef struct 
{Point_t stSrc;Point_t stDsc;
} Perspective_map_t;//解非齐次线性方程组Ax=b求x
int get_perspective_transform(Perspective_map_t stPointMap[4] ,Matrix_t *pstPerspectiveMat)
{int ret = 0;Matrix_t * pstMatrix_A = NULL;Matrix_t * pstMatrix_InvA = NULL;Matrix_t * pstMatrix_x = NULL;Matrix_t * pstMatrix_b = NULL;#define GET_2D_ARRAY_VAL(buf, i, j, column) *((buf) + (i)*(column) + (j))if(!pstPerspectiveMat || pstPerspectiveMat->row != 3 || pstPerspectiveMat->column!= 3){printf("Param err\n");return -1;}pstMatrix_A = MatCreate(8, 8);pstMatrix_InvA = MatCreate(8, 8);pstMatrix_x = MatCreate(8, 1);pstMatrix_b = MatCreate(8, 1);for(int i = 0; i < 8; i += 2){GET_2D_ARRAY_VAL(pstMatrix_A->matrix_data, i, 0, 8) = stPointMap[i /2 ].stSrc.x;GET_2D_ARRAY_VAL(pstMatrix_A->matrix_data, i, 1, 8) = stPointMap[i /2 ].stSrc.y;GET_2D_ARRAY_VAL(pstMatrix_A->matrix_data, i, 2, 8) = 1;GET_2D_ARRAY_VAL(pstMatrix_A->matrix_data, i, 6, 8) = -stPointMap[i /2 ].stSrc.x * stPointMap[i /2 ].stDsc.x;GET_2D_ARRAY_VAL(pstMatrix_A->matrix_data, i, 7, 8) = -stPointMap[i /2 ].stDsc.x * stPointMap[i /2 ].stSrc.y;GET_2D_ARRAY_VAL(pstMatrix_A->matrix_data, i+1, 3, 8) = stPointMap[i /2 ].stSrc.x;GET_2D_ARRAY_VAL(pstMatrix_A->matrix_data, i+1, 4, 8) = stPointMap[i /2 ].stSrc.y;GET_2D_ARRAY_VAL(pstMatrix_A->matrix_data, i+1, 5, 8) = 1;GET_2D_ARRAY_VAL(pstMatrix_A->matrix_data, i+1, 6, 8) = -stPointMap[i /2 ].stSrc.x * stPointMap[i /2 ].stDsc.y;GET_2D_ARRAY_VAL(pstMatrix_A->matrix_data, i+1, 7, 8) = -stPointMap[i /2 ].stSrc.y * stPointMap[i /2 ].stDsc.y;  pstMatrix_b->matrix_data[i] = stPointMap[i /2 ].stDsc.x;pstMatrix_b->matrix_data[i + 1] = stPointMap[i /2 ].stDsc.y;}ret = MatInv(pstMatrix_A, pstMatrix_InvA);ret |= MatMul(pstMatrix_InvA, pstMatrix_b, pstMatrix_x);memcpy(pstPerspectiveMat->matrix_data, pstMatrix_x->matrix_data, pstMatrix_x->row * pstMatrix_x->column * sizeof(double));GET_2D_ARRAY_VAL(pstPerspectiveMat->matrix_data, 2, 2, 3) = 1;MatRelease(pstMatrix_A);MatRelease(pstMatrix_InvA);MatRelease(pstMatrix_x);MatRelease(pstMatrix_b);#undef GET_2D_ARRAY_VALreturn ret;
}int main(int argc, char** argv)
{Matrix_t Matrix_A;double A[] = { -3, 2, -5, -1, 0, -2, 3, -4, 1 };Matrix_A.row = 3;Matrix_A.column = 3;Matrix_A.matrix_data = A;Matrix_t Matrix_B;double B[] = { 1, 4, 7, 3, 0, 5, -1, 9, 11 };Matrix_B.row = 3;Matrix_B.column = 3;Matrix_B.matrix_data = B;Matrix_t Matrix_C;double C[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9 };Matrix_C.row = 3;Matrix_C.column = 3;Matrix_C.matrix_data = C;Matrix_t Matrix_Adj;double Adj[9] = {0};Matrix_Adj.row = 3;Matrix_Adj.column = 3;Matrix_Adj.matrix_data = Adj;Matrix_t Matrix_Out;double Out[9] = {0};Matrix_Out.row = 3;Matrix_Out.column = 3;Matrix_Out.matrix_data = Out;printf("A+B:\n");MatAdd(&Matrix_A, &Matrix_B, &Matrix_Out); MatShow(&Matrix_Out);printf("A-B:\n");MatSub(&Matrix_A, &Matrix_B, &Matrix_Out); MatShow(&Matrix_Out);printf("A*B:\n");MatMul(&Matrix_A, &Matrix_B, &Matrix_Out);MatShow(&Matrix_Out);printf("2*C:\n");MatMulk(&Matrix_C, 2, &Matrix_Out);MatShow(&Matrix_Out);printf("C的转置:\n");MatT(&Matrix_C, &Matrix_Out); MatShow(&Matrix_Out);double det = 0.0;printf("B的行列式值:\n");MatDet(&Matrix_B, &det);printf("%16lf\n", det);printf("C的行列式值:\n");MatDet(&Matrix_C, &det);printf("%16lf\n", det);//矩阵的逆printf("A的逆:\n");MatInv(&Matrix_A, &Matrix_Out); MatShow(&Matrix_Out);printf("C的逆:\n");MatInv(&Matrix_C, &Matrix_Out);MatShow(&Matrix_Out);//矩阵代数余子式printf("C的(0,0)元素的代数余子式:\n");printf("%16lf\n", MatACof(C, 3, 0, 0));//矩阵伴随矩阵printf("A的伴随矩阵:\n");MatAdj(&Matrix_A, &Matrix_Adj); MatShow(&Matrix_Adj);//蒋方正矩阵库应用:多元线性回归//多元线性回归公式:β=(X'X)^(-1)X'Ydouble X[15][5] = {1, 316, 1536, 874, 981,//第一列要补11, 385, 1771, 777, 1386,1, 299, 1565, 678, 1672,1, 326, 1970, 785, 1864,1, 441, 1890, 785, 2143,1, 460, 2050, 709, 2176,1, 470, 1873, 673, 1769,1, 504, 1955, 793, 2207,1, 348, 2016, 968, 2251,1, 400, 2199, 944, 2390,1, 496, 1328, 749, 2287,1, 497, 1920, 952, 2388,1, 533, 1400, 1452, 2093,1, 506, 1612, 1587, 2083,1, 458, 1613, 1485, 2390};double Y[15][1] = {3894,4628,4569,5340,5449,5599,5010,5694,5792,6126,5025,5924,5657,6019,6141};Matrix_t *pstMatrix_X = NULL;Matrix_t *pstMatrix_Y = NULL;Matrix_t *pstMatrix_XT = NULL;Matrix_t *pstMatrix_XTX = NULL;Matrix_t *pstMatrix_InvXTX = NULL;Matrix_t *pstMatrix_InvXTXXT = NULL;Matrix_t *pstMatrix_InvXTXXTY = NULL;pstMatrix_X = MatCreateInitFromArray(15, 5, (double *)X);pstMatrix_Y = MatCreateInitFromArray(15, 1, (double *)Y);pstMatrix_XT = MatCreate(5, 15);pstMatrix_XTX = MatCreate(5, 5);pstMatrix_InvXTX = MatCreate(5, 5);pstMatrix_InvXTXXT = MatCreate(5, 15);pstMatrix_InvXTXXTY = MatCreate(5, 1);//多元线性回归公式:β=(X'X)^(-1)X'YMatT(pstMatrix_X, pstMatrix_XT);MatMul(pstMatrix_XT, pstMatrix_X, pstMatrix_XTX);MatInv(pstMatrix_XTX, pstMatrix_InvXTX);MatMul(pstMatrix_InvXTX, pstMatrix_XT, pstMatrix_InvXTXXT);MatMul(pstMatrix_InvXTXXT, pstMatrix_Y, pstMatrix_InvXTXXTY);printf("多元线性回归β系数:\n");MatShow(pstMatrix_InvXTXXTY);//保存矩阵到csvMatWrite("MulLinearBetaCoef.csv", pstMatrix_InvXTXXTY);MatRelease(pstMatrix_X);MatRelease(pstMatrix_Y);MatRelease(pstMatrix_XT);MatRelease(pstMatrix_XTX);MatRelease(pstMatrix_InvXTX);MatRelease(pstMatrix_InvXTXXT);MatRelease(pstMatrix_InvXTXXTY);printf("透视变换:\n");Perspective_map_t stPointMap[4] = {{{ 50 , 50 }  ,{ 0  , 0  }},{{ 200, 50 }  ,{ 300, 0  }},{{ 50 , 200}  ,{ 0  , 400}},{{ 200, 200}  ,{ 300, 400}},};Matrix_t *pstPerspectiveMat = NULL;Matrix_t *pstPerspectiveInvMat = NULL;pstPerspectiveMat = MatCreate(3, 3);pstPerspectiveInvMat = MatCreate(3, 3);	//获取透视变换矩阵get_perspective_transform(stPointMap , pstPerspectiveMat);MatShow(pstPerspectiveMat);//反透视变换矩阵MatInv(pstPerspectiveMat, pstPerspectiveInvMat);MatShow(pstPerspectiveInvMat);//保存矩阵到csvMatWrite("PerspectiveMat.csv", pstPerspectiveInvMat);MatRelease(pstPerspectiveMat);MatRelease(pstPerspectiveInvMat);//读取csv文件数据到矩阵printf("读取csv文件:\n");Matrix_t *pstReadMat = NULL;pstReadMat = MatCreate(3, 3);MatRead("PerspectiveMat.csv", pstReadMat);MatShow(pstReadMat);return 0;
}

//matlib.h#ifndef __MATLIB_H__
#define __MATLIB_H__//定义csv文件读写矩阵函数,用于测试用例
#define USE_CSV_FILE_TESTtypedef struct 
{int row; //行int column; //列double *matrix_data; //缓冲区
} Matrix_t;Matrix_t *MatCreate(int row, int column);
Matrix_t *MatCreateInitFromArray(int row, int column, double *Array);
void MatRelease(Matrix_t *Mat);
int MatCopy(Matrix_t *dsc, Matrix_t *src);int MatAdd(Matrix_t* A, Matrix_t* B, Matrix_t *Out);
int MatSub(Matrix_t* A, Matrix_t* B, Matrix_t *Out);
int MatMul(Matrix_t* A, Matrix_t* B, Matrix_t *Out);
int MatMulk(Matrix_t* A, double k, Matrix_t *Out);
int MatT(Matrix_t* A, Matrix_t *Out);
int MatDet(Matrix_t* A, double *Out);
int MatInv(Matrix_t* A, Matrix_t *Out);
double MatACof(double *A, int row, int m, int n);
int MatAdj(Matrix_t* A, Matrix_t *Out);void MatShow(Matrix_t* Mat);#ifdef USE_CSV_FILE_TEST
int MatRead(char *InCsvFileName, Matrix_t *Out);
int MatWrite(const char *OutCsvFileName, Matrix_t *In);
#endif //USE_CSV_FILE_TEST#endif //__MATLIB_H__
//matlib.c#include <stdio.h>
#include <stdlib.h>
#include <string.h>#include "matlib.h"// (det用)功能:求逆序对的个数
static int inver_order(int *list, int n)
{int ret = 0;for (int i = 1; i < n; i++)for (int j = 0; j < i; j++)if (list[j] > list[i])ret++;return ret;
}// (det用)功能:符号函数,正数返回1,负数返回-1
static int sgn(int order)
{return order % 2 ? -1 : 1;
}// (det用)功能:交换两整数a、b的值
static void swap(int *a, int *b)
{int m;m = *a;*a = *b;*b = m;
}// 功能:求矩阵行列式的核心函数
static double det(double *p, int n, int k, int *list, double sum)
{if (k >= n){int order = inver_order(list, n);double item = (double)sgn(order);for (int i = 0; i < n; i++){//item *= p[i][list[i]];item *= *(p + i * n + list[i]);}return sum + item;}else{for (int i = k; i < n; i++){swap(&list[k], &list[i]);sum = det(p, n, k + 1, list, sum);swap(&list[k], &list[i]);}}return sum;
}Matrix_t *MatCreate(int row, int column)
{unsigned int len = row*column*sizeof(double);Matrix_t *pMatrix = malloc(sizeof(Matrix_t));if(!pMatrix){return NULL;}pMatrix->row = row;pMatrix->column = column;pMatrix->matrix_data = malloc(len);if(!pMatrix->matrix_data){free(pMatrix);return NULL;}memset(pMatrix->matrix_data, 0, len);return pMatrix;
}Matrix_t *MatCreateInitFromArray(int row, int column, double *Array)
{Matrix_t *pMatrix = MatCreate(row, column);memcpy(pMatrix->matrix_data, Array, row * column * sizeof(double));return pMatrix;
}void MatRelease(Matrix_t *Mat)
{if(Mat){if(Mat->matrix_data){free(Mat->matrix_data);}free(Mat);}
}// 功能:矩阵显示
// 形参:(输入)矩阵首地址指针Mat,矩阵行数row和列数col。
// 返回:无
void MatShow(Matrix_t* Mat)
{printf("\n");for (int i = 0; i < Mat->row * Mat->column; i++){printf("%16lf ", Mat->matrix_data[i]);if (0 == (i + 1) % Mat->column) {printf("\n");}}printf("\n");
}// 功能:矩阵相加
// 形参:(输入)矩阵A首地址指针A,矩阵B首地址指针B,矩阵A(也是矩阵B)行数row和列数col
// 返回:A+B
int MatAdd(Matrix_t* A, Matrix_t* B, Matrix_t* Out)
{if(!A || !B || !Out ||A->row != B->row || A->column != B->column || A->column != Out->column || A->row != Out->row ){printf("Input Matrix can not Add!\n");return -1;}for (int i = 0; i < A->row; i++)for (int j = 0; j < A->column; j++){Out->matrix_data[A->column*i + j] = A->matrix_data[A->column*i + j] + B->matrix_data[A->column*i + j];}return 0;
}// 功能:矩阵相减
// 形参:(输入)矩阵A,矩阵B,矩阵A(也是矩阵B)行数row和列数col
// 返回:A-B
int MatSub(Matrix_t* A, Matrix_t* B, Matrix_t *Out)
{if(!A || !B || !Out ||A->row != B->row || A->column != B->column || A->column != Out->column || A->row != Out->row ){printf("Input Matrix can not Sub!\n");return -1;}for (int i = 0; i < A->row; i++)for (int j = 0; j < A->column; j++){Out->matrix_data[A->column*i + j] = A->matrix_data[A->column*i + j] - B->matrix_data[A->column*i + j];}return 0;
}// 功能:矩阵相乘
// 形参:(输入)矩阵A,矩阵A行数row和列数col,矩阵B,矩阵B行数row和列数col
// 返回:A*B (Arow * Bcol)
int MatMul(Matrix_t* A, Matrix_t* B, Matrix_t *Out)
{if (!A || !B || !Out ||A->column != B->row){printf("Input Matrix can not Mul!\n");return -1;}if(Out->row != A->row ||  Out->column != B->column){printf("Output Matrix parameter err!\n");return -1;}int i, j, k;for (i = 0; i < A->row; i++)for (j = 0; j < B->column; j++){Out->matrix_data[B->column*i + j] = 0;for (k = 0; k < A->column; k++)Out->matrix_data[B->column*i + j] = Out->matrix_data[B->column*i + j] + A->matrix_data[A->column*i + k] * B->matrix_data[B->column*k + j];}return 0;
}// 功能:矩阵数乘(实数k乘以矩阵A)
// 形参:(输入)矩阵A首地址指针,矩阵行数row和列数col,实数k
// 返回:kA
int MatMulk(Matrix_t* A, double k, Matrix_t *Out)
{if(!A || !Out ||A->column != Out->column || A->row != Out->row ){printf("Input Matrix can not Mulk!\n");return -1;}for (int i = 0; i < A->row * A->column; i++){Out->matrix_data[i] = A->matrix_data[i] * k;}return 0;
}// 功能:矩阵转置
// 形参:(输入)矩阵A首地址指针A,行数row和列数col
// 返回:A的转置
int MatT(Matrix_t* A, Matrix_t *Out)
{if(!A || !Out ||Out->row != A->column || Out->column != A->row){printf("Input Matrix can not T! (%d %d)->(%d %d)\n", Out->row, Out->column, A->row, A->column);return -1;}for (int i = 0; i < A->row; i++)for (int j = 0; j < A->column; j++)Out->matrix_data[A->row*j + i] = A->matrix_data[A->column*i + j];return 0;
}// 功能:求行列式值
// 形参:(输入)矩阵A首地址指针A,行数row
// 返回:A的行列式值
int MatDet(Matrix_t* A, double *Out)
{if(!A || !Out ||A->column != A->row){printf("Input Matrix can not Det!\n");return -1;}int *list = malloc(A->row * sizeof(int));for (int i = 0; i < A->row; i++)list[i] = i;*Out = det(A->matrix_data, A->row, 0, list, 0.0);free(list);return 0;
}// 功能:矩阵的逆
// 形参:(输入)矩阵A首地址指针A,行数row和列数col
// 返回:A的逆
int MatInv(Matrix_t* A, Matrix_t *Out)
{if(!A || !Out ||A->column != A->row ||Out->row != A->column || Out->column != A->row){printf("Input Matrix can not Inv!\n");return -1;}double det;MatDet(A, &det); //求行列式if (det == 0){printf("Matrix can not Inv!\n");return -1;}MatAdj(A, Out); //求伴随矩阵int len = A->row * A->row;for (int i = 0; i < len; i++)Out->matrix_data[i] /= det;return 0;
}// 功能:求代数余子式
// 形参:(输入)矩阵A首地址指针A,矩阵行数row, 元素a的下标m,n(从0开始),
// 返回:NxN 矩阵中元素A(mn)的代数余子式
double MatACof(double *A, int row, int m, int n)
{Matrix_t *pstMatrix_cofactor = MatCreate(row - 1, row - 1);int count = 0;int raw_len = row * row;double det = 0;for (int i = 0; i < raw_len; i++)if (i / row != m && i % row != n){*(pstMatrix_cofactor->matrix_data + count++) = *(A + i);}MatDet(pstMatrix_cofactor, &det);if ((m + n) % 2)det = -det;MatRelease(pstMatrix_cofactor);return det;
}// 功能:求伴随矩阵
// 形参:(输入)矩阵A首地址指针A,行数row和列数col
// 返回:A的伴随矩阵
int MatAdj(Matrix_t* A, Matrix_t *Out)
{if(!A || !Out ||Out->row != A->row || Out->column != A->column){printf("Input Matrix can not Adj!\n");return -1;}int len = A->row * A->row;for (int i = 0; i < len; i++){Out->matrix_data[i] = MatACof(A->matrix_data, A->row, i % A->row, i / A->row);}return 0;
}#ifdef USE_CSV_FILE_TEST
// 读取文件行数
static int FileReadRow(const char *filename)
{FILE *f = fopen(filename, "r");int i = 0;char str[4096];while (NULL != fgets(str, 4096, f))++i;printf("数组行数:%d\n", i);return i;
}// 读取文件每行数据数(逗号数+1)
static int FileReadCol(const char *filename)
{FILE *f = fopen(filename, "r");int i = 0;char str[4096];fgets(str, 4096, f);for (int j = 0; j < strlen(str); j++){if (',' == str[j]) i++;}i++;// 数据数=逗号数+1printf("数组列数:%d\n", i);return i;
}// 逗号间隔数据提取
static void GetCommaData(char str_In[4096], double double_Out[1024])
{int str_In_len = strlen(str_In); //printf("str_In_len:%d\n", str_In_len);char str_Data_temp[128];int j = 0;int double_Out_num = 0;for (int i = 0; i < str_In_len; i++){//不是逗号,则是数据,存入临时数组中if (',' != str_In[i]) str_Data_temp[j++] = str_In[i];//是逗号或\n(最后一个数据),则数据转换为double,保存到输出数组if (',' == str_In[i] || '\n' == str_In[i]) { str_Data_temp[j] = '\0'; j = 0; /*printf("str_Data_temp:%s\n", str_Data_temp); */double_Out[double_Out_num++] = atof(str_Data_temp); memset(str_Data_temp, 0, sizeof(str_Data_temp)); }}
}// 功能:从csv文件读矩阵,保存到指针中
// 形参:(输入)csv文件名,预计行数row和列数col
// 返回:矩阵指针A
int MatRead(char *InCsvFileName, Matrix_t *Out)
{int row = FileReadRow(InCsvFileName); int col = FileReadCol(InCsvFileName);FILE *f = fopen(InCsvFileName, "r");char buffer[4096];while (fgets(buffer, sizeof(buffer), f)){//printf("buffer[%s]\n",buffer);double double_Out[1024] = { 0 };GetCommaData(buffer, double_Out);for (int i = 0; i < col; i++){//printf("double_Out:%lf\n", double_Out[i]);*Out->matrix_data++ = double_Out[i];}}Out->matrix_data = Out->matrix_data - row * col;//指针移回数据开头fclose(f);return 0;
}// 功能:将矩阵A存入csv文件中
// 形参:(输入)保存的csv文件名,矩阵A首地址指针A,行数row和列数col
// 返回:无
int MatWrite(const char *OutCsvFileName, Matrix_t *In)
{FILE *DateFile;double *Ap = In->matrix_data;DateFile = fopen(OutCsvFileName, "w");//追加的方式保存生成的时间戳for (int i = 0; i < In->row*In->column; i++){if ((i+1) % In->column == 0) fprintf(DateFile, "%lf\n", *Ap);//保存到文件,到列数换行else fprintf(DateFile, "%lf,", *Ap);//加逗号Ap++;}fclose(DateFile);return 0;
}
#endif //USE_CSV_FILE_TEST

我测试了一下解非齐次线性方程组(求透视变换矩阵),实现简单,但速度慢且内存需求较大,有兴趣可以尝试去优化。

C++矩阵运算库中,Eigen库是比较高效的

https://eigen.tuxfamily.org/index.php?title=Main_Pagehttps://eigen.tuxfamily.org/index.php?title=Main_Pagehttps://eigen.tuxfamily.org/index.php?title=Main_Page

相关文章:

简易C语言矩阵运算库

参考网址&#xff1a; 异想家纯C语言矩阵运算库 - Sandeepin - 博客园 这次比opencv快⑥倍&#xff01;&#xff01;&#xff01; 参考上述网址&#xff0c;整理了一下代码&#xff1a; //main.c#include <stdio.h> #include <stdlib.h> #include <string.h…...

通过C/C++编程语言实现“数据结构”课程中的链表

引言 链表(Linked List)是数据结构中最基础且最重要的线性存储结构之一。与数组的连续内存分配不同,链表通过指针将分散的内存块串联起来,具有动态扩展和高效插入/删除的特性。本文将以C/C++语言为例,从底层原理到代码实现,手把手教你构建完整的链表结构,并深入探讨其应…...

【分布式架构理论3】分布式调用(2):API 网关分析

文章目录 一、API 网关的作用1. 业务层面&#xff1a;简化调用复杂性2. 系统层面&#xff1a;屏蔽客户端调用差异3. 其他方面&#xff1a; 二、API 网关的技术原理1. 协议转换2. 链式处理3. 异步请求机制1. Zuul1&#xff1a;同步阻塞处理2. Zuul2&#xff1a;异步非阻塞处理 三…...

基于Kamailio、MySQL、Redis、Gin、Vue.js的微服务架构

每个服务使用一台独立的服务器的可行部署方案&#xff0c;尤其是在高并发、高可用性要求较高的场景中。这种方案通常被称为分布式部署或微服务架构。以下是针对您的VoIP管理系统&#xff08;基于Kamailio、MySQL、Redis、Gin、Vue.js&#xff09;的详细分析和建议。 1. 分布式部…...

6S模型的编译问题解决

使用python处理遥感光谱数据&#xff0c;免不了进行大气校正&#xff0c;基本上免费的就是使用Py6s&#xff0c;而py6s库只是一个接口&#xff0c;还需要自己配置6S模型&#xff0c;可以查到很多资料&#xff0c;6S模型是古老的fortran语言写的&#xff0c;基本配置流程就是安装…...

C++11详解(二) -- 引用折叠和完美转发

文章目录 2. 右值引用和移动语义2.6 类型分类&#xff08;实践中没什么用&#xff09;2.7 引用折叠2.8 完美转发2.9 引用折叠和完美转发的实例 2. 右值引用和移动语义 2.6 类型分类&#xff08;实践中没什么用&#xff09; C11以后&#xff0c;进一步对类型进行了划分&#x…...

实验十四 EL和JSTL

实验十四 EL和JSTL 一、实验目的 1、掌握EL表达式的使用 2、掌握JSTL的使用 二、实验过程 1、在数据库Book中建立表Tbook&#xff0c;包含图书ID&#xff0c;图书名称&#xff0c;图书价格。实现在bookQuery.jsp页面中模糊查询图书&#xff0c;如果图书的价格在50元以上&#…...

为什么在springboot中使用autowired的时候它黄色警告说不建议使用字段注入

byType找到多种实现类导致报错 Autowired: 通过byType 方式进行装配, 找不到或是找到多个&#xff0c;都会抛出异常 我们在单元测试中无法进行字段注入 字段注入通常是 private 修饰的&#xff0c;Spring 容器通过反射为这些字段注入依赖。然而&#xff0c;在单元测试中&…...

DeepSeek大模型介绍、本地化部署与使用!【AI大模型】

一、DeepSeek 是什么&#xff1f; 1.技术定位 专注大模型与AGI研究&#xff0c;开发高性能基座模型&#xff08;如 DeepSeek LLM 系列&#xff09;&#xff0c;支持长文本、多模态、代码生成等复杂任务。 提供开源模型&#xff08;如 DeepSeek-MoE、DeepSeek-V2&#xff09;…...

备考蓝桥杯嵌入式4:使用LCD显示我们捕捉的PWM波

上一篇博客我们提到了定时器产生PWM波&#xff0c;现在&#xff0c;我们尝试的想要捕获我们的PWM波&#xff0c;测量它的频率&#xff0c;我们应该怎么做呢&#xff1f;答案还是回到我们的定时器上。 我们知道&#xff0c;定时器是一个高级的秒表&#xff08;参考笔者的比喻&a…...

智能化转型2.0:从“工具应用”到“价值重构”

过去几年&#xff0c;“智能化”从一个模糊的概念逐渐成为企业发展的核心议题。2024年&#xff0c;随着生成式AI、大模型、智能体等技术的爆发式落地&#xff0c;中国企业正式迈入智能化转型的2.0时代。这一阶段的核心特征是从单一场景的“工具应用”转向全链条的“价值重构”&…...

机器学习之数学基础:线性代数、微积分、概率论 | PyTorch 深度学习实战

前一篇文章&#xff0c;使用线性回归模型逼近目标模型 | PyTorch 深度学习实战 本系列文章 GitHub Repo: https://github.com/hailiang-wang/pytorch-get-started 本篇文章内容来自于 强化学习必修课&#xff1a;引领人工智能新时代【梗直哥瞿炜】 线性代数、微积分、概率论 …...

9.PPT:儿童孤独症介绍【22】

目录 NO12345​ NO6789 NO12345 1-3张素材.txt中的大纲→素材文档PPT.pptx设计→主题→积分字体&#xff1a;幻灯片母版在幻灯片母版右上角的相同位置插入任一剪贴画&#xff0c;改变该剪贴画的图片样式、为其重新着色&#xff0c;并使其不遮挡其他文本或对象 开始→版式动画…...

离散浣熊优化算法(DCOA)求解大规模旅行商问题(Large-Scale Traveling Salesman Problem,LTSP),MATLAB代码

大规模旅行商问题&#xff08;Large-Scale Traveling Salesman Problem&#xff0c;LTSP&#xff09;是经典旅行商问题&#xff08;TSP&#xff09;在规模上的扩展&#xff0c;是一个具有重要理论和实际意义的组合优化问题&#xff1a; 一、问题定义 给定一组城市和它们之间的…...

Java 引入和使用jcharset,支持UTF-7字符集

一、背景说明 Java标准库不直接支持UTF-7字符集&#xff0c;但通过我们可以使用第三方库jcharset方便地处理UTF-7编码的数据。 二、引入说明 JDK8及以下版本&#xff0c;我们将jcharset.jar并将其放到${JAVA_HOME}/jre/lib/ext/下即可完成引入。 JDK17及以后版本&#xff0c;对…...

rust安装笔记

安装笔记 安装加速cargo 国内源nightly版本安装其他目标将现有项目迁移到新版本升级 安装加速 export RUSTUP_UPDATE_ROOT"https://mirrors.ustc.edu.cn/rust-static/rustup" export RUSTUP_DIST_SERVERhttps://mirrors.tuna.tsinghua.edu.cn/rustup curl --proto h…...

扣子平台的选择器节点:让智能体开发更简单,扣子免费系列教程(17)

欢迎来到涛涛聊AI。今天&#xff0c;我们来聊聊一个非常实用的工具——扣子平台的选择器节点。即使你不是计算机专业人员&#xff0c;但对计算机操作比较熟悉&#xff0c;这篇文章也能帮你快速上手。我们会从基础知识讲起&#xff0c;一步步带你了解选择器节点的使用方法和应用…...

Ubuntu 下 nginx-1.24.0 源码分析 - ngx_sprintf_num 函数

ngx_sprintf_num 声明就在 ngx_string.c 的开头 static u_char *ngx_sprintf_num(u_char *buf, u_char *last, uint64_t ui64,u_char zero, ngx_uint_t hexadecimal, ngx_uint_t width); ngx_sprintf_num 实现 static u_char * ngx_sprintf_num(u_char *buf, u_char *last,…...

Vue的状态管理:用响应式 API 做简单状态管理、状态管理库(Pinia )

文章目录 引言单向数据流多个组件共享一个共同的状态I 用响应式 API 做简单状态管理使用 reactive()创建一个在多个组件实例间共享的响应式对象使用ref()返回一个全局状态II 状态管理库Pinia枚举状态管理引言 单向数据流 每一个 Vue 组件实例都在“管理”它自己的响应式状态了…...

AI工具如何辅助写文章(科研版)

文章总览:[YuanDaiMa2048博客文章总览](https://blog.csdn.net/2301_79288416/article/details/137397359?spm=1001.2014.3001.5501)https://blog.csdn.net/2301_79288416/article/details/137397359?spm=1001.2014.3001.5501 在科研领域,撰写论文是一个复杂且耗时的过程。…...

使用docker在3台服务器上搭建基于redis 6.x的一主两从三台均是哨兵模式

一、环境及版本说明 如果服务器已经安装了docker,则忽略此步骤,如果没有安装,则可以按照一下方式安装: 1. 在线安装(有互联网环境): 请看我这篇文章 传送阵>> 点我查看 2. 离线安装(内网环境):请看我这篇文章 传送阵>> 点我查看 说明&#xff1a;假设每台服务器已…...

中南大学无人机智能体的全面评估!BEDI:用于评估无人机上具身智能体的综合性基准测试

作者&#xff1a;Mingning Guo, Mengwei Wu, Jiarun He, Shaoxian Li, Haifeng Li, Chao Tao单位&#xff1a;中南大学地球科学与信息物理学院论文标题&#xff1a;BEDI: A Comprehensive Benchmark for Evaluating Embodied Agents on UAVs论文链接&#xff1a;https://arxiv.…...

visual studio 2022更改主题为深色

visual studio 2022更改主题为深色 点击visual studio 上方的 工具-> 选项 在选项窗口中&#xff0c;选择 环境 -> 常规 &#xff0c;将其中的颜色主题改成深色 点击确定&#xff0c;更改完成...

Spring Boot面试题精选汇总

&#x1f91f;致敬读者 &#x1f7e9;感谢阅读&#x1f7e6;笑口常开&#x1f7ea;生日快乐⬛早点睡觉 &#x1f4d8;博主相关 &#x1f7e7;博主信息&#x1f7e8;博客首页&#x1f7eb;专栏推荐&#x1f7e5;活动信息 文章目录 Spring Boot面试题精选汇总⚙️ **一、核心概…...

Map相关知识

数据结构 二叉树 二叉树&#xff0c;顾名思义&#xff0c;每个节点最多有两个“叉”&#xff0c;也就是两个子节点&#xff0c;分别是左子 节点和右子节点。不过&#xff0c;二叉树并不要求每个节点都有两个子节点&#xff0c;有的节点只 有左子节点&#xff0c;有的节点只有…...

JavaScript基础-API 和 Web API

在学习JavaScript的过程中&#xff0c;理解API&#xff08;应用程序接口&#xff09;和Web API的概念及其应用是非常重要的。这些工具极大地扩展了JavaScript的功能&#xff0c;使得开发者能够创建出功能丰富、交互性强的Web应用程序。本文将深入探讨JavaScript中的API与Web AP…...

如何更改默认 Crontab 编辑器 ?

在 Linux 领域中&#xff0c;crontab 是您可能经常遇到的一个术语。这个实用程序在类 unix 操作系统上可用&#xff0c;用于调度在预定义时间和间隔自动执行的任务。这对管理员和高级用户非常有益&#xff0c;允许他们自动执行各种系统任务。 编辑 Crontab 文件通常使用文本编…...

day36-多路IO复用

一、基本概念 &#xff08;服务器多客户端模型&#xff09; 定义&#xff1a;单线程或单进程同时监测若干个文件描述符是否可以执行IO操作的能力 作用&#xff1a;应用程序通常需要处理来自多条事件流中的事件&#xff0c;比如我现在用的电脑&#xff0c;需要同时处理键盘鼠标…...

Python 训练营打卡 Day 47

注意力热力图可视化 在day 46代码的基础上&#xff0c;对比不同卷积层热力图可视化的结果 import torch import torch.nn as nn import torch.optim as optim from torchvision import datasets, transforms from torch.utils.data import DataLoader import matplotlib.pypl…...

【Linux】Linux安装并配置RabbitMQ

目录 1. 安装 Erlang 2. 安装 RabbitMQ 2.1.添加 RabbitMQ 仓库 2.2.安装 RabbitMQ 3.配置 3.1.启动和管理服务 4. 访问管理界面 5.安装问题 6.修改密码 7.修改端口 7.1.找到文件 7.2.修改文件 1. 安装 Erlang 由于 RabbitMQ 是用 Erlang 编写的&#xff0c;需要先安…...