(4)ardunio 矩阵求解官方库改造,添加逆的求解
多此一举,原来官方库给了求逆的函数,在源码里
除此之外,还有转置矩阵,只不过样例没显示出来。
//Matrix Inversion Routine
// * This function inverts a matrix based on the Gauss Jordan method.
// * Specifically, it uses partial pivoting to improve numeric stability.
// * The algorithm is drawn from those presented in
// NUMERICAL RECIPES: The Art of Scientific Computing.
// * The function returns 1 on success, 0 on failure.
// * NOTE: The argument is ALSO the result matrix, meaning the input matrix is REPLACED
int MatrixMath::Invert(mtx_type* A, int n)
{
// A = input matrix AND result matrix
// n = number of rows = number of columns in A (n x n)
int pivrow = 0; // keeps track of current pivot row
int k, i, j; // k: overall index along diagonal; i: row index; j: col index
int pivrows[n]; // keeps track of rows swaps to undo at end
mtx_type tmp; // used for finding max value and making column swaps for (k = 0; k < n; k++)
{
// find pivot row, the row with biggest entry in current column
tmp = 0;
for (i = k; i < n; i++)
{
if (abs(A[i * n + k]) >= tmp) // 'Avoid using other functions inside abs()?'
{
tmp = abs(A[i * n + k]);
pivrow = i;
}
} // check for singular matrix
if (A[pivrow * n + k] == 0.0f)
{
Serial.println("Inversion failed due to singular matrix");
return 0;
} // Execute pivot (row swap) if needed
if (pivrow != k)
{
// swap row k with pivrow
for (j = 0; j < n; j++)
{
tmp = A[k * n + j];
A[k * n + j] = A[pivrow * n + j];
A[pivrow * n + j] = tmp;
}
}
pivrows[k] = pivrow; // record row swap (even if no swap happened) tmp = 1.0f / A[k * n + k]; // invert pivot element
A[k * n + k] = 1.0f; // This element of input matrix becomes result matrix // Perform row reduction (divide every element by pivot)
for (j = 0; j < n; j++)
{
A[k * n + j] = A[k * n + j] * tmp;
} // Now eliminate all other entries in this column
for (i = 0; i < n; i++)
{
if (i != k)
{
tmp = A[i * n + k];
A[i * n + k] = 0.0f; // The other place where in matrix becomes result mat
for (j = 0; j < n; j++)
{
A[i * n + j] = A[i * n + j] - A[k * n + j] * tmp;
}
}
}
} // Done, now need to undo pivot row swaps by doing column swaps in reverse order
for (k = n - 1; k >= 0; k--)
{
if (pivrows[k] != k)
{
for (i = 0; i < n; i++)
{
tmp = A[i * n + k];
A[i * n + k] = A[i * n + pivrows[k]];
A[i * n + pivrows[k]] = tmp;
}
}
}
return 1;
}
ESP8266 07模块
首先安装库

搜索

运行基本实例

这个例子没有矩阵求逆的函数,自己添加。
使用的ESP8266芯片 07板 可外置天线

