- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我需要一种有效的方法来在 python 中反转 7000x7000 空气动力影响系数(密集)矩阵。在使用 FORTRAN 例程之前,我已经开始使用 LAPACK 中的 LU 分解例程来处理问题,我已经看到它在其他相关应用程序中的使用非常有效。不过,我读到,NumPy 和 SciPy 线性系统求解器大多基于直接调用 C 中相同的 LAPACK/BLAS 函数,并且想知道切换到 FORTRAN 是否真的会将计算时间减少到足以证明放弃的水平一种更简单、更高级的语言。
如果有 Python 求解器可以保证该大小(1000 到 10000,方形)的矩阵具有相似的性能,它们是哪些?
我确实需要矩阵逆,因此切换到迭代 Ax=b 解决方案不是一个选择。
最佳答案
事实上,Numpy 和 Scipy 有效地调用 LAPACK 例程来执行 numpy.linalg.inv
和 scipy.linalg.inv
.
要逆一般矩阵, numpy.linalg.inv
解决A.x=np.eye((n,n))
。函数inv()来电 ainv = _umath_linalg.inv(a, signature=signature, extobj=extobj)
,其中 calls call_@lapack_func@(¶ms);
哪里params.B
是单位矩阵并且 @lapack_func@
是 sgesv, dgesv, cgesv, zgesv
之一,它们是一般矩阵的线性求解器。
另一方面,scipy.linalg.inv
calls getri
,定义为get_lapack_funcs(('getri'),(a1,))
。它对应于 DGETRI()
lapack 的函数,旨在使用 DGETRF()
计算的 LU 分解来计算矩阵的逆。 因此,如果您使用 DGETRI()
在 Fortran 中,利用 scipy.linalg.inv()
在 python 中可能会实现类似的性能和结果。
大多数 Lapack 函数都可以使用 scipy.linalg.lapack
调用。这是一个使用 scipy.linalg.cython_lapack.dgetri()
的示例在 cython 模块中:How to compile C extension for Python where C function uses LAPACK library?下面是一个示例代码,在 1000x1000 矩阵上比较 scipy.linalg.cython_lapack.dgetrf()+scipy.linalg.cython_lapack.dgetri() 、 numpy 和 scipy.linalg.inv() :
import numpy as np
from scipy import linalg
import time
import myinverse
n=1000
A=np.random.rand(n,n)
start= time.time()
Am,info,string=myinverse.invert(A.copy())
end= time.time()
print 'DGETRF+DGETRI, ', end-start, ' seconds'
if info==0:
print 'residual ',np.linalg.norm(A.dot(Am)-np.identity(n), np.inf)
else :
print "inversion failed, info=",info, string
start= time.time()
Am=np.linalg.inv(A.copy())
end= time.time()
print 'np.linalg.inv ', end-start, ' seconds'
print 'residual ', np.linalg.norm(A.dot(Am)-np.identity(n), np.inf)
start= time.time()
Am=linalg.inv(A.copy())
end= time.time()
print 'scipy.linalg.inv ', end-start, ' seconds'
print 'residual ',np.linalg.norm(A.dot(Am)-np.identity(n), np.inf)
输出是:
DGETRF+DGETRI, 0.22541308403 seconds
residual 4.2155882951089296e-11
np.linalg.inv 0.29932808876 seconds
residual 4.371813154546711e-11
scipy.linalg.inv 0.298856973648 seconds
residual 9.110997546690758e-11
对于 2000x2000 矩阵:
DGETRF+DGETRI, 1.64830899239 seconds
residual 8.541625644634121e-10
np.linalg.inv 2.02795410156 seconds
residual 7.448244269611659e-10
scipy.linalg.inv 1.61937093735 seconds
residual 1.6453560233026243e-09
LAPACK inversion routine strangely mixes up all variables 中提供了链接 DGETRF()+DGETRI() 的 Fortran 代码。进行一些更改后,运行:
PROGRAM solvelinear
implicit none
REAL(8), dimension(1000,1000) :: A,Ainv,M,LU
REAL(8),allocatable :: work(:)
REAL(8) :: wwork
INTEGER :: info,lwork
INTEGER,dimension(1000) :: ipiv
INTEGER :: i,j
real :: start, finish
! put code to test here
info=0
!work=0
ipiv=0
call RANDOM_NUMBER(A)
call cpu_time(start)
!-- LU factorisation
LU = A
CALL DGETRF(1000,1000,LU,1000,ipiv,info)
!-- Inversion of matrix A using the LU
Ainv=LU
lwork=-1
CALL DGETRI(1000,Ainv,1000,Ipiv,wwork,lwork,info)
lwork =INT( wwork+0.1)
allocate(work(lwork))
CALL DGETRI(1000,Ainv,1000,Ipiv,work,lwork,info)
deallocate(work)
call cpu_time(finish)
print '("Time = ",f6.3," seconds.")',finish-start
!-- computation of A^-1 * A to check the inverse
M = matmul(Ainv,A)
print*,"M = "
do i=1,3
do j=1,3
print*,M(i,j)
enddo
end do
END PROGRAM solvelinear
使用 gfortran main2.f90 -o main2 -llapack -lblas -lm -Wall
编译后,1000x1000矩阵需要0.42s,2000x2000矩阵需要3s。
最后,如果 Fortran 代码和 Python 代码未链接到相同的 Blas/Lapack 库,则可能会出现不同的性能。要调查此问题,请键入类似 np.__config__.show()
的命令。如Link ATLAS/MKL to an installed Numpy所示或 How to check BLAS/LAPACK linkage in NumPy and SciPy? 中报告的命令.
为了进一步利用分布式计算,petsc不鼓励对完整矩阵求逆,因为很少需要这样做。还写道MatMatSolve(A,B,X)
,其中B
和X
可以使用稠密矩阵来做到这一点。此外,Python接口(interface)petsc4py中提供了这个功能。作为方法matSolve(self, Mat B, Mat X)
对于对象 petsc4py.PETSc.Mat
。不再维护 Elemental library被列为实现密集矩阵的直接求解器。虽然 Elemental 库支持 python 接口(interface),但它的分支 Hydrogen 不再支持它。尽管如此,Elemental 页面还是列出了一些与分布式密集线性代数相关的开源项目。 ScaLapack 提供了例程 PDGETRI()
/ PZGETRI()
使用 LU 分解来反转分布式稠密矩阵。这可能会为更快的反转留下一些空间。
关于python - 使用 python 求解 7000x7000 线性系统时的最佳性能方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59460326/
问题故障解决记录 -- Java RMI Connection refused to host: x.x.x.x .... 在学习JavaRMI时,我遇到了以下情况 问题原因:可
我正在玩 Rank-N-type 并尝试输入 x x .但我发现这两个函数可以以相同的方式输入,这很不直观。 f :: (forall a b. a -> b) -> c f x = x x g ::
这个问题已经有答案了: How do you compare two version Strings in Java? (31 个回答) 已关闭 8 年前。 有谁知道如何在Java中比较两个版本字符串
这个问题已经有答案了: How do the post increment (i++) and pre increment (++i) operators work in Java? (14 个回答)
下面是带有 -n 和 -r 选项的 netstat 命令的输出,其中目标字段显示压缩地址 (127.1/16)。我想知道 netstat 命令是否有任何方法或选项可以显示整个目标 IP (127.1.
我知道要证明 : (¬ ∀ x, p x) → (∃ x, ¬ p x) 证明是: theorem : (¬ ∀ x, p x) → (∃ x, ¬ p x) := begin intro n
x * x 如何通过将其存储在“auto 变量”中来更改?我认为它应该仍然是相同的,并且我的测试表明类型、大小和值显然都是相同的。 但即使 x * x == (xx = x * x) 也是错误的。什么
假设,我们这样表达: someIQueryable.Where(x => x.SomeBoolProperty) someIQueryable.Where(x => !x.SomeBoolProper
我有一个字符串 1234X5678 我使用这个正则表达式来匹配模式 .X|..X|X. 我得到了 34X 问题是为什么我没有得到 4X 或 X5? 为什么正则表达式选择执行第二种模式? 最佳答案 这里
我的一个 friend 在面试时遇到了这个问题 找到使该函数返回真值的 x 值 function f(x) { return (x++ !== x) && (x++ === x); } 面试官
这个问题在这里已经有了答案: 10年前关闭。 Possible Duplicate: Isn't it easier to work with foo when it is represented b
我是 android 的新手,我一直在练习开发一个针对 2.2 版本的应用程序,我需要帮助了解如何将我的应用程序扩展到其他版本,即 1.x、2.3.x、3 .x 和 4.x.x,以及一些针对屏幕分辨率
为什么案例 1 给我们 :error: TypeError: x is undefined on line... //case 1 var x; x.push(x); console.log(x);
代码优先: # CASE 01 def test1(x): x += x print x l = [100] test1(l) print l CASE01 输出: [100, 100
我正在努力温习我的大计算。如果我有将所有项目移至 'i' 2 个空格右侧的函数,我有一个如下所示的公式: (n -1) + (n - 2) + (n - 3) ... (n - n) 第一次迭代我必须
给定 IP 字符串(如 x.x.x.x/x),我如何或将如何计算 IP 的范围最常见的情况可能是 198.162.1.1/24但可以是任何东西,因为法律允许的任何东西。 我要带198.162.1.1/
在我作为初学者努力编写干净的 Javascript 代码时,我最近阅读了 this article当我偶然发现这一段时,关于 JavaScript 中的命名空间: The code at the ve
我正在编写一个脚本,我希望避免污染 DOM 的其余部分,它将是一个用于收集一些基本访问者分析数据的第 3 方脚本。 我通常使用以下内容创建一个伪“命名空间”: var x = x || {}; 我正在
我尝试运行我的test_container_services.py套件,但遇到了以下问题: docker.errors.APIError:500服务器错误:内部服务器错误(“ b'{” message
是否存在这两个 if 语句会产生不同结果的情况? if(x as X != null) { // Do something } if(x is X) { // Do something } 编
我是一名优秀的程序员,十分优秀!