计算物理精解【1】-C++计算(1)

news2024/9/27 21:25:13

文章目录

  • 基础
    • 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>
  • 存储顺序详解
    矩阵和二维数组有两种不同的存储顺序:列为主和行为主
    当矩阵存储在内存中时,条目必须以某种方式线性排列。有两种主要的方法可以做到这一点,按行和按列。
  1. 如果一个矩阵是逐行存储的,我们就说它是按行主序存储 row-major的。首先存储整个第一行,然后是整个第二行,依此类推。以矩阵为例
    在这里插入图片描述
8 2 2 9 9 1 4 4 3 5 4 5 
  1. 如果一个矩阵是按列存储 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)中的任意一个。虽然只为这五种类型定义了类型定义,但这并不意味着它们是唯一受支持的标量类型

参考文献

  1. Eigen
  2. learn.microsoft.com
  3. 百度百科之geline

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2165607.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

DNS协议解析

DNS协议解析 什么是DNS协议 IP地址&#xff1a;一长串唯一标识网络上的计算机的数字 域名&#xff1a;一串由点分割的字符串名字 网址包含了域名 DNS&#xff1a;域名解析协议 IP>域名 --反向解析 域名>IP --正向解析 域名 由ICANN管理&#xff0c;有级别&#xf…

2.1 HuggingFists系统架构(二)

部署架构 上图为HuggingFists的部署架构。从架构图可知&#xff0c;HuggingFists主要分为服务器(Server)、计算节点(Node)以及数据库(Storage)三部分。这三部分可以分别部署在不同的机器上&#xff0c;以满足系统的性能需求。为部署方便&#xff0c;HuggingFists社区版将这三部…

Python | Leetcode Python题解之第419题棋盘上的战舰

题目&#xff1a; 题解&#xff1a; class Solution:def countBattleships(self, board: List[List[str]]) -> int:return sum(ch X and not (i > 0 and board[i - 1][j] X or j > 0 and board[i][j - 1] X)for i, row in enumerate(board) for j, ch in enumerat…

vue全局注册和局部注册的区别

1.全局注册&#xff1a; a、b为注册的组件 2.局部注册 3.有图可以看出&#xff0c;全局注册会影响白屏时间

2024最新Python Debugger工具pdb的用法(深度学习项目),了解输入输出的形状大小

侵入式方法 &#xff08;在被调试的代码中添加以下代码然后再正常运行代码&#xff09; import pdb pdb.set_trace() 例如&#xff1a; 正常运行训练文件后&#xff1a; 在命令行发现输出以下内容&#xff1a; 出现了(Pdb) 的提示符&#xff0c;说明已经打开pdb 在使用Pyth…

解决fatal: unable to access ‘https://........git/‘: Recv failure: Operation time

目录 前言 解决方法一 解决方法二 解决方法三 解决方法四 总结 前言 在使用 Git 进行代码拉取时&#xff0c;可能会遇到连接超时的问题&#xff0c;特别是在某些网络环境下&#xff0c;例如公司网络或防火墙严格的环境中。这种情况下&#xff0c;Git 无法访问远程仓…

红帽认证会过期吗?一文给你解释清楚!

红帽认证以其权威性、实用性和高含金量受到了广大IT人士的青睐&#xff0c;尤其是Linux领域。然而&#xff0c;许多人在考取红帽认证后&#xff0c;心中都有一个疑问&#xff1a;红帽认证会过期吗?本文将为大家详细解答这个问题。 红帽认证是什么? 红帽认证是由红帽公司(Re…

Windows 2003系统的防护技巧,禁止IPC$空连接

一、修改管理员帐号和新建“陷阱”帐号 多年以来&#xff0c;微软一直在强调建议重命名Administrator账号并禁用Guest账号&#xff0c;提高计算机的安全性。Windows Server 2003系统&#xff0c;Guest 账号是默认禁用的&#xff0c;管理员账号默认是Administrator&#xff0c;…

html 几行的空间分成3个区域

1.代码 <!DOCTYPE html> <html lang"en"> <head> <meta charset"UTF-8"> <meta name"viewport" content"widthdevice-width, initial-scale1.0"> <title>三个区域示例</title> …

深入解析Python 中的 sortedcontainers 库:高效的排序数据结构

在日常的 Python 编程中&#xff0c;列表&#xff08;list&#xff09;、集合&#xff08;set&#xff09;和字典&#xff08;dict&#xff09;是常用的数据结构。然而&#xff0c;在某些特定的场景下&#xff0c;我们需要对数据进行排序&#xff0c;并且希望在插入、删除或访问…