源程序
#include <MatrixMath.h>
#include "math.h"
float a[4][4]={
{1,0,0,0},
{1,0.5,0,0},
{1,0,1,0},
{1,0,0,1},
};
float **b = new float *[4]; // 拷贝a
void setup()
{
Serial.begin(115200);
int i,j;
for (i=0; i< 4; i++)
{
b[i] = new float[4];
for (j=0; j< 4; j++)
b[i][j]=a[i][j]; // 拷贝a
}
Serial.print("\nMAT A IS:");
for (int i=0; i<=3; i++)
{ Serial.println();
for (int j=0; j<=3; j++)
{ Serial.print(a[i][j]);Serial.print(" , ");}
}
Matrix.NI(b,4);
Serial.print("\nMAT A- IS:");
for (int i=0; i<=3; i++)
{
Serial.println("");
for (int j=0; j<=3; j++)
{ Serial.print(b[i][j]);Serial.print(" , ");}
}
}
void loop()
{
// Matrix.Multiply((mtx_type*)A, (mtx_type*)B, N, N, N, (mtx_type*)C);
//
// Serial.println("\nAfter multiplying C = A*B:");
// Matrix.Print((mtx_type*)A, N, N, "A");
//
// Matrix.Print((mtx_type*)B, N, N, "B");
// Matrix.Print((mtx_type*)C, N, N, "C");
// Matrix.Print((mtx_type*)v, N, 1, "v");
//
// Matrix.Add((mtx_type*) B, (mtx_type*) C, N, N, (mtx_type*) C);
// Serial.println("\nC = B+C (addition in-place)");
// Matrix.Print((mtx_type*)C, N, N, "C");
// Matrix.Print((mtx_type*)B, N, N, "B");
//
// Matrix.Copy((mtx_type*)A, N, N, (mtx_type*)B);
// Serial.println("\nCopied A to B:");
// Matrix.Print((mtx_type*)B, N, N, "B");
//
// Matrix.Invert((mtx_type*)A, N);
// Serial.println("\nInverted A:");
// Matrix.Print((mtx_type*)A, N, N, "A");
//
// Matrix.Multiply((mtx_type*)A, (mtx_type*)B, N, N, N, (mtx_type*)C);
// Serial.println("\nC = A*B");
// Matrix.Print((mtx_type*)C, N, N, "C");
//
// // Because the library uses pointers and DIY indexing,
// // a 1D vector can be smoothly handled as either a row or col vector
// // depending on the dimensions we specify when calling a function
// Matrix.Multiply((mtx_type*)C, (mtx_type*)v, N, N, 1, (mtx_type*)w);
// Serial.println("\n C*v = w:");
// Matrix.Print((mtx_type*)v, N, 1, "v");
// Matrix.Print((mtx_type*)w, N, 1, "w");
// while(1);
}
依赖库文家修改
头文件
添加一个函数
int NI(mtx_type **a, int n);

/*
* MatrixMath.h Library for Matrix Math
*
* Created by Charlie Matlack on 12/18/10.
* Modified from code by RobH45345 on Arduino Forums, algorithm from
* NUMERICAL RECIPES: The Art of Scientific Computing.
* Modified to work with Arduino 1.0/1.5 by randomvibe & robtillaart
* Made into a real library on GitHub by Vasilis Georgitzikis (tzikis)
* so that it's easy to use and install (March 2015)
*/ #ifndef MatrixMath_h
#define MatrixMath_h #define mtx_type float #if defined(ARDUINO) && ARDUINO >= 100
#include "Arduino.h"
#else
#include "WProgram.h"
#endif class MatrixMath
{
public:
//MatrixMath();
void Print(mtx_type* A, int m, int n, String label);
void Copy(mtx_type* A, int n, int m, mtx_type* B);
void Multiply(mtx_type* A, mtx_type* B, int m, int p, int n, mtx_type* C);
void Add(mtx_type* A, mtx_type* B, int m, int n, mtx_type* C);
void Subtract(mtx_type* A, mtx_type* B, int m, int n, mtx_type* C);
void Transpose(mtx_type* A, int m, int n, mtx_type* C);
void Scale(mtx_type* A, int m, int n, mtx_type k);
int Invert(mtx_type* A, int n);
// 自己添加的求逆函数
int NI(mtx_type **a, int n);
}; extern MatrixMath Matrix;
#endif
库文件.cpp修改

