Python 具有大矩阵的辛编译函数

Python 具有大矩阵的辛编译函数,python,c,cython,sympy,Python,C,Cython,Sympy,我一直在使用sympy处理微分方程组。我以符号的方式编写方程,使用autowrap通过cython编译它们,然后将结果函数传递给scipy ODE解算器。这样做的一个主要好处是,我可以使用sympyjacobian函数象征性地求解jacobian,编译它,并将它也编译到ODE解算器 这对于大约30个变量的系统来说非常有效。最近我试着用150个变量来做,结果是编译雅可比函数时内存不足。这是Windows上的AcANDA和微软Visual C++ 14的Python工具。基本上,在编译jacobia

我一直在使用
sympy
处理微分方程组。我以符号的方式编写方程,使用
autowrap
通过cython编译它们,然后将结果函数传递给scipy ODE解算器。这样做的一个主要好处是,我可以使用sympy
jacobian
函数象征性地求解jacobian,编译它,并将它也编译到ODE解算器

这对于大约30个变量的系统来说非常有效。最近我试着用150个变量来做,结果是编译雅可比函数时内存不足。这是Windows上的AcANDA和微软Visual C++ 14的Python工具。基本上,在编译jacobian(现在是22000个元素向量)的过程中,链接步骤中的内存使用量上升到了7GB左右(在我的8GB笔记本电脑上),最后崩溃了

在我去试一台内存更大的机器之前,有人有什么建议吗?其他操作系统或其他C编译器有可能改善这种情况吗

我知道很多人都做这类工作,所以如果有答案的话,对社区的大部分人都是有益的

编辑:对乔纳森的一些评论的回应:

是的,我完全知道这是一个N^2问题。雅可比矩阵是所有偏导数的矩阵,因此其大小为N^2。这种缩放没有真正的方法。然而,22000个元素的数组远没有达到在运行时产生内存问题的级别——我只在编译时遇到了这个问题

基本上,我们可以从三个层面解决这个问题

1) 在不使用雅可比矩阵的情况下解决ODE问题,或者以某种方式拆分雅可比矩阵,使其没有150x150矩阵。这将解决根本问题,但它肯定限制了我的能力,而且我还不相信编译雅可比函数是不可能的

2) 更改
sympy
自动生成C代码的方式,将其拆分为多个块,对中间表达式使用更多函数,以某种方式缩小.C文件。有着更多同情心经历的人可能对此有一些想法

3) 改变C语言的编译方式,减少所需的内存


我认为,通过发布一个更加面向#3()的单独问题,我会得到不同听众的回答。事实上,事情就是这样。也许#3的答案是“你做不到”,但这也是有用的信息。

根据在上发布的大量示例,我能够将其编译

关键是 1) 不要使用
autowrap
,而是直接编写C代码,并对其进行更多控制。除其他外,这允许将参数列表作为向量传递,而不是扩展它。这需要一些努力才能开始工作(通过distutils等设置编译器标志),但最终效果很好。以上述课程中的回购协议为例,帮助很大

2) 使用公共子表达式消除(
sympy.cse
)显著减小雅可比元素表达式的大小

(1) 在这种情况下,它本身并没有起到多大的帮助作用(尽管我能够使用它来大大提高较小型号的性能)。代码仍然是200MB,而不是原来的300MB。但将它与(2)相结合(
cse
)我能够将它降低到1.7MB(尽管有14000个临时变量)


cse
在我的笔记本电脑上大约需要20-30分钟。之后,它会很快编译。

我不得不附议这个问题,因为我也受到同样的限制;然而,对我来说,我得到的消息是“致命错误C1002:编译器在第2次过程中堆空间不足”,而不是直接的崩溃。不幸的是,在同事的机器上快速尝试ubuntu+gcc编译器并没有解决问题。如果没有其他帮助的话,可以通过在雅可比矩阵的几个子矩阵上使用“自动换行”来解决这个问题,并在python中定义一个函数来重新组合各个部分。这当然是一个解决办法,离理想还很远。是的,对不起,我使用了“崩溃”这个词,有点松散。我得到相同或相似的错误。注意下面的问题。当前已作为此的副本关闭。如果复制状态已更改,请将此注释标记为“不再需要”。如另一个问题中所述,您的问题似乎是缩放O(N²)。随着问题规模的增长,无论您拥有多少内存,您都会很快耗尽内存。您需要找到一种方法来避免解决方案代码的二次增长。