从Mathematica到Python

9 投票
3 回答
5970 浏览
提问于 2025-04-16 05:40

这段内容在问,怎么把这段Mathematica代码转换成Python代码?提问者对Mathematica的语法不太了解,所以在理解这段代码时遇到了困难,希望能用更传统的编程语言来描述。

mathematica code

来源(第5页): http://subjoin.net/misc/m496pres1.nb.pdf

3 个回答

3

你可以用 sympy 来进行符号计算。结合KennyTM的回答,下面这样的代码可能就是你想要的:

from __future__ import division
from sympy import Symbol, apart, binomial

x = Symbol('x')
poly = (1-x**20)**5 / ((1-x)**2 * (1-x**2) * (1-x**5) * (1-x**10))
poly2 = apart(poly,x)

def a(j):
    return poly2.coeff(x**j)

def f(n):
    v = n // 5
    q = v // 20
    r = v % 20
    return sum(binomial(q+5-j, 5)*a(r+20*j) for j in range(5))

不过我得承认,f(n) 这个函数不太好用(我对Python不太熟)。

5

根据之前答案中提到的解决方案,我发现 sympy 这个库在计算有理数的 apart() 时,似乎有点搞不清楚状况,不能直接得出结果。此外,使用 *Poly.all_coeffs()* 返回的系数列表在 Python 中和 Mathematica 中的含义也不一样。因此在 a() 的定义中需要用到 try-except 语句来处理这种情况。

下面的代码可以正常运行,并且对于一些测试值,输出结果和 Mathematica 7 中的公式给出的答案是一致的:

from __future__ import division
from sympy import expand, Poly, binomial, apart
from sympy.abc import x

A = Poly(apart(expand(((1-x**20)**5)) / expand((((1-x)**2)*(1-x**2)*(1-x**5)*(1-x**10))))).all_coeffs()

def a(n):
    try:
        return A[n]
    except IndexError:
        return 0

def f(n):
    v = n // 5
    q = v // 20
    r = v % 20
    return sum(a[r+20*j]* binomial(q+5-j, 5) for j in range(5))

print map(f, [100, 50, 1000, 150])
7

这个内容不能直接转到Python,因为a[j]使用了Mathematica的符号运算功能。

a[j]其实就是在那个有理函数的级数展开中,xj的系数。

假设你已经有了a[j],那么f[n]就很简单了。在Mathematica中,Block的作用是为变量创建一个作用域。第一个列表是用来初始化变量的,后面的部分就是执行代码。所以

from __future__ import division
def f(n):
  v = n // 5
  q = v // 20
  r = v % 20
  return sum(binomial(q+5-j, 5) * a[r+20*j] for j in range(5))

(binomial二项式系数。)

撰写回答