c++ check point: Bjarne Stroutstrup, file io, class, template
c++ check point 2: vector/array, char/string, map, auto, lambda, sort, unique
I came to realize the huge blindspot in my “Data Structure” class 5 years ago. The professor, head of our CS department, never taught us how to use C++ libraries. He asked us to implement array, vector, linked list and tree from scratch. These assignments did help us understand the building block of data structure. But we should never end there.
Just a few days ago when I was preparing for a C++ interview, I learned to use
vector
and sort
, and appreciated the beauty of pointer. I came to realize that Python has hidden so many implementation details. On one hand it is easy to use and reach more users, but on the other hand it slow down the calculation speed and it is less flexible to make some fundamental changes.
Python has package management tools such as
pip
and conda
. But for c++, it only use brew
. And the default C++ STL such as vector
, algorithm
is located at /Library/Developer/CommandLineTools/usr/include/c++/v1
I am confused that several places storing somewhat differently command lines:
/Library/Developer/CommandLineTools/usr/bin
/usr/bin
For the same command, there may be multiple alias, such as: c++, clang, cc.
What I really want to talk about is these 2 important c++ libraries:
Boost and Eigen.
how to use Boost
$ brew install boost
🍺 /usr/local/Cellar/boost/1.64.0_1: 12,628 files, 398.7MB
Boost is a collection of extensive libraries. And the most popular ones has been migrated into C++11, C++14, etc.
In my “warmup” project, my
CMakeLists.txt
file is as follows:cmake_minimum_required(VERSION 3.7)
project(warmup)
find_package(Boost 1.64.0 COMPONENTS system filesystem REQUIRED) # library + version
if(Boost_FOUND)
message(STATUS "Boost_INCLUDE_DIRS: ${Boost_INCLUDE_DIRS}")
message(STATUS "Boost_LIBRARIES: ${Boost_LIBRARIES}")
message(STATUS "Boost_VERSION: ${Boost_VERSION}")
include_directories(${Boost_INCLUDE_DIRS})
endif()
set(CMAKE_CXX_STANDARD 11)
set(SOURCE_FILES main.cpp)
add_executable(warmup ${SOURCE_FILES})
if(Boost_FOUND)
target_link_libraries(warmup ${Boost_LIBRARIES}) # link
endif()
Note:
find_package()
can automatically find the include and library dir: /usr/local/lib/*
, which is actually the alias of the real ones that brew has installed /usr/local/Cellar/boost/1.64.0_1
. Surprisingly, manually setting the dir will cause … version.hpp" cannot be read
error.
Alternatively, you can copy all the library files to your project folder and use
#include "boost/xxx"
, which is more space costly.
The following cpp codes can be used to test whether the boost library is properly configured.
#include <boost/lambda/lambda.hpp>
#include <iostream>
int main(){
typedef std::istream_iterator<int> in;
std::cout << "Type in any number: ";
std::for_each(
in(std::cin), in(), std::cout
<< (boost::lambda::_1 * 10)
<< "\nType in another number: " );
}
how to use Eigen
$ brew install eigen
$ brew list eigen
/usr/local/Cellar/eigen/3.3.3/include/eigen3/ (477 files)
/usr/local/Cellar/eigen/3.3.3/share/cmake/Modules/FindEigen3.cmake
/usr/local/Cellar/eigen/3.3.3/share/eigen3/ (4 files)
/usr/local/Cellar/eigen/3.3.3/share/pkgconfig/eigen3.pc
The whole Eigen folder is only 5.5 /3.8 MB (before/after compilation), which contains a batch of headers and their corresponding cpp files stored in
src
folder.
There are 2 ways to use eigen libraries:
- copy the whole eigen folder to the project folder. write
#include "Eigen/Dense"
in main.cpp. - keep eigen folder where brew put it. write
#include <Eigen/Dense>
in main.cpp. Addinclude_directories (/usr/local/Cellar/eigen/3.3.3/include/eigen3/)
in “CMakeLists.txt”.
We are using the
Dense
here, which is a header condensing 7 headers together, such as Coure, LU, QR, EigenValues, Geometry.data type
In STL, list is implemented as
vector<int> a (5,0)
or array<int, 3> ={0,0,0}
.
In Eigen, it is interesting that the data class is named as
[Matrix/Vector][1234X][ifdc]
. For example, MatrixXf
means Matrix with a dynamic size and filled with float numbers.Vector3i
means a Vector of size 3 and filled with integers.#include <Eigen/Dense>
#include <iostream>
using namespace std;
using namespace Eigen;
int main(){
MatrixXf m1;
m1.setOnes(2,3);
cout<<"m1_1=\n"<<m1<<endl;
m1 << 1.3, 4,-8,
0,0.9,2; // manual input, match existing size
cout<<"m1_2=\n"<<m1<<endl;
cout<< m1(1,1) <<endl; // access by ()
m1 = MatrixXf:: Zero(2,5); // change sizes
cout<<"m1_3=\n"<<m1<<endl;
m1.setRandom();
cout<<"m1_4=\n" <<m1 <<endl;
m1 = m1.array() * m1.array(); // element-wise operation
cout<<"m1_5=\n" <<m1 <<endl;
Vector3i v1 = Vector3i::Ones();
cout<<"v1=\n"<<v1<<endl;
cout<< v1(0)<<v1[0]<<endl;
cout<<"v1=\n"<<v1.transpose()<<endl;
MatrixXf m2(5,2);
m2.setRandom();
cout << m1*m2 <<endl;
cout << v1.dot(v1) <<endl;
cout << m1.maxCoeff() <<endl;
cout << m1.mean() <<endl;
}
No comments:
Post a Comment
Note: Only a member of this blog may post a comment.