我欢迎对以下代码优化问题提供任何帮助:
我有一个 N 个大小相同的稀疏矩阵 ([s1 s2]
) 的集合,存储在元胞数组 A
和存储在向量w
中的相应数量的标量权重。我想计算 A
中所有矩阵的总和,并按 w
中存储的值加权。通过我的程序的迭代,只有 w
中的值发生变化。因此,我可以先验地计算结果中非零元素的数量,并使用 spalloc
为其预先分配一些内存。
目前我有这样的想法:
result = spalloc(s1,s1,number_of_non_zero);
for i=1:N
result = result + w(i)*A{i};
end
我真的需要优化这部分,目前它占用了我程序中的大部分计算时间(使用分析工具检查)。
一些附加信息:
-上述代码运行了数百万次,因此即使是很小的改进也是受欢迎的。
-A
中的矩阵来自有限元代码(一维或二维)
-如果我可以节省一些时间(例如使用cell2mat(A)),我可以毫无问题地离开单元结构。
感谢您提供有关如何加快这部分代码速度的任何提示。
一个。
I welcome any help for the following code optimization problem:
I have a collection of N sparse matrices of identical sizes ([s1 s2]
) stored in a cell array A
and a corresponding number of scalar weights stored in an vector w
. I want to compute the sum of all the matrices in A
weighted by the values stored in w
. Through the iterations of my program, only the values in w
change. I can therefore compute a priori the number of non-zero elements in my result and pre-allocate some memory for it using spalloc
.
For the moment I have something like:
result = spalloc(s1,s1,number_of_non_zero);
for i=1:N
result = result + w(i)*A{i};
end
I really need do optimize this part which for the moment takes most of the computing time in my program (checked with the profiling tools).
Some additional information:
-The above code runs millions of times so even minor improvements are welcome.
-The matrices in A
come from a finite element code (1D or 2D)
-I have no problem moving away from the cell structure if I can save some time (like using cell2mat(A)
)
Thank you for any hint on how to speed up this part of the code.
A.
发布评论
评论(2)
我不能肯定地说这个解决方案是否会更具计算效率,但它是其他可以尝试的东西......
如果你真的必须将你的矩阵表示为稀疏矩阵(即完整矩阵占用太多内存)并且 MATLAB 中的内置稀疏表示 无法提供您想要的性能,那么你可以尝试用不同的方式表示稀疏矩阵。具体来说,您可以将它们表示为 N×3 矩阵,其中前两列包含所有非零值的矩阵行索引和列索引,第三列包含非零值。您可以使用函数 FIND 将数据转换为这种形式,如下所示:
每次需要计算这些矩阵的加权和时,首先需要将这些值乘以权重:
然后,您可以使用函数 ACCUMARRAY:
在这种情况下,变量
result
将是一个完整的矩阵。如果您需要result
为稀疏矩阵,您可以在对 ACCUMARRAY 像这样:I can't say for sure if this solution will be more computationally-efficient, but it's something else to try...
If you really have to represent your matrices as sparse (i.e. full matrices take up too much memory) and the built-in sparse representation in MATLAB isn't giving you the performance you desire, then you can try representing the sparse matrices in a different way. Specifically, you can represent them as N-by-3 matrices where the first two columns contain the row and column indices into the matrix for all the non-zero values and the third column contains the non-zero values. You can convert your data to this form using the function FIND like so:
Each time you need to compute the weighted sum of these matrices, you first need to multiply the values by the weights:
Then, you can compute the final sum using the function ACCUMARRAY:
The variable
result
in this case will be a full matrix. If you needresult
to be a sparse matrix, you can add extra arguments in the call to ACCUMARRAY like so:如果将
A
转换为矩阵而不是元胞数组,那么您可以使用一些 RESHAPE 和 REPMAT杂技。假设我们有以下数据:重塑
w
以便您可以进行逐个元素的乘法,然后求和:If you convert
A
to a matrix instead of a cell array then you could vectorize the loop using some RESHAPE and REPMAT acrobatics. Pretend we have the following data:Reshape
w
so that you can do an element-by-element multiplication and then sum: