Eigen入门之密集矩阵 3 - Array操作
簡介
在Eigen內,有Matrix,vector進行線性代數的相關運算,但也需要執行對矩陣內的系數的相關操作時,這是正常的功能需求。Eigen中的Array類就是滿足此需求的。
Array 定義
和前面介紹的Matrix和Vector類似,Array類也是一個模板類
/** \class Array* \ingroup Core_Module** \brief General-purpose arrays with easy API for coefficient-wise operations** The %Array class is very similar to the Matrix class. It provides* general-purpose one- and two-dimensional arrays. The difference between the* %Array and the %Matrix class is primarily in the API: the API for the* %Array class provides easy access to coefficient-wise operations, while the* API for the %Matrix class provides easy access to linear-algebra* operations.** See documentation of class Matrix for detailed information on the template parameters* storage layout.** This class can be extended with the help of the plugin mechanism described on the page* \ref TopicCustomizing_Plugins by defining the preprocessor symbol \c EIGEN_ARRAY_PLUGIN.** \sa \blank \ref TutorialArrayClass, \ref TopicClassHierarchy*/ template<typename _Scalar, int _Rows, int _Cols, int _Options, int _MaxRows, int _MaxCols> class Array: public PlainObjectBase<Array<_Scalar, _Rows, _Cols, _Options, _MaxRows, _MaxCols> >同樣,Eigen也使用macro為Array定義了一些快捷簡單Array類型。如下:
/** \defgroup arraytypedefs Global array typedefs* \ingroup Core_Module** Eigen defines several typedef shortcuts for most common 1D and 2D array types.** The general patterns are the following:** \c ArrayRowsColsType where \c Rows and \c Cols can be \c 2,\c 3,\c 4 for fixed size square matrices or \c X for dynamic size,* and where \c Type can be \c i for integer, \c f for float, \c d for double, \c cf for complex float, \c cd* for complex double.** For example, \c Array33d is a fixed-size 3x3 array type of doubles, and \c ArrayXXf is a dynamic-size matrix of floats.** There are also \c ArraySizeType which are self-explanatory. For example, \c Array4cf is* a fixed-size 1D array of 4 complex floats.** \sa class Array*/#define EIGEN_MAKE_ARRAY_TYPEDEFS(Type, TypeSuffix, Size, SizeSuffix) \ /** \ingroup arraytypedefs */ \ typedef Array<Type, Size, Size> Array##SizeSuffix##SizeSuffix##TypeSuffix; \ /** \ingroup arraytypedefs */ \ typedef Array<Type, Size, 1> Array##SizeSuffix##TypeSuffix;#define EIGEN_MAKE_ARRAY_FIXED_TYPEDEFS(Type, TypeSuffix, Size) \ /** \ingroup arraytypedefs */ \ typedef Array<Type, Size, Dynamic> Array##Size##X##TypeSuffix; \ /** \ingroup arraytypedefs */ \ typedef Array<Type, Dynamic, Size> Array##X##Size##TypeSuffix;#define EIGEN_MAKE_ARRAY_TYPEDEFS_ALL_SIZES(Type, TypeSuffix) \ EIGEN_MAKE_ARRAY_TYPEDEFS(Type, TypeSuffix, 2, 2) \ EIGEN_MAKE_ARRAY_TYPEDEFS(Type, TypeSuffix, 3, 3) \ EIGEN_MAKE_ARRAY_TYPEDEFS(Type, TypeSuffix, 4, 4) \ EIGEN_MAKE_ARRAY_TYPEDEFS(Type, TypeSuffix, Dynamic, X) \ EIGEN_MAKE_ARRAY_FIXED_TYPEDEFS(Type, TypeSuffix, 2) \ EIGEN_MAKE_ARRAY_FIXED_TYPEDEFS(Type, TypeSuffix, 3) \ EIGEN_MAKE_ARRAY_FIXED_TYPEDEFS(Type, TypeSuffix, 4)EIGEN_MAKE_ARRAY_TYPEDEFS_ALL_SIZES(int, i) EIGEN_MAKE_ARRAY_TYPEDEFS_ALL_SIZES(float, f) EIGEN_MAKE_ARRAY_TYPEDEFS_ALL_SIZES(double, d) EIGEN_MAKE_ARRAY_TYPEDEFS_ALL_SIZES(std::complex<float>, cf) EIGEN_MAKE_ARRAY_TYPEDEFS_ALL_SIZES(std::complex<double>, cd)#undef EIGEN_MAKE_ARRAY_TYPEDEFS_ALL_SIZES #undef EIGEN_MAKE_ARRAY_TYPEDEFS#undef EIGEN_MAKE_ARRAY_TYPEDEFS_LARGE#define EIGEN_USING_ARRAY_TYPEDEFS_FOR_TYPE_AND_SIZE(TypeSuffix, SizeSuffix) \ using Eigen::Matrix##SizeSuffix##TypeSuffix; \ using Eigen::Vector##SizeSuffix##TypeSuffix; \ using Eigen::RowVector##SizeSuffix##TypeSuffix;#define EIGEN_USING_ARRAY_TYPEDEFS_FOR_TYPE(TypeSuffix) \ EIGEN_USING_ARRAY_TYPEDEFS_FOR_TYPE_AND_SIZE(TypeSuffix, 2) \ EIGEN_USING_ARRAY_TYPEDEFS_FOR_TYPE_AND_SIZE(TypeSuffix, 3) \ EIGEN_USING_ARRAY_TYPEDEFS_FOR_TYPE_AND_SIZE(TypeSuffix, 4) \ EIGEN_USING_ARRAY_TYPEDEFS_FOR_TYPE_AND_SIZE(TypeSuffix, X) \ #define EIGEN_USING_ARRAY_TYPEDEFS \ EIGEN_USING_ARRAY_TYPEDEFS_FOR_TYPE(i) \ EIGEN_USING_ARRAY_TYPEDEFS_FOR_TYPE(f) \ EIGEN_USING_ARRAY_TYPEDEFS_FOR_TYPE(d) \ EIGEN_USING_ARRAY_TYPEDEFS_FOR_TYPE(cf) \ EIGEN_USING_ARRAY_TYPEDEFS_FOR_TYPE(cd)特殊一點的地方在于,Array有一維數組,還有多維數組。一維數組的便利簡單名稱采樣形如: ArrayNt,這里N為該維度中數組大小,t為系數數據類型。二維數組形如:ArrayNNt。
示例
| Array<float,Dynamic,1> | ArrayXf |
| Array<float,3,1> | Array3f |
| Array<double,Dynamic,Dynamic> | ArrayXXd |
| Array<double,3,3> | Array33d |
對數組系數的訪問及操作
如Matrix中,重載的括號運算符()用來訪問數組中的系數, 可以用來取值,也可以用于賦值。如代碼中所看到的,還可以使用operator<<來初始化一個數組。
// array_1.cpp #include <Eigen/Dense> #include <iostream>using namespace Eigen; using namespace std;int main() {ArrayXXf m(2,2);// assign some values coefficient by coefficientm(0,0) = 1.0; m(0,1) = 1.1;m(1,0) = 2.0; m(1,1) = m(0,1) + m(1,0);// print values to standard outputcout << m << endl << endl;// using the comma-initializer is also allowedm << 2.0,3.0,8.0,9.0;// print values to standard outputcout << m << endl; }執行結果:
$ g++ -I /usr/local/include/eigen3 array_1.cpp -o array_1 $ ./array_1 1 1.12 3.12 3 8 9加法及減法運算
Array重載了operator+, operator-,可以對2個Array進行加法或減法運算,當然這2個array得有相同的Size,可很容易理解。
還重載實現了一種計算:array + scalar。這會將標量加到每個數組元素上去。
示例程序:
// array_2.cpp #include <Eigen/Dense> #include <iostream>using namespace Eigen; using namespace std;int main() {ArrayXXf a(3,3);ArrayXXf b(3,3);a << 1,2,3,4,5,6,7,8,9;b << 1,2,3,1,2,3,1,2,3;cout<<"array a:" << endl << a <<endl;cout<<"array b:" << endl << b <<endl; // array +/- arraycout << "a + b = " << endl << a + b << endl << endl;// array - scalarcout << "a - 1 = " << endl << a - 1 << endl; }執行效果:
$ g++ -I /usr/local/include/eigen3 array_2.cpp -o array_2 $ $ ./array_2 array a: 1 2 3 4 5 6 7 8 9 array b: 1 2 3 1 2 3 1 2 3 a + b = 2 4 65 7 98 10 12a - 1 = 0 1 2 3 4 5 6 7 8乘法運算
乘法分為兩種: array * scalar、 array * array。其中 array * scalar與matrix一樣;array * array是面向數組系數的操作,對應匹配的系數進行相乘,只有2個具有相同維度的數組才能相乘。
//array_multi.cpp#include <Eigen/Dense> #include <iostream>using namespace Eigen; using namespace std;int main() {ArrayXXf a(2,2);ArrayXXf b(2,2);a << 1,2,3,4;b << 5,6,7,8;cout<<"array a:" << endl << a <<endl;cout<<"array b:" << endl << b <<endl; cout << "a * b = " << endl << a * b << endl;cout<< "a * 2 = " << endl << a * 2 << endl;}執行:
$ g++ -I /usr/local/include/eigen3 array_multi.cpp -o array_multi $ $ ./array_multi array a: 1 2 3 4 array b: 5 6 7 8 a * b = 5 12 21 32 a * 2 = 2 4 6 8其他的面向系數的計算
針對array,除了上面提到的 +, -, *的計算,這些都是面向數組系數的,還有其他的一些函數操作。比如abs(), sqrt(), min(.)。
//array_others.cpp#include <Eigen/Dense> #include <iostream>using namespace Eigen; using namespace std;int main() {ArrayXf a = ArrayXf::Random(5);a *= 2;cout << "a =" << endl << a << endl;cout << "a.abs() =" << endl << a.abs() << endl;cout << "a.abs().sqrt() =" << endl << a.abs().sqrt() << endl;cout << "a.min(a.abs().sqrt()) =" << endl << a.min(a.abs().sqrt()) << endl; }執行:
$ g++ -I /usr/local/include/eigen3 array_others.cpp -o array_other $ $ ./array_other a =-1.99997-1.473851.02242 -0.1653990.131069 a.abs() =1.999971.473851.02242 0.165399 0.131069 a.abs().sqrt() =1.41421.214021.01115 0.406693 0.362034 a.min(a.abs().sqrt()) =-1.99997-1.473851.01115 -0.1653990.131069在Array與Matrix直接轉換
在Eigen內,Matrix用于線性代理計算;而Array用于針對系數進行操作,它們有不同的目的。
Matrix類表達式expression 提供了.array()函數方法,用于將矩陣matrix轉換成array expression,然后就可以很容易對系數進行各種操作。對應地,Array也提供了.matrix(),用于從Array得到一個matrix expression表達式。
.array(),.matrix()既可以用于右值、也可以用于左值。但在一個表達式內,混合.array(),.matrix()是不可以的。比如,你不能直接讓一個矩陣matrix和數組array相加。但可以通過.array(),.matrix()進行一下轉換,再進行計算。
因為經常有這樣的計算需求,Eigen中Matrix提供了一個便利函數cwiseProduct(Matrix),用于處理Matrix.array() * Matrix.array()計算。
示例:
//array_matrix_1.cpp#include <Eigen/Dense> #include <iostream>using namespace Eigen; using namespace std;int main() {MatrixXf m(2,2);MatrixXf n(2,2);MatrixXf result(2,2);m << 1,2,3,4;n << 5,6,7,8;cout<<"array m:" << endl << m <<endl;cout<<"array n:" << endl << n <<endl<<"-----------------"<< endl;result = m * n;cout << "-- Matrix m*n: --" << endl << result << endl << endl;result = m.array() * n.array();cout << "-- Array m*n: --" << endl << result << endl << endl;result = m.cwiseProduct(n);cout << "-- With cwiseProduct: --" << endl << result << endl << endl;result = m.array() + 4;cout << "-- Array m + 4: --" << endl << result << endl << endl; }執行一下,檢查結果:
$ g++ -I /usr/local/include/eigen3 array_matrix_1.cpp -o array_matrix_1 $ $ ./array_matrix_1 array m: 1 2 3 4 array n: 5 6 7 8 ----------------- -- Matrix m*n: -- 19 22 43 50-- Array m*n: --5 12 21 32-- With cwiseProduct: --5 12 21 32-- Array m + 4: -- 5 6 7 8總結
以上是生活随笔為你收集整理的Eigen入门之密集矩阵 3 - Array操作的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 美国将微信、淘宝、拼多多再度列入“恶名市
- 下一篇: “人形机器人第一股”要来了?优必选提交赴