多此一举,原来官方库给了求逆的函数,在源码里

除此之外,还有转置矩阵,只不过样例没显示出来。

//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 矩阵求解官方库改造,添加逆的求解的更多相关文章

  1. arm-none-eabi-gcc,makefile,stm官方库构建stm32f4xx工程

    参考文章:http://www.stmcu.org/module/forum/forum.php?mod=viewthread&tid=603753&highlight=ubuntu ...

  2. 关于如何使用Altium Designer 10以上版本官方库

    开卷有益:如果本帖不适合在此板块,请斑竹自行删除,发帖的目的纯属报答各位Amofans.    Altium公司的Altium Designer 09版本及以下还能到Altium官网下载第三方Labr ...

  3. EXCEL类型库的添加

    1. 创建新的C++工程 创建基于对话框的MFC程序 2. 添加库.添加Excel类库 在工程名上右键,选择“添加”—“类”(或者点击菜单栏的“项目”->“添加类”),选择“TypeLib中的M ...

  4. CMake 添加头文件目录,链接动态、静态库(添加子文件夹)

    CMake支持大写.小写.混合大小写的命令. 当编译一个需要第三方库的项目时,需要知道: 去哪找头文件(.h),-I(GCC) INCLUDE_DIRECTORIES() 去哪找库文件(.so/.dl ...

  5. Qt下Eigen矩阵函数库的添加

    第1步: 下载一个Eigen文件包,在官网下即可: http://eigen.tuxfamily.org/index.php?title=Main_Page 第2步: 用Qt随便建一个GUI工程,在. ...

  6. Eclispe使用Maven添加官方库的jar包

    先到百度或google搜索maven仓库,在仓库中搜索需要的jar包,如poi.jar. 搜索到之后找到需要的jar包,找到这里

  7. 用Modelsim仿真QuartusII综合后网表时库的添加方法(转)

    这两天做综合后仿真,发现FPGA器件库又不会加了,无奈上网找方法.说起来不好意思,很早就接触Modelsim这个仿真软件了,可是没有好好琢磨.把这两天找的方法贴出来,再加上自己的理解,以后忘了可以上博 ...

  8. Git学习笔记(一)创建版本库并添加文件

    最近从廖雪峰老师的个人网站上学习git,做点笔记. ★★★★★ 先注册自己的username和email,否则会报如下错误: 注册:git config --global user.name &quo ...

  9. 初学git,初始化库|添加文件ignore|提交方法

    1.初始化git仓库: 进入任意目录,右键选择:Git Bash Here,输入命令:git status 查看当前git库的状态. 如要排除文件,在库根目录下创建.gitignore文件(新建文件改 ...

随机推荐

  1. [BZOJ4382][POI2015]Podział naszyjnika (神奇HASH)

    [问题描述]    长度为n 的一串项链,每颗珠子是K 种颜色之一.第i 颗与第i-1,i+1 颗珠子相邻,第n 颗与第1 颗也相邻.    切两刀,把项链断成两条链.要求每种颜色的珠子只能出现在其中 ...

  2. Linux基础(11)原始套接字

    一边接收函数返回一边判断返回值时一定要把接收的优先级加()提高再去判断 例 if((sockfd = socket()) < 0) 问题: 如何实现SYN扫描器扫描端口 , 比如AB两个设备要进 ...

  3. Go基础编程实践(一)—— 操作字符串

    修剪空格 strings包中的TrimSpace函数用于去掉字符串首尾的空格. package main import ( "fmt" "strings" ) ...

  4. Taylor()函数总结

    Taylor()函数总结 Taylor展开式公式的具体形式见百度百科:https://baike.baidu.com/item/%E6%B3%B0%E5%8B%92%E5%85%AC%E5%BC%8F ...

  5. Linux 服务器 关闭FTP匿名访问

    service vsftpd status //查看FTP运行状态 vim /etc/vsftpd/vsftpd.conf //修改配置文件 找到vsftpd.conf中的 anonymous_ena ...

  6. json_rpc_2 implementation

    https://stackoverflow.com/questions/52670255/flutter-json-rpc-2-implementation import 'dart:convert' ...

  7. 【i.MX6UL/i.MX6ULL开发常见问题】单独编译内核,uboot生成很多文件,具体用哪一个?

    [i.MX6UL/i.MX6ULL开发常见问题]2.3单独编译内核,uboot生成很多文件,具体用哪一个? 答:内核编译出来的文件是~/MYiR-imx-Linux/arch/arm/boot/目录下 ...

  8. vue mixins是什么及应用

    mixins是什么? 官网对此的解释比较文绉绉,通俗的理解很简单,就是提供功能抽象 如A,B,C ...Z等很多个页面用到同一个功能,此时的做法就应该把该功能抽象出来,mixins就是干这个的 当然, ...

  9. 英语dyamaund钻石

    dyamaund  英文词汇,中文翻译为金刚石的;镶钻;用钻石装饰 中文名:镶钻;钻石装饰 外文名:dyamaund 目录 释义 dyamaund 读音:[ˈdaɪəmənd, ˈdaɪmənd] ...

  10. JMeter性能测试,入门

    原文转自:https://blog.csdn.net/lovesoo/article/details/78579547 Apache JMeter是一款纯java编写负载功能测试和性能测试开源工具软件 ...