我有一个中等大的Ax = b
问题,我想解决。矩阵A是600x600
。
我的代码解决了这个问题,但需要很长时间才能完成。
因此,我尝试检查(使用System.currentTimeMillis()
)以查看代码放慢的位置。
事实证明,在计算A期间,我执行命令A = L1 * A0 * L1.transpose()
。该过程几乎占用了该行总时间的100%。
奇怪的是,L1是600x600
单位矩阵(即A[i,j] = 1
,i == j
和0
,否则)。所以,这一行不应该花那么长的时间来执行。在这个问题中也应该很容易绕过
但是,如果我试图通过将其注释掉并用A = A0
替换它来绕过该行,则会发生更奇怪的事情。然后代码占用太长时间(在我杀死它的原始时间的10倍之后)执行。此外,CPU使用率达到100%。
我检查过,结果A
和L1 * A0 * L1.transpose()
相同。
总结一下,使用我的Java代码的一部分(我使用库ojalgo来处理矩阵):
// PrimitiveMatrix A0, L1, b are already calculated.
long startTime = System.currentTimeMillis();
System.out.println((System.currentTimeMillis() - startTime0) / 1000.0); // this prints about 2 seconds, concerning calculations of A0, L1, b.
PrimitiveMatrix A = L1.multiply(A0).multiply((L1).transpose());
System.out.println((System.currentTimeMillis() - startTime0) / 1000.0); // this prints about 67 seconds
// PrimitiveMatrix A = A0; // if this is NOT a comment, then the code has not run after (10+)x my "normal" time
final PrimitiveMatrix x = (A.invert()).multiply(b);
System.out.println((System.currentTimeMillis() - startTime0) / 1000.0); // this prints about 69 seconds
// I checked that
// A0.equals(L1.multiply(A0).multiply((L1).transpose())
// returns true
整个过程大约需要69秒,其中65个是在一个简单的计算中消耗的,我没有绕过。对于较小的矩阵(60x60),过去已成功运行相同的程序。
我不确定如何继续我的调试尝试。任何帮助将不胜感激。
似乎问题比我原先估计的要深一点。我试图打印这些矩阵以便上传它们,但随后出现了另一个问题。我发现第一次运行System.out.println(A0.get(aRow,aColumn));
时我的代码崩溃了。 A0
是通过向尺寸为600x600
的零矩阵的每个位置添加double类型的数字而创建的。此外,还会显示以下消息:
Exception in thread "main" java.lang.StackOverflowError
at org.ojalgo.matrix.store.SuperimposedStore.get(SuperimposedStore.java:84)
at org.ojalgo.matrix.store.SuperimposedStore.get(SuperimposedStore.java:84)
at org.ojalgo.matrix.store.SuperimposedStore.get(SuperimposedStore.java:84)
...
同样,我想强调,当这些矩阵为60x60
时,相同的过程会正常运行。
答案 0 :(得分:2)
我假设您正在使用BasicMatrix#add(int,int,Number)
您是否将该方法称为600x600次以构建矩阵?你不应该这样做!
在较新版本的ojAlgo中,该方法已被删除,因为它经常被误解/误用。
您应该阅读:https://github.com/optimatika/ojAlgo/wiki/Getting-Started