稀疏矩陣理論與實踐


稀疏矩陣理論與實踐

1.稀疏矩陣的優化

l  多線程。使用openmp或者mpi

l  numanode awareness 特性。把稀疏矩陣的存儲均勻地分配到兩顆處理器各自的本地內存中,最大程度的利用內存帶寬

l  利用硬件cache特性,對矩陣進行分塊或矩陣的循環進行限制

l  利用pipeline,多流水線並行處理

l  自適應分塊存儲結構。由於稀疏矩陣的非零元分布不一定均勻,有的分塊會非常稀疏,有的則會相對稠密。對於極稀疏的分塊(非零元數量遠小於行數),如果用和CSR相似的壓縮行存儲策略,則會浪費空間,所以用COO的方式反而更能節省存儲空間,提高訪問效率。

2. 矩陣(稀疏矩陣)壓縮存儲(3種方式)

數據結構中,提供針對某些特殊矩陣的壓縮存儲結構。
這里所說的特殊矩陣,主要分為以下兩類:

  • 含有大量相同數據元素的矩陣,比如對稱矩陣;
  • 含有大量 0 元素的矩陣,比如稀疏矩陣、上(下)三角矩陣;
    針對以上兩類矩陣,數據結構的壓縮存儲思想是:矩陣中的相同數據元素(包括元素 0)只存儲一個。
    對稱矩陣

 

 1 對稱矩陣示意圖

圖 1 的矩陣中,數據元素沿主對角線對應相等,這類矩陣稱為對稱矩陣。

矩陣中有兩條對角線,其中圖 1 中的對角線稱為主對角線,另一條從左下角到右上角的對角線為副對角線。對稱矩陣指的是各數據元素沿主對角線對稱的矩陣。

結合數據結構壓縮存儲的思想,可以使用一維數組存儲對稱矩陣。由於矩陣中沿對角線兩側的數據相等,因此數組中只需存儲對角線一側(包含對角線)的數據即可。
對稱矩陣的實現過程是,若存儲下三角中的元素,只需將各元素所在的行標 i 和列標 j 代入下面的公式:

 

 

 存儲上三角的元素要將各元素的行標 i 和列標 j 代入另一個公式:

 

 

 最終求得的 k 值即為該元素存儲到數組中的位置(矩陣中元素的行標和列標都從 1 開始)。

例如,在數組 skr[6] 中存儲圖 1 中的對稱矩陣,則矩陣的壓縮存儲狀態如圖 3 所示(存儲上三角和下三角的結果相同):

 

 

 圖 3 對稱矩陣的壓縮存儲示意圖

注意,以上兩個公式既是用來存儲矩陣中元素的,也用來從數組中提取矩陣相應位置的元素。例如,如果想從圖 3 中的數組提取矩陣中位於 (3,1) 處的元素,由於該元素位於下三角,需用下三角公式獲取元素在數組中的位置,即:

 

 

 結合圖 3,數組下標為 3 的位置存儲的是元素 3,與圖 1 對應。

上(下)三角矩陣

 

 

 圖 4 上(下)三角矩陣


如圖 4 所示,主對角線下的數據元素全部相同的矩陣為上三角矩陣(圖 4a)),主對角線上元素全部相同的矩陣為下三角矩陣(圖 4b))。

對於這類特殊的矩陣,壓縮存儲的方式是:上(下)三角矩陣采用對稱矩陣的方式存儲上(下)三角的數據(元素 0 不用存儲)。

例如,壓縮存儲圖 4a) 中的上三角矩陣,矩陣最終的存儲狀態同圖 3 相同。因此可以得出這樣一個結論,上(下)三角矩陣存儲元素和提取元素的過程和對稱矩陣相同。

稀疏矩陣

 

 

 圖 5 稀疏矩陣示意圖


如圖 5 所示,如果矩陣中分布有大量的元素 0,即非 0 元素非常少,這類矩陣稱為稀疏矩陣。

壓縮存儲稀疏矩陣的方法是:只存儲矩陣中的非 0 元素,與前面的存儲方法不同,稀疏矩陣非 0 元素的存儲需同時存儲該元素所在矩陣中的行標和列標。

例如,存儲圖 5 中的稀疏矩陣,需存儲以下信息:

  • (1,1,1):數據元素為 1,在矩陣中的位置為 (1,1);
  • (3,3,1):數據元素為 3,在矩陣中的位置為 (3,1);
  • (5,2,3):數據元素為 5,在矩陣中的位置為 (2,3);
  • 除此之外,還要存儲矩陣的行數 3 和列數 3;
    由此,可以成功存儲一個稀疏矩陣。

注意,以上 3 種特殊矩陣的壓縮存儲,除了將數據元素存儲起來,還要存儲矩陣的行數值和列數值,具體的實現方式后續會介紹 3 種,本節僅需了解矩陣壓縮存儲的原理。

3. 矩陣壓縮存儲的 3 種方式

對於以上 3 種特殊的矩陣,對陣矩陣和上下三角矩陣的實現方法是相同的,且實現過程比較容易,僅需套用上面給出的公式即可。

稀疏矩陣的壓縮存儲,數據結構提供有 3 種具體實現方式:

三元組順序表

行邏輯鏈接的順序表

十字鏈表

在Python中稀疏矩陣

SciPy提供了使用多種數據結構創建稀疏矩陣的工具,以及將稠密矩陣轉換為稀疏矩陣的工具。

許多在NumPy陣列上運行的線性代數NumPy和SciPy函數可以透明地操作SciPy稀疏數組。此外,使用NumPy數據結構的機器學習庫也可以在SciPy稀疏數組上透明地進行操作,例如用於一般機器學習的scikit-learn和用於深度學習的Keras。

存儲在NumPy數組中的稠密矩陣可以通過調用csr_matrix()函數將其轉換為一個稀疏矩陣。

在下面的例子中,我們將一個3×6的稀疏矩陣定義為一個稠密數組,將它轉換為CSR稀疏表示,然后通過調用todense()函數將它轉換回一個稠密數組。

運行該示例首先打印已定義的稠密數組,接着是CSR表示,然后是重新構建的稠密矩陣。

 

NumPy並沒有提供一個函數來計算矩陣的稀疏性。

 

不過,我們可以很容易地計算出矩陣的密度,然后從一個矩陣中減去它。NumPy數組中的非零元素可以由count_nonzero()函數給出,數組中元素的總數可以由數組的大小屬性給出。因此,數組的稀疏性可以被計算為:

下面的例子演示了如何計算數組的稀疏性。

 

運行這個例子首先打印出定義的稀疏矩陣,接着是矩陣的稀疏性。

 

[[1 0 0 1 0 0]
 [0 0 2 0 0 1]
 [0 0 0 2 0 0]]
 
0.7222222222222222

 

 

參考鏈接:

https://zhuanlan.zhihu.com/p/34534763

http://data.biancheng.net/view/183.html

https://blog.csdn.net/yhb1047818384/article/details/78996906

 

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM