加快SymPy中符号行列式的计算 [英] Speeding up computation of symbolic determinant in SymPy

查看:615
本文介绍了加快SymPy中符号行列式的计算的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个4x4矩阵A,在每个条目中都有相当长但很简单的符号表达式.涉及大约30个不同的符号. 简单"是指仅使用加/减,乘/除和整数幂来组合这些符号. 长"是指如果我打印出矩阵,它将覆盖三到四个屏幕.

I have a 4x4 matrix A with rather long but simple symbolic expressions in each of its entries. About 30 different symbols are involved. By "simple" I mean that these symbols are combined using only addition/subtraction, multiplication/division, and integer powers. By "long" I mean that if I print out the matrix, it covers three or four screens worth.

我需要这个矩阵的行列式.或者,更具体地说,我知道行列式是一个特定符号中的四阶多项式,并且我需要该多项式的系数. A.det()在运行数小时后不会终止,因此我需要一种不同的方法.有任何想法吗?到目前为止,我已经尝试在A的每个元素上抛出各种simplify函数,但均未成功.

I need the determinant of this matrix. Or, to be more specific, I know that the determinant is a fourth-order polynomial in one particular symbol, and I need the coefficients of this polynomial. A.det() does not terminate after hours and hours of running, so I need a different approach. Any ideas? So far I've tried to throw various simplify functions at each element of A without any success.

是否可以使用一些策略让SymPy知道表达式的简单结构,或者我知道结果是其中一个符号的多项式?

Is there some strategy I can employ to let SymPy be aware of the simple structure of my expressions, or that I know that the result is a polynomial in one of the symbols?

推荐答案

也许可以为4x4行列式创建通用表达式

Maybe it would work to create the general expression for a 4x4 determinant

In [30]: A = Matrix(4, 4, symbols('A:4:4'))

In [31]: A
Out[31]:
⎡A₀₀  A₀₁  A₀₂  A₀₃⎤
⎢                  ⎥
⎢A₁₀  A₁₁  A₁₂  A₁₃⎥
⎢                  ⎥
⎢A₂₀  A₂₁  A₂₂  A₂₃⎥
⎢                  ⎥
⎣A₃₀  A₃₁  A₃₂  A₃₃⎦

In [32]: A.det()
Out[32]:
A₀₀⋅A₁₁⋅A₂₂⋅A₃₃ - A₀₀⋅A₁₁⋅A₂₃⋅A₃₂ - A₀₀⋅A₁₂⋅A₂₁⋅A₃₃ + A₀₀⋅A₁₂⋅A₂₃⋅A₃₁ + A₀₀⋅A₁₃⋅A₂₁⋅A₃₂ - A₀₀⋅A₁₃⋅A₂₂⋅A₃₁ - A₀₁⋅A₁₀⋅A₂₂⋅A₃₃ + A₀₁⋅A₁₀⋅A₂₃⋅A₃₂ + A₀₁⋅A₁₂⋅A₂₀⋅
A₃₃ - A₀₁⋅A₁₂⋅A₂₃⋅A₃₀ - A₀₁⋅A₁₃⋅A₂₀⋅A₃₂ + A₀₁⋅A₁₃⋅A₂₂⋅A₃₀ + A₀₂⋅A₁₀⋅A₂₁⋅A₃₃ - A₀₂⋅A₁₀⋅A₂₃⋅A₃₁ - A₀₂⋅A₁₁⋅A₂₀⋅A₃₃ + A₀₂⋅A₁₁⋅A₂₃⋅A₃₀ + A₀₂⋅A₁₃⋅A₂₀⋅A₃₁ - A₀₂⋅A₁
₃⋅A₂₁⋅A₃₀ - A₀₃⋅A₁₀⋅A₂₁⋅A₃₂ + A₀₃⋅A₁₀⋅A₂₂⋅A₃₁ + A₀₃⋅A₁₁⋅A₂₀⋅A₃₂ - A₀₃⋅A₁₁⋅A₂₂⋅A₃₀ - A₀₃⋅A₁₂⋅A₂₀⋅A₃₁ + A₀₃⋅A₁₂⋅A₂₁⋅A₃₀

,然后用类似的内容代替条目

and then substitute in the entries with something like

A.det().subs(zip(list(A), list(your_matrix)))

SymPy生成4x4行列式的速度很慢,但这是一个错误.您应在 https://github.com/sympy/sympy/issues/new.

SymPy being slow to generate a 4x4 determinant is a bug, though. You should report it at https://github.com/sympy/sympy/issues/new.

编辑(这不适合评论)

Matrix.det似乎正在调用简化函数.对于3x3或更小的矩阵,行列式公式已明确写出,但对于较大的矩阵,使用Bareis算法进行计算.您可以看到简化函数(cancel)在哪里被称为此处,这是计算的一部分,这是必需的,但最终却做了很多工作,因为它试图简化非常大的表达式.仅执行取消行列式本身的项所需的简化可能会更明智.为此,我打开了一个问题.

It looks like Matrix.det is calling a simplification function. For matrices 3x3 and smaller, the determinant formula is written out explicitly, but for larger matrices, it is computed using the Bareis algorithm. You can see where the simplification function (cancel) is called here, which is necesssary as part of the computation, but end up doing a lot of work because it tries to simplify your very large expressions. It would probably be smarter to only do the simplifications that are needed to cancel terms of the determinant itself. I opened an issue for this.

另一种加快速度的可能性(我不确定是否可行)将是选择其他行列式算法.选项为Matrix.det(method=alg),其中alg"bareis"(默认值),"berkowitz""det_LU"之一.

Another possibility to speed this up, which I'm not sure will work or not, would be to select a different determinant algorithm. The options are Matrix.det(method=alg) where alg is one of "bareis" (the default), "berkowitz", or "det_LU".

这篇关于加快SymPy中符号行列式的计算的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