超好用的纯C语言矩阵运算库 easyMatrix

最近开发基于异构传感器的异步定位数据的卡尔曼滤波,因为最终要用在一个老爷DSP上,已有代码都是C写的,不想研究这种老爷设备下的C++调用,Eigen这超好用的矩阵运算库算是没法用了。随便搜了几个C矩阵库发现不是超难用就是有bug,比如csdn某小哥写的matrix库,矩阵维数一大,逆矩阵计算就出错。项目结束后,想着可能很多嵌入式开发人员也许有类似的需求,决定自己还是写一个操作友好的matrix库,工具虽小,好用就行。
支持矩阵的加、减、乘法运算,转置、逆矩阵、伴随矩阵、LU分解、行列式计算、线性方程求解等功能
废话不说,上代码:
github地址:https://github.com/fellylanma/easyMatrix

//使用例子
int main() {//create matrix on stackfloat val1[] = {1,2,3,4,5,6,7,8,9};float val2[] = {1,1,1,1,1,1,1,1,1};CREATE_MATRIX_ONSTACK(3,3,A,val1);CREATE_MATRIX_ONSTACK(3,3,B,val2);CREATE_MATRIX_ONSTACK(3,3,C,NULL);addMatrix(&A,&B,&C);dumpMatrix(&C);printf("det is:%f\n",detMatrix(&A));int x = A.rows;int y = A.cols;printf("element[1,1] is:%f\n",A.element[1*x+1]);//create matrix on heap and you need to delete the pointerCREATE_DYNAMIC_MATRIX_ONHEAP(x,y,D,val1);CREATE_DYNAMIC_MATRIX_ONHEAP(x,y,E,val2);CREATE_DYNAMIC_MATRIX_ONHEAP(x,y,F,NULL);multiMatrix(D,E,&C);multiMatrix(D,E,F);DELETE_DYNAMIC_MATRIX(D);DELETE_DYNAMIC_MATRIX(E);DELETE_DYNAMIC_MATRIX(F);
}

easyMatrix.h

#ifndef _MAGRIDE_PLANNING_EASYMATRIX_H_
#define _MAGRIDE_PLANNING_EASYMATRIX_H_#include <stdlib.h>
typedef unsigned char uint8;
typedef float DATA_TYPE;#define CREATE_MATRIX_ONSTACK(x,y,matrix,initval) \
struct easyMatrix matrix;\
DATA_TYPE val##x##N##y##N##matrix[x*y];\matrix.rows = x;\matrix.cols = y;\matrix.element = val##x##N##y##N##matrix;\if(initval!=NULL) setMatrix(initval, &(matrix))#define CREATE_DYNAMIC_MATRIX_ONHEAP(x,y,matrix,initval) \
struct easyMatrix *matrix = (struct easyMatrix*)malloc(sizeof(struct easyMatrix));\
matrix->rows = x;\
matrix->cols = y;\
matrix->element = (DATA_TYPE*) malloc(sizeof(DATA_TYPE)*(x)*(y));\
if(initval!=NULL) setMatrix(initval, (matrix))#define DELETE_DYNAMIC_MATRIX(matrix) \free((matrix)->element);\free(matrix)struct easyMatrix {\uint8 rows,cols;\DATA_TYPE* element;
};\struct easyMatrix* setMatrix(DATA_TYPE* const a,struct easyMatrix* c);
struct easyMatrix* copyMatrix(struct easyMatrix* const a,struct easyMatrix* c);
struct easyMatrix* transMatrix(struct easyMatrix* const a,struct easyMatrix* c);DATA_TYPE detMatrix(struct easyMatrix* const a);DATA_TYPE invMatrix(struct easyMatrix* const a, struct easyMatrix*b);struct easyMatrix* scaleMatrix(DATA_TYPE, struct easyMatrix* const a, struct easyMatrix*);struct easyMatrix* addMatrix(const struct easyMatrix* const a, const struct easyMatrix *const  b, struct easyMatrix * c);struct easyMatrix* leftMatrix(uint8, uint8, struct easyMatrix* const a, struct easyMatrix* b);struct easyMatrix* subMatrix(struct easyMatrix* const a, struct easyMatrix* const  b, struct easyMatrix* c);struct easyMatrix* multiMatrix(struct easyMatrix* const a, struct easyMatrix* const b, struct easyMatrix* c);struct easyMatrix* zerosMatrix(struct easyMatrix* e);struct easyMatrix* eyesMatrix(struct easyMatrix* e);void dumpMatrix(struct easyMatrix* const e);struct easyMatrix* adjMatrix(struct easyMatrix* const a,struct easyMatrix* c);struct easyMatrix* getLUMatrix(struct easyMatrix* const A, struct easyMatrix* L,struct easyMatrix* U) ;struct easyMatrix* invLMatrix(struct easyMatrix* const L, struct easyMatrix* L_inv) ;
struct easyMatrix* invUMatrix(struct easyMatrix* const U, struct easyMatrix* U_inv) ;struct easyMatrix* solveEquationMatrix(const struct easyMatrix* const A,const struct easyMatrix* const Y, struct easyMatrix* X) ;DATA_TYPE fastDetMatrix(struct easyMatrix* const in) ;
#endif//_MAGRIDE_PLANNING_EASYMATRIX_H_

