我有一个m维向量的arraylist(存储为简单数组)v1, v2 ... vn.
我必须重复计算从这些向量中选择的两个向量之间的内积。
这样做的一种方法是在所有组件上进行简单的for循环。
double sum=0;
for(int i=0; i<m; i++)
sum+=v1[i]*v2[i];
这几乎是我打算对我的数据执行的唯一线性代数操作。
导入像JAMA或la4j这样的linalg库,将所有内容存储为矩阵,并计算内部产品会更有效吗? (这些甚至不是大型矩阵乘法,只是1D向量之间的内积)
la4j(等)如何实现点积?它是否也不会遍历每个索引并将每对组件相乘?
答案 0 :(得分:3)
la4j
是开放源代码,请查看the code。使用AbstractVector
的内部产品效率低于您自己的代码,因为它实例化了其他操作对象,这里是OoPlaceInnerProduct。
然而:在大多数情况下,我仍然更喜欢使用现有的,经过良好测试的矢量数学包而不是实现我自己的数学包。 (Knuth:“我们应该忘记效率低,大约97%的时间说:过早的优化是所有邪恶的根源。”
请注意multithreading doesn't help either。即使是效率很高的LAPACK
软件包也会使用same code。
答案 1 :(得分:1)
关于la4j libray:upcomming版本0.5.0使用轻量级稀疏迭代器,所以你不必担心在稀疏向量中迭代零值。这是API示例
Vector a = new BasicVector(...); // dense
Vector b = new CompressedVector(...); // sparse
double dot = a.innerProduct(b);
您可以组合任何可能的对:稀疏密集,稀疏稀疏,密集密集,密集稀疏。 la4j库将始终使用最有效的算法,具体取决于您的数据。
答案 2 :(得分:0)
如果你想计算所有内部产品,我推荐这个:在矩阵A中将你的向量存储在行中,在B中,将它们存储在cols中。然后在A * B中,您将获得v_i和v_j的内部产品(i,j)。
诀窍是正常的矩阵乘法需要n ^ 3次,但是一些聪明的算法有更高效的方法,但仅适用于~30和更多的向量。