【发布时间】:2017-09-03 21:33:06
【问题描述】:
我正在尝试使用 MathNet 包从父矩阵中提取一个大型子矩阵。我找不到内置函数,所以我在 VB.net 中编写了这个简单的函数:
Private Function Extract(s As Matrix, RowsAndColumns As Int32()) As SparseMatrix
Dim Sadj = MathNet.Numerics.LinearAlgebra.Double.SparseMatrix.Build.Sparse(RowsAndColumns.Count, RowsAndColumns.Count)
For i = 0 To RowsAndColumns.Count - 1
For j = 0 To RowsAndColumns.Count - 1
Sadj(i, j) = s(RowsAndColumns (i), RowsAndColumns (j))
Next
Next
Return Sadj
End Function
但是,这个函数的性能非常慢,因为通常原始矩阵非常大,而子矩阵的大小接近它。所以我正在寻找优化这一点的可能方法。任何帮助将不胜感激。
作为背景知识,我正在尝试从大型稀疏矩阵中提取子矩阵,然后使用 CSparse 来求解大型方程组。
Dim Sred = Extract(S, FreeDOFs)
Dim storage = DirectCast(Sred.Storage, MathNet.Numerics.LinearAlgebra.Storage.SparseCompressedRowMatrixStorage(Of Double)) ' Get CSR storage.
Dim A = New CSparse.Double.SparseMatrix(Sred.ColumnCount, Sred.ColumnCount) With {.ColumnPointers = storage.RowPointers, .RowIndices = storage.ColumnIndices, .Values = storage.Values} ' Create CSparse matrix and Assign storage arrays.
For i = 0 To NumofLoadCases - 1
Dim Fred = Extract(NodeLoads.Item(ASP.AnalysisLoadCases.Keys(i)) - Pf.Item(ASP.AnalysisLoadCases.Keys(i)), FreeDOFs)
Dim Dred = Sred.LU().Solve(Fred)
Dvec.Add(ASP.AnalysisLoadCases.Keys(i), ReverseExtract(Dred, FreeDOFs, 6 * NumOfNodes))
Next
【问题讨论】:
-
在 MathNet 中闲逛了一下之后,这可能会起作用 ..
Sadj = s.submatrix(0, RowsAndColumns.Count - 1, 0, RowsAndColumns.Count - 1),不过,我对 MathNet 一无所知,我只是犯错了.. 在这里的文档中找到了它 - numerics.mathdotnet.com/api/… - 搜索页面中的子矩阵 -
大卫,感谢您的帮助。我需要提取大多数行和列,但不是全部。抱歉,我可能不是 100% 清楚。
-
不用担心——就像我说的。我对这一切都不是很熟悉 - 只是拍了一张 :-)
-
当你说大多数行和列时,你的意思是不是一个连续的块是一个子矩阵呢?
-
例如,假设原始矩阵称为 S,大小为 1000x1000。我想提取一个较小的子矩阵 Sred = S([1:600,610:700,800:950,999],[1:600,610:700,800:950,999])。事实上,矩阵要大得多,循环遍历它需要大量时间。