C++ 的 Eign 類庫學習
Eign 是一個 C++ 中的用於科學計算(矩陣)的類庫,提供了非常方便的介面,最近我們小組需要做一個專案,裡面涉及到很多的矩陣的計算,於是我打算使用這個類庫結合我的 CLion 寫程式碼
二、如何配置
下載最新的 release 安裝包 解壓到專案的目錄下(當然任何目錄都可以,我習慣上解壓到專案的目錄下,這樣比較方便管理),然後我們配置我們的 CMakeLists.txt
<!- more –>
CMakeLists.txt
cmake_minimum_required(VERSION 3.10) project(juzhen) set(CMAKE_CXX_STANDARD 11) include_directories(../eigen)//這裡寫你的解壓目錄 add_executable(juzhen main.cpp)
main.cpp
#include <iostream> #include <Eigen/Dense> using namespace Eigen; using namespace std; int main() { typedef Matrix<int,3,3> hh; MatrixXd m = MatrixXd::Random(3,3); //m = (m + MatrixXd::Constant(3,3,1.2)) * 50; MatrixXd c = MatrixXd::Constant(3,3,1)*10; hh x; cout << "m =" << endl << m << endl; cout << "c =" << endl << c << endl; cout << "x =" << endl << x << endl; }
這樣就能執行啦
三、Eigen 基礎
1.Matrix 類
1.基本:
在Eigen中,所有矩陣和向量都是Matrix模板類的物件。向量只是矩陣的一種特殊情況,有1行或1列。
Matrix的三個必需模板引數是:
Matrix <typename Scalar,int RowsAtCompileTime,int ColsAtCompileTime>
例如:Matrix4f是浮動的4x4矩陣
typedef Matrix <float,4,4> Matrix4f ;
假如:我想生成一個 int 型的 3x3 的矩陣
示例程式碼:
#include <iostream> #include <Eigen/Dense> using namespace Eigen; using namespace std; int main() { typedef Matrix<int,3,3> hh; hh x; cout << "x =" << endl << x << endl; }
結果:
x = 2001839094360 20017911116880932 1275664310 -146880948
2.向量
向量只是一種特殊的矩陣而已
列向量:
typedef Matrix <float,3,1> Vector3f ;
行向量:
typedef Matrix <int,1,2> RowVector2i ;
3.動態值
我們當然不滿足在編譯時就確定矩陣的大小,於是他給我們也提供了對應的方法
例如,便捷typedef MatrixXd,即具有動態大小的雙精度矩陣,定義如下:
typedef Matrix <double,Dynamic,Dynamic> MatrixXd ;
同樣,我們定義了一個不言自明的typedef VectorXi如下:
typedef Matrix <int,Dynamic,1> VectorXi ;
您可以完美地擁有例如具有動態列數的固定行數,如下所示:
Matrix <float,3,Dynamic>
4.建構函式
預設建構函式始終可用,從不執行任何動態記憶體分配,也從不初始化矩陣係數。你可以做:
Matrix3f a; MatrixXf b;
a 是一個3乘3的矩陣,具有未初始化係數的普通浮點數
b 是一個動態大小的矩陣,其大小目前是0乘0,並且其係數陣列尚未分配。
注意:
Matrix3i d;
這裡代表聲明瞭一個 Int 型的 3x3 的矩陣,也就是說 最後的f 代表的是 float
對於矩陣,始終首先傳遞行數。對於向量,只需傳遞向量大小。它們使用給定的大小分配係數陣列,但不自行初始化係數:
MatrixXf a(10,15); VectorXf b(30);
a 是一個10x15動態大小的矩陣,具有已分配但當前未初始化的係數。
b 是一個大小為30的動態大小向量,具有已分配但當前未初始化的係數
注意:
RowVector2d e(1.0,2.0);
這個代表生成的是一個行向量(不加 row 是列向量)
5.係數訪問器
示例程式碼:
#include <iostream> #include <Eigen/Dense> using namespace Eigen; using namespace std; int main() { MatrixXd m(2,2); m(0,0)= 3; m(1,0)= 2.5; m(0,1)= -1; m(1,1)= m(1,0)+ m(0,1); std :: cout << "這是矩陣m:\n" << m << std :: endl; VectorXd v(2); v(0)= 4; v(1)= v(0) - 1; std :: cout << "這是向量v:\n" << v << std :: endl; }
結果:
這是矩陣m: 3-1 2.5 1.5 這是向量v: 4 3
6.逗號初始化
示例程式碼:
int main() { Matrix3f m; m << 1,2,3, 4,5,6, 7,8,9; std :: cout << m <<endl; }
結果:
7.調整
可以通過rows(),cols()和size()檢索矩陣的當前大小。這些方法分別返回行數,列數和係數數。調整動態大小矩陣的大小由resize()方法完成。
示例程式碼:
int main() { MatrixXd m(2,5); m.resize(4,3); std :: cout << "矩陣m的大小" << m.rows() << "x" << m.cols()<< std :: endl; std :: cout << "它有" << m.size()<< "係數" << std :: endl; VectorXd v(2); v.resize(5); std :: cout << "向量v的大小為" << v.size()<< std :: endl; std :: cout << "作為矩陣,v的大小" << v.rows()<< "x" << v.cols()<< std :: endl; }
結果:
矩陣m的大小4x3 它有12係數 向量v的大小為5 作為矩陣,v的大小5x1
8.分配和調整大小
這裡實際上是個C++ 中等號的過載
Eigen自動調整左側的矩陣大小,使其與右側大小的矩陣大小相匹配。例如:
示例程式碼:
int main() { MatrixXf a(2,2); std :: cout << "a is size " << a.rows() << "x" << a.cols()<< std :: endl; MatrixXf b(3,3); a = b; std :: cout << "a現在大小" << a.rows()<< "x" << a.cols()<< std :: endl; }
結果:
a is size 2x2 a現在大小3x3
四、矩陣和向量算數
1.加減
二元運算子+如 a+b
二元運算子 - 如 a-b
一元運算元 - 如同 -a
複合運算子+ =如 a+=b
複合運算子 - =如 a-=b
注意:
運算子的左值和右值,必須要有相同的型別和相同數量的行列
示例程式碼:
int main() { Matrix2d a; a << 1,2, 3,4; MatrixXd b(2,2); b << 2,3, 1,4; std :: cout << "a + b = \n" << a + b << std :: endl; std :: cout << "a-b = \n" << a-b << std :: endl; std :: cout << "做一個+ = b;" << std :: endl; a += b; std :: cout << "現在 a = \n" << a << std :: endl; Vector3d v(1,2,3); Vector3d w(1,0,0); std :: cout << "-v + w - v = \n" <<-v + w - v << std :: endl; }
2.標量的乘除
二元運算子如 matrix scalar
二元運算子如 scalar matrix
二元運算子/如 matrix/scalar
複合運算子=如 matrix =scalar
複合運算子/ =如 matrix/=scalar
示例程式碼:
int main() { Matrix2d a; a << 1,2, 3,4; Vector3d v(1,2,3); std :: cout << "a * 2.5 = \n" << a * 2.5 << std :: endl; std :: cout << "0.1 * v = \n" << 0.1 * v << std :: endl; std :: cout << "做v *= 2;" << std :: endl; v *= 2; std :: cout << "現在v = \n" << v << std :: endl; }
結果:
a * 2.5 = 2.55 7.510 0.1 * v = 0.1 0.2 0.3 做v *= 2; 現在v = 2 4 6
3.轉置、共軛、伴隨
通過成員函式transpose(),conjugate()和adjoint()分別獲得矩陣或向量的轉置$ a ^ T $,共軛$ \ bar {a} $和伴隨(即,共軛轉置)。$ a ^ * $$ a $
示例程式碼:
int main() { MatrixXf a = MatrixXf :: Random(2,2); cout << "這是矩陣a \n" << a << endl; cout << "這是矩陣a 的轉置\n" << a.transpose()<< endl; cout << "這是矩陣a 的共軛\n" << a.conjugate()<<endl; cout << "這是矩陣a 的伴隨\n" << a.adjoint()<< endl; }
結果:
這是矩陣a -0.997497 -0.613392 0.1271710.617481 這是矩陣a 的轉置 -0.9974970.127171 -0.6133920.617481 這是矩陣a 的共軛 -0.997497 -0.613392 0.1271710.617481 這是矩陣a 的伴隨 -0.9974970.127171 -0.6133920.617481
4.矩陣 - 矩陣和矩陣 - 向量乘法
示例程式碼:
int main() { Matrix2d mat; mat << 1, 2, 3, 4; Vector2d u(-1,1), v(2,0); std::cout << "Here is mat*mat:\n" << mat * mat << std::endl; std::cout << "Here is mat*u:\n" << mat*u << std::endl; std::cout << "Here is u^T*mat:\n" << u.transpose()*mat << std::endl; std::cout << "Here is u^T*v:\n" << u.transpose()*v << std::endl; std::cout << "Here is u*v^T:\n" << u*v.transpose() << std::endl; std::cout << "Let's multiply mat by itself" << std::endl; mat = mat*mat; std::cout << "Now mat is mat:\n" << mat << std::endl; }
結果:
Here is mat*mat: 7 10 15 22 Here is mat*u: 1 1 Here is u^T*mat: 2 2 Here is u^T*v: -2 Here is u*v^T: -2 -0 20 Let's multiply mat by itself Now mat is mat: 7 10 15 22
五、高階初始化
1.將矩陣進行拼接
請記住,必須先設定大小,然後才能使用逗號初始值設定項
示例程式碼:
int main() { RowVectorXd vec1(3); vec1 << 1, 2, 3; std::cout << "vec1 = " << vec1 << std::endl; RowVectorXd vec2(4); vec2 << 1, 4, 9, 16; std::cout << "vec2 = " << vec2 << std::endl; RowVectorXd joined(7); joined << vec1, vec2; std::cout << "joined = " << joined << std::endl; }
結果:
vec1 = 1 2 3 vec2 =149 16 joined =123149 16
我們可以使用相同的技術來初始化具有塊結構的矩陣。
例項程式碼:
int main() { MatrixXf matA(2, 2); matA << 1, 2, 3, 4; MatrixXf matB(4, 4); matB << matA, matA/10, matA/10, matA; std::cout << matB << std::endl; }
結果:
12 0.1 0.2 34 0.3 0.4 0.1 0.212 0.3 0.434
更高階的填充:
示例程式碼:
int main() { Matrix3f m; m.row(0) << 1, 2, 3; m.block(1,0,2,2) << 4, 5, 7, 8; m.col(2).tail(2) << 6, 9; std::cout << m; }
結果:
2.特殊矩陣
矩陣和陣列都有特殊方法 Zero()
示例程式碼:
int main() { std::cout << "A fixed-size array:\n"; Array33f a1 = Array33f::Zero(); std::cout << a1 << "\n\n"; std::cout << "A one-dimensional dynamic-size array:\n"; ArrayXf a2 = ArrayXf::Zero(3); std::cout << a2 << "\n\n"; std::cout << "A two-dimensional dynamic-size array:\n"; ArrayXXf a3 = ArrayXXf::Zero(3, 4); std::cout << a3 << "\n"; }
結果:
A fixed-size array: 0 0 0 0 0 0 0 0 0 A one-dimensional dynamic-size array: 0 0 0 A two-dimensional dynamic-size array: 0 0 0 0 0 0 0 0 0 0 0 0
類似地:
1.靜態方法Constant(value)將所有係數設定為value。如果需要指定物件的大小,則附加引數將在value引數之前,如MatrixXd::Constant(rows, cols, value)。
2.方法Random()用隨機係數填充矩陣或陣列。
3.可以通過呼叫Identity()獲得單位矩陣; 此方法僅適用於Matrix,而不適用於Array,因為“單位矩陣”是線性代數概念。
4.LinSpaced方法(大小,低,高)僅適用於向量和一維陣列;
它產生一個指定大小的向量,其係數在low和之間等間隔high。
Eigen定義了實用函式
如setZero(),MatrixBase :: setIdentity()和DenseBase :: setLinSpaced(),可以方便地執行此操作。以下示例對比了構造矩陣的三種方法
使用靜態方法和賦值,使用靜態方法和逗號初始化程式,或使用setXxx()方法。
示例程式碼:
int main() { const int size = 6; MatrixXd mat1(size, size); mat1.topLeftCorner(size/2, size/2)= MatrixXd::Zero(size/2, size/2); mat1.topRightCorner(size/2, size/2)= MatrixXd::Identity(size/2, size/2); mat1.bottomLeftCorner(size/2, size/2)= MatrixXd::Identity(size/2, size/2); mat1.bottomRightCorner(size/2, size/2) = MatrixXd::Zero(size/2, size/2); std::cout << mat1 << std::endl << std::endl; MatrixXd mat2(size, size); mat2.topLeftCorner(size/2, size/2).setZero(); mat2.topRightCorner(size/2, size/2).setIdentity(); mat2.bottomLeftCorner(size/2, size/2).setIdentity(); mat2.bottomRightCorner(size/2, size/2).setZero(); std::cout << mat2 << std::endl << std::endl; MatrixXd mat3(size, size); mat3 << MatrixXd::Zero(size/2, size/2), MatrixXd::Identity(size/2, size/2), MatrixXd::Identity(size/2, size/2), MatrixXd::Zero(size/2, size/2); std::cout << mat3 << std::endl; }
結果:
3.用作臨時物件
靜態方法如Zero()和Constant()可用於在宣告時或在賦值運算子的右側初始化變數。您可以將這些方法視為返回矩陣或陣列; 實際上,它們返回所謂的表示式物件 ,在需要時可以計算矩陣或陣列。
示例程式碼:
int main() { MatrixXd m = MatrixXd::Random(3,3); m = (m + MatrixXd::Constant(3,3,1.2)) * 50; cout << "m =" << endl << m << endl; VectorXd v(3); v << 1, 2, 3; cout << "m * v =" << endl << m * v << endl; }
結果:
m = 10.1251 90.8741 45.0291 66.3585 68.5009 99.5962 29.3304 57.987392.284 m * v = 326.961 502.149 422.157
六、陣列
1.概念:
Array是一個類模板,採用與Matrix相同的模板引數
Array <typename Scalar,int RowsAtCompileTime,int ColsAtCompileTime>
我們採用的形式是ArrayNt形式的typedef代表一維陣列,其中N和t是大小和標量型別。對於二維陣列,我們使用ArrayNNt形式的typedef。
下表顯示了一些示例:
Array<float,Dynamic,1>ArrayXf Array<float,3,1>Array3f Array<double,Dynamic,Dynamic>ArrayXXd Array<double,3,3>Array33d
2.訪問Array中的值
括號運算子被過載以提供對陣列係數的寫和讀訪問,就像使用矩陣一樣。此外,<<操作符可用於初始化陣列(通過逗號初始化程式)或列印它們。
示例程式碼:
#include <iostream> #include <Eigen/Dense> using namespace Eigen; using namespace std; int main() { ArrayXXfm(2,2); // assign some values coefficient by coefficient m(0,0) = 1.0; m(0,1) = 2.0; m(1,0) = 3.0; m(1,1) = m(0,1) + m(1,0); // print values to standard output cout << m << endl << endl; // using the comma-initializer is also allowed m << 1.0,2.0, 3.0,4.0; // print values to standard output cout << m << endl; }
結果:
3.加減
新增和減去兩個陣列與矩陣相同。如果兩個陣列具有相同的大小,則該操作有效,並且以係數方式進行加法或減法。
陣列還支援表單的表示式,該表示式為陣列中的array + scalar每個係數新增標量。這提供了一種不能直接用於Matrix物件的功能。
示例程式碼:
#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; // Adding two arrays cout << "a + b = " << endl << a + b << endl << endl; // Subtracting a scalar from an array cout << "a - 2 = " << endl << a - 2 << endl; }
結果:
a + b = 246 579 8 10 12 a - 2 = -101 234 567
4.陣列乘法
首先,當然你可以用一個標量乘以一個數組,這與矩陣的工作方式相同。陣列與矩陣根本不同的是,當你將兩個陣列相乘時。矩陣將乘法解釋為矩陣乘積,並且陣列將乘法解釋為係數乘積。因此,當且僅當它們具有相同的尺寸時,兩個陣列可以相乘。
示例程式碼:
#include <iostream> #include <Eigen/Dense> 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 << "a * b = " << endl << a * b << endl; }
結果:
a * b = 5 12 21 32
5.其他係數運算
例如,.abs()方法取每個係數的絕對值,而.sqrt()計算係數的平方根。如果你有兩個相同大小的陣列,你可以呼叫.min(.)來構造陣列,其係數是兩個給定陣列的相應係數的最小值。以下示例說明了這些操作。
示例程式碼:
#include <iostream> #include <Eigen/Dense> 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; }
結果:
a = -1.99499 0.254341 -1.22678 1.23496 0.340037 a.abs() = 1.99499 0.254341 1.22678 1.23496 0.340037 a.abs().sqrt() = 1.41244 0.504323 1.1076 1.11129 0.583127 a.min(a.abs().sqrt()) = -1.99499 0.254341 -1.22678 1.11129 0.340037
七、在陣列和矩陣表示式之間轉換
什麼時候應該使用Matrix類的物件?何時應該使用Array類的物件?您不能對陣列應用Matrix運算,也不能對矩陣應用Array運算。因此,如果你需要進行矩陣乘法等線性代數運算,那麼你應該使用矩陣; 如果你需要進行係數運算,那麼你應該使用陣列。但是,有時它並不那麼簡單,但您需要同時使用Matrix和Array操作。在這種情況下,您需要將矩陣轉換為陣列或反向轉換。無論選擇將物件宣告為陣列還是矩陣,都可以訪問所有操作。
矩陣表示式有一個.array()方法 ,可以將它們“轉換”為陣列表示式,因此可以輕鬆應用係數方法。相反,陣列表示式具有.matrix()方法 。與所有Eigen表示式抽象一樣,這沒有任何執行時成本(假設您讓編譯器進行優化)。即.array()和.matrix()可被用作右值和作為左值。
Eigen禁止在表示式中混合矩陣和陣列。例如,您無法直接新增矩陣和陣列; 該規則的例外是賦值運算子:允許將矩陣表示式賦給陣列變數,或者將陣列表示式賦給矩陣變數。
以下示例說明如何通過使用.array()方法對Matrix物件使用陣列操作
示例程式碼1:
#include <iostream> #include <Eigen/Dense> 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; 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; }
結果:
-- 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
類似地,如果array1和array2是陣列,那麼表示式array1.matrix() * array2.matrix()計算它們的矩陣乘積。
示例程式碼2:
#include <iostream> #include <Eigen/Dense> 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; result = (m.array() + 4).matrix() * m; cout << "-- Combination 1: --" << endl << result << endl << endl; result = (m.array() * n.array()).matrix() * m; cout << "-- Combination 2: --" << endl << result << endl << endl; }
結果:
-- Combination 1: -- 23 34 31 46 -- Combination 2: -- 4158 117 170
求矩陣的行列式
八、例項應用
1. 求矩陣的行列式
m.determinant()
注意:矩陣m要是double 型別,要不然報錯
下面是我寫的一個生成 32x32 位 01 可逆矩陣的類,這裡面我在生成32位矩陣的時候使用的是矩陣的拼接技術,但是這樣就會出現大量的陣列,並且不能用迴圈實現,很尷尬。
示例程式碼:
#include <iostream> #include <Eigen/Dense> #include <cstdlib> #include <ctime> #include <cmath> using namespace Eigen; using namespace std; typedef Matrix <double,32,32> Matrix32d; class cM32{ public: Matrix32d create(){//返回一個可逆的32x32 隨機 01 矩陣 Matrix32d m = createPT32(); if(check(m)) { cout << "可逆 " << "行列式為: " << m.determinant() << endl; return m; }else{ cout << "不可逆" << endl; create(); } } private: Matrix32d createPT32(){//建立一個隨機的32x32 的01矩陣 Matrix32d m5; Matrix2d* arrayM =new Matrix2d[256]; for(int i=0;i<256;i++){ arrayM[i] = create2(); } m5 << arrayM[0], arrayM[1], arrayM[2], arrayM[3], arrayM[4], arrayM[5], arrayM[6], arrayM[7], arrayM[8], arrayM[9], arrayM[10], arrayM[11], arrayM[12], arrayM[13], arrayM[14], arrayM[15], arrayM[16], arrayM[17], arrayM[18], arrayM[19], arrayM[20], arrayM[21], arrayM[22], arrayM[23], arrayM[24], arrayM[25], arrayM[26], arrayM[27], arrayM[28], arrayM[29], arrayM[30], arrayM[31], arrayM[32], arrayM[33], arrayM[34], arrayM[35], arrayM[36], arrayM[37], arrayM[38], arrayM[39], arrayM[40], arrayM[41], arrayM[42], arrayM[43], arrayM[44], arrayM[45], arrayM[46], arrayM[47], arrayM[48], arrayM[49], arrayM[50], arrayM[51], arrayM[52], arrayM[53], arrayM[54], arrayM[55], arrayM[56], arrayM[57], arrayM[58], arrayM[59], arrayM[60], arrayM[61], arrayM[62], arrayM[63], arrayM[64], arrayM[65], arrayM[66], arrayM[67], arrayM[68], arrayM[69], arrayM[70], arrayM[71], arrayM[72], arrayM[73], arrayM[74], arrayM[75], arrayM[76], arrayM[77], arrayM[78], arrayM[79], arrayM[80], arrayM[81], arrayM[82], arrayM[83], arrayM[84], arrayM[85], arrayM[86], arrayM[87], arrayM[88], arrayM[89], arrayM[90], arrayM[91], arrayM[92], arrayM[93], arrayM[94], arrayM[95], arrayM[96], arrayM[97], arrayM[98], arrayM[99], arrayM[100], arrayM[101], arrayM[102], arrayM[103], arrayM[104], arrayM[105], arrayM[106], arrayM[107], arrayM[108], arrayM[109], arrayM[110], arrayM[111], arrayM[112], arrayM[113], arrayM[114], arrayM[115], arrayM[116], arrayM[117], arrayM[118], arrayM[119], arrayM[120], arrayM[121], arrayM[122], arrayM[123], arrayM[124], arrayM[125], arrayM[126], arrayM[127], arrayM[128], arrayM[129], arrayM[130], arrayM[131], arrayM[132], arrayM[133], arrayM[134], arrayM[135], arrayM[136], arrayM[137], arrayM[138], arrayM[139], arrayM[140], arrayM[141], arrayM[142], arrayM[143], arrayM[144], arrayM[145], arrayM[146], arrayM[147], arrayM[148], arrayM[149], arrayM[150], arrayM[151], arrayM[152], arrayM[153], arrayM[154], arrayM[155], arrayM[156], arrayM[157], arrayM[158], arrayM[159], arrayM[160], arrayM[161], arrayM[162], arrayM[163], arrayM[164], arrayM[165], arrayM[166], arrayM[167], arrayM[168], arrayM[169], arrayM[170], arrayM[171], arrayM[172], arrayM[173], arrayM[174], arrayM[175], arrayM[176], arrayM[177], arrayM[178], arrayM[179], arrayM[180], arrayM[181], arrayM[182], arrayM[183], arrayM[184], arrayM[185], arrayM[186], arrayM[187], arrayM[188], arrayM[189], arrayM[190], arrayM[191], arrayM[192], arrayM[193], arrayM[194], arrayM[195], arrayM[196], arrayM[197], arrayM[198], arrayM[199], arrayM[200], arrayM[201], arrayM[202], arrayM[203], arrayM[204], arrayM[205], arrayM[206], arrayM[207], arrayM[208], arrayM[209], arrayM[210], arrayM[211], arrayM[212], arrayM[213], arrayM[214], arrayM[215], arrayM[216], arrayM[217], arrayM[218], arrayM[219], arrayM[220], arrayM[221], arrayM[222], arrayM[223], arrayM[224], arrayM[225], arrayM[226], arrayM[227], arrayM[228], arrayM[229], arrayM[230], arrayM[231], arrayM[232], arrayM[233], arrayM[234], arrayM[235], arrayM[236], arrayM[237], arrayM[238], arrayM[239], arrayM[240], arrayM[241], arrayM[242], arrayM[243], arrayM[244], arrayM[245], arrayM[246], arrayM[247], arrayM[248], arrayM[249], arrayM[250], arrayM[251], arrayM[252], arrayM[253], arrayM[254], arrayM[255]; return m5; } Matrix2d create2(){//建立 2x2 的01隨機矩陣 Matrix2d m1; m1(0,0) = rand()%2; m1(1,0) = rand()%2; m1(0,1) = rand()%2; m1(1,1) = rand()%2; return m1; } int check(Matrix32d m){//檢查是不是可逆的 if(fabs(m.determinant())){ return 1; }else{ return 0; } } }; int main(){ srand((unsigned int)time(NULL)); cM32 *m = new cM32; for(int i=0;i<1000;i++){ m->create(); } }