2

我有一个 m 维向量的数组列表(存储为简单数组)v1, v2 ... vn.

我必须重复计算从这些向量中选择的两个向量之间的内积。

一种方法是在其所有组件上进行简单的 for 循环。

double sum=0;
for(int i=0; i<m; i++)
    sum+=v1[i]*v2[i];

这几乎是我打算对我的数据执行的唯一线性代数运算。

  1. 导入 JAMA 或 la4j 之类的 linalg 库,将所有内容存储为矩阵并计算内积会更有效吗?(这些甚至不是大矩阵乘法,只是一维向量之间的内积)

  2. la4j(etc) 如何实现点积?它不会也遍历每个索引并乘以每对组件吗?

4

3 回答 3

3

la4j是开源的,看看代码。使用AbstractVector的内积比您自己的代码效率低,因为它实例化了额外的操作对象,这里是OoPlaceInnerProduct

但是:在大多数情况下,我仍然更喜欢使用现有的、经过充分测试的矢量数学包,而不是实现我自己的包。(Knuth:“我们应该忘记小的效率,比如说大约 97% 的时间:过早的优化是万恶之源”。)

请注意,多线程也无济于事。即使是高效的LAPACK包也使用与您相同的代码

于 2014-05-27T09:46:56.100 回答
1

关于 la4j 库:即将发布的 0.5.0 版使用轻量级稀疏迭代器,因此您不必担心遍历稀疏向量中的零值。这是 API 示例

Vector a = new BasicVector(...); // dense
Vector b = new CompressedVector(...); // sparse
double dot = a.innerProduct(b);

您可以组合任何可能的对:sparse-dense、sparse-sparse、dense-dense、dense-sparse。la4j 库将始终根据您的数据使用最有效的算法。

于 2014-07-21T09:21:05.487 回答
0

如果你想计算所有内积,我建议:在矩阵 A 中将向量存储在行中,在 B 中,将它们存储在 cols 中。然后在 A*B 中,您将拥有 v_i 和 v_j 的位置 (i,j) 内积。

诀窍是普通矩阵乘法需要 n^3 时间,但一些聪明的算法有更有效的方法,但仅适用于 ~ 30 和更多的向量。

于 2014-05-27T10:10:39.357 回答