#easyMatrix.c

#include <stdlib.h>
#include <float.h>
#include "easyMatrix.h"int isFiniteNumber(double d) {return (d<=DBL_MAX&&d>=-DBL_MAX);
}
struct easyMatrix* setMatrix(DATA_TYPE * const a,struct easyMatrix* c) {uint8 x = c->rows;uint8 y = c->cols;int t = x*y;for(int i=0;i<t;++i) {c->element[i] = a[i];}return c;
}struct easyMatrix* copyMatrix(struct easyMatrix* const a,struct easyMatrix* c) {if(a->rows != c->rows) return NULL;if(a->cols != c->cols) return NULL;int t = a->rows*a->cols;for(int i=0;i<t;++i) {c->element[i] = a->element[i];}return c;
}struct easyMatrix* transMatrix(struct easyMatrix* const a,struct easyMatrix* c) {if(a->rows != c->cols) return NULL;if(a->cols != c->rows) return NULL;int index = 0;int index_src = 0;for(uint8 ii=0;ii<a->cols;++ii) {index_src=ii;for(uint8 jj=0;jj<a->rows;++jj) {//c->element[index] = a->element[jj*a->cols+ii];c->element[index] = a->element[index_src];index++;index_src+=a->cols;}}return c;
}struct easyMatrix* leftMatrix(uint8 x_i,uint8 y_i, struct easyMatrix* const in, struct easyMatrix* out) {if(in->rows != in->cols) return NULL;if(out->rows != out->cols) return NULL;if(in->rows != (out->rows+1)) return NULL;int index = 0;int index_src = 0;uint8 x =in->rows;uint8 y =in->cols;for(uint8 kk=0;kk<x;++kk) {for(uint8 ww=0;ww<y;++ww) {if(!(kk==x_i||ww==y_i)) {//out->element[index] = in->element[kk*y+ww];out->element[index] = in->element[index_src];index++;}index_src++;}}return out;
}
struct easyMatrix* adjMatrix(struct easyMatrix* const in, struct easyMatrix* out) {if(in->rows != out->cols) return NULL;if(in->cols != out->rows) return NULL;int index = 0;uint8 x = in->rows;uint8 y = in->cols;CREATE_DYNAMIC_MATRIX_ONHEAP(x-1,y-1,ret,NULL);signed char sign1 = 1;signed char sign2 = 1;for(uint8 ii=0;ii<x;++ii) {sign2 = sign1;index = ii;for(uint8 jj=0;jj<y;++jj) {leftMatrix(ii,jj,in,ret);//out->element[jj*y+ii] = sign2*detMatrix(ret);out->element[index] = sign2*detMatrix(ret);sign2 = - sign2;    index+=y;}sign1 = - sign1;}DELETE_DYNAMIC_MATRIX(ret);return out;
}DATA_TYPE invMatrix(struct easyMatrix *const in , struct easyMatrix * out) {if(in->cols!=in->rows) return 0;if(in->rows != out->cols) return 0;if(in->cols != out->rows) return 0;uint8 N = in->cols;CREATE_DYNAMIC_MATRIX_ONHEAP(N,N,L,NULL);CREATE_DYNAMIC_MATRIX_ONHEAP(N,N,LINV,NULL);CREATE_DYNAMIC_MATRIX_ONHEAP(N,N,U,NULL);CREATE_DYNAMIC_MATRIX_ONHEAP(N,N,UINV,NULL);getLUMatrix(in,L,U);invLMatrix(L,LINV);invUMatrix(U,UINV);multiMatrix(UINV,LINV,out);double s = 1;for(int i = 0;i<N;i++) s *= U->element[i*N+i];   /*adjMatrix(in,out);DATA_TYPE scale = detMatrix(in);if(scale<1e-5&&scale>-1e-5) return 0.0;scale = 1/scale;scaleMatrix(scale,out,out);
*/DELETE_DYNAMIC_MATRIX(L);DELETE_DYNAMIC_MATRIX(U);DELETE_DYNAMIC_MATRIX(LINV);DELETE_DYNAMIC_MATRIX(UINV);return isFiniteNumber(s);
}struct easyMatrix* getLUMatrix(struct easyMatrix* const A, struct easyMatrix* L,struct easyMatrix* U) {int row=0;DATA_TYPE s = 0;uint8 N = A->cols;int t = N*N;for(int i =0;i<t;i++) {L->element[i] = 1e-20;U->element[i] = 1e-20;}for(int i=0;i<N;i++) {L->element[i*N+i] = 1.0;}for(int i=0;i<N;i++) {for(int j=i;j<N;j++) {s = 0.0;for(int k=0;k<i;++k) {s+=L->element[i*N+k]*U->element[k*N+j];}U->element[i*N+j]= A->element[i*N+j] - s; }for (int j = i + 1;j < N;j++) {s = 0.0;for (int k = 0; k < i; k++){s += L->element[j*N+k] * U->element[k*N+i];}L->element[j*N+i] = (A->element[j*N+i] - s) / U->element[i*N+i];      //按列计算l值}}return L;}struct easyMatrix* invLMatrix(struct easyMatrix* const L, struct easyMatrix* L_inv) { uint8 N = L->cols;DATA_TYPE s;int t = N*N;for(int i =0;i<t;i++) {L_inv->element[i] = 1e-13;}for (uint8 i = 0;i < N;i++)  {L_inv->element[i*N+i] = 1;}for (uint8 i= 1;i < N;i++) {for (uint8 j = 0;j < i;j++) {s = 0;for (uint8 k = 0;k < i;k++) {s += L->element[i*N+k] * L_inv->element[k*N+j];}L_inv->element[i*N+j] = -s;}}return L_inv;
}
struct easyMatrix* invUMatrix(struct easyMatrix* const U, struct easyMatrix* U_inv) { uint8 N = U->cols;DATA_TYPE s;int t = N*N;for(int i =0;i<t;i++) {U_inv->element[i] = 1e-13;}for (uint8 i = 0;i < N;i++)                    //按列序,列内按照从下到上,计算u的逆矩阵{U_inv->element[i*N+i] = 1 / U->element[i*N+i];}for (uint8 i = 1;i < N;i++) {for (int j = i - 1;j >=0;j--) {s = 0;for (uint8 k = j + 1;k <= i;k++) {s += U->element[j*N+k] * U_inv->element[k*N+i];}U_inv->element[j*N+i] = -s / U->element[j*N+j];}}return U_inv;
}
DATA_TYPE fastDetMatrix(struct easyMatrix* const in) {uint8 x = in->rows;uint8 y = in->cols;if(x!=y) return 0;if(x==0 ) return 0;if(x==1 ) return in->element[0];DATA_TYPE *a =in->element;if(x==2) return(a[0]*a[3]-a[1]*a[2]);int N = x;CREATE_DYNAMIC_MATRIX_ONHEAP(N,N,L,NULL);CREATE_DYNAMIC_MATRIX_ONHEAP(N,N,U,NULL);getLUMatrix(in,L,U);double s = 1;for(int i = 0;i<N;i++) s *= U->element[i*N+i];DELETE_DYNAMIC_MATRIX(L);DELETE_DYNAMIC_MATRIX(U);return s;
}DATA_TYPE detMatrix(struct easyMatrix* const in) {uint8 x = in->rows;uint8 y = in->cols;if(x!=y) return 0;if(x==0 ) return 0;if(x==1 ) return in->element[0];DATA_TYPE *a =in->element;if(x==2) return(a[0]*a[3]-a[1]*a[2]);DATA_TYPE result = 0;signed char sign = 1;CREATE_DYNAMIC_MATRIX_ONHEAP(x-1,y-1,ret,NULL);for(uint8 i=0;i<x;++i) {leftMatrix(0,i,in,ret);result += sign*a[i]*detMatrix(ret);sign = - sign;}DELETE_DYNAMIC_MATRIX(ret);return result;
}struct easyMatrix* addMatrix(const struct easyMatrix* const a,const struct easyMatrix* const b, struct easyMatrix* c) {if(a->cols != b->cols) return NULL;if(a->rows != b->rows) return NULL;struct easyMatrix* obj = (struct easyMatrix*)a;int t = obj->rows*obj->cols;for(int i=0;i<t;++i) {c->element[i] = obj->element[i]+b->element[i];}return c;
}struct easyMatrix* subMatrix(struct easyMatrix* const a, struct easyMatrix* const b, struct easyMatrix* c) {if(a->cols != b->cols) return NULL;if(a->rows != b->rows) return NULL;struct easyMatrix* obj = (struct easyMatrix*)a;int t = obj->rows*obj->cols;for(int i=0;i<t;++i) {c->element[i] = obj->element[i]-b->element[i];}return c;
}struct easyMatrix* scaleMatrix(DATA_TYPE scale, struct easyMatrix* const a, struct easyMatrix* b) {int t = a->cols*a->rows;for (int i = 0;i<t;++i) {b->element[i] = a->element[i]*scale;}return b;
}struct easyMatrix* multiMatrix(struct easyMatrix* const a,struct easyMatrix* const b, struct easyMatrix* c) {if(NULL==c) return NULL;if(c == a || c == b) return NULL;if(a->cols != b->rows) return NULL;int count = 0;int t_cnt = 0;int z_cnt = 0;uint8 x = a->rows;uint8 y = a->cols;uint8 z = b->cols;for(uint8 i = 0;i<x;++i) {for(uint8 k = 0;k<z;++k) {c->element[count] = 0;z_cnt = 0;for(uint8 j = 0;j<y;++j) {c->element[count] += a->element[t_cnt+j]*b->element[z_cnt+k];z_cnt += z;}count++;}t_cnt+=y;}return c;
}struct easyMatrix* zerosMatrix(struct easyMatrix* e) {int t = e->cols*e->rows;for(int i=0;i<t;++i) {e->element[i] = 0;}return e;
}struct easyMatrix* eyesMatrix(struct easyMatrix* e) {if(e->rows != e->cols) return NULL;zerosMatrix(e);int index = 0;for(uint8 i=0;i<e->rows;++i) {e->element[index] = 1.0;index+=(e->cols);++index;}return e;
}struct easyMatrix* solveEquationMatrix(const struct easyMatrix* const A,const struct easyMatrix* const Y, struct easyMatrix* X) { CREATE_DYNAMIC_MATRIX_ONHEAP(A->rows,A->cols,AINV,NULL);invMatrix(A,AINV);multiMatrix(AINV,Y,X);DELETE_DYNAMIC_MATRIX(AINV);return X;
}
void dumpMatrix(struct easyMatrix* const e) {int count = 0;int x = e->rows;int y = e->cols;printf("cols is:%d, rows is:%d\n",x,y);for(uint8 i = 0;i<x;++i) {for(uint8 j = 0;j<y;++j) {printf("%8f,",e->element[count]);++count;}printf("\n");}return;
}

超好用的纯C语言矩阵运算库相关推荐

  1. 异想家纯C语言矩阵运算库

    Sandeepin最近做的项目中需要在嵌入式芯片里跑一些算法,而这些单片机性能不上不下,它能跑些简单的程序,但又还没到上Linux系统的地步.所以只好用C语言写一些在高级语言里一个函数就解决的算法了, ...

  2. C语言矩阵运算库大起底

    GSL GNU Scientific Library自带的矩阵运算,据说速度一般. Blitz++ Blitz++ 与 MTL 都是基于 C++ template 高效数值计算程序库,不过他们专注于不 ...

  3. 基于C语言的矩阵运算库

    最近本着锻炼自己编程能力的目的,捣鼓了一下矩阵运算,看到网上很多的矩阵运算库都是基于C++的,很少有基于C语言的,于是自己想要写一个纯C语言的矩阵运算库.大神看到了不要喷我,我只是个小白. 个人感觉矩 ...

  4. 使用纯C语言开始win32 sdk编程

    使用纯C语言开始win32 sdk编程 今天开始加强用c语言进行win32 sdk编程的训练,不为别的,只为进一步加强自己对代码的感觉,加强快速写出正确代码的能力.因为c是如些地具有挑战性而灵活的语言 ...

  5. java的开源项目哪里找,我想参加开源项目的开发,请问在网上去哪找这样的项目? 纯C语言的(非C++或JAVA)...

    我想参加开源项目的开发,请问在网上去哪找这样的项目? 纯C语言的(非C++或JAVA)以下文字资料是由(历史新知网www.lishixinzhi.com)小编为大家搜集整理后发布的内容,让我们赶快一起 ...

  6. 用ram实现寄存器堆_纯C语言实现bootloader

    之前有用很少一部分汇编实现过bootloader,但经过后来慢慢改进,发现是可以用纯C语言实现嵌入式操作系统的引导. 下面是之前对不能完全使用C语言引导系统的几点说明: 1.C程序中所有的代码都是以函 ...

  7. 河南理工大学c语言报告封面,河南理工大学图书信息管理系统设计_纯c语言课程设计.doc...

    河南理工大学图书信息管理系统设计_纯c语言课程设计 C语言课程设计报告 题 目:图书信息管理系统设计 河南理工大学计算机学院 目 录 第一章 题目与要求 1.1 问题提出1 1.2 本系统涉及的知识点 ...

  8. linux c语言 电子相册,纯C语言开发(电子相册).doc

    纯C语言开发(电子相册) PAGE PAGE 4 毕 业 论 文 课 题:(C语言)电子相册 摘要:对于java,.net,C++等一些面向对象的语言来说,结合相应的开发工具做出一个电子相册并非难事, ...

  9. c语言实现协议层层消息,纯C语言实现面向对象分析与示例分享.pdf

    纯C语言实现面向对象分析与示例分享 采用 语言实现的关键是如何运用 语言本身的特性来实现多态.继承面.封装的面向对 C C 象的特征最近给出了例子,大家可以参考使用 , C语言的对象化模型 面向对象的 ...

最新文章

  1. 为Jupyter notebook配置R kernel过程及踩坑记录
  2. Construct Binary Tree from Inorder and Postorder Traversal
  3. Tensorflow实战之下载MNIST数据,自动分成train, validation和test三个数据集
  4. bicg matlab,除了bicg之外,还可以使用哪些迭代子解算器来解决MATLAB中的牛顿方程?...
  5. 1086 Tree Traversals Again (25 分)【一般 / 建树 树的遍历】
  6. idea ssh连接mysql数据库_mysql命令行客户端如何通过ssh服务器连接数据库啊?
  7. 入行十年,总结出了数据仓库、数据集市、数据库的精华,你一定不能错过
  8. 记录接触过的开源与非开源
  9. 关于C# winform开发时datagridview图片显示异常的处理
  10. 手把手教你强化学习 (八) 强化学习中的值函数近似算法
  11. java8中Function函数
  12. [Python程序设计] 用Scrapy爬取学堂在线计算机类课程页面的信息
  13. Ant下载安装配置及使用
  14. 解压软件Bandizip
  15. 使用python批量修改图片名称
  16. 对自己的大学期望与目标
  17. Invalid MEX-file 'C:\Users\zs\Desktop\CSR-DCF\mex\mex_extractforeground.mexw64': 找不到指定模块
  18. autojs联众识图
  19. pp模块常用表 sap_SAP PP模块常用T-CODE
  20. Win10配置pytorch深度学习环境

热门文章

  1. rsync复制软件应用于实践
  2. 云智能电销系统比传统电销模式,有哪些突出的优势?
  3. class path resource [mapper/] cannot be resolved to URL because it does not exist解决办法
  4. openwrt各软件包对应功能_极路由 1 刷 openwrt记录
  5. 千米之外的景色 之 远距离无线图传
  6. kingedit 上传php_JS文件上传神器bootstrap fileinput详解
  7. 超高功率光纤激光切割机选购指南
  8. Lua源码笔记--字符串连接
  9. EPOLL机制,使服务数以万计的连线用户多达10000请求/秒成为可能
  10. go课堂笔记20210913