在julia中有效地求解一个特殊的线性系统

在julia中有效地求解一个特殊的线性系统,julia,linear-algebra,numerical-methods,Julia,Linear Algebra,Numerical Methods,我广泛使用julia的线性方程求解器res=X\b。由于参数的变化,我不得不在我的程序中使用它数百万次。这工作正常,因为我使用的是小尺寸(最多为30)。现在我想分析更大的系统,到1000,线性解算器不再有效 我认为这是一个可行的办法。但是我必须说,有时候我的X矩阵是稠密的,有时候是稀疏的,所以我需要对这两种情况都适用的东西 b向量是一个全零的向量,除了一个条目总是1(实际上它总是最后一个条目)。此外,我不需要所有的res向量,只需要它的第一个条目。通常当人们谈论加速线性解算器res=X\b时,它

我广泛使用julia的线性方程求解器
res=X\b
。由于参数的变化,我不得不在我的程序中使用它数百万次。这工作正常,因为我使用的是小尺寸(最多为
30
)。现在我想分析更大的系统,到
1000
,线性解算器不再有效

我认为这是一个可行的办法。但是我必须说,有时候我的X矩阵是稠密的,有时候是稀疏的,所以我需要对这两种情况都适用的东西


b
向量是一个全零的向量,除了一个条目总是
1
(实际上它总是最后一个条目)。此外,我不需要所有的
res
向量,只需要它的第一个条目。

通常当人们谈论加速线性解算器
res=X\b
时,它适用于多个
b
s。但是由于您的
b
没有改变,而您只是不断地改变
X
,因此这些技巧都不适用

从数学角度来看,加快速度的唯一方法似乎是确保Julia为
X\b
选择最快的解算器,也就是说,如果您知道
X
是正定的,请使用Cholesky等,了解它如何选择解算器用于
X\b
,用于密集和稀疏
X
,很可能Julia也实现了一些类似于这些流程图的东西,但同样,也许您可以找到一些方法来简化或简化它


所有与编程相关的加速(多线程虽然每个单独的解算器可能已经是多线程的,但当每个解算器使用的线程少于内核时,并行运行多个解算器可能是值得的;如果您愿意深入了解解算器本身;OpenCL/CUDA库等)然后可以应用。

如果问题的形式为
(A-µI)x=b
,其中
µ
是一个可变参数,
A
b
是固定的,则可以使用对角化

A=PDP°
其中
表示
p
的倒数。然后可以将
(PDP°-µI)x=b
转换为

(D - µI)P°x = P°b, 
P°x = P°b / (D - µI), 
x = P(P°b / (D - µI)).
/
操作表示各个向量元素被标量所除
Dr-µ

A
对角化后,计算任何
µ
的解将减少为两个矩阵/向量积,或者如果还可以预计算
p°b
,则计算一个矩阵/向量积


数值不稳定性将出现在
A

的特征值附近,提高效率的最佳方法是使用:JuliaMath/IterativeSolvers.jl。对于
A*x=b
问题,我建议
x=lsmr(A,b)

第二个最好的替代方法是向编译器提供更多的信息:如果Cholesky分解对您有效,则执行
x=inv(a'a)*a'*b
,而不是
x=inv(cholfact(a'a))a'*b
。否则,您可以尝试
U,S,Vt=svd(A)
x=Vt'*diagm(sqrt.(S))*U'*b


不确定是否优化了
x=pinv(A)*b
,但可能比
x=A\b

效率略高这可能不是您想要的,但我已经非常迷恋GPU的功能。如果你能使用这些硬件,它可能对你的情况非常有用。你必须解决它数百万次。保存LU因子分解怎么样?如果您不在每次迭代中更改X,这将起作用。只需执行
X=lufact(X)
,然后
X\b
应该会更快。但是如果你改变了
b
(这在很多PDE解算器中都会发生)。也许它会起作用,但是
X
确实会改变。它以
X=X*eye(N,N)-T
的形式编写,其中
T
是一个固定矩阵。x是一个参数,我必须求解系统
res=x\b
。减去与单位矩阵成比例的某个参数会以很难预测的方式改变因子分解,因此我认为因子分解在这里没有帮助。如果任何人有一个数学技巧来加快这个问题(使用
x*eye(N,N)-T的因式分解来获得一个不同
x
的因式分解)。有人可能会有一篇研究文章,因为这可能与进行相关的特征值计算有多大关系,但我认为做好这项工作在数学上比预期的要困难。如果GPU是一个选项,你可能会想尝试和,这是一次解决一批小型线性系统的优化方法。正如预期的那样,我关上数学加速门是错误的!看见