稀疏矩陣
C++ 矩陣操作
假設我們需要操作一個 N*M 的矩陣。為了簡單,我們使用 int 型別進行說明。在實際編碼中,肯定是需要使用 STL template。
矩陣的儲存
靜態儲存
const int MAXN=1e5; //定義矩陣最大行數
const int MAXM=1e5; //定義矩陣最大列數
int array[MAXN][MAXM]; //定義矩陣
使用指標
使用指標包括兩部分程式碼。一部分是記憶體申請,另外一部分是記憶體釋放。
記憶體申請
int **array;//指向指標的指標,表示一個二維陣列
array=new int *[n];//申請行
for (int i=0; i<n; i++) {
array[i]=new int[m];//申請列
}
記憶體釋放
for (int i=0; i<n; i++) {
delete[] array[i];//釋放列
}
delete[] array;//釋放行
使用 STL 的 vector
vector<vector<int> > array(m); //這個m一定不能少
空間複雜度
從上面的 C++ 程式碼,我們可以非常明顯的知道,矩陣的空間複雜度為 O(N*M),也就是 O(N^2)。
矩陣的遍歷
我們知道一個 N*M 的矩陣,如果使用最基礎的 C++ 程式實現,就是一個兩重迴圈的遍歷。程式碼如下
for (int i=0; i<n; i++) {
for (int j=0; j<m; j++) {
cout<<array[i][j];
}
}
時間複雜度
從上面的 C++ 程式碼,我們可以非常明顯的知道,矩陣的時間複雜度為 O(N*M),也就是 O(N^2)。
稀疏矩陣定義
在矩陣中,若數值為0的元素數目遠遠多於非0元素的數目,並且非0元素分佈沒有規律時,則稱該矩陣為稀疏矩陣。如下圖所示的 15*15 矩陣就是稀疏矩陣。
為什麼要研究稀疏矩陣
從上面的內容,我們可以看到,一個滿陣,它的時間複雜度和空間複雜度都是非常大的。尤其在數學研究的時候,維度 N 可能會趨向無窮大。
大型稀疏矩陣在計算科學以及工程應用中往往應用於求解 PDE(偏微分方程)。
因此,研究稀疏矩陣是數值計算,科學搬磚中必不可少的內容。其實這是一個造輪子的過程,只是為了加深對矩陣的理解。
稀疏矩陣儲存
由於稀疏矩陣的特性,我們不需要使用滿陣進行儲存。
Coordinate Format(COO)
COO 是一種座標形式的稀疏矩陣。採用三個陣列 row、col 和 data 儲存非零元素的資訊,這三個陣列的長度相同。row 陣列儲存元素的行,col 陣列儲存元素的列,data 陣列儲存元素的值。
儲存的主要優點是靈活、簡單,僅儲存非零元素以及每個非零元素的座標。但是 COO 不支援元素的存取和增刪,一旦建立之後,除了將之轉換成其它格式的矩陣,幾乎無法對其做任何操作和矩陣運算。
對應的 C++ 程式碼如下:
int row[] ={0, 0, 1, 1, 2, 2, 2, 3, 3};
int col[] ={0, 1, 1, 2, 0, 2, 3, 1, 3};
int data[]={1, 7, 2, 8, 5, 3, 9, 6, 4};
我們可以看到 COO 在儲存的列中有重複,還不是最節約的方式。
Compressed Sparse Row Format(CSR)
行壓縮,是按行儲存一個稀疏矩陣的方式。需要三類資料來表達:數值,列號,以及行偏移。CSR 不是三元組,而是整體的編碼方式。數值和列號與 COO 一致,表示一個元素以及其列號,行偏移表示某一行的第一個元素在 values 裡面的起始偏移位置。
如上圖中,第一行元素 1 是 0 偏移,第二行元素 2 是 2 偏移,第三行元素 5 是 4 偏移,第 4 行元素 6 是 7 偏移。在行偏移的最後補上矩陣總的元素個數,本例中是 9。
和 COO 相比,我們通過行壓縮,節約了儲存空間。
對應的 C++ 程式碼如下:
int row[] ={0, 2, 4, 7, 9};
int col[] ={0, 1, 1, 2, 0, 2, 3, 1, 3};
int data[]={1, 7, 2, 8, 5, 3, 9, 6, 4};
Compressed Sparse Column Format(CSC)
列壓縮,是按列儲存一個稀疏矩陣的方式。需要三類資料來表達:數值,行號,以及列偏移。CSC 不是三元組,而是整體的編碼方式。數值和行號與 COO 一致,表示一個元素以及其行號,列偏移表示某一列的第一個元素在 values 裡面的起始偏移位置。
如上圖中,第一列元素 1 是 0 偏移,第二列元素 7 是 2 偏移,第三列元素 8 是 5 偏移,第 4 列元素 9 是 7 偏移。在列偏移的最後補上矩陣總的元素個數,本例中是 9。
和 COO 相比,我們通過列壓縮,節約了儲存空間。
對應的 C++ 程式碼如下:
int row[] ={0, 0, 1, 1, 2, 2, 2, 3, 3};
int col[] ={0, 2, 5, 7, 9};
int data[]={1, 5, 7, 2, 6, 8, 3, 9, 4};
總結
COO、CSR 和 CSC 三種方法各有用途,我們使用 CSR 最多,因為在大部分科學計算中,基本都是執行 Ax=b 這個問題。
下一步工作
將稀疏矩陣儲存原理部分解釋完成後,下面將開始造輪子的過程。也就是自己寫一個稀疏矩陣的類,用於儲存。將來在這個基礎上,進一步擴充程式碼。逐步完成矩陣運算。
整個造輪子的過程,相關的程式碼都會儲存在 Github 中,https://github.com/zhouyium/SparseMatrix.git。
相關文章
- 稀疏矩陣轉置矩陣
- 【scipy 基礎】--稀疏矩陣矩陣
- CUDA版本稀疏矩陣向量乘矩陣
- OpenMP 版本稀疏矩陣向量乘矩陣
- 資料結構(一)-稀疏矩陣資料結構矩陣
- 資料結構:陣列,稀疏矩陣,矩陣的壓縮。應用:矩陣的轉置,矩陣相乘資料結構陣列矩陣
- 用三列二維陣列表示的稀疏矩陣類陣列矩陣
- MKL稀疏矩陣運算示例及函式封裝矩陣函式封裝
- 稀疏陣列陣列
- 讀取大型稀疏矩陣&KNN演算法的OpenCL加速版本矩陣KNN演算法
- 用十字連結串列表示的稀疏矩陣類矩陣
- 用三元組連結串列表示的稀疏矩陣類矩陣
- 稀疏矩陣之三元組壓縮儲存並且轉置矩陣
- 生成螺旋矩陣(方陣、矩陣)矩陣
- 稀疏陣列、佇列陣列佇列
- 20_稀疏陣列陣列
- 一種比較省記憶體的稀疏矩陣Python儲存方案記憶體矩陣Python
- 鄰接矩陣、度矩陣矩陣
- 巨大的矩陣(矩陣加速)矩陣
- 奇異矩陣,非奇異矩陣,偽逆矩陣矩陣
- golang實現稀疏陣列Golang陣列
- 矩陣矩陣
- 3D圖形:矩陣的行列式,矩陣的逆、正交矩陣、齊次矩陣3D矩陣
- 資料結構學習(C++)——稀疏矩陣(十字連結串列【2】) (轉)資料結構C++矩陣
- 資料結構學習(C++)——稀疏矩陣(十字連結串列【1】) (轉)資料結構C++矩陣
- 矩陣中最大的二維矩陣矩陣
- 求任意矩陣的伴隨矩陣矩陣
- 二維陣列和稀疏陣列互轉陣列
- java稀疏陣列是什麼Java陣列
- 機器學習中的矩陣向量求導(五) 矩陣對矩陣的求導機器學習矩陣求導
- 矩陣和陣列矩陣陣列
- 理解矩陣矩陣
- 矩陣相乘矩陣
- 矩陣分解矩陣
- Numpy 矩陣矩陣
- 穿越矩陣矩陣
- 混淆矩陣矩陣
- 魔方矩陣矩陣