文章目录
- 基础
- hello,world
- getline
- std::cin
- 引用与指针
- 函数
- 数据类型
- 基本数据类型
- 更多类型
- sizeof
- 正则表达式
- 单次匹配
- 多次匹配
- 组匹配
- 字符串的匹配
- split
- map
- 基础
- 实战
- 整型变量符号表
- 简单分析生成整型变量表
- 正则表达式
- 基础
- regex_match
- regex_replace
- swap
- Eigen
- 概述
- 简单例子
- Matrix
- 基础
- 例
- 编译时固定尺寸
- 运行指定大小
- 矩阵元素定义
- 矩阵加法
- 矩阵乘法
- 向量
- 编译时设置大小
- 矩阵初始化
- 多维矩阵
- 矩阵和向量size
- 固定大小or 动态大小
- Matrix类六个模板参数
- 初始化向量
- 元素类型
- 参考文献
基础
hello,world
#include <iostream>
using namespace std;
int main()
{
cout << "Hello world!" << endl;
return 0;
}
getline
成员函数getline()是从输入流中读取一行字符,读到终止符时会将’\0’存入结果缓冲区中 [4],作为输入的终止。终止符可以是默认的终止符,也可以是定义的终止符。函数的语法结构是:
getline(<字符数组chs>,<读取字符的个数n>,<终止符>)
#include <iostream>
using namespace std;
int main()
{
string name;
string welcomeMessage;
cout << "Hello world!" << endl;
cin>>name;
cout << "Hi!" <<name<< endl;
getline(cin,welcomeMessage,'#');
cout<<welcomeMessage<<endl;
return 0;
}
Hello world!
lisi
Hi!lisi
you are good student!
#
you are good student!
Process returned 0 (0x0) execution time : 11.410 s
Press any key to continue.
std::cin
可同时接收多个数据输入,每个数据用空格分隔!
Hello world!
name age
lisi 29
Hi!lisi 29
Process returned 0 (0x0) execution time : 3.817 s
Press any key to continue.
#include <iostream>
using namespace std;
int main()
{
string name;
int age;
int temp;
string welcomeMessage;
cout << "Hello world!" << endl;
cout<<"name age"<<endl;
cin>>name>>age;
cout << "Hi!" <<name<<" "<<age<<endl;
return 0;
}
引用与指针
- 标量
100
100
88
99
Process returned 0 (0x0) execution time : 1.819 s
Press any key to continue.
#include <iostream>
using namespace std;
int main()
{
int a;
int &a1=a;
int *a2=&a;
cin>>a;
cout<<a<<endl;
a1=88;
cout<<a<<endl;
*a2=99;
cout<<a<<endl;
return 0;
}
- 数组指针
#include <iostream>
using namespace std;
int main()
{
int a[]{1,2,3,4,5,6,7,8};
int *s=a;
for (int *p=a;p<s+8;p++){
cout<<p<<":"<<*p<<endl;
}
}
#include <iostream>
using namespace std;
int main()
{
int a[]{1,2,3,4,5,6,7,8};
for (int *p=a;p<a+8;p++){
cout<<p<<":"<<*p<<endl;
}
}
1
2
3
4
5
6
7
8
Process returned 0 (0x0) execution time : 0.126 s
Press any key to continue.
- 数组的引用
下面的程序是错误的
#include <iostream>
using namespace std;
int main()
{
int a[]{1,2,3,4,5,6,7,8};
for (int (&p)[8]=a;p<a+7;p++){
cout<<*p<<endl;
}
}
错误如下
正确的写法只能如下:
#include <iostream>
using namespace std;
int main()
{
int a[]{1,2,3,4,5,6,7,8};
int (&p)[8]=a;
for (int i=0;i<8;i++){
cout<<p[i]<<endl;
}
}
如果一定要用指针,只能考虑另外使用一个指针变量了,因为引用指向的内容可以更改,但引用本身的指向是不能更改,只读的。
#include <iostream>
using namespace std;
int main()
{
int a[]{1,2,3,4,5,6,7,8};
int (&p)[8]=a;
for (int *p1=p;p1<a+8;p1++){
cout<<*p1<<endl;
}
}
函数
#include <iostream>
using namespace std;
void goThrough(int (&arr)[8]){
for (int *p1=arr;p1<arr+8;p1++){
cout<<*p1<<endl;
}
}
int main()
{
int a[]{1,2,3,4,5,6,7,8};
goThrough(a);
}
更改数组元素
#include <iostream>
using namespace std;
void goThrough(int (&arr)[8]){
for (int *p1=arr;p1<arr+8;p1++){
cout<<*p1<<endl;
}
for (int *p1=arr;p1<arr+8;p1++){
*p1*=10;
}
for (int *p1=arr;p1<arr+8;p1++){
cout<<*p1<<endl;
}
}
int main()
{
int a[]{1,2,3,4,5,6,7,8};
goThrough(a);
}
1
2
3
4
5
6
7
8
10
20
30
40
50
60
70
80
Process returned 0 (0x0) execution time : 0.130 s
Press any key to continue.
数据类型
基本数据类型
在C++中,基本数据类型包括整数类型、浮点类型和字符类型。整数类型包括short、int、long和char,浮点类型包括float和double。
以下是各种基本数据类型的大小和范围:
整数类型:
short:2字节
int:通常是4字节
long:在64位系统上是8字节,32位系统是4字节
char:通常是1字节,可能是有符号的,也可能是无符号的
浮点类型:
float:4字节
double:8字节
字符类型:
char:通常是1字节,可以是有符号的也可以是无符号的
short shortVar = 123;
int intVar = 12345678;
long longVar = 123456789012345;
float floatVar = 1.23f;
double doubleVar = 1.23456789;
char charVar = 'A';
以上内容引用自AI生成内容:AI自动生成内容
更多类型
1、bool型(布尔型):true或false
bool isOk=true;
bool isBlue=false;
2、string
C++string 是C++中的字符串。 字符串对象是一种特殊类型的容器,专门设计来操作的字符序列。 不像传统的c-strings,只是在数组中的一个字符序列,我们称之为字符数组,而C + +字符串对象属于一个类,这个类有很多内置的特点,在操作方式,更直观,另外还有很多有用的成员函数。
string 的定义为:typedef basic_string string;
更多内容请见string,百度百科
sizeof
在 C++ 语言中,sizeof() 是一个判断数据类型或者表达式长度的运算符。
cout<<sizeof(int)<<endl;
正则表达式
smatch 对应于 string,wsmatch 对应于 wstring,cmatch 对应于 char 或 wcmatch 对应于 wchar_t*。*
单次匹配
#include <iostream>
#include <regex>
#include <string>
int main() {
using namespace std;
const char *str = "abce12389iiu4645ppp";
const char *first=str;
const char *last=str+strlen(str);
regex strRx(R"(\d+)");
cmatch match;
bool found = regex_search(first, last, match, strRx);
if (found)
cout <<"find the number:"<<match.str() << endl;
return 0;
}
find the number:12389
Process returned 0 (0x0) execution time : 0.045 s
Press any key to continue.
多次匹配
#include <iostream>
#include <regex>
#include <string>
using namespace std;
int main() {
const char *str = "abce12389iiu4645ppp";
const char *first=str;
const char *last=str+strlen(str);
typedef regex_iterator<const char *> StrIter;
StrIter::regex_type strRx(R"(\d+)");
StrIter next(first, last, strRx);
StrIter end;
for (; next != end; ++next)
std::cout << "find number: " << next->str() << std::endl;
}
find number: 12389
find number: 4645
Process returned 0 (0x0) execution time : 0.293 s
Press any key to continue.
组匹配
find the str:12389iiu4645
find the str:12389
find the str:iiu
find the str:4645
Process returned 0 (0x0) execution time : 0.287 s
Press any key to continue.
#include <iostream>
#include <regex>
#include <string>
int main() {
using namespace std;
const char *str = "abce12389iiu4645ppp";
const char *first=str;
const char *last=str+strlen(str);
regex strRx(R"((\d+)(\D+)(\d+))");
cmatch matchs;
bool found = regex_search(first, last, matchs, strRx);
if (found){
cout <<"find the str:"<<matchs[0].str() << endl;
cout <<"find the str:"<<matchs[1].str() << endl;
cout <<"find the str:"<<matchs[2].str() << endl;
cout <<"find the str:"<<matchs[3].str() << endl;
}
return 0;
}
字符串的匹配
使用smatch
smatch 对应于 string,wsmatch 对应于 wstring,cmatch 对应于 char 或 wcmatch 对应于 wchar_t*。*
#include <iostream>
#include <regex>
#include <string>
int main() {
using namespace std;
string str = "abce12389iiu4645ppp";
regex strRx(R"((\d+)(\D+)(\d+))");
smatch matchs;
bool found = regex_search(str, matchs, strRx);
if (found){
cout <<"find the str:"<<matchs[0].str() << endl;
cout <<"find the str:"<<matchs[1].str() << endl;
cout <<"find the str:"<<matchs[2].str() << endl;
cout <<"find the str:"<<matchs[3].str() << endl;
}
return 0;
}
split
c+中没有split,于是需要自己实现这个函数。
#include <iostream>
#include <vector>
#include <string>
#include <sstream>
using namespace std;
vector<string> split(const string &text, char separator) {
vector<string> tokens;
stringstream ss(text);
string item;
while (getline(ss, item, separator)) {
if (!item.empty()) {
tokens.push_back(item);
}
}
return tokens;
}
int main() {
string codeStr = "x:long=88;y:float=11.22;z:int=99";
char delimiter = ';';
vector<string> codeTokens=split(codeStr,delimiter);
for (const std::string &codeLineToken : codeTokens) {
cout << codeLineToken << endl;
}
return 0;
}
x:long=88
y:float=11.22
z:int=99
Process returned 0 (0x0) execution time : 0.041 s
Press any key to continue.
- getline会生成一个包含一串从输入流读入的字符的字符串,直到以下情况发生会导致生成的此字符串结束:1)到文件结束,2)遇到函数的定界符,3)输入达到最大限度。
- 在函数遇到和结束定界符相等的字符时函数结束,同时函数抽出定界符,此种情况下该定界符既不被放回输入流,也不被放入要生成的字符串。所以由此可以理解输入结束后的第一个回车是定界符,被确认后抛弃,而第二个才是程序执行运行时正常需要的。
- 更多 见百度百科
map
用于存储和检索集合中的数据,此集合中的每个元素均为包含数据值和排序键的元素对。 键的值是唯一的,用于自动排序数据。
更多见百度百科
基础
在C++中,map是一个关联容器,用于存储键值对,并且通过键来对数据进行排序。
下面引用自百度百科的自动生成内容:
下面是一个简单的使用map的例子:
#include <map> #include <iostream> int main() { std::map<int, std::string> exampleMap; // 插入元素 exampleMap[1] = "one"; exampleMap[2] = "two"; exampleMap[3] = "three"; // 访问元素 std::cout << "Key 2 corresponds to Value " << exampleMap[2] << std::endl; // 遍历元素 for (const auto& pair : exampleMap) { std::cout << "Key: " << pair.first << " Value: " << pair.second << std::endl; } return 0; } ```这段代码展示了如何创建一个map,如何插入元素,如何通过键访问元素,以及如何遍历map中的所有键值对。
实战
整型变量符号表
//value_type
//存储为 map 中的元素的对象的类型。
typedef pair<const Key, Type> value_type;
#include <iostream>
#include <string>
#include <map>
using namespace std;
typedef map<string, int> TableIntMap;
int main()
{
TableIntMap intSymbols;
intSymbols.insert(TableIntMap::value_type("a1", 1));
intSymbols.insert(TableIntMap::value_type("a2", 2));
intSymbols.insert(TableIntMap::value_type("a3", 3));
// find and show elements
cout << "intSymbols.at('a1') == " << intSymbols.at("a1") << endl;
cout << "intSymbols.at('a2') == " << intSymbols.at("a2") << endl;
cout << "intSymbols.at('a3') == " << intSymbols.at("a3") << endl;
return (0);
}
intSymbols.at('a1') == 1
intSymbols.at('a2') == 2
intSymbols.at('a3') == 3
Process returned 0 (0x0) execution time : 0.132 s
Press any key to continue.
简单分析生成整型变量表
#include <iostream>
#include <map>
#include <vector>
#include <string>
#include <sstream>
#include <algorithm>
using namespace std;
typedef map<string, int> TableIntMap;
vector<string> split(const string &text, char separator) {
vector<string> tokens;
stringstream ss(text);
string item;
while (getline(ss, item, separator)) {
if (!item.empty()) {
tokens.push_back(item);
}
}
return tokens;
}
string removeSpaces(const string& input) {
string result = input;
result.erase(std::remove(result.begin(), result.end(), ' '), result.end());
return result;
}
int main(){
string codeStr = "x:int=88;y:int=11;z:int=99";
char delimiter = ';';
vector<string> codeTokens=split(codeStr,delimiter);
TableIntMap intSymbols;
vector<string> symbolTokens,sysmbolVarTokens;
for (const std::string &codeLineToken : codeTokens) {
delimiter = '=';
symbolTokens=split(codeLineToken,delimiter);
delimiter = ':';
sysmbolVarTokens=split(symbolTokens[0],delimiter);
if (removeSpaces(sysmbolVarTokens[1])=="int"){
string intSysbol=removeSpaces(sysmbolVarTokens[0]);
int intValue=stoi(removeSpaces(symbolTokens[1]));
intSymbols.insert(TableIntMap::value_type(intSysbol, intValue));
}
}
cout<<"int "<<endl;
for (const auto& elem : intSymbols) {
cout << " [" << elem.first << ": " << elem.second << "]"<<endl;
}
return (0);
}
int
[x: 88]
[y: 11]
[z: 99]
Process returned 0 (0x0) execution time : 0.037 s
Press any key to continue.
正则表达式
基础
- 正则表达式,又称规则表达式,(Regular Expression,在代码中常简写为regex、regexp或RE),是一种文本模式,包括普通字符(例如,a 到 z 之间的字母)和特殊字符(称为"元字符"),是计算机科学的一个概念。正则表达式使用单个字符串来描述、匹配一系列匹配某个句法规则的字符串,通常被用来检索、替换那些符合某个模式(规则)的文本。
- 更多请见百度百科
regex_match
测试正则表达式是否与整个目标字符串相匹配。这是一种完全匹配,不是部分匹配
#include <iostream>
#include <map>
#include <vector>
#include <string>
#include <sstream>
#include <algorithm>
#include <regex>
using namespace std;
vector<string> split(const string &text, char separator) {
vector<string> tokens;
stringstream ss(text);
string item;
while (getline(ss, item, separator)) {
if (!item.empty()) {
tokens.push_back(item);
}
}
return tokens;
}
string removeSpaces(const string& input) {
string result = input;
result.erase(std::remove(result.begin(), result.end(), ' '), result.end());
return result;
}
int main(){
string codeStr = "x:int=88.11;y:int=11;z:int=99";
char delimiter = ';';
vector<string> codeTokens=split(codeStr,delimiter);
vector<string> symbolTokens,sysmbolVarTokens;
regex strRx(R"((\d+)(\.)(\d+))");
smatch match;
for (const std::string &codeLineToken : codeTokens) {
delimiter = '=';
symbolTokens=split(codeLineToken,delimiter);
delimiter = ':';
sysmbolVarTokens=split(symbolTokens[0],delimiter);
if (removeSpaces(sysmbolVarTokens[1])=="int"){
string intSysbol=removeSpaces(sysmbolVarTokens[0]);
string value=removeSpaces(symbolTokens[1]);
bool found = regex_match(value, match, strRx);
if (found)
cout <<"非法赋值" <<intSysbol<<":"<<value<< endl;
else{
cout << "合法赋值" <<intSysbol<<":"<<value<< endl;
}
}
}
return (0);
}
非法赋值x:88.11
合法赋值y:11
合法赋值z:99
Process returned 0 (0x0) execution time : 0.214 s
Press any key to continue.
regex_replace
替换匹配正则表达式。
所有大写字母全部用“.”替换。
#include <iostream>
#include <string>
#include <regex>
using namespace std;
int main(){
string str = "aBjDEIFoo998089";
regex strRx(R"([A-Z])");
string fmt(".");
smatch match;
std::cout << "replacement == "
<< std::regex_replace(str, strRx, fmt) << std::endl;
return (0);
}
replacement == a.j....oo998089
Process returned 0 (0x0) execution time : 0.220 s
Press any key to continue.
swap
交换两个 basic_regex 或 match_results 对象。
#include <iostream>
#include <string>
#include <regex>
using namespace std;
int main(){
string str = "a99jDEIFoo998089";
regex strRx1(R"([A-Z]+)");
regex strRx2;
smatch match1;
smatch match2;
swap(strRx1, strRx2);
bool found =regex_search(str, match2, strRx2);
if (found)
cout<<match2.str()<<endl;
return (0);
}
#include <iostream>
#include <string>
#include <regex>
using namespace std;
int main(){
string str = "a99jDEIFoo998089";
regex strRx1(R"([A-Z]+)");
regex strRx2;
smatch match1;
smatch match2;
swap(strRx1, strRx2);
bool found =regex_search(str, match2, strRx2);
swap(match1, match2);
if (found)
cout<<match1.str()<<endl;
return (0);
}
DEIF
Process returned 0 (0x0) execution time : 0.197 s
Press any key to continue.
Eigen
概述
- Eigen是一个用于线性代数的c++模板库:矩阵、向量、数值求解器和相关算法。
- 除了c++标准库之外,Eigen没有任何依赖关系。
- 具体见Eigen
简单例子
#include <iostream>
#include "f:/learn/eigen-3.4.0/Eigen/Dense"
using Eigen::MatrixXd;
using Eigen::VectorXd;
int main()
{
MatrixXd m = MatrixXd::Random(3,3);
m = (m + MatrixXd::Constant(3,3,1.2)) * 50;
std::cout << "m =" << std::endl << m << std::endl;
VectorXd v(3);
v << 1, 2, 3;
std::cout << "m * v =" << std::endl << m * v << std::endl;
}
m =
10.1251 90.8741 45.0291
66.3585 68.5009 99.5962
29.3304 57.9873 92.284
m * v =
326.961
502.149
422.157
Process returned 0 (0x0) execution time : 0.168 s
Press any key to continue.
Matrix
基础
- 所有矩阵和向量都是Matrix模板类的对象。
- 向量也是矩阵,单行或单列。
- Matrix模板类6个参数,常用就3个参数,其它3个参数有默认值。
Matrix<typename Scalar, int RowsAtCompileTime, int ColsAtCompileTime>
分别是元素标量类型,编译时行数和列数
-下面定义float类型元素,4*5的矩阵
typedef Matrix<float, 4, 4> Matrix4f;
- 4*1列 向量
typedef Matrix<float, 4, 1> Vector3f;
- 1*2行向量
typedef Matrix<int, 1, 2> RowVector2i;
- 运行时再指定维度
typedef Matrix<double, Dynamic, Dynamic> MatrixXd;
typedef Matrix<int, Dynamic, 1> VectorXi;
//只指定行
Matrix<float, 3, Dynamic>
MatrixXf a(10,15);
VectorXf b(30);
- 初始化元素
Vector2i a(1, 2);
Matrix<int, 5, 1> b {1, 2, 3, 4, 5};
Matrix<int, 1, 5> c = {1, 2, 3, 4, 5};
例
编译时固定尺寸
- Matrix4f
#include <iostream>
#include "f:/learn/eigen-3.4.0/Eigen/Dense"
using Eigen::Matrix4f;
int main()
{
Matrix4f m = Matrix4f::Random();
std::cout << m << std::endl;
}
-0.997497 0.170019 0.64568 0.421003
0.127171 -0.0402539 0.49321 0.0270699
-0.613392 -0.299417 -0.651784 -0.39201
0.617481 0.791925 0.717887 -0.970031
Process returned 0 (0x0) execution time : 0.099 s
Press any key to continue.
- Vector3f
#include <iostream>
#include "f:/learn/eigen-3.4.0/Eigen/Dense"
using Eigen::Vector3f;
int main()
{
Vector3f m = Vector3f::Random();
std::cout << m << std::endl;
}
-0.997497
0.127171
-0.613392
Process returned 0 (0x0) execution time : 0.103 s
Press any key to continue.
- RowVector2i
#include <iostream>
#include "f:/learn/eigen-3.4.0/Eigen/Dense"
using Eigen::RowVector2i;
int main()
{
RowVector2i m = RowVector2i::Random();
std::cout << m << std::endl;
}
-16343 2083
Process returned 0 (0x0) execution time : 0.091 s
Press any key to continue.
- 指定大小
6*6的矩阵
#include <iostream>
#include "f:/learn/eigen-3.4.0/Eigen/Dense"
using Eigen::Matrix;
typedef Matrix<int,6,6> Matrix6i;
int main()
{
Matrix6i m = Matrix6i::Random();
std::cout << m << std::endl;
}
-16343 -4906 6897 -11557 -16092 -10937
2083 12974 443 -10948 -4002 5342
-10050 10578 -6423 16007 1037 -1613
10116 8080 -15893 -1780 2332 -4846
2785 -10679 -13389 -12482 3334 -14515
-660 11761 -4442 -16231 3511 3528
Process returned 0 (0x0) execution time : 0.101 s
Press any key to continue.
运行指定大小
- double型元素
#include <iostream>
#include "f:/learn/eigen-3.4.0/Eigen/Dense"
using Eigen::MatrixXf;
int main()
{
MatrixXf m = MatrixXf::Random(3,3);
std::cout << m << std::endl;
}
-0.997497 0.617481 -0.299417
0.127171 0.170019 0.791925
-0.613392 -0.0402539 0.64568
Process returned 0 (0x0) execution time : 0.099 s
Press any key to continue.
- int型元素
#include <iostream>
#include "f:/learn/eigen-3.4.0/Eigen/Dense"
using Eigen::MatrixXi;
int main()
{
MatrixXi m = MatrixXi::Random(3,3);
std::cout << m << std::endl;
}
-16343 10116 -4906
2083 2785 12974
-10050 -660 10578
Process returned 0 (0x0) execution time : 0.098 s
Press any key to continue.
- 指定元素值
#include <iostream>
#include "f:/learn/eigen-3.4.0/Eigen/Dense"
using Eigen::Vector2i;
using Eigen::Matrix;
int main()
{
Vector2i a(1, 2);
Matrix<int, 5, 1> b {1, 2, 3, 4, 5};
Matrix<int, 1, 5> c = {1, 2, 3, 4, 5};
std::cout << a<< std::endl;
std::cout << b<< std::endl;
std::cout << c<< std::endl;
}
1
2
1
2
3
4
5
1 2 3 4 5
Process returned 0 (0x0) execution time : 0.094 s
Press any key to continue.
矩阵元素定义
- 定义每个元素值
[ 1 3 2 4 ] \begin{bmatrix} 1& 3 \\2& 4 \end{bmatrix} [1234]
#include <iostream>
#include "f:/learn/eigen-3.4.0/Eigen/Dense"
using Eigen::MatrixXd;
int main()
{
MatrixXd m(2,2);
m(0,0) = 1;
m(1,0) = 2;
m(0,1) = 3;
m(1,1) = 4;
std::cout << m << std::endl;
}
1 3
2 4
Process returned 0 (0x0) execution time : 0.151 s
Press any key to continue.
- 随机矩阵
#include <iostream>
#include "f:/learn/eigen-3.4.0/Eigen/Dense"
using Eigen::MatrixXd;
int main()
{
MatrixXd m = MatrixXd::Random(2,2);
std::cout << m << std::endl;
}
-0.997497 -0.613392
0.127171 0.617481
Process returned 0 (0x0) execution time : 0.110 s
Press any key to continue.
矩阵加法
MatrixXd::Constant(4,4,10)
是一个4*4的矩阵(方阵),每个元素都是10.
#include <iostream>
#include "f:/learn/eigen-3.4.0/Eigen/Dense"
using Eigen::MatrixXd;
int main()
{
MatrixXd m = MatrixXd::Random(4,4);
std::cout << m << std::endl;
m = (m + MatrixXd::Constant(4,4,10));
std::cout << m << std::endl;
}
-0.997497 0.170019 0.64568 0.421003
0.127171 -0.0402539 0.49321 0.0270699
-0.613392 -0.299417 -0.651784 -0.39201
0.617481 0.791925 0.717887 -0.970031
9.0025 10.17 10.6457 10.421
10.1272 9.95975 10.4932 10.0271
9.38661 9.70058 9.34822 9.60799
10.6175 10.7919 10.7179 9.02997
Process returned 0 (0x0) execution time : 0.042 s
Press any key to continue.
#include <iostream>
#include "f:/learn/eigen-3.4.0/Eigen/Dense"
using Eigen::MatrixXd;
int main()
{
MatrixXd m = MatrixXd::Random(4,2);
std::cout << m << std::endl;
m = m + MatrixXd::Constant(4,2,10);
std::cout << m << std::endl;
}
-0.997497 0.170019
0.127171 -0.0402539
-0.613392 -0.299417
0.617481 0.791925
9.0025 10.17
10.1272 9.95975
9.38661 9.70058
10.6175 10.7919
Process returned 0 (0x0) execution time : 0.114 s
Press any key to continue.
矩阵乘法
MatrixXd::Constant(2,4,10)
是一个2*4的矩阵(方阵),每个元素都是10.
#include <iostream>
#include "f:/learn/eigen-3.4.0/Eigen/Dense"
using Eigen::MatrixXd;
int main()
{
MatrixXd m = MatrixXd::Random(4,2);
std::cout << m << std::endl;
m = m * MatrixXd::Constant(2,4,10);
std::cout << m << std::endl;
}
-0.997497 0.170019
0.127171 -0.0402539
-0.613392 -0.299417
0.617481 0.791925
-8.27479 -8.27479 -8.27479 -8.27479
0.869167 0.869167 0.869167 0.869167
-9.12809 -9.12809 -9.12809 -9.12809
14.0941 14.0941 14.0941 14.0941
Process returned 0 (0x0) execution time : 0.291 s
Press any key to continue.
向量
- VectorXd
#include <iostream>
#include "f:/learn/eigen-3.4.0/Eigen/Dense"
using Eigen::MatrixXd;
using Eigen::VectorXd;
using namespace std;
int main()
{
MatrixXd m = MatrixXd::Random(3,3);
VectorXd v(3);
v << 10, 20, 30;
cout << "v =" << endl << v << endl;
cout << "m * v =" << endl << m * v << endl;
}
v =
10
20
30
m * v =
-6.60787
28.4298
12.4314
Process returned 0 (0x0) execution time : 0.167 s
Press any key to continue.
- MatrixXd
可使用矩阵函数定义向量
#include <iostream>
#include "f:/learn/eigen-3.4.0/Eigen/Dense"
using Eigen::MatrixXd;
using Eigen::VectorXd;
using namespace std;
int main()
{
MatrixXd m = MatrixXd::Random(3,3);
MatrixXd v(3,1);
v(0,0) = 10;
v(1,0) = 20;
v(2,0) = 30;
cout << "v =" << endl << v << endl;
cout << "m * v =" << endl << m * v << endl;
}
编译时设置大小
本节前面的例子都是在运行时动态设置矩阵size,下面的例子是在编译时设置
#include <iostream>
#include <Eigen/Dense>
using Eigen::Matrix3d;
using Eigen::Vector3d;
int main()
{
Matrix3d m = Matrix3d::Random();
m = (m + Matrix3d::Constant(1.2)) * 50;
std::cout << "m =" << std::endl << m << std::endl;
Vector3d v(1,2,3);
std::cout << "m * v =" << std::endl << m * v << std::endl;
}
矩阵初始化
多维矩阵
- 数组
MatrixXi a { // construct a 2x2 matrix
{1, 2}, // first row
{3, 4} // second row
};
Matrix<double, 2, 3> b {
{2, 3, 4},
{5, 6, 7},
};
#include <iostream>
#include "f:/learn/eigen-3.4.0/Eigen/Dense"
using Eigen::Matrix;
int main()
{
Matrix<int,3,2> a {{1, 2}, {3, 4}, {5, 6}};
std::cout << a<< std::endl;
}
1 2
3 4
5 6
Process returned 0 (0x0) execution time : 0.117 s
Press any key to continue.
- 重定向操作符
Matrix3f m;
m << 1, 2, 3,
4, 5, 6,
7, 8, 9;
std::cout << m;
1 2 3
4 5 6
7 8 9
矩阵和向量size
- rows:矩阵行
- cols:矩阵列
- resize:重新规划size
#include <iostream>
#include "e:/eigen/Eigen/Dense"
using namespace std;
using namespace Eigen;
int main()
{
MatrixXf m(2,5);
cout << "The matrix m is of size "
<< m.rows() << "x" << m.cols() << std::endl;
m.resize(4,3);
cout << "The matrix m resized is of size "
<< m.rows() << "x" << m.cols() << std::endl;
cout << "It has " << m.size() << " coefficients" << std::endl;
VectorXf v(2);
cout << "The vector v is of size " << v.size() << std::endl;
v.resize(5);
cout << "The vector v resized is of size " << v.size() << std::endl;
cout << "As a matrix, v is of size "
<< v.rows() << "x" << v.cols() << std::endl;
}
The matrix m is of size 2x5
The matrix m resized is of size 4x3
It has 12 coefficients
The vector v is of size 2
The vector v resized is of size 5
As a matrix, v is of size 5x1
Process returned 0 (0x0) execution time : 0.317 s
Press any key to continue.
固定大小or 动态大小
什么时候应该使用固定大小(例如Matrix4f),什么时候应该使用动态大小(例如MatrixXf)?
- 简单的答案是:对于非常小的尺寸尽可能使用固定大小,对于较大的尺寸或必须使用动态大小。对于较小的大小,特别是小于(大约)16的大小,使用固定大小对性能非常有益,因为它允许Eigen避免动态内存分配并展开循环。
- 当然,使用固定大小的限制是,只有在编译时知道大小时才有可能。此外,对于足够大的大小,例如大于(大约)32的大小,使用固定大小的性能优势变得可以忽略不计。
- 更糟糕的是,尝试在函数内部使用固定大小创建一个非常大的矩阵可能会导致堆栈溢出,因为Eigen会尝试将数组自动分配为局部变量,而这通常是在堆栈上完成的。
Matrix类六个模板参数
- 模板参数
Matrix<typename Scalar,
int RowsAtCompileTime,
int ColsAtCompileTime,
int Options = 0,
int MaxRowsAtCompileTime = RowsAtCompileTime,
int MaxColsAtCompileTime = ColsAtCompileTime>
- Options是位字段。
RowMajor。它指定这种类型的矩阵使用行为主存储顺序;默认情况下,存储顺序是以列为主的。请参阅存储订单页面。例如,此类型表示行为主的3x3矩阵:
Matrix<float, 3, 3, RowMajor>
- MaxRowsAtCompileTime和MaxColsAtCompileTime
在需要指定时非常有用,即使在编译时不知道矩阵的确切大小,但在编译时知道一个固定的上限。这样做的最大原因可能是为了避免动态内存分配。例如,下面的矩阵类型使用12个浮点数的普通数组,没有动态内存分配
Matrix<float, Dynamic, Dynamic, 0, 3, 4>
- 存储顺序详解
矩阵和二维数组有两种不同的存储顺序:列为主和行为主
当矩阵存储在内存中时,条目必须以某种方式线性排列。有两种主要的方法可以做到这一点,按行和按列。
- 如果一个矩阵是逐行存储的,我们就说它是按行主序存储 row-major的。首先存储整个第一行,然后是整个第二行,依此类推。以矩阵为例
8 2 2 9 9 1 4 4 3 5 4 5
- 如果一个矩阵是按列存储 column-major 的,那么它是以列为主顺序存储的,从整个第一列开始,然后是整个第二列,依此类推。若将上述矩阵按列主序存储,则其布局如下:
8 9 3 2 1 5 2 4 4 9 4 5
3、例
定义一个4*3的矩阵A,然后分别以按行或按列存储。
使用PlainObjectBase::data()函数,该函数返回指向矩阵第一个条目的内存位置的指针。
#include <iostream>
#include "e:/eigen/Eigen/Dense"
using namespace std;
using namespace Eigen;
int main()
{
Matrix<int, 4, 3, ColMajor> Acolmajor;
Acolmajor << 1,2,3,4,
5,6,7,8,
9,10,11,12;
cout << "The matrix A:" << endl;
cout << Acolmajor << endl << endl;
cout << "In memory (column-major):" << endl;
for (int i = 0; i < Acolmajor.size(); i++)
cout << *(Acolmajor.data() + i) << " ";
cout << endl << endl;
Matrix<int, 4, 3, RowMajor> Arowmajor = Acolmajor;
cout << "In memory (row-major):" << endl;
for (int i = 0; i < Arowmajor.size(); i++)
cout << *(Arowmajor.data() + i) << " ";
cout << endl;
}
The matrix A:
1 2 3
4 5 6
7 8 9
10 11 12
In memory (column-major):
1 4 7 10 2 5 8 11 3 6 9 12
In memory (row-major):
1 2 3 4 5 6 7 8 9 10 11 12
Process returned 0 (0x0) execution time : 0.404 s
Press any key to continue.
-
Matrix类模板有六个模板参数,其中三个是强制性的(Scalar, RowsAtCompileTime和ColsAtCompileTime),另外三个是可选的(Options, MaxRowsAtCompileTime和MaxColsAtCompileTime)。如果Options参数设置为RowMajor,则矩阵或数组按行主要顺序存储;如果设置为ColMajor,则按列主顺序存储。该机制在上述特征程序中用于指定存储顺序。
-
如果未指定存储顺序,则Eigen默认以列为主的方式存储条目。如果使用方便类型(Matrix3f、ArrayXXd等)之一,也会出现这种情况。
-
使用一种存储顺序的矩阵和数组可以分配给使用另一种存储顺序的矩阵和数组,就像上面的程序中使用Acolmajor初始化Arowmajor时发生的那样。Eigen将自动重新排序条目。更一般地说,行为主矩阵和列为主矩阵可以在表达式中混合使用。
-
您应该在程序中使用哪种存储顺序呢?这个问题没有简单的答案;这取决于您的应用程序。以下是一些需要牢记的要点:
1.您的用户可能希望您使用特定的存储顺序。或者,您可以使用Eigen以外的其他库,这些库可能需要特定的存储顺序。在这些情况下,在整个程序中使用这种存储顺序可能是最简单和最快的。
2.当矩阵以行为主的顺序存储时,由于更好的数据局部性,逐行遍历矩阵的算法将运行得更快。类似地,对于列主矩阵,逐列遍历更快。为了找出适合您的特定应用程序的更快的方法,进行一些实验可能是值得的。
3.缺省情况下,Eigen是列为主的。自然地,大多数特征库的开发和测试都是用列主矩阵完成的。这意味着,尽管我们的目标是透明地支持列为主和行为主的存储顺序,但Eigen库可能最适合列为主的矩阵。
初始化向量
#include <iostream>
#include "f:/learn/eigen-3.4.0/Eigen/Dense"
using Eigen::VectorXd;
using Eigen::RowVectorXd;
int main()
{
VectorXd a {{1.5, 2.5, 3.5}};
RowVectorXd b {{1.0, 2.0, 3.0, 4.0}};
std::cout << a<< std::endl;
std::cout << b<< std::endl;
}
1.5
2.5
3.5
1 2 3 4
Process returned 0 (0x0) execution time : 0.110 s
Press any key to continue.
元素类型
MatrixNt for Matrix<type, N, N>. For example, MatrixXi for Matrix<int, Dynamic, Dynamic>.
MatrixXNt for Matrix<type, Dynamic, N>. For example, MatrixX3i for Matrix<int, Dynamic, 3>.
MatrixNXt for Matrix<type, N, Dynamic>. For example, Matrix4Xd for Matrix<d, 4, Dynamic>.
VectorNt for Matrix<type, N, 1>. For example, Vector2f for Matrix<float, 2, 1>.
RowVectorNt for Matrix<type, 1, N>. For example, RowVector3d for Matrix<double, 1, 3>.
- N可以是2、3、4或X中的任意一个(表示动态)。
- T可以是I (int)、f (float)、d (double)、cf (complex)或CD (complex)中的任意一个。虽然只为这五种类型定义了类型定义,但这并不意味着它们是唯一受支持的标量类型
参考文献
- Eigen
- learn.microsoft.com
- 百度百科之geline