4.2章节python中选择结构

选择结构主要通过if、elif&#xff08;else if的缩写&#xff09;和else语句来实现。这些语句允许程序根据条件执行不同的代码块。另外还有表达式中多个条件连接等。 一、基本语句if if 语句后面跟一个条件表达式&#xff0c;如果条件为真&#xff08;True&#xff09;&#…

Machine Learning Specialization 学习笔记(4)

文章目录 前言一、模型评估训练集常规训练集线性回归逻辑回归 交叉验证集 偏差与方差正则化 学习曲线数据集的添加&#xff08;数据增强&#xff09;迁移学习精确率与召回率 二、决策树基本概念决策树的工作原理决策树的优点决策树的缺点决策树算法的变体决策树在Python中的实现…

OpenCV4.8 开发实战系列专栏之 01- 环境搭建与图像读写

大家好&#xff0c;欢迎大家学习OpenCV4.8 开发实战专栏&#xff0c;长期更新&#xff0c;不断分享源码。 专栏代码全部基于C 与Python双语演示&#xff0c;专栏答疑群 请联系微信 OpenCVXueTang_Asst 本文关键知识点&#xff1a; 开发环境搭建、读取图像与显示图像,读取图像…

什么是换电连接器

换电连接器是一种高压连接器&#xff0c;安装在整车中&#xff0c;属于车载连接器。它利用导体和绝缘体的特性&#xff0c;将电能和数据信号从换电站设备传输到电动汽车的电池组&#xff0c;实现能源的快速补充。换电连接器通常由插头和插座两部分组成&#xff0c;通过精密的对…

紫光展锐 携手摩托罗拉在全球市场推出强竞争力5G手机moto G35

moto G35 5G亮点 ■ 高清视界&#xff1a;6.72英寸FHDLCD屏幕&#xff0c;120Hz高刷新率&#xff1b; ■ 震撼音效&#xff1a;配备立体声扬声器和杜比全景声Dolby Atmos&#xff1b; ■ 大师影像&#xff1a;5000万像素后置AI相机&#xff1b; ■ 强劲核芯&#xff1a;紫光…

计算机毕业设计Hadoop+Spark知识图谱美团美食推荐系统 美团餐厅推荐系统 美团推荐系统 美食价格预测 美团爬虫 美食数据分析 美食可视化大屏

《HadoopSpark知识图谱美团美食推荐系统》开题报告 一、引言 随着互联网技术的快速发展&#xff0c;大数据已成为企业竞争力的关键要素。美团作为国内领先的本地生活服务平台&#xff0c;拥有海量的用户行为数据和丰富的业务场景。为了进一步提升用户体验&#xff0c;提高推荐…

JVM内存区域详解及DirectByteBuffer内存

Java虚拟机&#xff08;JVM&#xff09;是Java程序运行的基础&#xff0c;它为Java程序提供了一个与平台无关的执行环境。JVM内存区域的划分对于理解Java程序的运行机制至关重要。本文将详细介绍JVM的内存区域&#xff0c;并探讨对外内存中的DirectByteBuffer。 方法区&#x…

炉石传说辅助攻略—VMOS云手机助攻:国服回归任务要点,哪个辅助更好?

在《炉石传说》中想要轻松完成各种任务并享受游戏的乐趣&#xff0c;VMOS云手机是您的最佳辅助工具&#xff01;VMOS云手机为《炉石传说》提供了专属定制版的云手机&#xff0c;内置游戏安装包&#xff0c;不需要重新下载安装游戏&#xff0c;让您快速上手。更棒的是&#xff0…

Misc-流量分析基础

第一种&#xff1a;直接搜索flag字符串 第二种&#xff1a;flag进行了十六进制编码&#xff0c;通过十六进制编码解决 第三种&#xff1a;压缩包流量&#xff1a;tar.gz的压缩包可以直接在wireshark中解压查看&#xff0c;其他的压缩包则要将流量导出来&#xff0c;然后去解码…

微信小程序注册流程及APPID获取(完整版图文教程)

文章目录 前言1. 注册微信小程序账号1.1微信小程序注册1.2 点击注册按钮&#xff0c;进入小程序注册步骤。1.3 填写邮箱、密码、验证码1.4 用户信息登记1.5 微信扫码认证后&#xff0c;回到微信公众平台点击确认提交1.6 进小程序后台&#xff0c;完成注册 2.完善小程序账号信息…