解压然后放在一个不会经常移动的地址,
在解决方案管理器一栏中选定项目名称->单击菜单栏中的项目->选择属性->VC++目录->包含目录
包含该路径就可以,注意该路径目录的下级目录应为一系列子文件,否则包含时候找不到,参见参考资源[1]。
Eigen库有不同的模块,需要对应的功能包含对应的头文件即可,详情见参考资源[2]。
在官网下载压缩包
下载文件解压缩后,文件格式大致如下
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-QRbOzjw0-1666150352018)(assets/image-20221006215332834.png)]
具体安装方法,参见INSTALL文件
Installation instructions for Eigen
***********************************
Explanation before starting
***************************
Eigen consists only of header files, hence there is nothing to compile
before you can use it. Moreover, these header files do not depend on your
platform, they are the same for everybody.
Method 1. Installing without using CMake
****************************************
You can use right away the headers in the Eigen/ subdirectory. In order
to install, just copy this Eigen/ subdirectory to your favorite location.
If you also want the unsupported features, copy the unsupported/
subdirectory too.
Method 2. Installing using CMake
********************************
Let's call this directory 'source_dir' (where this INSTALL file is).
Before starting, create another directory which we will call 'build_dir'.
Do:
cd build_dir
cmake source_dir
make install
The "make install" step may require administrator privileges.
You can adjust the installation destination (the "prefix")
by passing the -DCMAKE_INSTALL_PREFIX=myprefix option to cmake, as is
explained in the message that cmake prints at the end.
注意把其放置在一个不会轻易移动全英目录下
直接包含头文件即可
其余操作如写CMakeLists.txt 和json文件和其他程序相同
如果用到一些不常用的unsupported文件夹功能 ,其步骤类似
(推荐,按需要安装,不会安装多余的)
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-38Jh1izQ-1666150352019)(assets/image-20221007135944572.png)]
优点是 一次安装,一劳永逸,安装功能比较全
(可能安装文件较多,具体的没分析过其相应的安装CmakeLists文件)
make install的默认安装位置 /usr/local/bin
这样之后就可以写#include"Eigen/Dense"
了,(貌似是/usr/local/bin默认会进行搜索~)
在测试过程中需要包含对应的库文件
#include
#include using namespace Eigen; 官网 https://eigen.tuxfamily.org/index.php?title=Main_Page
内部原理
此处可见一个局限性,只能对应二维数组,不能建立高维数组
//通过矩阵类模板实现,带有默认参数,参数解析见参考资源[2]
Matrix
//函数模板声明与定义
template
T2 test(T1 tmp, T2 tmp1) {
T2 tmp2 = tmp + tmp1;
return tmp2;
}
//类模板
template
class Person {
public:
Person(NameType name, AgeType age) {
this->mName = name; this->mAge = age;
}
void showPerson() {
cout << "name: " << this->mName << " age: " << this->mAge << endl;
}
public:
NameType mName;
AgeType mAge;
};
//和tuple定义变量的方法进行对比
tuple tuple_var;
// 和vector进行对比
vector> v1;
/*
静态矩阵 Matrix2d
动态数组 MatrixXd
静态列向量 Vector2f
动态列向量 VectorXd
静态行向量 RowVector2f
动态行向量 RowVectorXd
*/
// 只定义了常用大小的矩阵和向量
Matrix5d Matrix_01; //报错,未定义
Vector5d Vector_01; //报错,未定义
// 也可以自行定义
void test() {
typedef Matrix Matrix5d;
Matrix5d Matrix_01;
}
#include
#include
using namespace Eigen;
void test() {
Matrix3i matrix_01; // 大小为3*3的int型矩阵
MatrixXf matrix_02(2,3); // 大小为2*3的float型矩阵
MatrixXd matrix_03; // double型矩阵
MatrixXd matrix_04; // double型矩阵
MatrixXd matrix_05; // double型矩阵
MatrixXd matrix_06; // double型矩阵
MatrixXd matrix_07(3,4); // 大小为3*4的double型矩阵
Vector3i Vector_01; // 大小为3*1的int型列向量
Vector3d Vector_02; // 大小为3*1的double型列向量
VectorXd Vector_03; // 大小为X*1的int型列向量
RowVectorXd Vector_04; // 大小为1*X的double型行向量
RowVector3d Vector_05; // 大小为1*3的double型行向量
// 赋值方法一,用>>输入初始化,必须指定大小
matrix_01<< 1, 2, 3, 4, 5, 6, 7, 8, 9;
matrix_02<< 1, 2, 3, 4, 5, 6;
Vector_01<< 1,2,3 ;
// 赋值方法二,对于以Vextor3d方式指定大小的向量可以花括号输入,
// 矩阵不可以和未指定大小、以其他方式指定大小的向量如“VectorXd Vector_02(3)”不可以
Vector_02 = { 4,5,6 };
//VectorXd Vector_02 = { 4,5,6 }; // 报错
//VectorXd Vector_02(3); vector_02= { 4,5,6 }; // 报错
//matrix_02 = { 1, 2, 3, 4, 5, 6 }; // 报错
// 赋值方法三,对于以Vextor3d方式指定大小的向量可以小括号的形式输入
typedef Matrix < double, 7, 1> Vector7d;
Vector7d Vector_06(1, 2, 3, 4, 5, 6, 7);
// 赋值方法四,用特殊函数初始化
// 注意左侧和右侧对应的类型需要统一
// 向量同样的定义方式
matrix_03 = MatrixXd::Zero(3, 4); // 全0矩阵,大写的Z
matrix_04 = MatrixXd::Ones(3, 4); // 全1矩阵
matrix_05 = MatrixXd::Identity(3, 4); // 单位阵
matrix_06 = MatrixXd::Random(3, 4); // 随机矩阵
// 赋值方法四,从txt中读取
// 此种方式,必须提前指定大小,否则会报错
ifstream infile;
infile.open("C:\\Users\\123\\Desktop\\C++下的Eigen库学习笔记\\matrix.txt", ios::in);
int numRow = 3;
int numCol = 4;
for (int ii = 0; ii < numRow; ii++) {
for (int jj = 0; jj < numCol; jj++) {
double temp;
infile >> temp;
matrix_07(ii,jj) = temp;
}
}
infile.close();
// 打印
cout << "matrix_01的值为:" << endl << matrix_01 << endl;
cout << "matrix_02的值为:" << endl << matrix_02 << endl;
cout << "matrix_03的值为:" << endl << matrix_03 << endl;
cout << "matrix_04的值为:" << endl << matrix_04 << endl;
cout << "matrix_05的值为:" << endl << matrix_05 << endl;
cout << "matrix_06的值为:" << endl << matrix_06 << endl;
cout << "matrix_07的值为:" << endl << matrix_07 << endl;
cout << "Vector_01的值为:" << endl << Vector_01 << endl;
cout << "Vector_02的值为:" << endl << Vector_02 << endl;
cout << "Vector_03的值为:" << endl << Vector_03 << endl;
cout << "Vector_04的值为:" << endl << Vector_04 << endl;
cout << "Vector_05的值为:" << endl << Vector_05 << endl;
cout << "Vector_06的值为:" << endl << Vector_06 << endl;
}
特别注意
// 空矩阵
void test02() {
MatrixXd matrix_01(0, 0);
cout << "matrix_01的值为:" << endl << matrix_01 << endl;
cout << "行数: " << matrix_01.rows() << endl;
cout << "列数: " << matrix_01.cols() << endl;
cout << "元素个数: " << matrix_01.size() << endl;
MatrixXd matrix_02(3, 0);
cout << "matrix_02的值为:" << endl << matrix_02 << endl;
cout << "行数: " << matrix_02.rows() << endl;
cout << "列数: " << matrix_02.cols() << endl;
cout << "元素个数: " << matrix_02.size() << endl;
}
void test01() {
Vector3d Vector_01; // 可以运行
//VectorXd Vector_01(3); // 可以运行
//VectorXd Vector_01; // 报错
Vector_01 << 4, 5, 6 ;
cout << Vector_01 << endl;
}
void test02() {
Matrix2d matrix_01; // 可以运行
//MatrixXd matrix_01(2,2); // 可以运行
//MatrixXd matrix_01; // 报错
matrix_01 <<1,2,3, 4 ;
cout << matrix_01 << endl;
}
void test() {
Vector3d Vector_01;
//VectorXd Vector_01(3); // 报错,THIS_METHOD_IS_ONLY_FOR_VECTORS_OF_A_SPECIFIC_SIZE
Vector_01 = { 4, 5, 6 };
cout << Vector_01 << endl;
}
// 转换原则:
// 1.行向量和列向量可以互相转换
// 2.行向量和列向量可以转为矩阵
// 3.向量型矩阵可以转为向量,但需要行列类型相对应,否则报错
void test999() {
VectorXd vector_01(4);
vector_01 << 1, 2, 3, 4;
// 行向量和列向量可以互相转换
// 注意,函数传递参数时如果以引用的方式传入,则不会进行自动转换
// 需要向量的形式相对应
RowVectorXd vector_02;
vector_02 = vector_01;
// 行向量和列向量可以转为矩阵
MatrixXd matrix_01 = vector_01;
MatrixXd matrix_02 = vector_02;
//向量型矩阵可以转为向量,但需要行列类型相对应,否则报错
VectorXd vector_03 = matrix_01; // matrix_01只有一列 RowVectorXd vector_03; 会报错
RowVectorXd vector_04 = matrix_02; //matrix_01只有一行 VectorXd vector_03; 会报错
cout << "vector_01的值为:" << endl << vector_01 << endl;
cout << "vector_02的值为:" << endl << vector_02 << endl;
cout << "vector_03的值为:" << endl << vector_03 << endl;
cout << "vector_04的值为:" << endl << vector_04 << endl;
cout << "matrix_01的值为:" << endl << matrix_01 << endl;
cout << "matrix_02的值为:" << endl << matrix_02 << endl;
}
VectorXd test01(RowVectorXd v1, VectorXd v2) {
return v1 + v2;
}
VectorXd test02(VectorXd v1, RowVectorXd& v2) {
return v1 + v2;
}
int main() {
VectorXd v1(4);
v1 << 1, 2, 3, 4;
VectorXd v2(4);
v2 << 1, 2, 3, 4;
RowVectorXd v3(4);
v2 << 1, 2, 3, 4;
cout << test111(v1, v2) << endl;
// cout << test222(v1, v2) << endl; //类型不对应,报错
cout << test222(v1, v3) << endl;
}
// 有待研究 @TODO
void test01() {
// 报错,参见矩阵模板定义可以知道,只有定义二维数组;
// MatrixXd matrix_01(2, 3, 4);
// matrix_01 << 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24;
// cout << "matrix_01的值为:" << endl << matrix_01 << endl;
}
// 采用tuple函数和vector容器,可以多个矩阵组成高维度矩阵(各矩阵大小可以不同)
// 缺点是切片索引时不如Matlab高维数据灵活
void test02() {
MatrixXd matrix_01(2, 3);
MatrixXd matrix_02(2, 3);
MatrixXd matrix_03(2, 2);
matrix_01 << 1, 2, 3, 4, 5, 6;
matrix_02 << 11, 12, 13, 14, 15, 16;
matrix_03 << 31, 32, 33, 34;
// 方式一,构建一个大小为2*3*3的矩阵,适合小矩阵
tuple matrix_3dim_01=make_tuple(matrix_01,matrix_02,matrix_03);
// 方式二,采用vector容器
vector matrix_3dim_02;
matrix_3dim_02.push_back(matrix_01);
matrix_3dim_02.push_back(matrix_02);
matrix_3dim_02.push_back(matrix_03);
MatrixXd matrix_04 = get<2>(matrix_3dim_01);
MatrixXd matrix_05 = matrix_3dim_02[2];
cout << "matrix_01的值为:" << endl << matrix_01 << endl;
cout << "matrix_02的值为:" << endl << matrix_02 << endl;
cout << "matrix_03的值为:" << endl << matrix_03 << endl;
cout << "matrix_04的值为:" << endl << matrix_04 << endl;
cout << "matrix_05的值为:" << endl << matrix_05 << endl;
}
//常规矩阵
void test01() {
// 大小为3*4的double型矩阵
MatrixXd matrix_01(2, 3);
matrix_01 << 1, 2, 3, 4, 5, 6;
cout << "行数: " << matrix_01.rows() << endl;
cout << "列数: " << matrix_01.cols() << endl;
cout << "元素个数: " << matrix_01.size() << endl;
// 不会改变matrix_01,需要赋值给一个新的变量
matrix_01.transpose();
cout << "matrix_01的值为:" << endl << matrix_01 << endl;
// 会改变matrix_01
matrix_01.transposeInPlace();
cout << "matrix_01的值为:" << endl << matrix_01 << endl;
// 会改变尺寸
MatrixXd matrix_02 = matrix_01.transpose();
cout << "matrix_02的值为:" << endl << matrix_02 << endl;
}
// 空矩阵
void test02() {
MatrixXd matrix_01(0, 0);
cout << "matrix_01的值为:" << endl << matrix_01 << endl;
cout << "行数: " << matrix_01.rows() << endl;
cout << "列数: " << matrix_01.cols() << endl;
cout << "元素个数: " << matrix_01.size() << endl;
}
void test() {
/* 注意索引从零开始,用()进行索引,向量还可以用[]进行索引*/
MatrixXd matrix_01(4, 5);
matrix_01 << 1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
11,12, 13, 14, 15, 16, 17, 18, 19, 20;
VectorXd vector_01(4);
vector_01 << 1, 2, 3, 4;
// 读取某个元素
double var_01 = matrix_01(0, 2);
double var_02 = vector_01(2);
double var_03 = vector_01[2];
// 读取某行或某列元素,可以用行向量或列矩阵接收都可以
VectorXd Vector_01 = matrix_01.row(0);
VectorXd Vector_02 = matrix_01.col(0);
// 读取某个块儿矩阵
// 表示从矩阵(i, j)元素开始,取p行q列个元素组成新矩阵
//写法一 matrix.block(i,j, p, q) :
//写法二 matrix.block(i, j)
MatrixXd matrix_02 = matrix_01.block<2, 3>(0, 0);
MatrixXd matrix_03 = matrix_01.block(0, 0, 2, 3);
// 读取某行列的区间元素
// 行列类型需要对应,读取行定义RowVectorXd,读取列定义VectorXd
// 第m行第a列到第b列, matrix_01.block(m-1, a-1, 1, b-a+1)
// 第n列第a行到第b行, matrix_01.block(a-1, n-1, b-a+1,1)
RowVectorXd Vector_03 = matrix_01.block(1, 2, 1, 3); //读取第2行3-5个元素,从2行第3个读取一个1*3的行向量
VectorXd Vector_04 = matrix_01.block(1, 1, 3, 1); //读取第2列2-4个元素,从第2列第2个元素读取一个3*1的列向量
cout << "matrix_01的值为:" << endl << matrix_01 << endl;
cout << "matrix_02的值为:" << endl << matrix_02 << endl;
cout << "matrix_03的值为:" << endl << matrix_03 << endl;
cout << "Vector_01的值为:" << endl << Vector_01 << endl;
cout << "Vector_02的值为:" << endl << Vector_02 << endl;
cout << "Vector_03的值为:" << endl << Vector_03 << endl;
cout << "Vector_04的值为:" << endl << Vector_04 << endl;
cout << "var_01的值为:" << endl << var_01 << endl;
cout << "var_02的值为:" << endl << var_02 << endl;
cout << "var_03的值为:" << endl << var_03 << endl;
}
一个索引时需要注意的点
// 有时经常需要用一个向量的值作为索引
// 注意向量的类型需要转为int
MatrixXd m(5,5);
VectorXd v(5);
doueble val=m(3,(int)v(0)); // 注意,v是一个double,需要转成int
// 矩阵角操作
// 左上角、左下角、右上角、右下角
// 前q行、后q行、前q列、后q列
// 具体函数参见参考文献[2]
void test05() {
MatrixXd matrix_01(4, 4);
matrix_01 << 1, 2, 3, 4,
5, 6, 7, 8,
9, 10, 11, 12,
13, 14, 15, 16;
MatrixXd matrix_02=matrix_01.topLeftCorner<2, 2>();
MatrixXd matrix_03 = matrix_01.topRows<2>();
// 回顾block的写法,需要知道大小
MatrixXd matrix_04 = matrix_01.block(0, 0, 2, 2); //左上角
MatrixXd matrix_05 = matrix_01.block(0, 0, 2, 4); //前两行
cout << "matrix_01的值为:" << endl << matrix_01 << endl;
cout << "matrix_02的值为:" << endl << matrix_02 << endl;
cout << "matrix_03的值为:" << endl << matrix_03 << endl;
cout << "matrix_04的值为:" << endl << matrix_04 << endl;
cout << "matrix_05的值为:" << endl << matrix_05 << endl;
}
void test() {
//顺序n个元素
VectorXd vector_01(6);
vector_01 << 1, 2, 3, 4, 5, 6;
int i = 2;
int n = 4;
// 前n个元素
VectorXd vector_02=vector_01.head(n);
//后n个元素
VectorXd vector_03 = vector_01.tail(n);
//第i个位置起截取n个元素
VectorXd vector_04 = vector_01.segment(i, n);
cout << "vector_01的值为:" << endl << vector_01 << endl;
cout << "vector_02的值为:" << endl << vector_02 << endl;
cout << "vector_03的值为:" << endl << vector_03 << endl;
cout << "vector_04的值为:" << endl << vector_04 << endl;
}
void test() {
MatrixXi matrix_01(3, 4);
matrix_01 << 1, 2, 3, 4,
5, 6, 7, 8,
9, 10, 11, 12;
cout << "原始matrix_01的值为:" << endl << matrix_01 << endl;
matrix_01(0, 0) = 100;
cout << "更改元素后matrix_01的值为:" << endl << matrix_01 << endl;
RowVectorXi rowVector_01(4);
rowVector_01 << 1, 2, 3, 4;
matrix_01.row(1) = rowVector_01;
cout << "更改行元素后matrix_01的值为:" << endl << matrix_01 << endl;
int aa = 100;
int bb = 200;
matrix_01.block(2, 2, 1, 2) << aa, bb;
cout << "更改块元素后matrix_01的值为:" << endl << matrix_01 << endl;
}
删除向量某个位置的元素,返回一个新的向量
采用下面的方法即可,向量是特殊的矩阵
删除矩阵某些行,返回一个新的矩阵
#include // 包含头文件
// 传入待删除的行数索引向量
MatrixXd deleteMatrixRows(MatrixXd matrix_pre, VectorXd rows2delete) {
// 将待待删除的行数索引向量转为保存的行数
vector index2save; // 需包含vector头文件
for (int ii = 0; ii < matrix_pre.rows(); ii++) {
bool saveFlag = true;
for (int jj= 0; jj < rows2delete.size(); jj++) {
// 检查rows2delete中元素,超限返回空矩阵
// 可将此语句注释,仅匹配正确值
if (rows2delete[jj] > matrix_pre.rows()-1|| rows2delete[jj] <0) {
cout << "待删除向量中索引超限!! " << endl;
MatrixXd matrix_temp(0, 0);
return matrix_temp;
}
if (ii == rows2delete[jj]) {
saveFlag = false;
break;
}
}
if (saveFlag) {
index2save.push_back(ii);
}
}
MatrixXd matrix_after(index2save.size(), matrix_pre.cols());
for (int tt = 0; tt < index2save.size(); tt++) {
matrix_after.row(tt) = matrix_pre.row(index2save[tt]);
}
return matrix_after;
}
void test01() {
MatrixXd matrix_01(4, 4);
matrix_01 << 1, 2, 3, 4,
5, 6, 7, 8,
9, 10, 11, 12,
13, 14, 15, 16;
// 正常删除
VectorXd v1(2);
v1 << 1, 3;
MatrixXd matrix_02 = deleteMatrixRows(matrix_01, v1);
cout << matrix_02 << endl;
// 返回一个空矩阵
VectorXd v2(4);
v2 << 0, 1, 2, 3;
MatrixXd matrix_03 = deleteMatrixRows(matrix_01, v2);
cout << matrix_03 << endl;
// 索引超限,报错!
VectorXd v3(3);
v3 << -1, 2, 3;
MatrixXd matrix_04 = deleteMatrixRows(matrix_01, v3);
cout << matrix_04 << endl;
}
// 删除向量某个位置的元素,返回一个新的向量
void test02() {
VectorXd vector_01(4);
vector_01 << 1, 2, 3, 4;
// 正常删除
VectorXd v1(2);
v1 << 1, 3;
VectorXd vector_02 = deleteMatrixRows(vector_01, v1);
cout << vector_02 << endl;
// 返回一个空向量
VectorXd v2(4);
v2 << 0, 1, 2, 3;
VectorXd vector_03 = deleteMatrixRows(vector_01, v2);
cout << vector_03 << endl;
// 索引超限,会进行提示!
// 由矩阵类型转换的知识可知
// 索引超限时return的矩阵需要改和接收类型相对应,否则报错
VectorXd v3(3);
v3 << -1, 2, 3;
VectorXd vector_04 = deleteMatrixRows(vector_01, v3);
cout << vector_04 << endl;
}
// 传入待删除的列数索引向量
MatrixXd deleteMatrixColumns(MatrixXd matrix_pre, VectorXd columns2delete) {
// 将待待删除的行数索引向量转为保存的行数
vector index2save;
for (int ii = 0; ii < matrix_pre.cols(); ii++) {
bool saveFlag = true;
for (int jj = 0; jj < columns2delete.size(); jj++) {
// 检查columns2delete中元素,超限返回空矩阵
// 可将此语句注释,仅匹配正确值
if (columns2delete[jj] > matrix_pre.rows() - 1 || columns2delete[jj] < 0) {
cout << "待删除向量中索引超限!! " << endl;
MatrixXd matrix_temp(0, 0);
return matrix_temp;
}
if (ii == columns2delete[jj]) {
saveFlag = false;
break;
}
}
if (saveFlag) {
index2save.push_back(ii);
}
}
MatrixXd matrix_after(matrix_pre.rows(), index2save.size());
for (int tt = 0; tt < index2save.size(); tt++) {
matrix_after.col(tt) = matrix_pre.col(index2save[tt]);
}
return matrix_after;
}
void test01() {
MatrixXd matrix_01(4, 4);
matrix_01 << 1, 2, 3, 4,
5, 6, 7, 8,
9, 10, 11, 12,
13, 14, 15, 16;
// 正常删除
VectorXd v1(2);
v1 << 1, 3;
MatrixXd matrix_02=deleteMatrixColumns(matrix_01, v1);
cout << matrix_02 << endl;
// 返回一个空矩阵
VectorXd v2(4);
v2 << 0,1, 2,3;
MatrixXd matrix_03 = deleteMatrixColumns(matrix_01, v2);
cout << matrix_03 << endl;
// 索引超限,报错!
VectorXd v3(3);
v3 << 4, 2, 3;
MatrixXd matrix_04 = deleteMatrixColumns(matrix_01, v3);
cout << matrix_04<< endl;
}
常常ismember返回的结果相结合,删除某些特定和的行列(ismember功能见2.3.2)
删除向量特定元素同理,向量是特殊的矩阵
// ismemberFlag是一个大小为矩阵matrix_pre行数或列数的向量
MatrixXd deleteMatrixRows(MatrixXd matrix_pre, VectorXd ismemberFlag) {
vector index2save; // 需包含vector头文件
for (int ii = 0; ii < matrix_pre.rows(); ii++) {
// 此处 ==-1 还是 !=-1需要根据实际判定
if (ismemberFlag[ii] == -1) {
index2save.push_back(ii);
}
//if (ismemberFlag[ii] != -1) {
// index2save.push_back(ii);
//}
}
MatrixXd matrix_after(index2save.size(), matrix_pre.cols());
for (int jj = 0; jj < index2save.size(); jj++) {
matrix_after.row(jj) = matrix_pre.row(index2save[jj]);
}
return matrix_after;
}
MatrixXd deleteMatrixColumns(MatrixXd matrix_pre, VectorXd ismemberFlag) {
vector index2save; // 需包含vector头文件
for (int ii = 0; ii < matrix_pre.cols(); ii++) {
// 此处 ==-1 还是 !=-1需要根据实际判定
if (ismemberFlag[ii] == -1) {
index2save.push_back(ii);
}
//if (ismemberFlag[ii] != -1) {
// index2save.push_back(ii);
//}
}
MatrixXd matrix_after(matrix_pre.rows(),index2save.size());
for (int jj = 0; jj < index2save.size(); jj++) {
matrix_after.col(jj) = matrix_pre.col(index2save[jj]);
}
return matrix_after;
}
void test() {
MatrixXd matrix_01(4, 4);
matrix_01 << 1, 2, 3, 4,
5, 6, 7, 8,
9, 10, 11, 12,
13, 14, 15, 16;
Vector4d vector_01;
vector_01<<-1,2, 4,-1;
MatrixXd matrix_02 = deleteMatrixRows(matrix_01,vector_01);
MatrixXd matrix_03 = deleteMatrixColumns(matrix_01, vector_01);
cout << "matrix_01的值为:" << endl << matrix_01 << endl;
cout << "matrix_02的值为:" << endl << matrix_02 << endl;
cout << "matrix_03的值为:" << endl << matrix_03 << endl;
}
void test() {
MatrixXd matrix_01(3, 4);
matrix_01 << 1, 2, 3, 4,
5, 6, 7, 8,
9, 10,11, 12;
// 加减,类型和维度都要对应,不具备广播特性
MatrixXd matrix_02 = matrix_01 + MatrixXd::Random(3, 4); //
MatrixXd matrix_03 = matrix_01 + 5 * MatrixXd::Ones(3, 4);
//MatrixXd matrix_02 = matrix_01 + MatrixXi::Random(3, 4); // 报错,int矩阵和double矩阵,类型不对应,
//MatrixXd matrix_03= matrix_01 + 5; // 报错,维度不对应,不具备广播特性
// 乘除常数
MatrixXd matrix_04 = matrix_01 * 2;
MatrixXd matrix_05 = MatrixXd::Ones(3, 4)/5;
// 矩阵乘法 大小m*n与大小n*s得到m*s的矩阵
MatrixXd matrix_06 = matrix_01 * MatrixXd::Ones(4, 2);
// 矩阵逐元素相乘,具体参见Array用法
//MatrixXd matrix_07 = matrix_01 * MatrixXd::Ones(3, 4);
// 矩阵除法A/B= A*inv(B)
MatrixXd matrix_temp = MatrixXd::Random(4, 4);
MatrixXd matrix_08 = matrix_01 * matrix_temp.inverse();
cout << "matrix_01的值为:" << endl << matrix_01 << endl;
cout << "matrix_02的值为:" << endl << matrix_02 << endl;
cout << "matrix_03的值为:" << endl << matrix_03 << endl;
cout << "matrix_04的值为:" << endl << matrix_04 << endl;
cout << "matrix_05的值为:" << endl << matrix_05 << endl;
cout << "matrix_06的值为:" << endl << matrix_06 << endl;
//cout << "matrix_07的值为:" << endl << matrix_07 << endl;
cout << "matrix_08的值为:" << endl << matrix_08 << endl;
}
void test() {
MatrixXi matrix_01(2, 3);
matrix_01 << 1.2, 2.1, 3.3,
4.2, 5.6, 6.7;
cout << "matrix_01的值为:" << endl << matrix_01 << endl;
}
void test09() {
MatrixXi matrix_01(2,3);
matrix_01 << 10, 12, 7, 14, 4, 3;
matrix_01 = matrix_01 / 5;
cout << "matrix_01的值为:" << endl << matrix_01 << endl;
//输出 2,2,1;2,0,0
}
// double矩阵无法转为int矩阵;int矩阵也无法转为double矩阵
void test() {
MatrixXd matrix_01(2, 3);
matrix_01 << 1.2, 2.1, 3.3,
4.2, 5.6, 6.7;
cout << "matrix_01的值为:" << endl << matrix_01 << endl;
MatrixXi matrix_02 = matrix_01 / 5;
}
void test() {
MatrixXi matrix_01(2, 2);
matrix_01 << 1, 2, 3, 4;
cout << matrix_01.inverse() << endl;
}
void test() {
Vector3d vector_01;
Vector3d vector_02;
vector_01 << 1, 2, 3;
vector_02 << 4, 5, 6;
//点积=标量积=数量积=内积(任意维度的向量都可以计算)
double var_01 = vector_01.dot(vector_02);
//向量积,(只能够对三维向量使用)
Vector3d vector_03=vector_01.cross(vector_02);
cout << "vector_01的值为:" << endl << vector_01 << endl;
cout << "vector_02的值为:" << endl << vector_02 << endl;
cout << "vector_03的值为:" << endl << vector_03 << endl;
cout << "var_01的值为:" << endl << var_01 << endl;
}
// 和、积、均值、最大值、最小值、行列式、逆矩阵
// 矩阵范数(向量模值)
void test() {
MatrixXd matrix_01(2, 2);
matrix_01 << 1, 2, 3, 4;
VectorXd vector_01(3);
vector_01 << 1, 2, 3;
double matrix_sum = matrix_01.sum();
double matrix_prod = matrix_01.prod();
double matrix_mean = matrix_01.mean();
double matrix_min = matrix_01.minCoeff();
double matrix_max = matrix_01.maxCoeff();
double matrix_trace = matrix_01.trace();
double matrix_det = matrix_01.determinant();
double matrix_norm = matrix_01.norm();
MatrixXd matrix_inv = matrix_01.inverse();
double vector_norm = vector_01.norm();
cout << "矩阵元素的和为: " << matrix_sum << endl;
cout << "矩阵元素的乘积为: " << matrix_prod<< endl;
cout << "矩阵元素的均值为: " << matrix_mean<< endl;
cout << "矩阵元素的最小值为: " << matrix_min << endl;
cout << "矩阵元素的最大值为:" << matrix_max << endl;
cout << "矩阵的迹为: " << endl << matrix_trace << endl;
cout << "矩阵的行列式为: " << endl << matrix_det << endl;
cout << "矩阵的2范数为: " << endl << matrix_norm << endl;
cout << "矩阵的逆矩阵为: " << endl << matrix_inv << endl;
cout << "向量的模值为: " << endl << matrix_norm << endl;
}
MatrixXd functionTest(MatrixXd matrix_01) {
MatrixXd matrix_temp(4, 4);
matrix_temp << 1, 2, 3, 4,
5, 6, 7, 8,
9, 10, 11, 12,
13, 14, 15, 16;
MatrixXd matrix_02 = matrix_01 + matrix_temp;
return matrix_02;
}
void test() {
MatrixXd matrix_01(4, 4);
matrix_01<< 1, 2, 3, 4,
5, 6, 7, 8,
9, 10, 11, 12,
13, 14, 15, 16;
MatrixXd matrix_02 = functionTest(matrix_01);
cout << "matrix_01的值为:" << endl << matrix_01 << endl;
cout << "matrix_02的值为:" << endl << matrix_02 << endl;
}
void test01() {
// 出错的函数
MatrixXd matrix_01(2, 3);
MatrixXi matrix_02 = matrix_01 * 2; // 类型不一致
}
void test02() {
//正常的函数
}
int main() {
test02(); //运行test02还是会报错
return 0;
}
复共轭、特征分解等
@TODO
// 返回一个向量,对两个向量进行求并集,并完成去重和排序
#include // 包含set容器
VectorXd fun_union(VectorXd v1, VectorXd v2)
{
Eigen::VectorXd v;
set set_union; //去重+排序
for (int i = 0; i < v1.size(); i++){
set_union.insert(v1[i]);
}
for (int i = 0; i < v2.size(); i++){
set_union.insert(v2[i]);
}
v.resize(set_union.size());
int i = 0;
for (set::iterator it = set_union.begin(); it != set_union.end(); it++, i++){
v[i] = *it;
}
return v;
}
void test() {
RowVector4d v1 = { 1,2,3,4 };
VectorXd v2(5);
v2 << 2, 3, 4, 5,9;
RowVectorXd v3 = fun_union(v1, v2); //可以行列类型转换
cout << v3 << endl;
}
// 返回一个向量,对两个向量进行求交集,并完成去重和排序
VectorXd util_fun_intersect(VectorXd v1, VectorXd v2)
{
VectorXd v;
set set_intersect;
for (int i = 0; i < v1.size(); i++) {
for (int j = 0; j < v2.size(); j++) {
if (v1[i] == v2[j]) {
set_intersect.insert(v1[i]);
break;
}
}
}
v.resize(set_intersect.size());
int i = 0;
for (set::iterator ite = set_intersect.begin(); ite != set_intersect.end(); ite++, i++)
{
v[i] = *ite;
}
return v;
}
int main() {
Vector4d v1 = { 1,2,3,2 } ;
Vector3d v2 = { 2,3,5 };
//VectorXd v2(0);
VectorXd v3= util_fun_intersect(v1, v2);
cout << v3 << endl;
}
//工具函数,求差集,返回v1中存在但v2中不存在的元素,并进行去重和排序
Eigen::VectorXd util_fun_setdiff(Eigen::VectorXd v1, Eigen::VectorXd v2)
{
Eigen::VectorXd v;
set set_setdiff;
for (int i = 0; i < v1.size(); i++) {
bool existFlag = true;
for (int j = 0; j < v2.size(); j++) {
if (v1[i] == v2[j]) {
existFlag = false;
break;
}
}
if (existFlag) {
set_setdiff.insert(v1[i]);
}
}
v.resize(set_setdiff.size());
int i = 0;
for (set::iterator ite = set_setdiff.begin(); ite != set_setdiff.end(); ite++, i++)
{
v[i] = *ite;
}
return v;
}
void test() {
Vector4d v1 = { 1,2,3,4 };
Vector3d v2 = { 7,2,4 };
VectorXd v3 = util_fun_setdiff(v1, v2);
cout << v3 << endl;
}
// 类似Matlab的find功能,
// 在向量中查找是否有某个元素,如果有返回索引(注意比位置小1)
VectorXd fun_find(VectorXd v1, double val) {
vector v_temp;
for (int ii = 0; ii < v1.size(); ii++){
if (v1(ii) == val) {
v_temp.push_back(ii);
}
}
VectorXd v2(v_temp.size());
for (int ii = 0; ii < v_temp.size(); ii++) {
v2(ii) = v_temp[ii];
}
return v2;
}
void test() {
VectorXd v1(6);
v1 << 1, 2, 3, 3, 4, 5;
VectorXd v2 = fun_find(v1, 3);
cout << v2 << endl;
}
// 类似Matlab的ismember功能,Pyhton的isin函数
// 此函数功能:
// 判断v1中的变量在v2中是否存在
// 返回一个大小同v1的向量,
// 如果不存在该变量,返回-1
// 如果存在,返回该变量在向量v2中的位置(如果有多个,返回最小索引)
VectorXd fun_ismember(VectorXd v1, VectorXd v2)
{
bool exist = false;
VectorXd v;
v.resize(v1.size());
for (int ii = 0; ii < v1.size(); ii++){
exist = false;
int jj; // 后边还要用 要定义在外部
for ( jj = 0; jj < v2.size(); jj++){
if (v1[ii] == v2[jj])
{
exist = true;
break;
}
}
if (exist){
v[ii] = jj;
}
else{
v[ii] = -1;
}
}
return v;
}
void test() {
RowVector4d v1 = { 1,2,3,4 };
VectorXd v2(5);
v2 << 2, 3, 4, 5,9;
RowVectorXd v3 = fun_ismember(v1, v2); //可以行列类型转换
cout << v3 << endl;
}
Array主要核心定义和语法与Matrix高度类似,主要对不同点进行介绍。
学习Array主要把握官方文档的“coeffience-wise”,Array是对逐系数(元素)进行操作的。
对数组内部每个元素进行的操作都可以用Array进行操作。
如果需要经常操作线性代数的操作,偶尔需要逐元素操作,可以用Matrix进行操作,在需要时进行转换即可。
template
class Array{}
void test() {
typedef Array Array23d; //自行定义
Array23d arr_01;
arr_01 << 1, 2, 3, 4,5,6;
cout << "arr_01的值为:" << endl << arr_01 << endl;
}
//向上向下四舍五入取整、绝对值、指数、三角函数等,具体参见参考资源[2]
void test() {
ArrayXXd arr_01(2, 2);
arr_01 << 1.1, 2.2, 3.5, 4.7;
Array22d arr_02 = round(arr_01);
Array22d arr_03=arr_01.round();
Array22d arr_04 = exp(arr_01);
Array22d arr_05 = arr_01.exp();
cout << "arr_01的值为:" << endl << arr_01 << endl;
cout << "arr_02的值为:" << endl << arr_02 << endl;
cout << "arr_03的值为:" << endl << arr_03 << endl;
cout << "arr_04的值为:" << endl << arr_04 << endl;
cout << "arr_05的值为:" << endl << arr_05 << endl;
}
void test() {
// 注意维度区别,第一种写法是一个2*1的列数组,后两个是2*2的矩阵
Array2d arr_01; //typedef Eigen::Array Eigen::Array2d
Array22d arr_01; //typedef Eigen::Array Eigen::Array22d
Matrix2d matrix_01; // typedef Eigen::Matrix Eigen::Matrix2d
}
//体会和Matrix的不同
void test() {
ArrayXXd arr_01(2, 2);
Array22d arr_02;
arr_01 << 1, 2, 3, 4;
arr_02 << 5, 6, 7, 8;
// 加减
Array22d arr_03=arr_01+2;
// 乘除
Array22d arr_04 = arr_01 * arr_02;
cout << "arr_01的值为:" << endl << arr_01 << endl;
cout << "arr_02的值为:" << endl << arr_02 << endl;
cout << "arr_03的值为:" << endl << arr_03 << endl;
cout << "arr_04的值为:" << endl << arr_04 << endl
}
void test() {
ArrayXXd arr_01(2,3);
ArrayXXd arr_02(2, 3);
MatrixXd matrix_01(2,3);
arr_01 << 1, 2, 3, 4, 5, 6;
matrix_01 = arr_01.matrix();
arr_02 = matrix_01.array();
cout << "arr_01的值为:" << endl << arr_01 << endl;
cout << "arr_02的值为:" << endl << arr_02 << endl;
cout << "matrix_01的值为:" << endl << matrix_01 << endl;
}
// 有待研究 @TODO
// 参见参考链接[2]
void test() {
double matrix_01[2][3] = { 1,2,3,4,5,6 };
MatrixXd matrix_02(2, 3);
// matrix_02 = matrix_01; // 会报错
// 打印
cout << "matrix_01的值为:" << endl << matrix_01 << endl;
cout << "matrix_02的值为:" << endl << matrix_02 << endl;
}
参考链接
文档1
https://blog.csdn.net/juluwangriyue/article/details/122162035?spm=1001.2101.3001.6661.1&utm_medium=distribute.pc_relevant_t0.none-task-blog-2%7Edefault%7EOPENSEARCH%7ERate-1-122162035-blog-126857577.pc_relevant_multi_platform_whitelistv3&depth_1-utm_source=distribute.pc_relevant_t0.none-task-blog-2%7Edefault%7EOPENSEARCH%7ERate-1-122162035-blog-126857577.pc_relevant_multi_platform_whitelistv3&utm_relevant_index=1
文档2
https://blog.csdn.net/geerniya/article/details/103202562?spm=1001.2101.3001.6661.1&utm_medium=distribute.pc_relevant_t0.none-task-blog-2%7Edefault%7ECTRLIST%7ERate-1-103202562-blog-122162035.topnsimilarv1&depth_1-utm_source=distribute.pc_relevant_t0.none-task-blog-2%7Edefault%7ECTRLIST%7ERate-1-103202562-blog-122162035.topnsimilarv1&utm_relevant_index=1
@TODO
[1] CSDN笔记 安装
https://blog.csdn.net/weixin_47442149/article/details/126031623?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522166124765716781667857113%2522%252C%2522scm%2522%253A%252220140713.130102334.pc%255Fall.%2522%257D&request_id=166124765716781667857113&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2allfirst_rank_ecpm_v1~pc_rank_34-5-126031623-null-null.142v42pc_rank_34,185v2control&utm_term=eigen%E5%BA%93%E9%85%8D%E7%BD%AE&spm=1018.2226.3001.4187
[2] CSDN笔记
https://blog.csdn.net/s12k39/article/details/108381018?spm=1001.2101.3001.6650.2&utm_medium=distribute.pc_relevant.none-task-blog-2%7Edefault%7ECTRLIST%7ERate-2-108381018-blog-122906472.pc_relevant_multi_platform_whitelistv3&depth_1-utm_source=distribute.pc_relevant.none-task-blog-2%7Edefault%7ECTRLIST%7ERate-2-108381018-blog-122906472.pc_relevant_multi_platform_whitelistv3&utm_relevant_index=5
[3] 参考笔记
https://blog.csdn.net/naibula/article/details/122906472?spm=1001.2101.3001.6650.8&utm_medium=distribute.pc_relevant.none-task-blog-2%7Edefault%7EBlogCommendFromBaidu%7ERate-8-122906472-blog-121171378.t5_layer_eslanding_S_0&depth_1-utm_source=distribute.pc_relevant.none-task-blog-2%7Edefault%7EBlogCommendFromBaidu%7ERate-8-122906472-blog-121171378.t5_layer_eslanding_S_0&utm_relevant_index=15