修改后
/*
* MatrixMath.cpp Library for Matrix Math
*
* Created by Charlie Matlack on 12/18/10.
* Modified from code by RobH45345 on Arduino Forums, algorithm from
* NUMERICAL RECIPES: The Art of Scientific Computing.
*/ #include "MatrixMath.h" #define NR_END 1 MatrixMath Matrix; // Pre-instantiate // Matrix Printing Routine
// Uses tabs to separate numbers under assumption printed mtx_type width won't cause problems
void MatrixMath::Print(mtx_type* A, int m, int n, String label)
{
// A = input matrix (m x n)
int i, j;
Serial.println();
Serial.println(label);
for (i = 0; i < m; i++)
{
for (j = 0; j < n; j++)
{
Serial.print(A[n * i + j]);
Serial.print("\t");
}
Serial.println();
}
} void MatrixMath::Copy(mtx_type* A, int n, int m, mtx_type* B)
{
int i, j;
for (i = 0; i < m; i++)
for(j = 0; j < n; j++)
{
B[n * i + j] = A[n * i + j];
}
} //Matrix Multiplication Routine
// C = A*B
void MatrixMath::Multiply(mtx_type* A, mtx_type* B, int m, int p, int n, mtx_type* C)
{
// A = input matrix (m x p)
// B = input matrix (p x n)
// m = number of rows in A
// p = number of columns in A = number of rows in B
// n = number of columns in B
// C = output matrix = A*B (m x n)
int i, j, k;
for (i = 0; i < m; i++)
for(j = 0; j < n; j++)
{
C[n * i + j] = 0;
for (k = 0; k < p; k++)
C[n * i + j] = C[n * i + j] + A[p * i + k] * B[n * k + j];
}
} //Matrix Addition Routine
void MatrixMath::Add(mtx_type* A, mtx_type* B, int m, int n, mtx_type* C)
{
// A = input matrix (m x n)
// B = input matrix (m x n)
// m = number of rows in A = number of rows in B
// n = number of columns in A = number of columns in B
// C = output matrix = A+B (m x n)
int i, j;
for (i = 0; i < m; i++)
for(j = 0; j < n; j++)
C[n * i + j] = A[n * i + j] + B[n * i + j];
} //Matrix Subtraction Routine
void MatrixMath::Subtract(mtx_type* A, mtx_type* B, int m, int n, mtx_type* C)
{
// A = input matrix (m x n)
// B = input matrix (m x n)
// m = number of rows in A = number of rows in B
// n = number of columns in A = number of columns in B
// C = output matrix = A-B (m x n)
int i, j;
for (i = 0; i < m; i++)
for(j = 0; j < n; j++)
C[n * i + j] = A[n * i + j] - B[n * i + j];
} //Matrix Transpose Routine
void MatrixMath::Transpose(mtx_type* A, int m, int n, mtx_type* C)
{
// A = input matrix (m x n)
// m = number of rows in A
// n = number of columns in A
// C = output matrix = the transpose of A (n x m)
int i, j;
for (i = 0; i < m; i++)
for(j = 0; j < n; j++)
C[m * j + i] = A[n * i + j];
} void MatrixMath::Scale(mtx_type* A, int m, int n, mtx_type k)
{
for (int i = 0; i < m; i++)
for (int j = 0; j < n; j++)
A[n * i + j] = A[n * i + j] * k;
} //Matrix Inversion Routine
// * This function inverts a matrix based on the Gauss Jordan method.
// * Specifically, it uses partial pivoting to improve numeric stability.
// * The algorithm is drawn from those presented in
// NUMERICAL RECIPES: The Art of Scientific Computing.
// * The function returns 1 on success, 0 on failure.
// * NOTE: The argument is ALSO the result matrix, meaning the input matrix is REPLACED
int MatrixMath::Invert(mtx_type* A, int n)
{
// A = input matrix AND result matrix
// n = number of rows = number of columns in A (n x n)
int pivrow = 0; // keeps track of current pivot row
int k, i, j; // k: overall index along diagonal; i: row index; j: col index
int pivrows[n]; // keeps track of rows swaps to undo at end
mtx_type tmp; // used for finding max value and making column swaps for (k = 0; k < n; k++)
{
// find pivot row, the row with biggest entry in current column
tmp = 0;
for (i = k; i < n; i++)
{
if (abs(A[i * n + k]) >= tmp) // 'Avoid using other functions inside abs()?'
{
tmp = abs(A[i * n + k]);
pivrow = i;
}
} // check for singular matrix
if (A[pivrow * n + k] == 0.0f)
{
Serial.println("Inversion failed due to singular matrix");
return 0;
} // Execute pivot (row swap) if needed
if (pivrow != k)
{
// swap row k with pivrow
for (j = 0; j < n; j++)
{
tmp = A[k * n + j];
A[k * n + j] = A[pivrow * n + j];
A[pivrow * n + j] = tmp;
}
}
pivrows[k] = pivrow; // record row swap (even if no swap happened) tmp = 1.0f / A[k * n + k]; // invert pivot element
A[k * n + k] = 1.0f; // This element of input matrix becomes result matrix // Perform row reduction (divide every element by pivot)
for (j = 0; j < n; j++)
{
A[k * n + j] = A[k * n + j] * tmp;
} // Now eliminate all other entries in this column
for (i = 0; i < n; i++)
{
if (i != k)
{
tmp = A[i * n + k];
A[i * n + k] = 0.0f; // The other place where in matrix becomes result mat
for (j = 0; j < n; j++)
{
A[i * n + j] = A[i * n + j] - A[k * n + j] * tmp;
}
}
}
} // Done, now need to undo pivot row swaps by doing column swaps in reverse order
for (k = n - 1; k >= 0; k--)
{
if (pivrows[k] != k)
{
for (i = 0; i < n; i++)
{
tmp = A[i * n + k];
A[i * n + k] = A[i * n + pivrows[k]];
A[i * n + pivrows[k]] = tmp;
}
}
}
return 1;
} //自己添加的求逆函数
int MatrixMath::NI(mtx_type **a, int n){ int *is = new int[n];
int *js = new int[n];
int i,j,k;
double d,p;
for ( k = 0; k < n; k++)
{
d = 0.0;
for (i=k; i<=n-1; i++)
for (j=k; j<=n-1; j++)
{
p=fabs(a[i][j]);
if (p>d) { d=p; is[k]=i; js[k]=j;}
}
if ( 0.0 == d )
{
free(is); free(js); Serial.println("err**not inv\n");
return(0);
}
if (is[k]!=k)
for (j=0; j<=n-1; j++)
{
p=a[k][j];
a[k][j]=a[is[k]][j];
a[is[k]][j]=p;
}
if (js[k]!=k)
for (i=0; i<=n-1; i++)
{
p=a[i][k];
a[i][k]=a[i][js[k]];
a[i][js[k]]=p;
}
a[k][k] = 1.0/a[k][k];
for (j=0; j<=n-1; j++)
if (j!=k)
{
a[k][j] *= a[k][k];
}
for (i=0; i<=n-1; i++)
if (i!=k)
for (j=0; j<=n-1; j++)
if (j!=k)
{
a[i][j] -= a[i][k]*a[k][j];
}
for (i=0; i<=n-1; i++)
if (i!=k)
{
a[i][k] = -a[i][k]*a[k][k];
}
}
for ( k = n-1; k >= 0; k--)
{
if (js[k]!=k)
for (j=0; j<=n-1; j++)
{
p = a[k][j];
a[k][j] = a[js[k]][j];
a[js[k]][j]=p;
}
if (is[k]!=k)
for (i=0; i<=n-1; i++)
{
p = a[i][k];
a[i][k]=a[i][is[k]];
a[i][is[k]] = p;
}
}
free(is); free(js);
return(1); }
(4)ardunio 矩阵求解官方库改造,添加逆的求解的更多相关文章
- arm-none-eabi-gcc,makefile,stm官方库构建stm32f4xx工程
参考文章:http://www.stmcu.org/module/forum/forum.php?mod=viewthread&tid=603753&highlight=ubuntu ...
- 关于如何使用Altium Designer 10以上版本官方库
开卷有益:如果本帖不适合在此板块,请斑竹自行删除,发帖的目的纯属报答各位Amofans. Altium公司的Altium Designer 09版本及以下还能到Altium官网下载第三方Labr ...
- EXCEL类型库的添加
1. 创建新的C++工程 创建基于对话框的MFC程序 2. 添加库.添加Excel类库 在工程名上右键,选择“添加”—“类”(或者点击菜单栏的“项目”->“添加类”),选择“TypeLib中的M ...
- CMake 添加头文件目录,链接动态、静态库(添加子文件夹)
CMake支持大写.小写.混合大小写的命令. 当编译一个需要第三方库的项目时,需要知道: 去哪找头文件(.h),-I(GCC) INCLUDE_DIRECTORIES() 去哪找库文件(.so/.dl ...
- Qt下Eigen矩阵函数库的添加
第1步: 下载一个Eigen文件包,在官网下即可: http://eigen.tuxfamily.org/index.php?title=Main_Page 第2步: 用Qt随便建一个GUI工程,在. ...
- Eclispe使用Maven添加官方库的jar包
先到百度或google搜索maven仓库,在仓库中搜索需要的jar包,如poi.jar. 搜索到之后找到需要的jar包,找到这里
- 用Modelsim仿真QuartusII综合后网表时库的添加方法(转)
这两天做综合后仿真,发现FPGA器件库又不会加了,无奈上网找方法.说起来不好意思,很早就接触Modelsim这个仿真软件了,可是没有好好琢磨.把这两天找的方法贴出来,再加上自己的理解,以后忘了可以上博 ...
- Git学习笔记(一)创建版本库并添加文件
最近从廖雪峰老师的个人网站上学习git,做点笔记. ★★★★★ 先注册自己的username和email,否则会报如下错误: 注册:git config --global user.name &quo ...
- 初学git,初始化库|添加文件ignore|提交方法
1.初始化git仓库: 进入任意目录,右键选择:Git Bash Here,输入命令:git status 查看当前git库的状态. 如要排除文件,在库根目录下创建.gitignore文件(新建文件改 ...
随机推荐
- 用Qt实现一个计算器
一· 介绍 目的: 做一个标准型的计算器.用于学习Qt基础学习. 平台: Qt 5.12.0 二· 结构框架设计 2.1最终产品样式 界面的设计大体按照win系统自带的计算器做模仿.左边是win7 的 ...
- 《学渣Linux笔记》——关于.bashrc与profile(涉及交互式与非交互式、登录与非登录shell)
<学渣Linux笔记>--关于.bashrc与profile(涉及交互式与非交互式.登录与非登录shell) 1.基本概念(个人理解) 交互式shell:等待用户输入,并执行相应操作的sh ...
- Linux基础(11)原始套接字
一边接收函数返回一边判断返回值时一定要把接收的优先级加()提高再去判断 例 if((sockfd = socket()) < 0) 问题: 如何实现SYN扫描器扫描端口 , 比如AB两个设备要进 ...
- java知识精要(二)
java知识精要(一) 集合 Iterable v.s. Iterator 两者都是接口,在Collection继承的是Iterable. Iterable表达了集合具备迭代访问的能力,而Iterat ...
- ZYNQ笔记(3):GPIO的使用(MIO、EMIO)——led灯
一.GPIO原理 1.GPIO介绍 程序员通过软件代码可以独立和动态地对每个 GPIO 进行控制,使其作为输入.输出或中断. (1)通过一个加载指令,软件可以读取一个 GPIO 组内所有 GPIO 的 ...
- C# 运行流程
转载 https://www.cnblogs.com/qcloud1001/p/9816956.html 从编译原理说起 一句话介绍编译器:编译器是将用某种程式语言写成的源代码(源语言),转换成另一 ...
- java之spring之整合ssh-2
这篇也是主要讲解 ssh 的整合,不同于上一篇的是它的注入方式. 这篇会采用扫描注入的方式,即去除 applicationContext-asd.xml 文件. 目录结构如下: 注意,这里只列举不同的 ...
- Django之创建超级用户
本文链接来自:https://blog.csdn.net/HuaCode/article/details/79721673 首选创建一个新用户,用来登录Django管理网站,进入manage.py目录 ...
- TCP连接与断开
两台宿主机 一台:作为服务器 另一台:作为客户端 服务器的步骤: 打开[控制面板]----点击[程序]---点击程序和功能中[打开或关闭Windows功能]---点击[Telnet服务器]--点击[确 ...
- 【面试突击】-Redis常见面试题(二)
1.什么是Redis?简述它的优缺点? Redis本质上是一个Key-Value类型的内存数据库,很像memcached,整个数据库统统加载在内存当中进行操作,定期通过异步操作把数据库数据flush到 ...