如何高效将SpMatrix转换为Matrix?寻求跳过中间步骤的方法
如何更简洁高效地将SpMatrix转换为Data.Matrix中的Matrix?
问题描述
我正在寻找一种更简洁或高效的方法,将Data.Sparse.SpMatrix中的SpMatrix转换为Data.Matrix中的Matrix。目前我通过内置函数实现的转换流程为:SpMatrix Double → [(IxRow, IxCol, Double)] → [Double] → Matrix Double,想了解是否可以跳过其中的某些中间步骤。
原实现代码
import Data.Sparse.Common import qualified Data.Matrix as M main :: IO () main = do let a = mkDiagonal 3 [1,2,3] :: SpMatrix Double b = toDenseListSM a c = map (\(_, _, x) -> x) b d = M.fromList 3 3 c print d
原输出
1.0 0.0 0.0 0.0 2.0 0.0 0.0 0.0 3.0
希望能够跳过步骤b和步骤c。
优化方案
可以直接利用Data.Sparse.Common提供的toDenseSM函数,跳过生成三元组列表和提取值的中间步骤,直接完成转换。
优化代码(方案一:用二维列表构造)
import Data.Sparse.Common import qualified Data.Matrix as M import Data.Vector (toList) main :: IO () main = do let a = mkDiagonal 3 [1,2,3] :: SpMatrix Double d = M.fromLists . map toList . toList $ toDenseSM a print d
优化代码(方案二:用扁平列表构造)
import Data.Sparse.Common import qualified Data.Matrix as M import Data.Vector (toList, concat) main :: IO () main = do let a = mkDiagonal 3 [1,2,3] :: SpMatrix Double d = M.fromList 3 3 . toList . concat $ toDenseSM a print d
说明
toDenseSM是Data.Sparse.Common的内置函数,会直接将稀疏矩阵转换为密集的二维Vector (Vector Double)结构,稀疏位置自动填充为0.0,一步完成稀疏到密集的转换。- 方案一使用
M.fromLists直接接收二维列表,逻辑更直观;方案二将二维Vector展平为一维列表后用M.fromList,和原实现的构造逻辑更接近,但都完全跳过了三元组列表的生成和值提取步骤。 - 这种方式不仅代码更简洁,效率也更高——
toDenseSM是针对稀疏矩阵优化的实现,比手动遍历三元组列表的性能更好。
内容的提问来源于stack exchange,提问作者Pompan
相关产品推荐
相关产品推荐

